From fea9082dd789537aed5ec3ebd7b4f7150778a66a Mon Sep 17 00:00:00 2001 From: Adrian Bergqvist Date: Mon, 19 Sep 2022 00:46:19 +0200 Subject: [PATCH] WIP: Almost --- .../forge/ForgeFML2ClientConnectionPhase.java | 38 ++++++++++++--- .../forge/ForgeFML2ConnectionType.java | 3 +- .../ambassador/forge/ForgeHandshakeUtils.java | 46 ++++++++++++++++++- .../velocity/VelocityEventHandler.java | 17 ++++--- .../VelocityForgeHandshakeSessionHandler.java | 7 ++- .../VelocityForgeBackendConnectionPhase.java | 44 ++++++++++++------ ...tyForgeBackendHandshakeSessionHandler.java | 4 +- 7 files changed, 130 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java b/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java index 81333b1..df7ff8a 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeFML2ClientConnectionPhase.java @@ -1,11 +1,19 @@ package org.adde0109.ambassador.forge; import com.velocitypowered.api.event.Continuation; +import com.velocitypowered.api.util.UuidUtils; +import com.velocitypowered.proxy.Velocity; +import com.velocitypowered.proxy.VelocityServer; +import com.velocitypowered.proxy.config.PlayerInfoForwarding; +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.StateRegistry; import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; +import com.velocitypowered.proxy.protocol.packet.PluginMessage; +import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; @@ -14,7 +22,12 @@ import org.adde0109.ambassador.velocity.VelocityForgeHandshakeSessionHandler; import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnectionPhase { private boolean isResettable; @@ -23,15 +36,15 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec public byte[] modListData; private final ArrayList listenerList = new ArrayList(); - private Continuation whenComplete; + private Runnable whenComplete; @Override public void handleLogin(ConnectedPlayer player,ForgeHandshakeUtils.CachedServerHandshake handshake, Continuation continuation) { - this.whenComplete = continuation; + this.whenComplete = continuation::resume; final MinecraftConnection connection = player.getConnection(); VelocityForgeHandshakeSessionHandler sessionHandler = new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player); if(handshake == null) { - connection.delayedWrite(new LoginPluginMessage(98,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateResetPacket()))); - listenerList.add(98); + connection.delayedWrite(new LoginPluginMessage(1,"fml:loginwrapper", Unpooled.wrappedBuffer(ForgeHandshakeUtils.generateEmptyModlist()))); + listenerList.add(1); } else { connection.delayedWrite(new LoginPluginMessage(1,"fml:loginwrapper", Unpooled.wrappedBuffer(handshake.modListPacket))); listenerList.add(1); @@ -59,9 +72,22 @@ public class ForgeFML2ClientConnectionPhase implements VelocityForgeClientConnec } modListData = ByteBufUtil.getBytes(packet.content()); } - if (listenerList.isEmpty()) { - whenComplete.resume(); + if (listenerList.isEmpty() && whenComplete != null) { + whenComplete.run(); + whenComplete = null; } return true; } + public void reset(ConnectedPlayer player,MinecraftConnection connection, List messages, Runnable whenComplete) { + this.whenComplete = whenComplete; + connection.setSessionHandler(new VelocityForgeHandshakeSessionHandler(connection.getSessionHandler(),player)); + connection.write(new PluginMessage("fml:handshake",Unpooled.wrappedBuffer(ForgeHandshakeUtils.generatePluginResetPacket()))); + listenerList.add(98); + connection.setState(StateRegistry.LOGIN); + for (int i = 0;i { + connection.setType(new ForgeFML2ConnectionType()); + serverCon.setConnectionPhase(new VelocityForgeBackendConnectionPhase(ambassador)); + byte[] response = ((VelocityForgeBackendConnectionPhase)serverCon.getPhase()).generateResponse(serverCon.getPlayer(), Unpooled.wrappedBuffer(event.getContents())); + event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(response)); + continuation.resume(); + MinecraftSessionHandler sessionHandler = new VelocityForgeBackendHandshakeSessionHandler(connection.getSessionHandler(),serverCon); + connection.setSessionHandler(sessionHandler); + }); } } diff --git a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java index 6cb5242..caf1753 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/VelocityForgeHandshakeSessionHandler.java @@ -15,6 +15,7 @@ import java.util.List; public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHandler { private final MinecraftSessionHandler original; private final ConnectedPlayer player; + public VelocityForgeHandshakeSessionHandler(MinecraftSessionHandler original, ConnectedPlayer player) { this.original = original; this.player = player; @@ -37,4 +38,8 @@ public class VelocityForgeHandshakeSessionHandler implements MinecraftSessionHan public void disconnected() { original.disconnected(); } -} + + public MinecraftSessionHandler getOriginal() { + return this.original; + } +} \ No newline at end of file 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 8961511..f379d44 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java +++ b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendConnectionPhase.java @@ -1,34 +1,43 @@ package org.adde0109.ambassador.velocity.backend; import com.google.common.io.ByteArrayDataInput; +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.ProtocolUtils; +import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage; import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse; import com.velocitypowered.proxy.protocol.packet.PluginMessage; import io.netty.buffer.ByteBuf; +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.ForgeHandshakeUtils; import org.adde0109.ambassador.velocity.VelocityForgeClientConnectionPhase; import java.io.EOFException; +import java.util.ArrayList; +import java.util.List; public class VelocityForgeBackendConnectionPhase implements BackendConnectionPhase { - public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) { - if (!message.getChannel().equals("fml:loginwrapper") || !(player.getPhase() instanceof VelocityForgeClientConnectionPhase)) { - return false; - } - MinecraftConnection connection = server.getConnection(); - if (connection == null) { - throw new NullPointerException(); - } + private final Ambassador ambassador; + private final List handshakeMessages = new ArrayList<>(); - ByteBuf content = message.content(); + public VelocityForgeBackendConnectionPhase(Ambassador ambassador) { + this.ambassador = ambassador; + } + + public void handleSuccess(VelocityServerConnection serverCon) { + ((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); @@ -38,14 +47,23 @@ public class VelocityForgeBackendConnectionPhase implements BackendConnectionPha case 1: final byte[] data = ((ForgeFML2ClientConnectionPhase) player.getPhase()).modListData; - connection.write(new LoginPluginResponse(message.getId(),true, Unpooled.wrappedBuffer(data))); - break; + return data; default: - connection.write(new LoginPluginResponse(message.getId(),true,Unpooled.wrappedBuffer(ForgeHandshakeUtils.ACKPacket))); - break; + return ForgeHandshakeUtils.ACKPacket; } + } + public boolean handle(VelocityServerConnection server, ConnectedPlayer player, LoginPluginMessage message) { + if (!message.getChannel().equals("fml:loginwrapper") || !(player.getPhase() instanceof VelocityForgeClientConnectionPhase)) { + return false; + } + MinecraftConnection connection = server.getConnection(); + if (connection == null) { + throw new NullPointerException(); + } + connection.write(new LoginPluginResponse(message.getId(),true, Unpooled.wrappedBuffer(generateResponse(player,message.content())))); return true; } + } diff --git a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java index 7e46568..da5700e 100644 --- a/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java +++ b/src/main/java/org/adde0109/ambassador/velocity/backend/VelocityForgeBackendHandshakeSessionHandler.java @@ -37,6 +37,8 @@ public class VelocityForgeBackendHandshakeSessionHandler implements MinecraftSes @Override public boolean handle(ServerLoginSuccess packet) { - return original.handle(packet); + original.handle(packet); + ((VelocityForgeBackendConnectionPhase) serverCon.getPhase()).handleSuccess(serverCon); + return true; } }