From 031d2b922597e4e2ecb58e79d915c9a217b674f1 Mon Sep 17 00:00:00 2001 From: Adrian Bergqvist Date: Thu, 23 Jun 2022 22:24:04 +0200 Subject: [PATCH] Handle when handshake server is offline --- build.gradle | 1 + gradle/wrapper/gradle-wrapper.properties | 2 +- .../org/adde0109/ambassador/Ambassador.java | 11 ---- .../adde0109/ambassador/AmbassadorConfig.java | 3 - .../ambassador/ForgeHandshakeDataHandler.java | 56 +++++++++++++++---- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/build.gradle b/build.gradle index f488406..9fd75eb 100644 --- a/build.gradle +++ b/build.gradle @@ -16,5 +16,6 @@ repositories { dependencies { implementation 'com.velocitypowered:velocity-api:3.1.2-SNAPSHOT' implementation 'com.electronwill.night-config:toml:3.6.5' + implementation 'com.google.guava:guava:31.1-jre' annotationProcessor 'com.velocitypowered:velocity-api:3.1.2-SNAPSHOT' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 69a9715..ffed3a2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/org/adde0109/ambassador/Ambassador.java b/src/main/java/org/adde0109/ambassador/Ambassador.java index 3ecc1bb..fdfeab4 100644 --- a/src/main/java/org/adde0109/ambassador/Ambassador.java +++ b/src/main/java/org/adde0109/ambassador/Ambassador.java @@ -1,11 +1,5 @@ package org.adde0109.ambassador; -import com.electronwill.nightconfig.core.CommentedConfig; -import com.electronwill.nightconfig.core.ConfigSpec; -import com.electronwill.nightconfig.core.UnmodifiableConfig; -import com.electronwill.nightconfig.core.file.CommentedFileConfig; -import com.electronwill.nightconfig.core.io.ParsingException; -import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; @@ -14,13 +8,8 @@ import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.server.RegisteredServer; -import ninja.leaping.configurate.commented.SimpleCommentedConfigurationNode; import org.slf4j.Logger; -import com.electronwill.nightconfig.core.file.FileConfig; -import java.io.IOException; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.*; diff --git a/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java b/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java index 9ec75c9..2b50c3b 100644 --- a/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java +++ b/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java @@ -3,7 +3,6 @@ package org.adde0109.ambassador; import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.file.CommentedFileConfig; -import com.electronwill.nightconfig.core.io.ParsingException; import com.google.common.collect.ImmutableMap; import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.server.RegisteredServer; @@ -13,11 +12,9 @@ import java.io.IOException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; -import java.rmi.NoSuchObjectException; import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.Optional; public class AmbassadorConfig { diff --git a/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java b/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java index d2de2fd..b4d854b 100644 --- a/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java +++ b/src/main/java/org/adde0109/ambassador/ForgeHandshakeDataHandler.java @@ -2,11 +2,10 @@ 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.permission.PermissionsSetupEvent; import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent; +import com.velocitypowered.api.event.player.ServerPostConnectEvent; import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.api.proxy.LoginPhaseConnection; import com.velocitypowered.api.proxy.Player; @@ -15,8 +14,9 @@ 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 java.net.InetSocketAddress; import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; +import net.kyori.adventure.text.Component; import org.slf4j.Logger; import java.nio.charset.StandardCharsets; @@ -29,7 +29,8 @@ public class ForgeHandshakeDataHandler { public Map recivedClientModlist = new HashMap(); public LoginPhaseConnection connection; - private Collection pendingConnections = new HashSet(); + + private Map syncedConnections = new HashMap(); private static final int PACKET_LENGTH_INDEX = 14; //length of "fml:handshake"+1 @@ -48,13 +49,38 @@ public class ForgeHandshakeDataHandler { return; } RegisteredServer server = config.getServer(event.getConnection().getProtocolVersion().getProtocol()); - getHandshake(server).thenAccept(p -> { - sendModlist(p.modListPacket,(LoginPhaseConnection) event.getConnection(),server); - sendOther(p.otherPackets,(LoginPhaseConnection) event.getConnection()); + getHandshake(server).whenComplete((msg,ex) -> { + if (ex != null) { + logger.warn("Could not sync player '" + event.getUsername() + "' to server '" + + server.getServerInfo().getName() +"' Cause: " + ex.getMessage()); + } else { + sendModlist(msg.modListPacket, (LoginPhaseConnection) event.getConnection(), server); + sendOther(msg.otherPackets, (LoginPhaseConnection) event.getConnection(), server); + } continuation.resume(); }); } + @Subscribe + public void onServerPostConnectEvent(ServerPostConnectEvent event) { + RegisteredServer server = getSyncedServer(event.getPlayer()).orElse(null); + if(server != null) { + event.getPlayer().sendMessage(Component.text("Synced to Server: " + server.getServerInfo().getName())); + } + } + + + public Optional getSyncedServer(Player player) { + return getSyncedServer(player.getRemoteAddress()); + } + + private Optional getSyncedServer(InetSocketAddress socketAddress) { + syncedConnections.keySet().removeIf(c -> !c.isActive()); + InboundConnection key = syncedConnections.keySet().stream() + .filter((c) -> c.getRemoteAddress()==socketAddress).findFirst().orElse(null); + return Optional.ofNullable(syncedConnections.get(key)); + } + @Subscribe public void onServerLoginPluginMessageEvent(ServerLoginPluginMessageEvent event, Continuation continuation) { if((!recivedClientModlist.containsKey(event.getConnection().getServer())) || (recivedClientACK == null)) { @@ -101,11 +127,12 @@ public class ForgeHandshakeDataHandler { connection.sendLoginPluginMessage(MinecraftChannelIdentifier.create("fml","loginwrapper"), modListPacket, responseBody -> recivedClientModlist.put(server,responseBody)); } - private void sendOther(List otherPackets, LoginPhaseConnection connection) { + private void sendOther(List otherPackets, LoginPhaseConnection connection, RegisteredServer server) { for (int i = 0;i recivedClientACK = responseBody : responseBody -> { - pendingConnections.add(connection); + syncedConnections.put(connection,server); + syncedConnections.keySet().removeIf(c -> !c.isActive()); }); } } @@ -151,14 +178,19 @@ public class ForgeHandshakeDataHandler { } private void ping(CompletableFuture future) { - forgeServer.ping().thenAccept((s) -> onBackendPong(s, future)); + forgeServer.ping().whenComplete((msg,ex) -> { + if (ex != null) { + future.completeExceptionally(ex); + } else { + onBackendPong(msg, future); + } + }); } public void onBackendPong(ServerPing status, CompletableFuture future) { numberOfRecivedParts++; if ((!status.getModinfo().isPresent()) || (!Objects.equals(status.getModinfo().get().getType(), "ambassador"))) { - future.cancel(true); - logger.error("The specified Forge server is not running the Forge-side version of this plugin!"); + future.completeExceptionally(new Exception("The specified Forge server is not running the Forge-side version of this plugin!")); return; }