From 2ab257ffe79aa7e70581cc08efdcfebe090b8450 Mon Sep 17 00:00:00 2001 From: Adrian Bergqvist Date: Thu, 22 Sep 2022 22:45:39 +0200 Subject: [PATCH] WIP: Restruct --- .../org/adde0109/ambassador/Ambassador.java | 3 + .../ambassador/forge/ForgeConstants.java | 5 ++ .../forge/ForgeFML2ClientConnectionPhase.java | 28 +++++++--- .../forge/ForgeFML2ConnectionType.java | 3 + .../ambassador/forge/ForgeHandshakeUtils.java | 17 +----- .../VelocityBackendChannelInitializer.java | 55 +++++++++++++++++++ .../velocity/VelocityEventHandler.java | 13 ++--- .../VelocityForgeBackendConnectionPhase.java | 33 +++-------- .../VelocityForgeBackendHandshakeHandler.java | 36 ++++++++++++ ...tyForgeBackendHandshakeSessionHandler.java | 51 ----------------- ...yForgeBackendTransitionSessionHandler.java | 54 ------------------ 11 files changed, 138 insertions(+), 160 deletions(-) create mode 100644 src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java create mode 100644 src/main/java/org/adde0109/ambassador/velocity/VelocityBackendChannelInitializer.java create mode 100644 src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeHandler.java delete mode 100644 src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java delete mode 100644 src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendTransitionSessionHandler.java diff --git a/src/main/java/org/adde0109/ambassador/Ambassador.java b/src/main/java/org/adde0109/ambassador/Ambassador.java index 6bb9ac5..f97f796 100644 --- a/src/main/java/org/adde0109/ambassador/Ambassador.java +++ b/src/main/java/org/adde0109/ambassador/Ambassador.java @@ -72,6 +72,9 @@ public class Ambassador { private void inject() throws ReflectiveOperationException { Field cmField = VelocityServer.class.getDeclaredField("cm"); cmField.setAccessible(true); + Field endpointMap = ConnectionManager.class.getDeclaredField("endpoints"); + endpointMap.setAccessible(true); + ChannelInitializer original = ((ConnectionManager) cmField.get(server)).serverChannelInitializer.get(); ((ConnectionManager) cmField.get(server)).serverChannelInitializer.set(new VelocityServerChannelInitializer(original)); } diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java b/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java new file mode 100644 index 0000000..eada8d1 --- /dev/null +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeConstants.java @@ -0,0 +1,5 @@ +package org.adde0109.ambassador.forge; + +public class ForgeConstants { + public static final String HANDLER = "Modern Forge handler"; +} diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java index 97c94d3..7296ea3 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java @@ -10,6 +10,7 @@ import com.velocitypowered.proxy.config.VelocityConfiguration; import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.client.ClientConnectionPhase; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; +import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; @@ -39,7 +40,7 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec public byte[] modListData; private final ArrayList listenerList = new ArrayList(); - public ArrayList packagesToSendAfterReset = new ArrayList<>(); + public ArrayList packagesToSendAfterReset = new ArrayList<>(); private Runnable whenComplete; public boolean isReady = false; @Override @@ -48,7 +49,7 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec final MinecraftConnection connection = player.getConnection(); VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player); if(handshake == null) { - connection.delayedWrite(new LoginPluginMessage(0,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateEmptyModlist()))); + connection.delayedWrite(new LoginPluginMessage(0,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.emptyModlist))); listenerList.add(0); } else { connection.delayedWrite(new LoginPluginMessage(0,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket))); @@ -69,7 +70,8 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec return true; } if (packet.getId() == 98) { - for (LoginPluginMessage packet1 : packagesToSendAfterReset) { + isReady = true; + for (MinecraftPacket packet1 : packagesToSendAfterReset) { player.getConnection().delayedWrite(packet1); } packagesToSendAfterReset = new ArrayList<>(); @@ -88,7 +90,7 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec } return true; } - public void reset(ConnectedPlayer player,MinecraftConnection connection, byte[] serverModlist) { + public void reset(ConnectedPlayer player,MinecraftConnection connection) { isReady = false; if (player.getConnectedServer() != null) { player.getConnectedServer().disconnect(); @@ -96,11 +98,23 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player)); connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket()))); listenerList.add(98); - send(player,new LoginPluginMessage(0,"fml:loginwrapper",Unpooled.wrappedBuffer(serverModlist))); - listenerList.add(0); connection.setState(StateRegistry.LOGIN); } - public void send(ConnectedPlayer player, LoginPluginMessage message) { + 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); + send(player,success); + + connection.setState(StateRegistry.PLAY); + connection.setSessionHandler(((VelocityForgeHandshakeSessionHandler) connection.getSessionHandler()).getOriginal()); + } + public void send(ConnectedPlayer player, MinecraftPacket message) { if (isReady) { player.getConnection().write(message); } else { diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ConnectionType.java b/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ConnectionType.java index be71854..fe2d34f 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ConnectionType.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ConnectionType.java @@ -9,6 +9,8 @@ import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases; import com.velocitypowered.proxy.connection.client.ClientConnectionPhase; import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendConnectionPhase; +import java.util.Collections; + public class ForgeFML2ConnectionType implements ConnectionType { @Override @@ -23,6 +25,7 @@ public class ForgeFML2ConnectionType implements ConnectionType { @Override public GameProfile addGameProfileTokensIfRequired(GameProfile original, PlayerInfoForwarding forwardingType) { + original.addProperties(Collections.singleton(new GameProfile.Property("extraData", "\1FML2\1", ""))); return original; } } diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java index d5f88fe..2a1626a 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java @@ -88,7 +88,8 @@ public class ForgeHandshakeUtils { return dataAndPacketIdStream.toByteArray(); } - public static byte[] generateEmptyModlist() { + public static final byte[] emptyModlist = generateEmptyModlist(); + private static byte[] generateEmptyModlist() { ByteArrayDataOutput dataAndPacketIdStream = ByteStreams.newDataOutput(); writeVarInt(dataAndPacketIdStream,1); writeVarInt(dataAndPacketIdStream,0); @@ -103,20 +104,6 @@ public class ForgeHandshakeUtils { return stream.toByteArray(); } - static 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); - - connection.setState(StateRegistry.PLAY); - connection.setSessionHandler(((VelocityForgeHandshakeSessionHandler) connection.getSessionHandler()).getOriginal()); - } public static final byte[] ACKPacket = generateACKPacket(); private static byte[] generateACKPacket() { diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityBackendChannelInitializer.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityBackendChannelInitializer.java new file mode 100644 index 0000000..72e5ea6 --- /dev/null +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityBackendChannelInitializer.java @@ -0,0 +1,55 @@ +package org.adde0109.ambassador.velocity; + +import com.velocitypowered.proxy.VelocityServer; +import com.velocitypowered.proxy.connection.MinecraftConnection; +import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import org.adde0109.ambassador.forge.ForgeConstants; +import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase; +import org.adde0109.ambassador.forge.ForgeFML2ConnectionType; +import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendHandshakeHandler; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; + +public class VelocityBackendChannelInitializer extends ChannelInitializer { + + private static final Method INIT_CHANNEL; + + private final ChannelInitializer original; + private final VelocityServer server; + + static { + try { + INIT_CHANNEL = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class); + INIT_CHANNEL.setAccessible(true); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public VelocityBackendChannelInitializer(ChannelInitializer original, VelocityServer server) { + this.original = original; + this.server = server; + } + + @Override + protected void initChannel(@NotNull Channel ch) throws Exception { + INIT_CHANNEL.invoke(original); + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + if (ctx.handler() instanceof MinecraftConnection connection) { + if (connection.getAssociation() instanceof VelocityServerConnection serverConnection) { + if (serverConnection.getPlayer().getPhase() instanceof ForgeFML2ClientConnectionPhase) { + connection.setType(new ForgeFML2ConnectionType()); + ctx.pipeline().addBefore(ctx.name(), ForgeConstants.HANDLER, new VelocityForgeBackendHandshakeHandler(connection, serverConnection, server)); + } + } + } + super.handlerAdded(ctx); + } +} diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java index 9bc1fd1..7edb4c7 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityEventHandler.java @@ -4,22 +4,17 @@ import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.permission.PermissionsSetupEvent; import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent; -import com.velocitypowered.proxy.VelocityServer; -import com.velocitypowered.proxy.connection.ConnectionTypes; import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; -import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases; import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; -import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import org.adde0109.ambassador.Ambassador; import org.adde0109.ambassador.forge.ForgeFML2ClientConnectionPhase; import org.adde0109.ambassador.forge.ForgeFML2ConnectionType; import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendConnectionPhase; -import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendHandshakeSessionHandler; +import org.adde0109.ambassador.velocity.backend.VelocityForgeBackendHandshakeHandler; import java.util.Objects; @@ -44,7 +39,7 @@ public class VelocityEventHandler { ambassador.forgeHandshakeHandler.handleLogin(player,continuation); } - @Subscribe + /*@Subscribe public void onServerLoginPluginMessageEvent(ServerLoginPluginMessageEvent event, Continuation continuation) { if (!Objects.equals(event.getIdentifier().getId(), "fml:loginwrapper") || !(((ConnectedPlayer)event.getConnection().getPlayer()).getPhase() instanceof VelocityForgeClientConnectionPhase)) { continuation.resume(); @@ -63,7 +58,7 @@ public class VelocityEventHandler { serverCon.setConnectionPhase(new VelocityForgeBackendConnectionPhase(ambassador)); byte[] response = ((VelocityForgeBackendConnectionPhase)serverCon.getPhase()).generateResponse(serverCon.getPlayer(), Unpooled.wrappedBuffer(event.getContents())); event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(response)); - MinecraftSessionHandler sessionHandler = new VelocityForgeBackendHandshakeSessionHandler(connection.getSessionHandler(),serverCon); + MinecraftSessionHandler sessionHandler = new VelocityForgeBackendHandshakeHandler(connection.getSessionHandler(),serverCon); connection.setSessionHandler(sessionHandler); ((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase()).reset(serverCon.getPlayer(), serverCon.getPlayer().getConnection(),event.getContents()); } else { @@ -71,5 +66,5 @@ public class VelocityEventHandler { } continuation.resume(); }); - } + }*/ } 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 8aac65a..40d0c25 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java @@ -1,5 +1,6 @@ package org.adde0109.ambassador.velocity.backend; +import com.velocitypowered.proxy.Velocity; import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase; @@ -21,42 +22,26 @@ import java.util.List; public class VelocityForgeBackendConnectionPhase implements BackendConnectionPhase { private final Ambassador ambassador; - private final List handshakeMessages = new ArrayList<>(); + private boolean vanilla = true; public VelocityForgeBackendConnectionPhase(Ambassador ambassador) { this.ambassador = ambassador; } - public void handleSuccess(VelocityServerConnection serverCon) { - ForgeHandshakeUtils.complete((VelocityServer) ambassador.server,serverCon.getPlayer(),serverCon.getPlayer().getConnection()); - //((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase()).reset(serverCon.getPlayer(),serverCon.getPlayer().getConnection(), handshakeMessages, - // () -> ForgeHandshakeUtils.complete((VelocityServer) ambassador.server,serverCon.getPlayer(),serverCon.getPlayer().getConnection())); - } - - public byte[] generateResponse(ConnectedPlayer player, ByteBuf content) { - content.readBytes(14); //Channel Identifier - ProtocolUtils.readVarInt(content); //Length - int packetID = ProtocolUtils.readVarInt(content); - - - switch (packetID) { - - case 1: - final byte[] data = ((ForgeFML2ClientConnectionPhase) player.getPhase()).modListData; - return data; - - default: - return ForgeHandshakeUtils.ACKPacket; + public void handleSuccess(VelocityServerConnection serverCon, VelocityServer server) { + ForgeFML2ClientConnectionPhase clientPhase = ((ForgeFML2ClientConnectionPhase) serverCon.getPlayer().getPhase()); + if (vanilla) { + clientPhase.reset(serverCon.getPlayer(),serverCon.getPlayer().getConnection()); } + clientPhase.complete((VelocityServer) ambassador.server,serverCon.getPlayer(),serverCon.getPlayer().getConnection()); } public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) { - if (!message.getChannel().equals("fml:loginwrapper") || !(player.getPhase() instanceof VelocityForgeClientConnectionPhase)) { - return false; - } + vanilla = false; message.retain(); ((ForgeFML2ClientConnectionPhase) player.getPhase()).send(player,message); return true; } + } diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeHandler.java new file mode 100644 index 0000000..7006efb --- /dev/null +++ b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeHandler.java @@ -0,0 +1,36 @@ +package org.adde0109.ambassador.velocity.backend; + +import com.velocitypowered.proxy.VelocityServer; +import com.velocitypowered.proxy.connection.MinecraftConnection; +import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; +import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; +import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.ReferenceCountUtil; + +public class VelocityForgeBackendHandshakeHandler extends ChannelInboundHandlerAdapter { + + private final MinecraftConnection connection; + private final VelocityServerConnection serverConnection; + private final VelocityServer server; + + public VelocityForgeBackendHandshakeHandler(MinecraftConnection connection, VelocityServerConnection serverConnection, VelocityServer server) { + this.connection = connection; + this.serverConnection = serverConnection; + this.server = server; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + if (msg instanceof LoginPluginMessage message && message.getChannel().equals("fml:loginwrapper")) { + ((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handle(serverConnection, serverConnection.getPlayer(), message); + ReferenceCountUtil.release(msg); + } else if (msg instanceof ServerLoginSuccess) { + ((VelocityForgeBackendConnectionPhase) serverConnection.getPhase()).handleSuccess(serverConnection,server); + ReferenceCountUtil.release(msg); + } else { + ctx.fireChannelRead(msg); + } + } +} diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java deleted file mode 100644 index 8d39fd6..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.adde0109.ambassador.velocity.backend; - -import com.velocitypowered.proxy.connection.MinecraftSessionHandler; -import com.velocitypowered.proxy.connection.backend.LoginSessionHandler; -import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; -import com.velocitypowered.proxy.connection.client.ConnectedPlayer; -import com.velocitypowered.proxy.protocol.MinecraftPacket; -import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; -import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; - -public class VelocityForgeBackendHandshakeSessionHandler implements MinecraftSessionHandler { - private final LoginSessionHandler original; - private final VelocityServerConnection serverCon; - - public VelocityForgeBackendHandshakeSessionHandler(MinecraftSessionHandler original, VelocityServerConnection serverCon) { - this.original = (LoginSessionHandler) original; - this.serverCon = serverCon; - } - - @Override - public void disconnected() { - original.disconnected(); - } - - @Override - public void handleGeneric(MinecraftPacket packet) { - packet.handle(original); - } - - @Override - public void exception(Throwable throwable) { - original.exception(throwable); - } - - @Override - public boolean handle(LoginPluginMessage packet) { - if (((VelocityForgeBackendConnectionPhase) serverCon.getPhase()).handle(serverCon, serverCon.getPlayer(), packet)) { - return true; - } else { - return original.handle(packet); - } - } - - @Override - public boolean handle(ServerLoginSuccess packet) { - ((VelocityForgeBackendConnectionPhase) serverCon.getPhase()).handleSuccess(serverCon); - original.handle(packet); - return true; - } -} diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendTransitionSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendTransitionSessionHandler.java deleted file mode 100644 index 91236e1..0000000 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendTransitionSessionHandler.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.adde0109.ambassador.velocity.backend; - -import com.velocitypowered.proxy.connection.MinecraftSessionHandler; -import com.velocitypowered.proxy.connection.backend.TransitionSessionHandler; -import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; -import com.velocitypowered.proxy.protocol.MinecraftPacket; -import com.velocitypowered.proxy.protocol.ProtocolUtils; -import com.velocitypowered.proxy.protocol.StateRegistry; -import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; -import com.velocitypowered.proxy.protocol.packet.PluginMessage; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -public class VelocityForgeBackendTransitionSessionHandler implements MinecraftSessionHandler { - private final TransitionSessionHandler original; - private final VelocityServerConnection serverCon; - - public VelocityForgeBackendTransitionSessionHandler(MinecraftSessionHandler original, VelocityServerConnection serverCon) { - this.original = (TransitionSessionHandler) original; - this.serverCon = serverCon; - } - - @Override - public boolean beforeHandle() { - return original.beforeHandle(); - } - - @Override - public void disconnected() { - original.disconnected(); - } - - @Override - public void handleGeneric(MinecraftPacket packet) { - packet.handle(original); - } - - @Override - public boolean handle(PluginMessage packet) { - if (serverCon.getPlayer().getConnection().getState() == StateRegistry.LOGIN) { - //So it can't send when the client is in LOGIN state. - //We can instead use forge's LoginWrapper - ByteBuf wrapped = Unpooled.buffer(); - ProtocolUtils.writeString(wrapped,"minecraft:register"); - ProtocolUtils.writeVarInt(wrapped, packet.content().readableBytes()); - wrapped.writeBytes(packet.content()); - serverCon.getPlayer().getConnection().write(new LoginPluginMessage(97,"fml:loginwrapper",wrapped)); - } else { - original.handle(packet); - } - return true; - } - -}