diff --git a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java index b166291b40..7f6912a697 100644 --- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java +++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java @@ -95,7 +95,8 @@ public boolean isSupported() { MINECRAFT_1_21_7(772, "1.21.7", "1.21.8"), MINECRAFT_1_21_9(773, "1.21.9", "1.21.10"), MINECRAFT_1_21_11(774, "1.21.11"), - MINECRAFT_26_1(775, "26.1", "26.1.1", "26.1.2"); + MINECRAFT_26_1(775, "26.1", "26.1.1", "26.1.2"), + MINECRAFT_26_2(776, "26.2"); private static final int SNAPSHOT_BIT = 30; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/TransitionSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/TransitionSessionHandler.java index cfcd8f5e00..da8513c00e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/TransitionSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/TransitionSessionHandler.java @@ -89,7 +89,7 @@ public boolean handle(KeepAlivePacket packet) { @Override public boolean handle(JoinGamePacket packet) { - MinecraftConnection smc = serverConn.ensureConnected(); + final MinecraftConnection smc = serverConn.ensureConnected(); final RegisteredServer previousServer = serverConn.getPreviousServer().orElse(null); final ConnectedPlayer player = serverConn.getPlayer(); final VelocityServerConnection existingConnection = player.getConnectedServer(); @@ -106,6 +106,9 @@ public boolean handle(JoinGamePacket packet) { // Reset Tablist header and footer to prevent desync player.clearPlayerListHeaderAndFooter(); + // Override online mode + packet.setOnlineMode(player.isOnlineMode()); + // The goods are in hand! We got JoinGame. Let's transition completely to the new state. smc.setAutoReading(false); server.getEventManager() diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java index 605388ea30..4d05da9ead 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/AuthSessionHandler.java @@ -236,6 +236,9 @@ private void completeLoginProtocolPhaseAndInitialize(ConnectedPlayer player) { success.setUsername(player.getUsername()); success.setProperties(player.getGameProfileProperties()); success.setUuid(player.getUniqueId()); + if (inbound.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_26_2)) { + success.setSessionId(UUID.randomUUID()); // use random uuid for now + } mcConnection.write(success); loginState = State.SUCCESS_SENT; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java index 787d858ebf..645dc7b687 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/JoinGamePacket.java @@ -52,6 +52,7 @@ public class JoinGamePacket implements MinecraftPacket { private @Nullable Pair lastDeathPosition; // 1.19+ private int portalCooldown; // 1.20+ private int seaLevel; // 1.21.2+ + private boolean onlineMode; // 26.2+ private boolean enforcesSecureChat; // 1.20.5+ public int getEntityId() { @@ -190,6 +191,10 @@ public void setSeaLevel(int seaLevel) { this.seaLevel = seaLevel; } + public void setOnlineMode(boolean onlineMode) { + this.onlineMode = onlineMode; + } + public boolean getEnforcesSecureChat() { return this.enforcesSecureChat; } @@ -213,7 +218,7 @@ public String toString() { dimensionInfo + '\'' + ", currentDimensionData='" + currentDimensionData + '\'' + ", previousGamemode=" + previousGamemode + ", simulationDistance=" + simulationDistance + ", lastDeathPosition='" + lastDeathPosition + '\'' + ", portalCooldown=" + portalCooldown + - ", seaLevel=" + seaLevel + + ", seaLevel=" + seaLevel + ", onlineMode=" + this.onlineMode + '}'; } @@ -358,6 +363,10 @@ private void decode1202Up(ByteBuf buf, ProtocolVersion version) { this.seaLevel = ProtocolUtils.readVarInt(buf); } + if (version.noLessThan(ProtocolVersion.MINECRAFT_26_2)) { + this.onlineMode = buf.readBoolean(); + } + if (version.noLessThan(ProtocolVersion.MINECRAFT_1_20_5)) { this.enforcesSecureChat = buf.readBoolean(); } @@ -510,6 +519,10 @@ private void encode1202Up(ByteBuf buf, ProtocolVersion version) { ProtocolUtils.writeVarInt(buf, seaLevel); } + if (version.noLessThan(ProtocolVersion.MINECRAFT_26_2)) { + buf.writeBoolean(this.onlineMode); + } + if (version.noLessThan(ProtocolVersion.MINECRAFT_1_20_5)) { buf.writeBoolean(this.enforcesSecureChat); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java index 322cd9b195..4b8e722a5b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ServerLoginSuccessPacket.java @@ -35,6 +35,7 @@ public class ServerLoginSuccessPacket implements MinecraftPacket { private @Nullable UUID uuid; private @Nullable String username; private @Nullable List properties; + private @Nullable UUID sessionId; private static final boolean strictErrorHandling = VelocityProperties .readBoolean("velocity.strictErrorHandling", true); @@ -68,6 +69,10 @@ public void setProperties(List properties) { this.properties = properties; } + public void setSessionId(@Nullable UUID sessionId) { + this.sessionId = sessionId; + } + @Override public String toString() { return "ServerLoginSuccess{" @@ -96,6 +101,10 @@ public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi if (version == ProtocolVersion.MINECRAFT_1_20_5 || version == ProtocolVersion.MINECRAFT_1_21) { buf.readBoolean(); } + + if (version.noLessThan(ProtocolVersion.MINECRAFT_26_2)) { + this.sessionId = ProtocolUtils.readUuid(buf); + } } @Override @@ -127,6 +136,10 @@ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersi if (version == ProtocolVersion.MINECRAFT_1_20_5 || version == ProtocolVersion.MINECRAFT_1_21) { buf.writeBoolean(strictErrorHandling); } + + if (version.noLessThan(ProtocolVersion.MINECRAFT_26_2)) { + ProtocolUtils.writeUuid(buf, this.sessionId); + } } @Override diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java index 203ab375cf..3c57cd753c 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/brigadier/ArgumentPropertyRegistry.java @@ -24,6 +24,7 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20_5; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21_5; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_21_6; +import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_26_2; import static com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentIdentifier.id; import static com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentIdentifier.mapSet; import static com.velocitypowered.proxy.protocol.packet.brigadier.DoubleArgumentPropertySerializer.DOUBLE; @@ -207,7 +208,7 @@ public void serialize(BoolArgumentType object, ByteBuf buf, empty(id("minecraft:block_predicate", mapSet(MINECRAFT_1_19, 13))); empty(id("minecraft:item_stack", mapSet(MINECRAFT_1_19, 14))); empty(id("minecraft:item_predicate", mapSet(MINECRAFT_1_19, 15))); - empty(id("minecraft:color", mapSet(MINECRAFT_1_19, 16))); + empty(id("minecraft:color", mapSet(MINECRAFT_26_2, -1), mapSet(MINECRAFT_1_19, 16))); // renamed to team_color in 26.2 empty(id("minecraft:component", mapSet(MINECRAFT_1_21_6, 18), mapSet(MINECRAFT_1_19, 17))); empty(id("minecraft:style", mapSet(MINECRAFT_1_21_6, 19), mapSet(MINECRAFT_1_20_3, 18))); // added 1.20.3 empty(id("minecraft:message", mapSet(MINECRAFT_1_21_6, 20), mapSet(MINECRAFT_1_20_3, 19), mapSet(MINECRAFT_1_19, 18))); @@ -281,6 +282,7 @@ public void serialize(BoolArgumentType object, ByteBuf buf, empty(id("minecraft:hex_color", mapSet(MINECRAFT_1_21_6, 17))); // added in 1.21.6 empty(id("minecraft:dialog", mapSet(MINECRAFT_1_21_6, 55))); // added in 1.21.6 + empty(id("minecraft:team_color", mapSet(MINECRAFT_26_2, 16))); // renamed from color in 26.2 // Crossstitch support register(id("crossstitch:mod_argument", mapSet(MINECRAFT_1_19, -256)), ModArgumentProperty.class, MOD);