From 6460be6e1c4fbc0f40ace516a55a50bd0a1a028b Mon Sep 17 00:00:00 2001 From: Adrian Bergqvist Date: Mon, 30 May 2022 23:35:28 +0200 Subject: [PATCH] Separated core functions to a new class --- .../org/adde0109/ambassador/Ambassador.java | 153 +----------------- .../ambassador/ForgeHandshakeDataHandler.java | 49 +++++- 2 files changed, 47 insertions(+), 155 deletions(-) diff --git a/src/main/java/org/adde0109/ambassador/Ambassador.java b/src/main/java/org/adde0109/ambassador/Ambassador.java index a073f55..b8a7f6c 100644 --- a/src/main/java/org/adde0109/ambassador/Ambassador.java +++ b/src/main/java/org/adde0109/ambassador/Ambassador.java @@ -32,12 +32,6 @@ public class Ambassador { private final Path dataDirectory; private RegisteredServer forgeServer; - private LoginPhaseConnection inbound; - private ChannelIdentifier loginWrapperChannel; - - private static final int MAX_DATA_LENGTH = 16000; - private static final int PACKET_LENGTH_INDEX = 14; - private static ForgeHandshakeDataHandler forgeHandshakeDataHandler; @Inject @@ -60,154 +54,9 @@ public class Ambassador { */ forgeServer = server.getServer("lobby").orElseThrow(IllegalAccessError::new); - loginWrapperChannel = MinecraftChannelIdentifier.create("fml","loginwrapper"); forgeHandshakeDataHandler = new ForgeHandshakeDataHandler(forgeServer,logger); + server.getEventManager().register(this, forgeHandshakeDataHandler); } - private int numberOfRecivedParts; - private byte[] recivedParts; - private int recivedBytes; - private int head; - - private byte[] recivedClientModlist; - private byte[] recivedClientACK; - - - - @Subscribe - public void onPreLoginEvent(PreLoginEvent event, Continuation continuation) { - if (forgeServer == null) { - continuation.resume(); - } - inbound = (LoginPhaseConnection) event.getConnection(); - - /*recivedParts = new byte[2000000]; - recivedBytes = 0; - numberOfRecivedParts = 0; - ping(continuation); - */ - forgeHandshakeDataHandler.onPreLogin(event,continuation); - } - - private void ping(Continuation continuation) { - forgeServer.ping().thenAccept((s) -> onBackendPong(s,continuation)); - } - - - public void onBackendPong(ServerPing status, Continuation continuation) { - numberOfRecivedParts++; - if((!status.getModinfo().isPresent()) || (!Objects.equals(status.getModinfo().get().getType(), "ambassador"))) { - continuation.resumeWithException(new Error("The specified Forge server is not running the Forge-side version of this plugin!")); - return; - } - - - ModInfo.Mod pair = status.getModinfo().orElseThrow(IllegalAccessError::new).getMods().get(0); - - int[] values = Arrays.stream(pair.getVersion().substring(pair.getVersion().indexOf(":")+1).split(":")).map(Integer::parseInt).mapToInt(x -> x).toArray(); - - int parts = Integer.parseInt((pair.getVersion().split(":")[0].split("-"))[1]); - int recivedPartNr = Integer.parseInt((pair.getVersion().split(":")[0].split("-"))[0]); - - logger.info("Downloaded part " + String.valueOf(numberOfRecivedParts) + " out of " + String.valueOf(parts)); - - placePartInArray(pair.getId().getBytes(StandardCharsets.ISO_8859_1),recivedPartNr-1); - - if(numberOfRecivedParts >= parts) - { - sendHandshake(splitPackets(recivedParts,values)); - continuation.resume(); - } - else { - ping(continuation); - } - } - - private void placePartInArray(byte[] temp, int partNr) { - head = partNr*MAX_DATA_LENGTH; - for(int i = 0;i splitPackets(byte[] data, int[] startPacketMarkers) { - List list = new ArrayList<>(); - for(int i = 0;i handshakePackets) { - handshakePackets.forEach((packet) -> { - inbound.sendLoginPluginMessage(loginWrapperChannel, packet, new LoginPhaseConnection.MessageConsumer() { - @Override - public void onMessageResponse(byte @Nullable [] responseBody) { - if (responseBody.length < PACKET_LENGTH_INDEX+5+5) { - recivedClientACK = responseBody; - } - else { - recivedClientModlist = responseBody; - } - } - }); - }); - } - - @Subscribe - public void onServerLoginPluginMessageEvent(ServerLoginPluginMessageEvent event, Continuation continuation) { - if((recivedClientModlist == null) || (recivedClientACK == null) || (!Objects.equals(event.getIdentifier().getId(), "fml:loginwrapper"))) { - continuation.resume(); - return; - } - ByteArrayDataInput data = event.contentsAsDataStream(); - if(data.skipBytes(PACKET_LENGTH_INDEX) != PACKET_LENGTH_INDEX) { //Channel Identifier - continuation.resumeWithException(new EOFException()); - return; - } - readVarInt(data); //Length - int packetID = readVarInt(data); - - if(packetID == 1) { - event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(forgeHandshakeDataHandler.recivedClientModlist)); - } - else { - event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(forgeHandshakeDataHandler.recivedClientACK)); - } - continuation.resume(); - - } - - - public static int readVarInt(ByteArrayDataInput stream) { - int i = 0; - int j = 0; - - byte b0; - do { - b0 = stream.readByte(); - i |= (b0 & 127) << j++ * 7; - if (j > 5) { - throw new RuntimeException("VarInt too big"); - } - } while((b0 & 128) == 128); - - return i; - } - - } diff --git a/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java b/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java index 560c0da..f67fdfc 100644 --- a/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java +++ b/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java @@ -1,12 +1,17 @@ package org.adde0109.ambassador; +import com.google.common.io.ByteArrayDataInput; import com.velocitypowered.api.event.Continuation; +import com.velocitypowered.api.event.PostOrder; +import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.PreLoginEvent; +import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent; import com.velocitypowered.api.proxy.LoginPhaseConnection; import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.ServerPing; import com.velocitypowered.api.util.ModInfo; +import java.io.EOFException; import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; @@ -33,11 +38,11 @@ public class ForgeHandshakeDataHandler { this.logger = logger; } - + @Subscribe(order = PostOrder.EARLY) public void onPreLogin(PreLoginEvent event, Continuation continuation) { if (cachedServerHandshake == null) { handshakeReceiver receiver = new handshakeReceiver(handshakeServer, logger); - receiver.getHandshake().thenAccept((p) -> { + receiver.downloadHandshake().thenAccept((p) -> { sendModlist(p.modListPacket,(LoginPhaseConnection) event.getConnection()); sendOther(p.otherPackets,(LoginPhaseConnection) event.getConnection()); continuation.resume(); @@ -45,6 +50,30 @@ public class ForgeHandshakeDataHandler { } } + @Subscribe + public void onServerLoginPluginMessageEvent(ServerLoginPluginMessageEvent event, Continuation continuation) { + if((recivedClientModlist == null) || (recivedClientACK == null) || (!Objects.equals(event.getIdentifier().getId(), "fml:loginwrapper"))) { + continuation.resume(); + return; + } + ByteArrayDataInput data = event.contentsAsDataStream(); + if(data.skipBytes(PACKET_LENGTH_INDEX) != PACKET_LENGTH_INDEX) { //Channel Identifier + continuation.resumeWithException(new EOFException()); + return; + } + readVarInt(data); //Length + int packetID = readVarInt(data); + + if(packetID == 1) { + event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(recivedClientModlist)); + } + else { + event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(recivedClientACK)); + } + continuation.resume(); + + } + private void sendModlist(byte[] modListPacket, LoginPhaseConnection connection) { @@ -57,7 +86,21 @@ public class ForgeHandshakeDataHandler { }); } + public static int readVarInt(ByteArrayDataInput stream) { + int i = 0; + int j = 0; + byte b0; + do { + b0 = stream.readByte(); + i |= (b0 & 127) << j++ * 7; + if (j > 5) { + throw new RuntimeException("VarInt too big"); + } + } while((b0 & 128) == 128); + + return i; + } private class handshakeReceiver { @@ -78,7 +121,7 @@ public class ForgeHandshakeDataHandler { } - public CompletableFuture getHandshake() { + public CompletableFuture downloadHandshake() { CompletableFuture future = new CompletableFuture(); ping(future); return future;