From cc1d8f8184d5bdb739a9cfd06813dd2eeecc2bb5 Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Mon, 30 Jul 2018 21:27:34 -0400 Subject: [PATCH] Initial Minecraft 1.9.x support --- .../client/ClientPlaySessionHandler.java | 22 +++++- .../proxy/protocol/ProtocolConstants.java | 12 +++- .../proxy/protocol/StateRegistry.java | 68 +++++++++++-------- .../proxy/protocol/packets/PluginMessage.java | 2 - 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java index 125ac5dd0..9bb1ca75b 100644 --- a/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java +++ b/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java @@ -110,6 +110,10 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { pingTask.cancel(false); pingTask = null; } + + if (brandMessage != null) { + brandMessage.getData().release(); + } } @Override @@ -169,6 +173,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { // Tell the server the client's brand if (brandMessage != null) { + brandMessage.getData().retain(); player.getConnectedServer().getChannel().delayedWrite(brandMessage); } @@ -218,12 +223,23 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { } if (packet.getChannel().equals("MC|Brand")) { - // Rewrite this packet to indicate that Velocity is running. Hurrah! - packet = PluginMessageUtil.rewriteMCBrand(packet); - this.brandMessage = packet; + if (this.brandMessage != null) { + // Rewrite this packet to indicate that Velocity is running. Hurrah! + packet = PluginMessageUtil.rewriteMCBrand(packet); + this.brandMessage = packet; + } else { + // Already have the brand packet and don't need this one. + return; + } } // No other special handling? + if (packet == original) { + // we'll decrement this thrice: once when writing to the server, once just below this block, + // and once in the MinecraftConnection (since this is a slice) + packet.getData().retain(); + } + player.getConnectedServer().getChannel().write(packet); } finally { ReferenceCountUtil.release(original.getData()); diff --git a/src/main/java/com/velocitypowered/proxy/protocol/ProtocolConstants.java b/src/main/java/com/velocitypowered/proxy/protocol/ProtocolConstants.java index e2de9cc28..a2007c1ff 100644 --- a/src/main/java/com/velocitypowered/proxy/protocol/ProtocolConstants.java +++ b/src/main/java/com/velocitypowered/proxy/protocol/ProtocolConstants.java @@ -4,6 +4,10 @@ import java.util.Arrays; public enum ProtocolConstants { ; public static final int MINECRAFT_1_7_2 = 4; + public static final int MINECRAFT_1_9 = 107; + public static final int MINECRAFT_1_9_1 = 108; + public static final int MINECRAFT_1_9_2 = 109; + public static final int MINECRAFT_1_9_4 = 110; public static final int MINECRAFT_1_10 = 210; public static final int MINECRAFT_1_11 = 315; public static final int MINECRAFT_1_11_1 = 316; @@ -11,10 +15,14 @@ public enum ProtocolConstants { ; public static final int MINECRAFT_1_12_1 = 338; public static final int MINECRAFT_1_12_2 = 340; - public static final int MINIMUM_VERSION_SUPPORTED = MINECRAFT_1_10; - public static final int MINIMUM_GENERIC_VERSION = MINECRAFT_1_10; + public static final int MINIMUM_VERSION_SUPPORTED = MINECRAFT_1_9; + public static final int MINIMUM_GENERIC_VERSION = MINECRAFT_1_9; public static final int[] SUPPORTED_VERSIONS = new int[] { + MINECRAFT_1_9, + MINECRAFT_1_9_1, + MINECRAFT_1_9_2, + MINECRAFT_1_9_4, MINECRAFT_1_10, MINECRAFT_1_11, MINECRAFT_1_11_1, diff --git a/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java index 899057807..e6fcc74e2 100644 --- a/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java +++ b/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java @@ -13,71 +13,77 @@ public enum StateRegistry { HANDSHAKE { { SERVERBOUND.register(Handshake.class, Handshake::new, - genericMapping(0x00)); + genericMappings(0x00)); } }, STATUS { { SERVERBOUND.register(StatusRequest.class, StatusRequest::new, - genericMapping(0x00)); + genericMappings(0x00)); SERVERBOUND.register(StatusPing.class, StatusPing::new, - genericMapping(0x01)); + genericMappings(0x01)); CLIENTBOUND.register(StatusResponse.class, StatusResponse::new, - genericMapping(0x00)); + genericMappings(0x00)); CLIENTBOUND.register(StatusPing.class, StatusPing::new, - genericMapping(0x01)); + genericMappings(0x01)); } }, PLAY { { SERVERBOUND.register(Chat.class, Chat::new, - map(0x02, MINECRAFT_1_10), + map(0x02, MINECRAFT_1_9), map(0x03, MINECRAFT_1_12), map(0x02, MINECRAFT_1_12_2)); SERVERBOUND.register(ClientSettings.class, ClientSettings::new, - map(0x04, MINECRAFT_1_10), + map(0x04, MINECRAFT_1_9), map(0x05, MINECRAFT_1_12), map(0x04, MINECRAFT_1_12_1)); SERVERBOUND.register(PluginMessage.class, PluginMessage::new, - map(0x09, MINECRAFT_1_10), + map(0x09, MINECRAFT_1_9), map(0x0A, MINECRAFT_1_12), map(0x09, MINECRAFT_1_12_1)); SERVERBOUND.register(KeepAlive.class, KeepAlive::new, - map(0x0B, MINECRAFT_1_10), + map(0x0B, MINECRAFT_1_9), map(0x0C, MINECRAFT_1_12), map(0x0B, MINECRAFT_1_12_1)); CLIENTBOUND.register(BossBar.class, BossBar::new, - map(0x0C, MINECRAFT_1_10)); + map(0x0C, MINECRAFT_1_9), + map(0x0C, MINECRAFT_1_12)); CLIENTBOUND.register(Chat.class, Chat::new, - map(0x0F, MINECRAFT_1_10)); + map(0x0F, MINECRAFT_1_9), + map(0x0F, MINECRAFT_1_12)); CLIENTBOUND.register(PluginMessage.class, PluginMessage::new, - map(0x18, MINECRAFT_1_10)); + map(0x18, MINECRAFT_1_9), + map(0x18, MINECRAFT_1_12)); CLIENTBOUND.register(Disconnect.class, Disconnect::new, - map(0x1A, MINECRAFT_1_10)); + map(0x1A, MINECRAFT_1_9), + map(0x1A, MINECRAFT_1_12)); CLIENTBOUND.register(KeepAlive.class, KeepAlive::new, - map(0x1F, MINECRAFT_1_10)); + map(0x1F, MINECRAFT_1_9), + map(0x1F, MINECRAFT_1_12)); CLIENTBOUND.register(JoinGame.class, JoinGame::new, - map(0x23, MINECRAFT_1_10)); + map(0x23, MINECRAFT_1_9), + map(0x23, MINECRAFT_1_12)); CLIENTBOUND.register(Respawn.class, Respawn::new, - map(0x33, MINECRAFT_1_10), + map(0x33, MINECRAFT_1_9), map(0x34, MINECRAFT_1_12), map(0x35, MINECRAFT_1_12_2)); CLIENTBOUND.register(ScoreboardDisplay.class, ScoreboardDisplay::new, - map(0x38, MINECRAFT_1_10), + map(0x38, MINECRAFT_1_9), map(0x3A, MINECRAFT_1_12), map(0x3B, MINECRAFT_1_12_1)); CLIENTBOUND.register(ScoreboardObjective.class, ScoreboardObjective::new, - map(0x3F, MINECRAFT_1_10), + map(0x3F, MINECRAFT_1_9), map(0x41, MINECRAFT_1_12), map(0x42, MINECRAFT_1_12_1)); CLIENTBOUND.register(ScoreboardTeam.class, ScoreboardTeam::new, - map(0x41, MINECRAFT_1_10), + map(0x41, MINECRAFT_1_9), map(0x43, MINECRAFT_1_12), map(0x44, MINECRAFT_1_12_1)); CLIENTBOUND.register(ScoreboardSetScore.class, ScoreboardSetScore::new, - map(0x42, MINECRAFT_1_10), + map(0x42, MINECRAFT_1_9), map(0x44, MINECRAFT_1_12), map(0x45, MINECRAFT_1_12_1)); } @@ -85,18 +91,18 @@ public enum StateRegistry { LOGIN { { SERVERBOUND.register(ServerLogin.class, ServerLogin::new, - genericMapping(0x00)); + genericMappings(0x00)); SERVERBOUND.register(EncryptionResponse.class, EncryptionResponse::new, - genericMapping(0x01)); + genericMappings(0x01)); CLIENTBOUND.register(Disconnect.class, Disconnect::new, - genericMapping(0x00)); + genericMappings(0x00)); CLIENTBOUND.register(EncryptionRequest.class, EncryptionRequest::new, - genericMapping(0x01)); + genericMappings(0x01)); CLIENTBOUND.register(ServerLoginSuccess.class, ServerLoginSuccess::new, - genericMapping(0x02)); + genericMappings(0x02)); CLIENTBOUND.register(SetCompression.class, SetCompression::new, - genericMapping(0x03)); + genericMappings(0x03)); } }; @@ -107,7 +113,8 @@ public enum StateRegistry { private static final IntObjectMap LINKED_PROTOCOL_VERSIONS = new IntObjectHashMap<>(); static { - LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_10, new int[] { MINECRAFT_1_11, MINECRAFT_1_11_1, MINECRAFT_1_12 }); + LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_9, new int[] { MINECRAFT_1_9_1, MINECRAFT_1_9_2, MINECRAFT_1_9_4 }); + LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_9_4, new int[] { MINECRAFT_1_10, MINECRAFT_1_11, MINECRAFT_1_11_1 }); LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_12, new int[] { MINECRAFT_1_12_1 }); LINKED_PROTOCOL_VERSIONS.put(MINECRAFT_1_12_1, new int[] { MINECRAFT_1_12_2 }); } @@ -232,7 +239,10 @@ public enum StateRegistry { return new PacketMapping(id, version); } - private static PacketMapping genericMapping(int id) { - return new PacketMapping(id, MINIMUM_GENERIC_VERSION); + private static PacketMapping[] genericMappings(int id) { + return new PacketMapping[]{ + map(id, MINECRAFT_1_9), + map(id, MINECRAFT_1_12) + }; } } diff --git a/src/main/java/com/velocitypowered/proxy/protocol/packets/PluginMessage.java b/src/main/java/com/velocitypowered/proxy/protocol/packets/PluginMessage.java index 6c62a1a2e..75db3b531 100644 --- a/src/main/java/com/velocitypowered/proxy/protocol/packets/PluginMessage.java +++ b/src/main/java/com/velocitypowered/proxy/protocol/packets/PluginMessage.java @@ -6,8 +6,6 @@ import com.velocitypowered.proxy.protocol.ProtocolUtils; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; -import java.util.Arrays; - public class PluginMessage implements MinecraftPacket { private String channel; private ByteBuf data;