From 682970912331b23b77dd070dc35e57bf8fa1fbb1 Mon Sep 17 00:00:00 2001 From: s809 <43530948+s809@users.noreply.github.com> Date: Sat, 30 Mar 2024 23:40:05 +0500 Subject: [PATCH] Fix reconnection logic --- .../client/ClientNetworkState.java | 2 +- .../server/RemotePlayerConnectionHandler.java | 13 ++++--- .../core/network/netty/NettyClient.java | 34 ++++++++++++------- .../minecraft/IMinecraftSharedWrapper.java | 4 +++ 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/ClientNetworkState.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/ClientNetworkState.java index deb834db5..ef0b5b249 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/ClientNetworkState.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/ClientNetworkState.java @@ -84,7 +84,7 @@ public class ClientNetworkState implements Closeable { return new String[]{ this.client.getRemoteAddress() != null - ? "Connected, ready: " + this.isReady() + ? (this.isReady() ? "Connected to server" : "Connecting to server...") : MessageFormat.format("Disconnected, attempts left: {0} / {1}", this.client.getReconnectionAttemptsLeft(), NettyClient.RECONNECTION_ATTEMPTS) }; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java index fe92cc14d..247e9d121 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java @@ -6,6 +6,7 @@ import com.google.common.collect.Maps; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener; import com.seibel.distanthorizons.core.config.types.ConfigEntry; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.level.DhServerLevel; import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfig; import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfigChangeListener; @@ -23,6 +24,7 @@ import com.seibel.distanthorizons.core.network.netty.NettyServer; import com.seibel.distanthorizons.core.network.netty.TrackableNettyMessage; import com.seibel.distanthorizons.core.network.plugin.PluginChannelHandler; import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.Nullable; @@ -40,8 +42,9 @@ import static com.seibel.distanthorizons.core.config.Config.Client.Advanced.Mult public class RemotePlayerConnectionHandler implements Closeable { - private static final boolean DEBUG_ALWAYS_USE_OVERRIDES = true; + private static final boolean DEBUG_ENABLE_OVERRIDES_IN_LAN = false; + private static final IMinecraftSharedWrapper MC_SERVER = SingletonInjector.INSTANCE.get(IMinecraftSharedWrapper.class); private static final ConfigEntry GENERATE_MULTIPLE_DIMENSIONS_CONFIG = Config.Client.Advanced.Multiplayer.ServerNetworking.generateMultipleDimensions; private final NettyServer server = new NettyServer(ServerNetworking.serverPort.get()); @@ -52,7 +55,7 @@ public class RemotePlayerConnectionHandler implements Closeable private final PluginChannelHandler pluginChannelHandler = new PluginChannelHandler(); private final ConfigChangeListener portChangeListener = new ConfigChangeListener<>(ServerNetworking.serverPort, this::onServerPortChanged); private final ConfigChangeListener connectIpOverrideChangeListener = new ConfigChangeListener<>(ServerNetworking.connectIpOverride, this::broadcastConnectInfo); - private final ConfigChangeListener connectPortOverrideChangeListener = new ConfigChangeListener<>(ServerNetworking.serverPort, this::broadcastConnectInfo); + private final ConfigChangeListener connectPortOverrideChangeListener = new ConfigChangeListener<>(ServerNetworking.connectPortOverride, this::broadcastConnectInfo); public NettyServer server() { return this.server; } @@ -126,9 +129,9 @@ public class RemotePlayerConnectionHandler implements Closeable } private void broadcastConnectInfo(@Nullable Object ignored) { - for (ServerPlayerState serverPlayerState : this.getConnectedPlayers()) + for (IServerPlayerWrapper serverPlayer : MC_SERVER.getPlayerList()) { - this.sendConnectInfo(serverPlayerState.serverPlayer); + this.sendConnectInfo(serverPlayer); } } private void sendConnectInfo(IServerPlayerWrapper serverPlayer) @@ -140,7 +143,7 @@ public class RemotePlayerConnectionHandler implements Closeable // IP/port overrides are intended for using with port forwarding services, // and LAN clients are unlikely to need to hop through internet InetAddress ip = ((InetSocketAddress) serverPlayer.getRemoteAddress()).getAddress(); - boolean isLanPlayer = !DEBUG_ALWAYS_USE_OVERRIDES && + boolean isLanPlayer = !DEBUG_ENABLE_OVERRIDES_IN_LAN && (ip.isLoopbackAddress() || ip.isLinkLocalAddress() || ip.isSiteLocalAddress()); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/netty/NettyClient.java b/core/src/main/java/com/seibel/distanthorizons/core/network/netty/NettyClient.java index a7a324100..df0513450 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/network/netty/NettyClient.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/netty/NettyClient.java @@ -38,6 +38,7 @@ import java.net.InetSocketAddress; import java.util.EnumSet; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; public class NettyClient extends NettyEventSource implements INettyConnection, AutoCloseable @@ -88,9 +89,9 @@ public class NettyClient extends NettyEventSource implements INettyConnection, A private Channel channel; - private int reconnectionAttemptsLeft = RECONNECTION_ATTEMPTS; + private final AtomicInteger reconnectionAttemptsLeft = new AtomicInteger(RECONNECTION_ATTEMPTS); /** Returns the amount of reconnections the client will attempt to perform before giving up. */ - public int getReconnectionAttemptsLeft() { return this.reconnectionAttemptsLeft; } + public int getReconnectionAttemptsLeft() { return this.reconnectionAttemptsLeft.get(); } public NettyClient() @@ -115,7 +116,10 @@ public class NettyClient extends NettyEventSource implements INettyConnection, A public void resetAndConnectTo(String host, int port) { - this.connectionState.set(EConnectionState.INITIAL); + if (this.connectionState.getAndUpdate(state -> state != EConnectionState.CLOSED ? EConnectionState.INITIAL : state) == EConnectionState.CLOSED) + { + return; + } this.address = new InetSocketAddress(host, port); if (this.channel != null) @@ -123,7 +127,7 @@ public class NettyClient extends NettyEventSource implements INettyConnection, A this.channel.close().syncUninterruptibly(); } - this.reconnectionAttemptsLeft = RECONNECTION_ATTEMPTS; + this.reconnectionAttemptsLeft.set(RECONNECTION_ATTEMPTS); this.connect(); } @@ -157,21 +161,25 @@ public class NettyClient extends NettyEventSource implements INettyConnection, A if (this.connectionState.get() == EConnectionState.OPEN) { - this.reconnectionAttemptsLeft--; - LOGGER.info("Reconnection attempts left: [" + this.reconnectionAttemptsLeft + "] of [" + RECONNECTION_ATTEMPTS + "]."); + int reconnectionAttemptsLeft = this.reconnectionAttemptsLeft.decrementAndGet(); + LOGGER.info("Reconnection attempts left: [" + this.reconnectionAttemptsLeft.get() + "] of [" + RECONNECTION_ATTEMPTS + "]."); - if (this.reconnectionAttemptsLeft != 0) + if (reconnectionAttemptsLeft != 0) { - this.connectionState.set(EConnectionState.RECONNECTING); - this.workerGroup.schedule(() -> + if (this.connectionState.compareAndSet(EConnectionState.OPEN, EConnectionState.RECONNECTING)) { - this.connectionState.set(EConnectionState.INITIAL); - this.connect(); - }, RECONNECTION_DELAY_SEC, TimeUnit.SECONDS); + this.workerGroup.schedule(() -> + { + if (this.connectionState.compareAndSet(EConnectionState.RECONNECTING, EConnectionState.INITIAL)) + { + this.connect(); + } + }, RECONNECTION_DELAY_SEC, TimeUnit.SECONDS); + } } else { - this.connectionState.set(EConnectionState.GOT_CLOSE_REASON); + this.connectionState.compareAndSet(EConnectionState.OPEN, EConnectionState.GOT_CLOSE_REASON); } } }); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java index 7f7594c8b..b7038e26c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java @@ -19,9 +19,11 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.minecraft; +import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; import java.io.File; +import java.util.List; //TODO: Maybe have IMCClientWrapper & IMCDedicatedWrapper extend this interface??? public interface IMinecraftSharedWrapper extends IBindable @@ -30,4 +32,6 @@ public interface IMinecraftSharedWrapper extends IBindable File getInstallationDirectory(); + List getPlayerList(); + }