diff --git a/Velocity b/Velocity new file mode 160000 index 0000000..5fe3663 --- /dev/null +++ b/Velocity @@ -0,0 +1 @@ +Subproject commit 5fe3663d5102c98df1128b06f002e0c5b212f61f diff --git a/build.gradle b/build.gradle index a2b0796..4cd568e 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'org.adde0109' -version '0.4.0' +version '0.5.0' repositories { maven { diff --git a/src/main/java/org/adde0109/ambassador/Ambassador.java b/src/main/java/org/adde0109/ambassador/Ambassador.java index 35d54cd..0db0d8d 100644 --- a/src/main/java/org/adde0109/ambassador/Ambassador.java +++ b/src/main/java/org/adde0109/ambassador/Ambassador.java @@ -23,7 +23,7 @@ import org.slf4j.Logger; import java.nio.file.Path; import java.util.*; -@Plugin(id = "ambassador", name = "Ambassador", version = "0.4.0", authors = {"adde0109"}) +@Plugin(id = "ambassador", name = "Ambassador", version = "0.5.0", authors = {"adde0109"}) public class Ambassador { public ProxyServer server; @@ -82,7 +82,7 @@ public class Ambassador { //Forge client ForgeConnection forgeConnection = forgeHandshakeHandler.getForgeConnection(event.getPlayer()).get(); if (forgeConnection.isForced()) { - event.setInitialServer(forgeConnection.getSyncedServer().get()); + event.setInitialServer(forgeConnection.getSyncResult().get().getSyncedServer()); } forgeConnection.setForced(config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol())); } diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java b/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java index 6f2836d..e38ff06 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java @@ -18,13 +18,11 @@ public class ForgeConnection { private final Logger logger; private final LoginPhaseConnection connection; - private Optional recivedClientModlist = Optional.empty(); - private static byte[] recivedClientACK; private boolean ignoreSyncExepction = false; - private Optional transmittedHandshake = Optional.empty(); private boolean forced = false; - private Optional syncedTo = Optional.empty(); + + private SyncResult syncResult; public ForgeConnection(LoginPhaseConnection connection, Logger logger) { @@ -47,34 +45,35 @@ public class ForgeConnection { - public CompletableFuture sync(ForgeServerConnection forgeServerConnection) { - CompletableFuture future = new CompletableFuture<>(); + public void startSync(ForgeServerConnection forgeServerConnection, Continuation continuation) { forgeServerConnection.getHandshake().whenComplete((msg,ex) -> { if (ex != null) { - future.complete(false); + continuation.resume(); logger.warn("Sync Exception: " + ex); } else { + CompletableFuture clientModListFuture = new CompletableFuture<>(); //This gets also sent to vanilla sendModlist(msg.modListPacket).thenAccept((response) -> { if (!ignoreSyncExepction && response == null) { logger.warn("Sync Exception: Client responded with an empty body."); } - recivedClientModlist = Optional.ofNullable(response); + clientModListFuture.complete(response); }); + syncResult = new SyncResult(msg,clientModListFuture, forgeServerConnection.getServer()); //This gets also sent to vanilla sendOther(msg.otherPackets).thenAccept((response) -> { if (!ignoreSyncExepction && response == null) { logger.warn("Sync Exception: Client responded with an empty body."); } //TODO: Generate the ACK packet ourself. - ForgeConnection.recivedClientACK = (response == null) ? ForgeConnection.recivedClientACK : response; - transmittedHandshake = Optional.of(msg); - syncedTo = Optional.of(forgeServerConnection.getServer()); + if (response != null && SyncResult.recivedClientACK == null) { + SyncResult.recivedClientACK = response; + } + syncResult.complete(syncResult); }); - future.complete(true); + continuation.resume(); } }); - return future; } private CompletableFuture sendModlist(byte[] modListPacket) { @@ -95,6 +94,11 @@ public class ForgeConnection { } public void handleServerHandshakePacket(ServerLoginPluginMessageEvent event, Continuation continuation) { + if (getSyncResult().isEmpty()) { + continuation.resumeWithException(new Exception("Client isn't synced. This should have been caught" + + " during serverPreConnect")); + return; + } ByteArrayDataInput data = event.contentsAsDataStream(); if (data.skipBytes(14) != 14) { //Channel Identifier continuation.resumeWithException(new EOFException()); @@ -104,41 +108,27 @@ public class ForgeConnection { int packetID = ForgeHandshakeUtils.readVarInt(data); if (packetID == 1) { - if (getRecivedClientModlist().isPresent()) { - event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(getRecivedClientModlist().get())); - } else { - continuation.resumeWithException(new Exception("Client isn't synced. This should have been caught" + - " during serverPreConnect")); - return; - } + getSyncResult().get().getRecivedClientModlist().whenComplete((msg,ex) -> { + event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(msg)); + continuation.resume(); + }); } else { - if (getRecivedClientACK() != null) { - event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(getRecivedClientACK())); + if (SyncResult.recivedClientACK != null) { + event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(SyncResult.recivedClientACK)); } else { - continuation.resumeWithException(new Exception("No response available.")); + continuation.resumeWithException(new Exception("No ACK response packet available.")); return; } + continuation.resume(); } - continuation.resume(); } public LoginPhaseConnection getConnection() { return connection; } - public Optional getTransmittedHandshake() { - return transmittedHandshake; - } - - public Optional getRecivedClientModlist() { - return recivedClientModlist; - } - - public static byte[] getRecivedClientACK() { - return recivedClientACK; - } - public Optional getSyncedServer() { - return syncedTo; + public Optional getSyncResult() { + return Optional.ofNullable(syncResult); } public void setForced(boolean forced) { this.forced = forced; @@ -146,4 +136,28 @@ public class ForgeConnection { public boolean isForced() { return forced; } + public static class SyncResult extends CompletableFuture { + private final ForgeHandshakeUtils.CachedServerHandshake transmittedHandshake; + private final CompletableFuture recivedClientModlist; + private static byte[] recivedClientACK; + private final RegisteredServer syncedTo; + + SyncResult(ForgeHandshakeUtils.CachedServerHandshake transmittedHandshake, CompletableFuture recivedClientModlist, RegisteredServer syncedTo) { + this.transmittedHandshake = transmittedHandshake; + this.recivedClientModlist = recivedClientModlist; + this.syncedTo = syncedTo; + } + + public ForgeHandshakeUtils.CachedServerHandshake getTransmittedHandshake() { + return transmittedHandshake; + } + + public CompletableFuture getRecivedClientModlist() { + return recivedClientModlist; + } + + public RegisteredServer getSyncedServer() { + return syncedTo; + } + } } diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java index 6e2b94e..4d32154 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java @@ -52,9 +52,7 @@ public class ForgeHandshakeHandler { }); if (ambassador.forgeServerSwitchHandler.reSyncMap.containsKey(event.getUsername())) { - forgeConnection.sync(ambassador.forgeServerSwitchHandler.reSyncMap.remove(event.getUsername())).thenAccept((done) -> { - continuation.resume(); - }); + forgeConnection.startSync(ambassador.forgeServerSwitchHandler.reSyncMap.remove(event.getUsername()),continuation); forgeConnection.setForced(true); } else if (defaultServer != null) { //If a connection does not already exist, create one. @@ -62,9 +60,7 @@ public class ForgeHandshakeHandler { forgeServerConnectionMap.put(defaultServer, new ForgeServerConnection(defaultServer)); } //Forge Handshake - forgeConnection.sync(forgeServerConnectionMap.get(defaultServer)).thenAccept((done) -> { - continuation.resume(); - }); + forgeConnection.startSync(forgeServerConnectionMap.get(defaultServer),continuation); forgeConnection.setForced(ambassador.config.getForced(forgeConnection.getConnection().getProtocolVersion().getProtocol())); } else { continuation.resume(); diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java b/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java index b64780f..37eb5ff 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java @@ -34,8 +34,9 @@ public class ForgeServerSwitchHandler { return; } Optional forgeServerConnectionOptional = ambassador.forgeHandshakeHandler.getForgeServerConnection(event.getOriginalServer()); - Optional forgeConnection = ambassador.forgeHandshakeHandler.getForgeConnection(event.getPlayer()); - if (forgeConnection.isPresent()) { + Optional forgeConnectionOptional = ambassador.forgeHandshakeHandler.getForgeConnection(event.getPlayer()); + if (forgeConnectionOptional.isPresent()) { + ForgeConnection forgeConnection = forgeConnectionOptional.get(); ForgeServerConnection forgeServerConnection = forgeServerConnectionOptional.orElseGet(() -> new ForgeServerConnection(event.getOriginalServer())); forgeServerConnection.getHandshake().whenComplete((msg, ex) -> { if (ex != null) { @@ -56,7 +57,7 @@ public class ForgeServerSwitchHandler { event.getPlayer().setGameProfileProperties(properties); if (ambassador.config.reSyncOptionForge() != AmbassadorConfig.reSyncOption.NEVER) { - if (forgeConnection.get().getTransmittedHandshake().isEmpty() || !msg.equals(forgeConnection.get().getTransmittedHandshake().get())) { + if (forgeConnection.getSyncResult().isEmpty() || !msg.equals(forgeConnection.getSyncResult().get().getTransmittedHandshake())) { event.setResult(ServerPreConnectEvent.ServerResult.denied()); reSync(event.getPlayer(),forgeServerConnection); }