From 91c3845b2e1a72ca68779bbd26035e838f8b68f4 Mon Sep 17 00:00:00 2001 From: mohammed jasem alaajel Date: Mon, 22 Apr 2024 16:27:14 +0400 Subject: [PATCH] add network id --- .../redisbungee/api/PlayerDataManager.java | 44 ++++++++++--------- .../redisbungee/api/ProxyDataManager.java | 39 +++++++++------- .../api/config/RedisBungeeConfiguration.java | 8 +++- .../api/config/loaders/ConfigLoader.java | 20 ++++++++- RedisBungee-API/src/main/resources/config.yml | 4 +- RedisBungee-Bungee/build.gradle.kts | 1 + RedisBungee-Velocity/build.gradle.kts | 1 + 7 files changed, 78 insertions(+), 39 deletions(-) diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/PlayerDataManager.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/PlayerDataManager.java index 84d46a7..a6d600a 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/PlayerDataManager.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/PlayerDataManager.java @@ -45,10 +45,14 @@ public abstract class PlayerDataManager> serverToPlayersCache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build(this::serversToPlayersBuilder); private final UnifiedJedis unifiedJedis; + private final String proxyId; + private final String networkId; public PlayerDataManager(RedisBungeePlugin

plugin) { this.plugin = plugin; this.unifiedJedis = plugin.proxyDataManager().unifiedJedis(); + this.proxyId = plugin.proxyDataManager().proxyId(); + this.networkId = plugin.proxyDataManager().networkId(); } // handle network wide @@ -84,7 +88,7 @@ public abstract class PlayerDataManager data = new HashMap<>(); data.put("server", server); data.put("last-server", server); - unifiedJedis.hset("redis-bungee::player::" + uuid + "::data", data); + unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", data); } protected void addPlayer(final UUID uuid, final InetAddress inetAddress) { Map redisData = new HashMap<>(); redisData.put("last-online", String.valueOf(0)); - redisData.put("proxy", plugin.configuration().getProxyId()); + redisData.put("proxy", this.proxyId); redisData.put("ip", inetAddress.getHostAddress()); - unifiedJedis.hset("redis-bungee::player::" + uuid + "::data", redisData); + unifiedJedis.hset("redis-bungee::" + this.networkId + "::player::" + uuid + "::data", redisData); JSONObject data = new JSONObject(); - data.put("proxy", plugin.configuration().getProxyId()); + data.put("proxy", this.proxyId); data.put("uuid", uuid); plugin.proxyDataManager().sendChannelMessage("redisbungee-player-join", data.toString()); plugin.fireEvent(plugin.createPlayerJoinedNetworkEvent(uuid)); @@ -173,10 +177,10 @@ public abstract class PlayerDataManager doPooledPipeline(Pipeline pipeline) { HashMap> responses = new HashMap<>(); for (UUID uuid : uuids) { - responses.put(uuid, pipeline.hget("redis-bungee::player::" + uuid + "::data", "server")); + responses.put(uuid, pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server")); } pipeline.sync(); responses.forEach((uuid, response) -> builder.put(response.get(), uuid)); @@ -252,7 +256,7 @@ public abstract class PlayerDataManager clusterPipeline(ClusterPipeline pipeline) { HashMap> responses = new HashMap<>(); for (UUID uuid : uuids) { - responses.put(uuid, pipeline.hget("redis-bungee::player::" + uuid + "::data", "server")); + responses.put(uuid, pipeline.hget("redis-bungee::" + networkId + "::player::" + uuid + "::data", "server")); } pipeline.sync(); responses.forEach((uuid, response) -> builder.put(response.get(), uuid)); diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/ProxyDataManager.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/ProxyDataManager.java index 5892244..05e608c 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/ProxyDataManager.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/ProxyDataManager.java @@ -24,6 +24,7 @@ import com.imaginarycode.minecraft.redisbungee.api.payloads.proxy.gson.Heartbeat import com.imaginarycode.minecraft.redisbungee.api.payloads.proxy.gson.PubSubPayloadSerializer; import com.imaginarycode.minecraft.redisbungee.api.payloads.proxy.gson.RunCommandPayloadSerializer; import com.imaginarycode.minecraft.redisbungee.api.tasks.RedisPipelineTask; +import com.imaginarycode.minecraft.redisbungee.api.util.RedisUtil; import redis.clients.jedis.*; import redis.clients.jedis.params.XAddParams; import redis.clients.jedis.params.XReadParams; @@ -38,7 +39,6 @@ import static com.google.common.base.Preconditions.checkArgument; public abstract class ProxyDataManager implements Runnable { - private static final String STREAM_ID = "redisbungee-stream"; private static final int MAX_ENTRIES = 10000; private final AtomicBoolean closed = new AtomicBoolean(false); @@ -49,8 +49,12 @@ public abstract class ProxyDataManager implements Runnable { // Proxy id, heartbeat (unix epoch from instant), players as int private final ConcurrentHashMap heartbeats = new ConcurrentHashMap<>(); + private final String networkId; + private final String proxyId; + private final String STREAM_ID; + // This different from proxy id, just to detect if there is duplicate proxy using same proxy id private final UUID dataManagerUUID = UUID.randomUUID(); @@ -63,6 +67,8 @@ public abstract class ProxyDataManager implements Runnable { this.proxyId = this.plugin.configuration().getProxyId(); this.unifiedJedis = plugin.getSummoner().obtainResource(); this.destroyProxyMembers(); + this.networkId = plugin.configuration().networkId(); + this.STREAM_ID = "network-" + this.networkId + "-redisbungee-stream"; } public abstract Set getLocalOnlineUUIDs(); @@ -106,7 +112,7 @@ public abstract class ProxyDataManager implements Runnable { public Set doPooledPipeline(Pipeline pipeline) { HashSet>> responses = new HashSet<>(); for (String proxyId : proxiesIds()) { - responses.add(pipeline.smembers("redisbungee::proxies::" + proxyId + "::online-players")); + responses.add(pipeline.smembers("redisbungee::" + networkId + "::proxies::" + proxyId + "::online-players")); } pipeline.sync(); HashSet uuids = new HashSet<>(); @@ -122,7 +128,7 @@ public abstract class ProxyDataManager implements Runnable { public Set clusterPipeline(ClusterPipeline pipeline) { HashSet>> responses = new HashSet<>(); for (String proxyId : proxiesIds()) { - responses.add(pipeline.smembers("redisbungee::proxies::" + proxyId + "::online-players")); + responses.add(pipeline.smembers("redisbungee::" + networkId + "::proxies::" + proxyId + "::online-players")); } pipeline.sync(); HashSet uuids = new HashSet<>(); @@ -207,8 +213,8 @@ public abstract class ProxyDataManager implements Runnable { for (UUID uuid : add) { addString.add(uuid.toString()); } - pipeline.srem("redisbungee::proxies::" + proxyId() + "::online-players", removeString.toArray(new String[]{})); - pipeline.sadd("redisbungee::proxies::" + proxyId() + "::online-players", addString.toArray(new String[]{})); + pipeline.srem("redisbungee::" + networkId + "::proxies::" + proxyId + "::online-players", removeString.toArray(new String[]{})); + pipeline.sadd("redisbungee::" + networkId + "::proxies::" + proxyId + "::online-players", addString.toArray(new String[]{})); pipeline.sync(); return null; } @@ -223,8 +229,8 @@ public abstract class ProxyDataManager implements Runnable { for (UUID uuid : add) { addString.add(uuid.toString()); } - pipeline.srem("redisbungee::proxies::" + proxyId() + "::online-players", removeString.toArray(new String[]{})); - pipeline.sadd("redisbungee::proxies::" + proxyId() + "::online-players", addString.toArray(new String[]{})); + pipeline.srem("redisbungee::" + networkId + "::proxies::" + proxyId + "::online-players", removeString.toArray(new String[]{})); + pipeline.sadd("redisbungee::" + networkId + "::proxies::" + proxyId + "::online-players", addString.toArray(new String[]{})); pipeline.sync(); return null; } @@ -236,12 +242,12 @@ public abstract class ProxyDataManager implements Runnable { } - // handle dead proxies "THAT" Didn't send death payload but considered dead due TIMEOUT ~10 seconds + // handle dead proxies "THAT" Didn't send death payload but considered dead due TIMEOUT ~30 seconds final Set deadProxies = new HashSet<>(); for (Map.Entry stringHeartbeatDataEntry : this.heartbeats.entrySet()) { String id = stringHeartbeatDataEntry.getKey(); long heartbeat = stringHeartbeatDataEntry.getValue().heartbeat(); - if (Instant.now().getEpochSecond() - heartbeat > 10) { + if (Instant.now().getEpochSecond() - heartbeat > RedisUtil.PROXY_TIMEOUT) { deadProxies.add(id); cleanProxy(id); } @@ -251,7 +257,7 @@ public abstract class ProxyDataManager implements Runnable { @Override public Void doPooledPipeline(Pipeline pipeline) { for (String deadProxy : deadProxies) { - pipeline.del("redisbungee::proxies::" + deadProxy + "::online-players"); + pipeline.del("redisbungee::" + networkId + "::proxies::" + deadProxy + "::online-players"); } pipeline.sync(); return null; @@ -260,7 +266,7 @@ public abstract class ProxyDataManager implements Runnable { @Override public Void clusterPipeline(ClusterPipeline pipeline) { for (String deadProxy : deadProxies) { - pipeline.del("redisbungee::proxies::" + deadProxy + "::online-players"); + pipeline.del("redisbungee::" + networkId + "::proxies::" + deadProxy + "::online-players"); } pipeline.sync(); return null; @@ -302,19 +308,19 @@ public abstract class ProxyDataManager implements Runnable { public void addPlayer(UUID uuid) { - this.unifiedJedis.sadd("redisbungee::proxies::" + this.proxyId + "::online-players", uuid.toString()); + this.unifiedJedis.sadd("redisbungee::" + this.networkId + "::proxies::" + this.proxyId + "::online-players", uuid.toString()); } public void removePlayer(UUID uuid) { - this.unifiedJedis.srem("redisbungee::proxies::" + this.proxyId + "::online-players", uuid.toString()); + this.unifiedJedis.srem("redisbungee::" + this.networkId + "::proxies::" + this.proxyId + "::online-players", uuid.toString()); } private void destroyProxyMembers() { - unifiedJedis.del("redisbungee::proxies::" + this.proxyId + "::online-players"); + unifiedJedis.del("redisbungee::" + this.networkId + "::proxies::" + this.proxyId + "::online-players"); } private Set getProxyMembers(String proxyId) { - Set uuidsStrings = unifiedJedis.smembers("redisbungee::proxies::" + proxyId + "::online-players"); + Set uuidsStrings = unifiedJedis.smembers("redisbungee::" + this.networkId + "::proxies::" + proxyId + "::online-players"); HashSet uuids = new HashSet<>(); for (String proxyMember : uuidsStrings) { uuids.add(UUID.fromString(proxyMember)); @@ -387,4 +393,7 @@ public abstract class ProxyDataManager implements Runnable { return unifiedJedis; } + public String networkId() { + return networkId; + } } diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java index e93d2fb..f76fb39 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/RedisBungeeConfiguration.java @@ -27,9 +27,10 @@ public class RedisBungeeConfiguration { private final boolean handleMotd; private final CommandsConfiguration commandsConfiguration; + private final String networkId; - public RedisBungeeConfiguration(String proxyId, List exemptAddresses, boolean kickWhenOnline, boolean handleReconnectToLastServer, boolean handleMotd, CommandsConfiguration commandsConfiguration) { + public RedisBungeeConfiguration(String networkId, String proxyId, List exemptAddresses, boolean kickWhenOnline, boolean handleReconnectToLastServer, boolean handleMotd, CommandsConfiguration commandsConfiguration) { this.proxyId = proxyId; ImmutableList.Builder addressBuilder = ImmutableList.builder(); for (String s : exemptAddresses) { @@ -40,6 +41,7 @@ public class RedisBungeeConfiguration { this.handleReconnectToLastServer = handleReconnectToLastServer; this.handleMotd = handleMotd; this.commandsConfiguration = commandsConfiguration; + this.networkId = networkId; } public String getProxyId() { @@ -79,4 +81,8 @@ public class RedisBungeeConfiguration { public CommandsConfiguration commandsConfiguration() { return commandsConfiguration; } + + public String networkId() { + return networkId; + } } diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java index a2e3791..a73b6ef 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/config/loaders/ConfigLoader.java @@ -46,6 +46,7 @@ public interface ConfigLoader extends GenericConfigLoader { final boolean kickWhenOnline = node.getNode("kick-when-online").getBoolean(true); String redisPassword = node.getNode("redis-password").getString(""); String redisUsername = node.getNode("redis-username").getString(""); + String networkId = node.getNode("network-id").getString("main"); String proxyId = node.getNode("proxy-id").getString("proxy-1"); final int maxConnections = node.getNode("max-redis-connections").getInt(10); @@ -70,6 +71,13 @@ public interface ConfigLoader extends GenericConfigLoader { plugin.logInfo("Overriding current configured proxy id {} and been set to {} by Environment variable REDISBUNGEE_PROXY_ID", proxyId, proxyIdFromEnv); proxyId = proxyIdFromEnv; } + + String networkIdFromEnv = System.getenv("REDISBUNGEE_NETWORK_ID"); + if (networkIdFromEnv != null) { + plugin.logInfo("Overriding current configured network id {} and been set to {} by Environment variable REDISBUNGEE_NETWORK_ID", networkId, networkIdFromEnv); + networkId = networkIdFromEnv; + } + // Configuration sanity checks. if (proxyId == null || proxyId.isEmpty()) { String genId = UUID.randomUUID().toString(); @@ -81,6 +89,16 @@ public interface ConfigLoader extends GenericConfigLoader { } else { plugin.logInfo("Loaded proxy id " + proxyId); } + + if (networkId.isEmpty()) { + networkId = "main"; + plugin.logWarn("network id was empty and replaced with 'main'"); + } + + plugin.logInfo("Loaded network id " + networkId); + + + boolean reconnectToLastServer = node.getNode("reconnect-to-last-server").getBoolean(); boolean handleMotd = node.getNode("handle-motd").getBoolean(true); plugin.logInfo("handle reconnect to last server: {}", reconnectToLastServer); @@ -112,7 +130,7 @@ public interface ConfigLoader extends GenericConfigLoader { boolean installPlist = node.getNode("commands", "redisbungee-legacy", "subcommands", "plist", "install").getBoolean(false); - RedisBungeeConfiguration configuration = new RedisBungeeConfiguration(proxyId, exemptAddresses, kickWhenOnline, reconnectToLastServer, handleMotd, new RedisBungeeConfiguration.CommandsConfiguration( + RedisBungeeConfiguration configuration = new RedisBungeeConfiguration(networkId, proxyId, exemptAddresses, kickWhenOnline, reconnectToLastServer, handleMotd, new RedisBungeeConfiguration.CommandsConfiguration( redisBungeeEnabled, redisBungeeLegacyEnabled, new RedisBungeeConfiguration.LegacySubCommandsConfiguration( findEnabled, glistEnabled, ipEnabled, diff --git a/RedisBungee-API/src/main/resources/config.yml b/RedisBungee-API/src/main/resources/config.yml index edbf81e..2e97d89 100644 --- a/RedisBungee-API/src/main/resources/config.yml +++ b/RedisBungee-API/src/main/resources/config.yml @@ -8,7 +8,7 @@ # - 'KeyDB' by Snapchat inc https://docs.keydb.dev/docs/download/ -# The Redis server you will use. +# The 'Redis', 'ValKey', 'KeyDB' server you will use. # these settings are ignored when cluster mode is enabled. redis-server: 127.0.0.1 redis-port: 6379 @@ -19,7 +19,7 @@ cluster-mode-enabled: false # FORMAT: # redis-cluster-servers: -# - host: 127.0.0.1 +# - host: 127.0.0.1` # port: 2020 # - host: 127.0.0.1 # port: 2021 diff --git a/RedisBungee-Bungee/build.gradle.kts b/RedisBungee-Bungee/build.gradle.kts index a8a9721..217be17 100644 --- a/RedisBungee-Bungee/build.gradle.kts +++ b/RedisBungee-Bungee/build.gradle.kts @@ -41,6 +41,7 @@ tasks { runWaterfall { waterfallVersion("1.20") environment["REDISBUNGEE_PROXY_ID"] = "bungeecord-1" + environment["REDISBUNGEE_NETWORK_ID"] = "dev" } compileJava { options.encoding = Charsets.UTF_8.name() diff --git a/RedisBungee-Velocity/build.gradle.kts b/RedisBungee-Velocity/build.gradle.kts index 390a9d7..fb9bc22 100644 --- a/RedisBungee-Velocity/build.gradle.kts +++ b/RedisBungee-Velocity/build.gradle.kts @@ -49,6 +49,7 @@ tasks { runVelocity { velocityVersion("3.3.0-SNAPSHOT") environment["REDISBUNGEE_PROXY_ID"] = "velocity-1" + environment["REDISBUNGEE_NETWORK_ID"] = "dev" } compileJava { options.encoding = Charsets.UTF_8.name()