From 6a2b945ed655c611ce995fbd0237e3661954352a Mon Sep 17 00:00:00 2001 From: Leymooo Date: Sun, 12 Aug 2018 02:38:37 +0300 Subject: [PATCH] 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 --- .gitignore | 9 +- .../com/velocitypowered/api/proxy/Player.java | 2 +- .../backend/BackendPlaySessionHandler.java | 11 -- .../client/ClientPlaySessionHandler.java | 104 ------------------ .../proxy/protocol/StateRegistry.java | 70 ++++++------ .../proxy/protocol/PacketRegistryTest.java | 6 +- 6 files changed, 51 insertions(+), 151 deletions(-) diff --git a/.gitignore b/.gitignore index cd03f954a..dc127090a 100644 --- a/.gitignore +++ b/.gitignore @@ -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 \ No newline at end of file +server-icon.png +/bin/ \ No newline at end of file diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index 89e4df3a6..1e41576a6 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -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 getCurrentServer(); - + /** * Sends a chat message to the player's client. * @param component the chat message to send diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java index b8975a0b3..b0784b179 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java @@ -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); } } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java index 06579a162..c1451ef9e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java @@ -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 serverBossBars = new ArrayList<>(); private final Set 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 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 getClientPluginMsgChannels() { return clientPluginMsgChannels; } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java index dc534f058..1ee67f806 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java @@ -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

void register(Class

clazz, Supplier

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) { diff --git a/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java b/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java index 187679f6c..b4541786a 100644 --- a/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java +++ b/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java @@ -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());