diff --git a/build.gradle b/build.gradle index 6d226ba..509d898 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'org.adde0109' -version '0.2.2' +version '0.2.3' repositories { maven { diff --git a/src/main/java/org/adde0109/ambassador/Ambassador.java b/src/main/java/org/adde0109/ambassador/Ambassador.java index 99aac65..8e57429 100644 --- a/src/main/java/org/adde0109/ambassador/Ambassador.java +++ b/src/main/java/org/adde0109/ambassador/Ambassador.java @@ -22,7 +22,7 @@ import org.slf4j.Logger; import java.nio.file.Path; import java.util.*; -@Plugin(id = "ambassador", name = "Ambassador", version = "0.2.2", authors = {"adde0109"}) +@Plugin(id = "ambassador", name = "Ambassador", version = "0.2.3", authors = {"adde0109"}) public class Ambassador { private final ProxyServer server; @@ -82,6 +82,7 @@ public class Ambassador { continuation.resume(); } else if (forgeConnection.isPresent()) { if (forgeConnection.get().getTransmittedHandshake().isPresent() + && forgeConnection.get().getRecivedClientModlist().isPresent() && msg.equals(forgeConnection.get().getTransmittedHandshake().get())) { //The client's registry is the same as the server's continuation.resume(); diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java b/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java index 893cca6..dc22ba9 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeConnection.java @@ -6,6 +6,8 @@ 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 org.slf4j.Logger; + import java.io.EOFException; import java.util.List; import java.util.Optional; @@ -13,26 +15,30 @@ import java.util.concurrent.CompletableFuture; public class ForgeConnection { + private final Logger logger; private final LoginPhaseConnection connection; - private byte[] recivedClientModlist; + private Optional recivedClientModlist = Optional.empty(); private static byte[] recivedClientACK; + private boolean ignoreSyncExepction = false; private Optional transmittedHandshake = Optional.empty(); private Optional syncedTo = Optional.empty(); - public ForgeConnection(LoginPhaseConnection connection) { + public ForgeConnection(LoginPhaseConnection connection, Logger logger) { this.connection = connection; + this.logger = logger; } - public static CompletableFuture testIfForge(LoginPhaseConnection connection) { + public CompletableFuture testIfForge(LoginPhaseConnection connection) { CompletableFuture future = new CompletableFuture<>(); byte[] testPacket = ForgeHandshakeUtils.generateTestPacket(); connection.sendLoginPluginMessage(MinecraftChannelIdentifier.create("fml", "loginwrapper"), testPacket, responseBody -> { future.complete(responseBody != null); + ignoreSyncExepction = responseBody == null; }); return future; } @@ -44,16 +50,24 @@ public class ForgeConnection { forgeServerConnection.getHandshake().whenComplete((msg,ex) -> { if (ex != null) { future.complete(false); - } + logger.warn("Sync Exception: " + ex); + } else { sendModlist(msg.modListPacket).thenAccept((response) -> { - recivedClientModlist = response; + if (!ignoreSyncExepction && response == null) { + logger.warn("Sync Exception: Client responded with an empty body."); + } + recivedClientModlist = Optional.ofNullable(response); }); sendOther(msg.otherPackets).thenAccept((response) -> { + if (!ignoreSyncExepction && response == null) { + logger.warn("Sync Exception: Client responded with an empty body."); + } ForgeConnection.recivedClientACK = response; transmittedHandshake = Optional.of(msg); syncedTo = Optional.of(forgeServerConnection.getServer()); }); - future.complete(true); + future.complete(true); + } }); return future; } @@ -85,9 +99,20 @@ public class ForgeConnection { int packetID = ForgeHandshakeUtils.readVarInt(data); if (packetID == 1) { - event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(getRecivedClientModlist())); + 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; + } } else { - event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(getRecivedClientACK())); + if (getRecivedClientACK() != null) { + event.setResult(ServerLoginPluginMessageEvent.ResponseResult.reply(getRecivedClientACK())); + } else { + continuation.resumeWithException(new Exception("No response available.")); + return; + } } continuation.resume(); } @@ -100,7 +125,7 @@ public class ForgeConnection { return transmittedHandshake; } - public byte[] getRecivedClientModlist() { + public Optional getRecivedClientModlist() { return recivedClientModlist; } diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java index bf6619b..a82ba4b 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeHandler.java @@ -50,8 +50,8 @@ public class ForgeHandshakeHandler { } RegisteredServer defaultServer = config.getServer(event.getConnection().getProtocolVersion().getProtocol()); - ForgeConnection forgeConnection = new ForgeConnection((LoginPhaseConnection) event.getConnection()); - ForgeConnection.testIfForge((LoginPhaseConnection) event.getConnection()) + ForgeConnection forgeConnection = new ForgeConnection((LoginPhaseConnection) event.getConnection(), logger); + forgeConnection.testIfForge((LoginPhaseConnection) event.getConnection()) .thenAccept((isForge) -> { registerForgeConnection(forgeConnection); }); @@ -113,6 +113,8 @@ public class ForgeHandshakeHandler { incomingForgeConnections.get(event.getConnection().getPlayer().getRemoteAddress()) .handleServerHandshakePacket(event,continuation); } else { + //This will lead to "multiplayer.disconnect.unexpected_query_response" + //and will be handled during KickFromServerEvent. continuation.resume(); } } diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java index 074ea63..93fbe26 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeHandshakeUtils.java @@ -77,7 +77,7 @@ public class ForgeHandshakeUtils { private HandshakeReceiver(ServerPing serverPing) throws Exception { if ((serverPing.getModinfo().isEmpty()) || (!Objects.equals(serverPing.getModinfo().get().getType(), "ambassador"))) { - throw new HandshakeNotAvailableException("The specified Forge server is not running the Forge-side version of this plugin!"); + throw new HandshakeNotAvailableException("The specified Forge server is not running the Ambassador-Forge mod!"); } ModInfo.Mod pair = serverPing.getModinfo().orElseThrow(IllegalAccessError::new).getMods().get(0);