From ce5420768d25b3acb0c4cf32bf103844287cae3b Mon Sep 17 00:00:00 2001 From: Adrian Bergqvist Date: Wed, 15 Feb 2023 20:25:15 +0100 Subject: [PATCH] Reorganized login process... ...in order to improve stability and maintainability. --- .../forge/FML2CRPMClientConnectionPhase.java | 20 +----- .../forge/FML2ClientConnectionPhase.java | 31 ++------- .../ambassador/forge/ForgeConstants.java | 1 + .../forge/ForgeFMLConnectionType.java | 2 +- .../velocity/VelocityEventHandler.java | 68 ++++++------------- .../VelocityForgeClientConnectionPhase.java | 32 +++------ .../VelocityForgeHandshakeSessionHandler.java | 17 +++-- .../VelocityHandshakeSessionHandler.java | 12 +++- .../backend/ForgeHandshakeSessionHandler.java | 18 ++--- .../VelocityForgeBackendConnectionPhase.java | 56 ++++++++++++--- .../client/OutboundSuccessHolder.java | 28 ++++++++ 11 files changed, 139 insertions(+), 146 deletions(-) create mode 100644 src/main/java/org/adde0109/ambassador/velocity/client/OutboundSuccessHolder.java diff --git a/src/main/java/org/adde0109/ambassador/forge/FML2CRPMClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/FML2CRPMClientConnectionPhase.java index 6ff7cfd..d5d49e7 100644 --- a/src/main/java/org/adde0109/ambassador/forge/FML2CRPMClientConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/forge/FML2CRPMClientConnectionPhase.java @@ -42,7 +42,7 @@ public class FML2CRPMClientConnectionPhase extends VelocityForgeClientConnection } MinecraftConnection connection = player.getConnection(); - connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),this)); + connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player)); ((VelocityServer) Ambassador.getInstance().server).unregisterConnection(player); this.clientPhase = null; @@ -63,25 +63,7 @@ public class FML2CRPMClientConnectionPhase extends VelocityForgeClientConnection connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket()))); return future; } - public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) { - VelocityConfiguration configuration = (VelocityConfiguration) server.getConfiguration(); - UUID playerUniqueId = player.getUniqueId(); - if (configuration.getPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE) { - playerUniqueId = UuidUtils.generateOfflinePlayerUuid(player.getUsername()); - } - ServerLoginSuccess success = new ServerLoginSuccess(); - success.setUsername(player.getUsername()); - success.setUuid(playerUniqueId); - connection.write(success); - this.clientPhase = this.clientPhase == ClientPhase.MODLIST ? ClientPhase.MODDED : ClientPhase.VANILLA; - - connection.setState(StateRegistry.PLAY); - connection.setSessionHandler(((VelocityForgeHandshakeSessionHandler) connection.getSessionHandler()).getOriginal()); - ((VelocityServer) Ambassador.getInstance().server).registerConnection(player); - - backupServer = null; - } public void handleKick(KickedFromServerEvent event) { if (backupServer != null && !(event.getResult() instanceof KickedFromServerEvent.RedirectPlayer)) { diff --git a/src/main/java/org/adde0109/ambassador/forge/FML2ClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/FML2ClientConnectionPhase.java index eaea17b..56da338 100644 --- a/src/main/java/org/adde0109/ambassador/forge/FML2ClientConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/forge/FML2ClientConnectionPhase.java @@ -8,21 +8,24 @@ import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; +import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; import io.netty.buffer.ByteBuf; import net.kyori.adventure.text.Component; import org.adde0109.ambassador.Ambassador; import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhase { private Throwable throwable; private RegisteredServer triedServer; - private Continuation continuation; + private CompletableFuture onServerSuccess; private CompletableFuture onJoinGame; private static final Method CONNECT_TO_INITIAL_SERVER; @@ -47,20 +50,9 @@ public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhas } @Override - public void handleLogin(ConnectedPlayer player, VelocityServer server, Continuation continuation) { - this.continuation = continuation; - final MinecraftConnection connection = player.getConnection(); - + public RegisteredServer chooseServer(ConnectedPlayer player) { forced = Ambassador.getTemporaryForced().remove(player.getUsername()); - if (forced != null) { - player.createConnectionRequest(forced).fireAndForget(); - } else { - try { - CONNECT_TO_INITIAL_SERVER.invoke(player.getConnection().getSessionHandler(),player); - } catch (ReflectiveOperationException e) { - continuation.resumeWithException(e); - } - } + return forced; } @Override @@ -77,17 +69,6 @@ public class FML2ClientConnectionPhase extends VelocityForgeClientConnectionPhas return future; } - @Override - public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) { - if (triedServer != null) - player.sendMessage(Component.translatable("velocity.error.connecting-server-error", - Component.text(triedServer.getServerInfo().getName()))); - clientPhase = clientPhase == ClientPhase.MODLIST ? ClientPhase.MODDED : ClientPhase.VANILLA; - internalServerConnection = player.getConnectionInFlight(); - player.resetInFlightConnection(); - this.onJoinGame = new CompletableFuture<>(); - continuation.resume(); - } public void handleJoinGame() { this.onJoinGame.complete(null); diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java b/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java index d80e411..c96553c 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java @@ -7,6 +7,7 @@ public class ForgeConstants { public static final String MARKER_ADDER = "FML2/3 Marker Adder"; public static final String OUTBOUND_CATCHER_NAME = "ambassador-catcher"; public static final String RESET_LISTENER = "ambassador-reset-listener"; + public static final String SERVER_SUCCESS_LISTENER = "ambassador-server-success-listener"; public static final String FML2Marker = "\0FML2\0"; public static final String FML3Marker = "\0FML3\0"; diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeFMLConnectionType.java b/src/main/java/org/adde0109/ambassador/forge/ForgeFMLConnectionType.java index ccf6d7d..a583d22 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeFMLConnectionType.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeFMLConnectionType.java @@ -24,7 +24,7 @@ public class ForgeFMLConnectionType implements ConnectionType { @Override public BackendConnectionPhase getInitialBackendPhase() { - return new VelocityForgeBackendConnectionPhase(); + return VelocityForgeBackendConnectionPhase.NOT_STARTED; } @Override diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java index fd9cfc4..d195321 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java @@ -3,19 +3,15 @@ package org.adde0109.ambassador.velocity; import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.LoginEvent; import com.velocitypowered.api.event.connection.PostLoginEvent; -import com.velocitypowered.api.event.permission.PermissionsSetupEvent; import com.velocitypowered.api.event.player.*; -import com.velocitypowered.proxy.VelocityServer; +import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; -import com.velocitypowered.proxy.protocol.packet.ClientSettings; +import com.velocitypowered.proxy.protocol.StateRegistry; import org.adde0109.ambassador.Ambassador; import org.adde0109.ambassador.forge.FML2CRPMClientConnectionPhase; -import org.adde0109.ambassador.forge.FML2ClientConnectionPhase; -import org.adde0109.ambassador.forge.ForgeConstants; -import org.adde0109.ambassador.forge.ForgeFMLConnectionType; -import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendConnectionPhase; public class VelocityEventHandler { @@ -26,16 +22,22 @@ public class VelocityEventHandler { } @Subscribe - public void onPermissionsSetupEvent(PermissionsSetupEvent event, Continuation continuation) { - if(!(event.getSubject() instanceof ConnectedPlayer player)) { - continuation.resume(); - return; + public void onLoginEvent(LoginEvent event, Continuation continuation) { + ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); + if (player.getPhase() instanceof VelocityForgeClientConnectionPhase) { + player.getConnection().eventLoop().submit(() -> player.getConnection().setState(StateRegistry.LOGIN)); } - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; + continuation.resume(); + } + + @Subscribe + public void onPostLoginEvent(PostLoginEvent event, Continuation continuation) { + ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); + if (player.getPhase() instanceof VelocityForgeClientConnectionPhase phase) { + VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(), player); + player.getConnection().eventLoop().submit(() -> player.getConnection().setSessionHandler(sessionHandler)); } - player.getConnection().eventLoop().submit(() -> phase.fireLoginEvent(player, (VelocityServer) ambassador.server,continuation)); + continuation.resume(); } @Subscribe(order = PostOrder.LAST) @@ -72,40 +74,10 @@ public class VelocityEventHandler { continuation.resume(); return; } - if (event.getInitialServer().isEmpty()) - event.setInitialServer(phase.internalServerConnection.getServer()); + RegisteredServer chosenServer = phase.chooseServer(player); + if (chosenServer != null) + event.setInitialServer(chosenServer); continuation.resume(); } - @Subscribe(order = PostOrder.LAST) - public void onServerPostConnectEvent(ServerPostConnectEvent event, Continuation continuation) { - ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; - } - if (phase instanceof FML2ClientConnectionPhase specialPhase) { - specialPhase.handleJoinGame(); - } - //if (((ConnectedPlayer) event.getPlayer()).getConnectedServer() != null && ((ConnectedPlayer) event.getPlayer()).getConnectedServer().getConnection() != null) { - // ((ConnectedPlayer) event.getPlayer()).getConnectedServer().getConnection().write(new ClientSettings("en_GB", (byte) 10, 0, true, (short) 0xFF,1,false,true)); - //} - continuation.resume(); - } - - @Subscribe - public void onLoginEvent(PostLoginEvent event, Continuation continuation) { - ConnectedPlayer player = (ConnectedPlayer) event.getPlayer(); - if (!(player.getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - continuation.resume(); - return; - } - - if (phase instanceof FML2ClientConnectionPhase specialPhase) { - specialPhase.awaitJoinGame().thenAcceptAsync((ignored) -> { - player.setConnectedServer(null); - continuation.resume(); - },player.getConnection().eventLoop()); - } - } } diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeClientConnectionPhase.java index a7046cd..97b1e2c 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeClientConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeClientConnectionPhase.java @@ -1,6 +1,5 @@ package org.adde0109.ambassador.velocity; -import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.proxy.VelocityServer; @@ -11,6 +10,7 @@ import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; +import java.lang.reflect.InvocationTargetException; import java.util.concurrent.CompletableFuture; public abstract class VelocityForgeClientConnectionPhase implements ClientConnectionPhase { @@ -30,45 +30,31 @@ public abstract class VelocityForgeClientConnectionPhase implements ClientConnec protected VelocityForgeClientConnectionPhase() { } - public void handleLogin(ConnectedPlayer player, VelocityServer server, Continuation continuation) { + public RegisteredServer chooseServer(ConnectedPlayer player) { + return null; } public CompletableFuture reset(RegisteredServer server, ConnectedPlayer player) { return CompletableFuture.completedFuture(false); } - public void complete(VelocityServer server, ConnectedPlayer player, MinecraftConnection connection) { - } - final void fireLoginEvent(ConnectedPlayer player, VelocityServer server, Continuation continuation) { - payloadManager = new VelocityLoginPayloadManager(player.getConnection()); - handleLogin(player,server,continuation); - - VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(player.getConnection().getSessionHandler(), this); - player.getConnection().setSessionHandler(sessionHandler); + final void onFirstLogin(ConnectedPlayer player, VelocityServer server) throws InterruptedException, InvocationTargetException, IllegalAccessException { } public void handleForward(VelocityServerConnection serverConnection, LoginPluginMessage payload) { } - final public void forwardPayload(VelocityServerConnection serverConnection, LoginPluginMessage payload) { - handleForward(serverConnection,payload); - if (payloadManager == null) { - payload.release(); - return; - } - payloadManager.sendPayload("fml:loginwrapper",payload.content()).thenAccept((responseData) -> { - //Move this to the backend. Backend should have its own forwarder. - serverConnection.getConnection().write(new LoginPluginResponse(payload.getId(),responseData.isReadable(),responseData.retain())); - }); - clientPhase = ClientPhase.MODLIST; - } - public final VelocityLoginPayloadManager getPayloadManager() { return payloadManager; } + public boolean handle(ConnectedPlayer player, LoginPluginResponse response, VelocityServerConnection server) { + server.getConnection().write(response.retain()); + return true; + } + public enum ClientPhase { VANILLA, HANDSHAKE, diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java index 2c65f0c..c34b0ff 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java @@ -1,26 +1,29 @@ package org.adde0109.ambassador.velocity; +import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; +import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; import io.netty.buffer.ByteBuf; public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHandler { private final MinecraftSessionHandler original; - private final VelocityForgeClientConnectionPhase phase; + private final ConnectedPlayer player; - public VelocityForgeHandshakeSessionHandler(MinecraftSessionHandler original, VelocityForgeClientConnectionPhase phase) { + public VelocityForgeHandshakeSessionHandler(MinecraftSessionHandler original, ConnectedPlayer player) { this.original = original; - this.phase = phase; + this.player = player; } @Override public boolean handle(LoginPluginResponse packet) { - if (phase.getPayloadManager().handlePayload(packet)) { - return true; - } else { - return original.handle(packet); + if (player.getPhase() instanceof VelocityForgeClientConnectionPhase phase) { + if (phase.handle(player,packet,player.getConnectionInFlight())) { + return true; + } } + return original.handle(packet); } @Override public void handleUnknown(ByteBuf buf) { diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityHandshakeSessionHandler.java index 1bc208a..863bac6 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityHandshakeSessionHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityHandshakeSessionHandler.java @@ -4,11 +4,13 @@ import com.velocitypowered.proxy.connection.ConnectionTypes; import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler; +import com.velocitypowered.proxy.network.Connections; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.Handshake; import io.netty.buffer.ByteBuf; import org.adde0109.ambassador.forge.ForgeConstants; +import org.adde0109.ambassador.velocity.client.OutboundSuccessHolder; public class VelocityHandshakeSessionHandler implements MinecraftSessionHandler { private final HandshakeSessionHandler original; @@ -26,8 +28,14 @@ public class VelocityHandshakeSessionHandler implements MinecraftSessionHandler final String[] markerSplit = handshake.getServerAddress().split("\0"); if (connection.getState() == StateRegistry.LOGIN && markerSplit.length > 1) { switch (markerSplit[1]) { - case "FML2" -> connection.setType(ForgeConstants.ForgeFML2); - case "FML3" -> connection.setType(ForgeConstants.ForgeFML3); + case "FML2": + connection.setType(ForgeConstants.ForgeFML2); + connection.getChannel().pipeline().addAfter(Connections.MINECRAFT_ENCODER,ForgeConstants.SERVER_SUCCESS_LISTENER, new OutboundSuccessHolder()); + break; + case "FML3": + connection.setType(ForgeConstants.ForgeFML3); + connection.getChannel().pipeline().addAfter(Connections.MINECRAFT_ENCODER,ForgeConstants.SERVER_SUCCESS_LISTENER, new OutboundSuccessHolder()); + break; } } } diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeHandshakeSessionHandler.java index 5692f26..f5f30c7 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeHandshakeSessionHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/backend/ForgeHandshakeSessionHandler.java @@ -2,6 +2,7 @@ package org.adde0109.ambassador.velocity.backend; import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; +import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases; import com.velocitypowered.proxy.connection.backend.LoginSessionHandler; import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.protocol.MinecraftPacket; @@ -31,16 +32,11 @@ public class ForgeHandshakeSessionHandler implements MinecraftSessionHandler { @Override public boolean handle(LoginPluginMessage packet) { if (packet.getChannel().equals("fml:loginwrapper")) { - if (!(serverConnection.getConnection().getType() instanceof ForgeFMLConnectionType)) { - if (!(serverConnection.getPlayer().getConnection().getType() instanceof ForgeFMLConnectionType clientType)) { - final String reason = "This server has mods that require Forge to be installed on the client. Contact your server admin for more details."; - original.handle(Disconnect.create(Component.text(reason, NamedTextColor.RED),serverConnection.getPlayer().getProtocolVersion())); - return true; - } - serverConnection.getConnection().setType(clientType); - serverConnection.setConnectionPhase(clientType.getInitialBackendPhase()); + if (serverConnection.getPhase() == BackendConnectionPhases.UNKNOWN) { + VelocityForgeBackendConnectionPhase.NOT_STARTED.handle(serverConnection,serverConnection.getPlayer(),packet); + } else if (serverConnection.getPhase() instanceof VelocityForgeBackendConnectionPhase phase1) { + phase1.handle(serverConnection,serverConnection.getPlayer(),packet); } - ((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handle(serverConnection,serverConnection.getPlayer(),packet); return true; } return original.handle(packet); @@ -48,8 +44,8 @@ public class ForgeHandshakeSessionHandler implements MinecraftSessionHandler { @Override public boolean handle(ServerLoginSuccess packet) { - if ((serverConnection.getPlayer().getPhase() instanceof VelocityForgeClientConnectionPhase phase)) { - phase.complete(server,serverConnection.getPlayer(),serverConnection.getPlayer().getConnection()); + if ((serverConnection.getPhase() instanceof VelocityForgeBackendConnectionPhase phase)) { + phase.onLoginSuccess(serverConnection,serverConnection.getPlayer()); } return original.handle(packet); } diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java index 939f474..9a93e58 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java @@ -1,26 +1,51 @@ package org.adde0109.ambassador.velocity.backend; -import com.velocitypowered.proxy.VelocityServer; +import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase; import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; +import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import io.netty.buffer.ByteBuf; -import io.netty.util.ReferenceCountUtil; +import org.adde0109.ambassador.forge.ForgeConstants; import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; -import java.util.ArrayList; -import java.util.List; +public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhase { + NOT_STARTED() { + @Override + VelocityForgeBackendConnectionPhase nextPhase() { + return WAITING_FOR_ACK; + } + }, + WAITING_FOR_ACK() { + @Override + public void onLoginSuccess(VelocityServerConnection serverCon, ConnectedPlayer player) { + serverCon.setConnectionPhase(VelocityForgeBackendConnectionPhase.COMPLETE); -public class VelocityForgeBackendConnectionPhase implements BackendConnectionPhase { + MinecraftConnection connection = player.getConnection(); + connection.getChannel().pipeline().remove(ForgeConstants.SERVER_SUCCESS_LISTENER); + connection.setState(StateRegistry.PLAY); + } + }, + COMPLETE() { + @Override + public boolean consideredComplete() { + return true; + } + }; - public VelocityForgeBackendConnectionPhase() { + VelocityForgeBackendConnectionPhase() { } public void handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) { + + + VelocityForgeBackendConnectionPhase newPhase = nextPhase(); + + server.setConnectionPhase(newPhase); + VelocityForgeClientConnectionPhase clientPhase = ((VelocityForgeClientConnectionPhase) player.getPhase()); - if (clientPhase.clientPhase == VelocityForgeClientConnectionPhase.ClientPhase.VANILLA) { + if (player.getConnection().getState() != StateRegistry.LOGIN) { final LoginPluginMessage msg = message; msg.content().retain().discardSomeReadBytes(); @@ -28,14 +53,25 @@ public class VelocityForgeBackendConnectionPhase implements BackendConnectionPha server.getConnection().getChannel().config().setAutoRead(false); clientPhase.reset(server.getServer(),player).thenAccept((success) -> { if (success) { - clientPhase.forwardPayload(server,msg); + player.getConnection().write(msg); server.getConnection().getChannel().config().setAutoRead(true); } else { msg.release(); } }); } else { - clientPhase.forwardPayload(server, (LoginPluginMessage) message.retain()); + player.getConnection().write(message.retain()); } } + + public void onLoginSuccess(VelocityServerConnection serverCon, ConnectedPlayer player) { + + } + VelocityForgeBackendConnectionPhase nextPhase() { + return this; + } + public boolean consideredComplete() { + return false; + } + } diff --git a/src/main/java/org/adde0109/ambassador/velocity/client/OutboundSuccessHolder.java b/src/main/java/org/adde0109/ambassador/velocity/client/OutboundSuccessHolder.java new file mode 100644 index 0000000..f4cc48d --- /dev/null +++ b/src/main/java/org/adde0109/ambassador/velocity/client/OutboundSuccessHolder.java @@ -0,0 +1,28 @@ +package org.adde0109.ambassador.velocity.client; + +import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelOutboundHandlerAdapter; +import io.netty.channel.ChannelPromise; + +public class OutboundSuccessHolder extends ChannelOutboundHandlerAdapter { + + private ServerLoginSuccess packet; + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + if ((msg instanceof ServerLoginSuccess packet)) { + this.packet = packet; + } else { + ctx.write(msg, promise); + } + } + + @Override + public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { + if (ctx.channel().isActive()) { + ctx.write(packet, ctx.voidPromise()); + ctx.flush(); + } + } +}