Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-06 00:00:47 +01:00
Do not handle scoreboards from backend
Changes in StateRegistry will allow to us skip packets decode which we don't want handle in BackendPlaySessionHandler for a specific versions Also do not handle respawn packet
Dieser Commit ist enthalten in:
Ursprung
21e72556c9
Commit
6a2b945ed6
9
.gitignore
vendored
9
.gitignore
vendored
@ -85,6 +85,12 @@ modules.xml
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Eclipse #
|
||||
**/.classpath
|
||||
**/.project
|
||||
**/.settings/
|
||||
**/bin/
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
@ -122,4 +128,5 @@ gradle-app.setting
|
||||
# Other trash
|
||||
logs/
|
||||
/velocity.toml
|
||||
server-icon.png
|
||||
server-icon.png
|
||||
/bin/
|
@ -30,7 +30,7 @@ public interface Player extends CommandInvoker, InboundConnection {
|
||||
* @return an {@link Optional} the server that the player is connected to, which may be empty
|
||||
*/
|
||||
Optional<ServerInfo> getCurrentServer();
|
||||
|
||||
|
||||
/**
|
||||
* Sends a chat message to the player's client.
|
||||
* @param component the chat message to send
|
||||
|
@ -7,7 +7,6 @@ import com.velocitypowered.proxy.protocol.packet.*;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
private final ServerConnection connection;
|
||||
@ -35,10 +34,6 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
connection.getProxyPlayer().handleConnectionException(connection.getServerInfo(), original);
|
||||
} else if (packet instanceof JoinGame) {
|
||||
playerHandler.handleBackendJoinGame((JoinGame) packet);
|
||||
} else if (packet instanceof Respawn) {
|
||||
// Record the dimension switch, and then forward the packet on.
|
||||
playerHandler.setCurrentDimension(((Respawn) packet).getDimension());
|
||||
connection.getProxyPlayer().getConnection().write(packet);
|
||||
} else if (packet instanceof BossBar) {
|
||||
BossBar bossBar = (BossBar) packet;
|
||||
switch (bossBar.getAction()) {
|
||||
@ -64,12 +59,6 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
connection.getProxyPlayer().getConnection().write(pm);
|
||||
} else {
|
||||
// Just forward the packet on. We don't have anything to handle at this time.
|
||||
if (packet instanceof ScoreboardTeam ||
|
||||
packet instanceof ScoreboardObjective ||
|
||||
packet instanceof ScoreboardSetScore ||
|
||||
packet instanceof ScoreboardDisplay) {
|
||||
playerHandler.handleServerScoreboardPacket(packet);
|
||||
}
|
||||
connection.getProxyPlayer().getConnection().write(packet);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,6 @@
|
||||
package com.velocitypowered.proxy.connection.client;
|
||||
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.command.VelocityCommand;
|
||||
import com.velocitypowered.api.server.ServerInfo;
|
||||
import com.velocitypowered.proxy.data.scoreboard.Objective;
|
||||
import com.velocitypowered.proxy.data.scoreboard.Score;
|
||||
import com.velocitypowered.proxy.data.scoreboard.Scoreboard;
|
||||
import com.velocitypowered.proxy.data.scoreboard.Team;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||
import com.velocitypowered.proxy.protocol.packet.*;
|
||||
@ -21,7 +15,6 @@ import net.kyori.text.format.TextColor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
@ -37,8 +30,6 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
private boolean spawned = false;
|
||||
private final List<UUID> serverBossBars = new ArrayList<>();
|
||||
private final Set<String> clientPluginMsgChannels = new HashSet<>();
|
||||
private int currentDimension;
|
||||
private Scoreboard serverScoreboard = new Scoreboard();
|
||||
private EntityIdRemapper idRemapper;
|
||||
|
||||
public ClientPlaySessionHandler(ConnectedPlayer player) {
|
||||
@ -161,7 +152,6 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
if (!spawned) {
|
||||
// nothing special to do here
|
||||
spawned = true;
|
||||
currentDimension = joinGame.getDimension();
|
||||
player.getConnection().delayedWrite(joinGame);
|
||||
idRemapper = EntityIdRemapper.getMapper(joinGame.getEntityId(), player.getConnection().getProtocolVersion());
|
||||
} else {
|
||||
@ -182,13 +172,6 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
int tempDim = joinGame.getDimension() == 0 ? -1 : 0;
|
||||
player.getConnection().delayedWrite(new Respawn(tempDim, joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType()));
|
||||
player.getConnection().delayedWrite(new Respawn(joinGame.getDimension(), joinGame.getDifficulty(), joinGame.getGamemode(), joinGame.getLevelType()));
|
||||
currentDimension = joinGame.getDimension();
|
||||
}
|
||||
|
||||
// Resend client settings packet to remote server if we have it, this preserves client settings across
|
||||
// transitions.
|
||||
if (player.getClientSettings() != null) {
|
||||
player.getConnectedServer().getMinecraftConnection().delayedWrite(player.getClientSettings());
|
||||
}
|
||||
|
||||
// Remove old boss bars.
|
||||
@ -200,9 +183,6 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
}
|
||||
serverBossBars.clear();
|
||||
|
||||
// Remove scoreboard junk.
|
||||
clearServerScoreboard();
|
||||
|
||||
// Tell the server about this client's plugin messages. Velocity will forward them on to the client.
|
||||
if (!clientPluginMsgChannels.isEmpty()) {
|
||||
String channel = player.getConnection().getProtocolVersion() >= ProtocolConstants.MINECRAFT_1_13 ?
|
||||
@ -216,10 +196,6 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
player.getConnectedServer().getMinecraftConnection().flush();
|
||||
}
|
||||
|
||||
public void setCurrentDimension(int currentDimension) {
|
||||
this.currentDimension = currentDimension;
|
||||
}
|
||||
|
||||
public List<UUID> getServerBossBars() {
|
||||
return serverBossBars;
|
||||
}
|
||||
@ -261,86 +237,6 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
player.getConnectedServer().getMinecraftConnection().write(packet);
|
||||
}
|
||||
|
||||
public void handleServerScoreboardPacket(MinecraftPacket packet) {
|
||||
if (packet instanceof ScoreboardDisplay) {
|
||||
ScoreboardDisplay sd = (ScoreboardDisplay) packet;
|
||||
serverScoreboard.setPosition(sd.getPosition());
|
||||
serverScoreboard.setDisplayName(sd.getDisplayName());
|
||||
}
|
||||
|
||||
if (packet instanceof ScoreboardObjective) {
|
||||
ScoreboardObjective so = (ScoreboardObjective) packet;
|
||||
switch (so.getMode()) {
|
||||
case ScoreboardObjective.ADD:
|
||||
Objective o = new Objective(so.getId());
|
||||
o.setDisplayName(so.getDisplayName());
|
||||
o.setType(so.getType());
|
||||
serverScoreboard.getObjectives().put(so.getId(), o);
|
||||
break;
|
||||
case ScoreboardObjective.REMOVE:
|
||||
serverScoreboard.getObjectives().remove(so.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet instanceof ScoreboardSetScore) {
|
||||
ScoreboardSetScore sss = (ScoreboardSetScore) packet;
|
||||
Objective objective = serverScoreboard.getObjectives().get(sss.getObjective());
|
||||
if (objective == null) {
|
||||
return;
|
||||
}
|
||||
switch (sss.getAction()) {
|
||||
case ScoreboardSetScore.CHANGE:
|
||||
Score score = new Score(sss.getEntity(), sss.getValue());
|
||||
objective.getScores().put(sss.getEntity(), score);
|
||||
break;
|
||||
case ScoreboardSetScore.REMOVE:
|
||||
objective.getScores().remove(sss.getEntity());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet instanceof ScoreboardTeam) {
|
||||
ScoreboardTeam st = (ScoreboardTeam) packet;
|
||||
switch (st.getMode()) {
|
||||
case ScoreboardTeam.ADD:
|
||||
// TODO: Preserve other team information? We might not need to...
|
||||
Team team = new Team(st.getId());
|
||||
serverScoreboard.getTeams().put(st.getId(), team);
|
||||
break;
|
||||
case ScoreboardTeam.REMOVE:
|
||||
serverScoreboard.getTeams().remove(st.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearServerScoreboard() {
|
||||
for (Objective objective : serverScoreboard.getObjectives().values()) {
|
||||
for (Score score : objective.getScores().values()) {
|
||||
ScoreboardSetScore sss = new ScoreboardSetScore();
|
||||
sss.setObjective(objective.getId());
|
||||
sss.setAction(ScoreboardSetScore.REMOVE);
|
||||
sss.setEntity(score.getTarget());
|
||||
player.getConnection().delayedWrite(sss);
|
||||
}
|
||||
|
||||
ScoreboardObjective so = new ScoreboardObjective();
|
||||
so.setId(objective.getId());
|
||||
so.setMode(ScoreboardObjective.REMOVE);
|
||||
player.getConnection().delayedWrite(so);
|
||||
}
|
||||
|
||||
for (Team team : serverScoreboard.getTeams().values()) {
|
||||
ScoreboardTeam st = new ScoreboardTeam();
|
||||
st.setId(team.getId());
|
||||
st.setMode(ScoreboardTeam.REMOVE);
|
||||
player.getConnection().delayedWrite(st);
|
||||
}
|
||||
|
||||
serverScoreboard = new Scoreboard();
|
||||
}
|
||||
|
||||
public Set<String> getClientPluginMsgChannels() {
|
||||
return clientPluginMsgChannels;
|
||||
}
|
||||
|
@ -99,35 +99,35 @@ public enum StateRegistry {
|
||||
map(0x23, MINECRAFT_1_12),
|
||||
map(0x25, MINECRAFT_1_13));
|
||||
CLIENTBOUND.register(Respawn.class, Respawn::new,
|
||||
map(0x07, MINECRAFT_1_8),
|
||||
map(0x33, MINECRAFT_1_9),
|
||||
map(0x34, MINECRAFT_1_12),
|
||||
map(0x35, MINECRAFT_1_12_2),
|
||||
map(0x38, MINECRAFT_1_13));
|
||||
map(0x07, MINECRAFT_1_8, false),
|
||||
map(0x33, MINECRAFT_1_9, false),
|
||||
map(0x34, MINECRAFT_1_12, false),
|
||||
map(0x35, MINECRAFT_1_12_2, false),
|
||||
map(0x38, MINECRAFT_1_13, false));
|
||||
CLIENTBOUND.register(ScoreboardDisplay.class, ScoreboardDisplay::new,
|
||||
map(0x3D, MINECRAFT_1_8),
|
||||
map(0x38, MINECRAFT_1_9),
|
||||
map(0x3A, MINECRAFT_1_12),
|
||||
map(0x3B, MINECRAFT_1_12_1),
|
||||
map(0x3E, MINECRAFT_1_13));
|
||||
map(0x3D, MINECRAFT_1_8, false),
|
||||
map(0x38, MINECRAFT_1_9, false),
|
||||
map(0x3A, MINECRAFT_1_12, false),
|
||||
map(0x3B, MINECRAFT_1_12_1, false),
|
||||
map(0x3E, MINECRAFT_1_13, false));
|
||||
CLIENTBOUND.register(ScoreboardObjective.class, ScoreboardObjective::new,
|
||||
map(0x3B, MINECRAFT_1_8),
|
||||
map(0x3F, MINECRAFT_1_9),
|
||||
map(0x41, MINECRAFT_1_12),
|
||||
map(0x42, MINECRAFT_1_12_1),
|
||||
map(0x45, MINECRAFT_1_13));
|
||||
map(0x3B, MINECRAFT_1_8, false),
|
||||
map(0x3F, MINECRAFT_1_9, false),
|
||||
map(0x41, MINECRAFT_1_12, false),
|
||||
map(0x42, MINECRAFT_1_12_1, false),
|
||||
map(0x45, MINECRAFT_1_13, false));
|
||||
CLIENTBOUND.register(ScoreboardTeam.class, ScoreboardTeam::new,
|
||||
map(0x3E, MINECRAFT_1_8),
|
||||
map(0x41, MINECRAFT_1_9),
|
||||
map(0x43, MINECRAFT_1_12),
|
||||
map(0x44, MINECRAFT_1_12_1),
|
||||
map(0x47, MINECRAFT_1_13));
|
||||
map(0x3E, MINECRAFT_1_8, false),
|
||||
map(0x41, MINECRAFT_1_9, false),
|
||||
map(0x43, MINECRAFT_1_12, false),
|
||||
map(0x44, MINECRAFT_1_12_1, false),
|
||||
map(0x47, MINECRAFT_1_13, false));
|
||||
CLIENTBOUND.register(ScoreboardSetScore.class, ScoreboardSetScore::new,
|
||||
map(0x3C, MINECRAFT_1_8),
|
||||
map(0x42, MINECRAFT_1_9),
|
||||
map(0x44, MINECRAFT_1_12),
|
||||
map(0x45, MINECRAFT_1_12_1),
|
||||
map(0x48, MINECRAFT_1_13));
|
||||
map(0x3C, MINECRAFT_1_8, false),
|
||||
map(0x42, MINECRAFT_1_9, false),
|
||||
map(0x44, MINECRAFT_1_12, false),
|
||||
map(0x45, MINECRAFT_1_12_1, false),
|
||||
map(0x48, MINECRAFT_1_13, false));
|
||||
}
|
||||
},
|
||||
LOGIN {
|
||||
@ -188,6 +188,7 @@ public enum StateRegistry {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public <P extends MinecraftPacket> void register(Class<P> clazz, Supplier<P> packetSupplier, PacketMapping... mappings) {
|
||||
if (mappings.length == 0) {
|
||||
throw new IllegalArgumentException("At least one mapping must be provided.");
|
||||
@ -198,8 +199,9 @@ public enum StateRegistry {
|
||||
if (version == null) {
|
||||
throw new IllegalArgumentException("Unknown protocol version " + mapping.protocolVersion);
|
||||
}
|
||||
|
||||
version.packetIdToSupplier.put(mapping.id, packetSupplier);
|
||||
if (mapping.needPacketDecode) {
|
||||
version.packetIdToSupplier.put(mapping.id, packetSupplier);
|
||||
}
|
||||
version.packetClassToId.put(clazz, mapping.id);
|
||||
|
||||
ImmutableIntArray linked = LINKED_PROTOCOL_VERSIONS.get(mapping.protocolVersion);
|
||||
@ -210,7 +212,7 @@ public enum StateRegistry {
|
||||
for (PacketMapping m : mappings) {
|
||||
if (linkedVersion == m.protocolVersion) continue links;
|
||||
}
|
||||
register(clazz, packetSupplier, map(mapping.id, linkedVersion));
|
||||
register(clazz, packetSupplier, map(mapping.id, linkedVersion, mapping.needPacketDecode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,10 +260,12 @@ public enum StateRegistry {
|
||||
public static class PacketMapping {
|
||||
private final int id;
|
||||
private final int protocolVersion;
|
||||
|
||||
public PacketMapping(int id, int protocolVersion) {
|
||||
private final boolean needPacketDecode;
|
||||
|
||||
public PacketMapping(int id, int protocolVersion, boolean needPacketDecode) {
|
||||
this.id = id;
|
||||
this.protocolVersion = protocolVersion;
|
||||
this.needPacketDecode = needPacketDecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -287,8 +291,12 @@ public enum StateRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
private static PacketMapping map(int id, int version, boolean handleFromBackend) {
|
||||
return new PacketMapping(id, version, handleFromBackend);
|
||||
}
|
||||
|
||||
private static PacketMapping map(int id, int version) {
|
||||
return new PacketMapping(id, version);
|
||||
return map(id, version, true);
|
||||
}
|
||||
|
||||
private static PacketMapping[] genericMappings(int id) {
|
||||
|
@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
class PacketRegistryTest {
|
||||
private StateRegistry.PacketRegistry setupRegistry() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(ProtocolConstants.Direction.CLIENTBOUND, StateRegistry.HANDSHAKE);
|
||||
registry.register(Handshake.class, Handshake::new, new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12));
|
||||
registry.register(Handshake.class, Handshake::new, new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, true));
|
||||
return registry;
|
||||
}
|
||||
|
||||
@ -44,8 +44,8 @@ class PacketRegistryTest {
|
||||
@Test
|
||||
void registrySuppliesCorrectPacketsByProtocol() {
|
||||
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(ProtocolConstants.Direction.CLIENTBOUND, StateRegistry.HANDSHAKE);
|
||||
registry.register(Handshake.class, Handshake::new, new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12_1));
|
||||
registry.register(Handshake.class, Handshake::new, new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, true),
|
||||
new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12_1, true));
|
||||
assertEquals(Handshake.class, registry.getVersion(MINECRAFT_1_12).createPacket(0x00).getClass());
|
||||
assertEquals(Handshake.class, registry.getVersion(MINECRAFT_1_12_1).createPacket(0x01).getClass());
|
||||
assertEquals(Handshake.class, registry.getVersion(MINECRAFT_1_12_2).createPacket(0x01).getClass());
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren