From df637cd59871dee74decd3d851e99a525ab6ed88 Mon Sep 17 00:00:00 2001 From: Daniel Naylor Date: Mon, 10 Sep 2018 18:12:01 +0100 Subject: [PATCH] Ensure the reset packet is not sent when Forge isn't expecting it. Fixes #69 --- .../connection/backend/LoginSessionHandler.java | 6 ++++++ .../client/ClientPlaySessionHandler.java | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java index 1a7f5e2df..c65f1745e 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java @@ -82,6 +82,12 @@ public class LoginSessionHandler implements MinecraftSessionHandler { if (existingConnection == null) { // Strap on the play session handler connection.getPlayer().getConnection().setSessionHandler(new ClientPlaySessionHandler(server, connection.getPlayer())); + + // This is for legacy Forge servers - during first connection the FML handshake will transition to complete regardless + // Thus, we need to ensure that a reset packet is ALWAYS sent on first switch. + // + // The call will handle if the player is not a Forge player appropriately. + connection.getPlayer().getConnection().setCanSendLegacyFMLResetPacket(true); } else { // The previous server connection should become obsolete. // Before we remove it, if the server we are departing is modded, we must always reset the client state. 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 8bc86848b..b7cb0f91e 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 @@ -214,7 +214,20 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { player.getConnection().flush(); player.getConnectedServer().getMinecraftConnection().flush(); player.getConnectedServer().setHasCompletedJoin(true); - player.getConnection().setCanSendLegacyFMLResetPacket(true); + if (player.getConnectedServer().isLegacyForge()) { + // We only need to indicate we can send a reset packet if we complete a handshake, that is, + // logged onto a Forge server. + // + // The special case is if we log onto a Vanilla server as our first server, FML will treat this + // as complete and **will** need a reset packet sending at some point. We will handle this + // during initial player connection if the player is detected to be forge. + // + // This is why we use an if statement rather than the result of VelocityServerConnection#isLegacyForge() + // because we don't want to set it false if this is a first connection to a Vanilla server. + // + // See LoginSessionHandler#handle for where the counterpart to this method is + player.getConnection().setCanSendLegacyFMLResetPacket(true); + } } public List getServerBossBars() {