diff --git a/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java b/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java index 87281ad..b119392 100644 --- a/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java +++ b/src/main/java/org/adde0109/ambassador/AmbassadorConfig.java @@ -18,10 +18,11 @@ import java.util.Objects; public class AmbassadorConfig { - + private static final int CONFIG_VERSION = 1; private final ProxyServer server; private final Logger logger; - private Differentiators settings; + private Differentiators differentiatorsSettings; + private ReSync reSyncSettings; private AmbassadorConfig(ProxyServer server,Logger logger) { @@ -32,17 +33,28 @@ public class AmbassadorConfig { public RegisteredServer getServer(int protocolVersion) { - return settings.differentiators.get(protocolVersion).handshakeServer; + return differentiatorsSettings.differentiators.get(protocolVersion).handshakeServer; } public boolean getForced (int protocolVersion) { - return settings.differentiators.get(protocolVersion).forced; + return differentiatorsSettings.differentiators.get(protocolVersion).forced; } public boolean shouldHandle(int protocolVersion) { - return settings.differentiators.containsKey(protocolVersion); + return differentiatorsSettings.differentiators.containsKey(protocolVersion); } + public int getReSyncTimeout() { + return reSyncSettings.reSyncTimeout; + } + + public reSyncOption reSyncOptionForge() { + return reSyncSettings.reSyncForgeForge; + } + + public reSyncOption reSyncOptionVanilla() { + return reSyncSettings.reSyncForgeVanilla; + } public static AmbassadorConfig readOrCreateConfig(Path dataDirectory,ProxyServer server, Logger logger) { @@ -68,10 +80,15 @@ public class AmbassadorConfig { .build(); config.load(); - CommentedConfig settingsConfig = config.get("Differentiators"); + if (config.getOrElse("config-version",0) != CONFIG_VERSION) { + throw new Exception("Incompatible config-version detected! Please delete 'ambassador.toml' and reload."); + } + CommentedConfig differentiatorsSettingsConfig = config.get("Differentiators"); + CommentedConfig reSyncSettingsConfig = config.get("ReSync"); - ambassadorConfig.settings = ambassadorConfig.new Differentiators(settingsConfig); + ambassadorConfig.differentiatorsSettings = ambassadorConfig.new Differentiators(differentiatorsSettingsConfig); + ambassadorConfig.reSyncSettings = ambassadorConfig.new ReSync(reSyncSettingsConfig); config.save(); @@ -83,6 +100,28 @@ public class AmbassadorConfig { } } + private class ReSync { + private int reSyncTimeout = 30; + private reSyncOption reSyncForgeForge = reSyncOption.ALWAYS; + private reSyncOption reSyncForgeVanilla = reSyncOption.NEVER; + + private ReSync(CommentedConfig config) { + if (config != null) { + reSyncTimeout = config.getOrElse("resync-timeout",reSyncTimeout); + reSyncForgeForge = reSyncOption.valueOf( + config.getOrElse("resync-forge-to-forge",reSyncForgeForge.name()).toUpperCase()); + } + reSyncForgeVanilla = reSyncOption.valueOf( + config.getOrElse("unsync-forge-to-vanilla",reSyncForgeVanilla.name()).toUpperCase()); + } + } + + public enum reSyncOption { + NEVER, + ASK, + ALWAYS + } + private class Differentiators { private Map differentiators = ImmutableMap.of( 758, new DifferentiatorSettings(), @@ -113,7 +152,7 @@ public class AmbassadorConfig { private DifferentiatorSettings(CommentedConfig config) throws Exception { if (config != null) { - String serverName = config.getOrElse("forge-server", ""); + String serverName = config.getOrElse("default-forge-server", ""); if (!Objects.equals(serverName, "")) handshakeServer = server.getServer(serverName) .orElseThrow(() -> new Exception(serverName + "is not a registered server!")); diff --git a/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java b/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java index 3a9cbee..b64780f 100644 --- a/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java +++ b/src/main/java/org/adde0109/ambassador/forge/ForgeServerSwitchHandler.java @@ -4,6 +4,7 @@ import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.player.ServerPreConnectEvent; +import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.util.GameProfile; import java.util.*; @@ -13,17 +14,16 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.adde0109.ambassador.Ambassador; +import org.adde0109.ambassador.AmbassadorConfig; import org.apache.commons.collections4.map.PassiveExpiringMap; public class ForgeServerSwitchHandler { - - private static final int RESYNC_EXPIRY_TIME = 20; private final Ambassador ambassador; public final PassiveExpiringMap reSyncMap; public ForgeServerSwitchHandler(Ambassador ambassador) { this.ambassador = ambassador; - this.reSyncMap = new PassiveExpiringMap<>(RESYNC_EXPIRY_TIME,TimeUnit.SECONDS); + this.reSyncMap = new PassiveExpiringMap<>(ambassador.config.getReSyncTimeout(),TimeUnit.SECONDS); } @@ -55,11 +55,11 @@ public class ForgeServerSwitchHandler { properties.add(new GameProfile.Property("extraData", "\1FML2\1","")); event.getPlayer().setGameProfileProperties(properties); - if (!msg.equals(forgeConnection.get().getTransmittedHandshake().get())) { - event.setResult(ServerPreConnectEvent.ServerResult.denied()); - ambassador.logger.info("Kicking {} because of re-sync needed", event.getPlayer()); - event.getPlayer().disconnect(Component.text("Please reconnect")); - reSyncMap.put(event.getPlayer().getUsername(),forgeServerConnection); + if (ambassador.config.reSyncOptionForge() != AmbassadorConfig.reSyncOption.NEVER) { + if (forgeConnection.get().getTransmittedHandshake().isEmpty() || !msg.equals(forgeConnection.get().getTransmittedHandshake().get())) { + event.setResult(ServerPreConnectEvent.ServerResult.denied()); + reSync(event.getPlayer(),forgeServerConnection); + } } } continuation.resume(); @@ -74,4 +74,9 @@ public class ForgeServerSwitchHandler { continuation.resume(); } } + private void reSync(Player player, ForgeServerConnection forgeServerConnection) { + ambassador.logger.info("Kicking {} because of re-sync needed", player); + player.disconnect(Component.text("Please reconnect")); + reSyncMap.put(player.getUsername(),forgeServerConnection); + } } diff --git a/src/main/resources/default-ambassador.toml b/src/main/resources/default-ambassador.toml index 78744a0..ef41372 100644 --- a/src/main/resources/default-ambassador.toml +++ b/src/main/resources/default-ambassador.toml @@ -1,21 +1,39 @@ -#Maybe you want to have one 1.16.5 modpack-server and one 1.18.2 modpack-server behind Velocity, in order for Ambassador to tell the -#diffrence between modpacks on the connecting client, the plugin looks at the client's protocol version. +config-version = 1 +# The player can only be synced to ONE forge server at a time. +# Resync will always happen if the player isn't synced to any server and is switching to a forge server. +[ReSync] +# In seconds. How much time the player has to reconnect before the resync cancels. +resync-timeout = 30 -#You may add more diffrentiators, just make sure they have diffrent protocol versions. +# Possible values: "Always", "Never". +# Always: Always kicks the player while switching servers. The safest. +# Never: Switches server without kicking/resyncing the player. Can cause client crashes depending on the mods. + +# When the player is connecting to a forge server while being synced to another. +# Default: "always" +resync-forge-to-forge = "always" +# When the player is connecting to a vanilla server and is synced to a forge server. +# Default "never". "always" not recommended for servers with vanilla hubs/lobbies. +unsync-forge-to-vanilla = "never" + +# Maybe you want to have one 1.16.5 modpack-server and one 1.18.2 modpack-server behind Velocity, in order for Ambassador to tell the +# diffrence between modpacks on the connecting client, the plugin looks at the client's protocol version. + +# You may add more diffrentiators, just make sure they have diffrent protocol versions. [Differentiators] -#Protocol version - 1.18.2 +# Protocol version - 1.18.2 [Differentiators.758] -#The name of the forge server that forge players should be able to connect to. -#This server must have Ambassador-forge installed. -#The name should be the same as specified in the "velocity.toml" config, e.g. "lobby". -forge-server = "" +# The server that players will initially sync to when connecting to the proxy. +# When left empty; Players will be able to join but will need to resync when joining connecting to a forge server. +# The name should be the same as specified in the "velocity.toml" config, e.g. "lobby". +default-forge-server = "" -#Some modpacks are not compatible with vanilla servers. -#To make sure they don't get connected to one upon login (like a vanilla lobby), change this to true. +# Some modpacks are not compatible with vanilla servers. +# To make sure they don't get connected to one upon login (like a vanilla lobby), change this to true. forced = false -#Protocol version - 1.16.5 +# Protocol version - 1.16.5 [Differentiators.754] -forge-server = "" +default-forge-server = "" forced = false \ No newline at end of file