diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java index 00ecf23..75ddc09 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java @@ -117,10 +117,8 @@ public final class RedisBungee extends Plugin { final Multimap serversToPlayers() { ImmutableMultimap.Builder multimapBuilder = ImmutableMultimap.builder(); - for (UUID p : getPlayers()) { - String name = dataManager.getServer(p); - if (name != null) - multimapBuilder.put(name, p); + for (ServerInfo info : getProxy().getServers().values()) { + multimapBuilder.putAll(info.getName(), getPlayersOnServer(info.getName())); } return multimapBuilder.build(); } @@ -130,23 +128,12 @@ public final class RedisBungee extends Plugin { } final int getCurrentCount() { - int c = getProxy().getOnlineCount(); + int c = 0; if (pool != null) { Jedis rsc = pool.getResource(); try { - List serverIds = getServerIds(); - Map counts = rsc.hgetAll("playerCounts"); - for (Map.Entry entry : counts.entrySet()) { - if (!serverIds.contains(entry.getKey())) - continue; - - if (entry.getKey().equals(serverId)) continue; - - try { - c += Integer.valueOf(entry.getValue()); - } catch (NumberFormatException e) { - rsc.hset("playerCounts", entry.getKey(), "0"); - } + for (String i : getServerIds()) { + c += rsc.scard("proxy:" + i + ":usersOnline"); } } catch (JedisConnectionException e) { // Redis server has disappeared! @@ -207,8 +194,29 @@ public final class RedisBungee extends Plugin { } final Set getPlayersOnServer(@NonNull String server) { - checkArgument(getProxy().getServerInfo(server) != null, "server doesn't exist"); - return ImmutableSet.copyOf(serversToPlayers().get(server)); + ServerInfo info = getProxy().getServerInfo(server); + checkArgument(info != null, "server doesn't exist"); + + ImmutableSet.Builder setBuilder = ImmutableSet.builder(); + + Jedis jedis = pool.getResource(); + try { + for (String s : jedis.smembers("server:" + server + ":players")) { + try { + setBuilder.add(UUID.fromString(s)); + } catch (IllegalArgumentException ignored) { + } + } + } catch (JedisConnectionException e) { + // Redis server has disappeared! + getLogger().log(Level.SEVERE, "Unable to get connection from pool - did your Redis server go away?", e); + pool.returnBrokenResource(jedis); + throw new RuntimeException("Unable to publish command", e); + } finally { + pool.returnResource(jedis); + } + + return setBuilder.build(); } final void sendProxyCommand(@NonNull String proxyId, @NonNull String command) { @@ -252,7 +260,6 @@ public final class RedisBungee extends Plugin { if (pool != null) { Jedis tmpRsc = pool.getResource(); try { - tmpRsc.hset("playerCounts", serverId, "0"); // reset tmpRsc.hset("heartbeats", serverId, String.valueOf(System.currentTimeMillis())); } finally { pool.returnResource(tmpRsc); @@ -265,13 +272,10 @@ public final class RedisBungee extends Plugin { public void run() { Jedis rsc = pool.getResource(); try { - Pipeline pipeline = rsc.pipelined(); - pipeline.hset("playerCounts", serverId, String.valueOf(getProxy().getOnlineCount())); - pipeline.hset("heartbeats", serverId, String.valueOf(System.currentTimeMillis())); - pipeline.sync(); + rsc.hset("heartbeats", serverId, String.valueOf(System.currentTimeMillis())); } catch (JedisConnectionException e) { // Redis server has disappeared! - getLogger().log(Level.SEVERE, "Unable to update proxy counts - did your Redis server go away?", e); + getLogger().log(Level.SEVERE, "Unable to update heartbeat - did your Redis server go away?", e); pool.returnBrokenResource(rsc); } finally { pool.returnResource(rsc); @@ -341,7 +345,6 @@ public final class RedisBungee extends Plugin { consumer.stop(); Jedis tmpRsc = pool.getResource(); try { - tmpRsc.hdel("playerCounts", serverId); tmpRsc.hdel("heartbeats", serverId); if (tmpRsc.scard("proxy:" + serverId + ":usersOnline") > 0) { Set players = tmpRsc.smembers("proxy:" + serverId + ":usersOnline"); diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConsumer.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConsumer.java index c2ade91..723bcdd 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConsumer.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConsumer.java @@ -59,6 +59,10 @@ public class RedisBungeeConsumer implements Runnable { PlayerLoggedOffConsumerEvent event1 = (PlayerLoggedOffConsumerEvent) event; Pipeline pipeline = jedis.pipelined(); jedis.hset("player:" + event1.getPlayer().getUniqueId().toString(), "online", String.valueOf(System.currentTimeMillis())); + + if (event1.getPlayer().getServer() != null) + pipeline.srem("server:" + event1.getPlayer().getServer().getInfo().getName() + ":players", event1.getPlayer().getUniqueId().toString()); + RedisUtil.cleanUpPlayer(event1.getPlayer().getUniqueId().toString(), pipeline); pipeline.publish("redisbungee-data", RedisBungee.getGson().toJson(new DataManager.DataManagerMessage(event1.getPlayer().getUniqueId(), DataManager.DataManagerMessage.Action.LEAVE))); pipeline.sync(); @@ -66,6 +70,11 @@ public class RedisBungeeConsumer implements Runnable { PlayerChangedServerConsumerEvent event1 = (PlayerChangedServerConsumerEvent) event; Pipeline pipeline = jedis.pipelined(); pipeline.hset("player:" + event1.getPlayer().getUniqueId().toString(), "server", event1.getNewServer().getName()); + + if (event1.getOldServer() != null) + pipeline.srem("server:" + event1.getOldServer().getName() + ":players", event1.getPlayer().getUniqueId().toString()); + + pipeline.sadd("server:" + event1.getNewServer().getName() + ":players", event1.getPlayer().getUniqueId().toString()); pipeline.publish("redisbungee-data", RedisBungee.getGson().toJson(new DataManager.DataManagerMessage(event1.getPlayer().getUniqueId(), DataManager.DataManagerMessage.Action.SERVER_CHANGE))); pipeline.sync(); } diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisUtil.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisUtil.java index ebb1ddc..00730dc 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisUtil.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisUtil.java @@ -11,10 +11,15 @@ import redis.clients.jedis.Pipeline; class RedisUtil { public static void cleanUpPlayer(String player, Jedis rsc) { - rsc.srem("proxy:" + RedisBungee.getApi().getServerId() + ":usersOnline", player); - rsc.hdel("player:" + player, "server"); - rsc.hdel("player:" + player, "ip"); - rsc.hdel("player:" + player, "proxy"); + String server = rsc.hget("player:" + player, "server"); + + Pipeline pipeline = rsc.pipelined(); + + if (server != null) + pipeline.srem("server:" + server + ":players", player); + + cleanUpPlayer(player, pipeline); + pipeline.sync(); } public static void cleanUpPlayer(String player, Pipeline rsc) { diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/consumerevents/PlayerChangedServerConsumerEvent.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/consumerevents/PlayerChangedServerConsumerEvent.java index ca704f8..42ba59d 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/consumerevents/PlayerChangedServerConsumerEvent.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/consumerevents/PlayerChangedServerConsumerEvent.java @@ -6,14 +6,19 @@ */ package com.imaginarycode.minecraft.redisbungee.consumerevents; -import lombok.AllArgsConstructor; import lombok.Getter; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; -@AllArgsConstructor @Getter public class PlayerChangedServerConsumerEvent implements ConsumerEvent { private final ProxiedPlayer player; + private final ServerInfo oldServer; private final ServerInfo newServer; + + public PlayerChangedServerConsumerEvent(ProxiedPlayer player, ServerInfo newServer) { + this.player = player; + this.newServer = newServer; + this.oldServer = player.getServer() != null ? player.getServer().getInfo() : null; + } }