From 1c3c1f3ef2034402c398fac6120bcac869c3d54c Mon Sep 17 00:00:00 2001 From: Tux Date: Sun, 10 Jan 2016 12:47:49 -0500 Subject: [PATCH] Drastic bandwidth usage reduction. --- .../minecraft/redisbungee/RedisBungee.java | 48 +++++++++++-------- src/main/resources/lua/get_server_players.lua | 33 +++++++++++++ 2 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 src/main/resources/lua/get_server_players.lua diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java index d293623..e9bad75 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java @@ -60,6 +60,10 @@ public final class RedisBungee extends Plugin { private boolean usingLua; private LuaManager.Script serverToPlayersScript; private LuaManager.Script getPlayerCountScript; + private LuaManager.Script getServerPlayersScript; + + private static final Object SERVER_TO_PLAYERS_KEY = new Object(); + private final InternalCache> serverToPlayersCache = new InternalCache<>(2000); /** * Fetch the {@link RedisBungeeAPI} object created on plugin start. @@ -121,21 +125,30 @@ public final class RedisBungee extends Plugin { } final Multimap serversToPlayers() { - Collection data = (Collection) serverToPlayersScript.eval(ImmutableList.of(), getServerIds()); + try { + return serverToPlayersCache.get(SERVER_TO_PLAYERS_KEY, new Callable>() { + @Override + public Multimap call() throws Exception { + Collection data = (Collection) serverToPlayersScript.eval(ImmutableList.of(), getServerIds()); - ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); - String key = null; - for (String s : data) { - if (key == null) { - key = s; - continue; - } + ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); + String key = null; + for (String s : data) { + if (key == null) { + key = s; + continue; + } - builder.put(key, UUID.fromString(s)); - key = null; + builder.put(key, UUID.fromString(s)); + key = null; + } + + return builder.build(); + } + }); + } catch (ExecutionException e) { + throw new RuntimeException(e); } - - return builder.build(); } final int getCount() { @@ -181,15 +194,7 @@ public final class RedisBungee extends Plugin { final Set getPlayersOnServer(@NonNull String server) { checkArgument(getProxy().getServers().containsKey(server), "server does not exist"); - Multimap serversToPlayers = serversToPlayers(); - - for (String s : serversToPlayers.keySet()) { - if (s.equalsIgnoreCase(server)) { - return ImmutableSet.copyOf(serversToPlayers.get(s)); - } - } - - return Collections.emptySet(); + return ImmutableSet.copyOf((Collection) getServerPlayersScript.eval(ImmutableList.of(), ImmutableList.of(server))); } final void sendProxyCommand(@NonNull String proxyId, @NonNull String command) { @@ -234,6 +239,7 @@ public final class RedisBungee extends Plugin { LuaManager manager = new LuaManager(this); serverToPlayersScript = manager.createScript(IOUtil.readInputStreamAsString(getResourceAsStream("lua/server_to_players.lua"))); getPlayerCountScript = manager.createScript(IOUtil.readInputStreamAsString(getResourceAsStream("lua/get_player_count.lua"))); + getServerPlayersScript = manager.createScript(IOUtil.readInputStreamAsString(getResourceAsStream("lua/get_server_players.lua"))); } break; } diff --git a/src/main/resources/lua/get_server_players.lua b/src/main/resources/lua/get_server_players.lua new file mode 100644 index 0000000..49601b0 --- /dev/null +++ b/src/main/resources/lua/get_server_players.lua @@ -0,0 +1,33 @@ +local c = redis.call +local u = string.upper + +local curTime = c("TIME") +local time = tonumber(curTime[1]) + +local heartbeats = c("HGETALL", "heartbeats") +local all = {} +local key + +local preUppercased = u(ARGV[1]) + +for _, v in ipairs(heartbeats) do + if not key then + key = v + else + local n = tonumber(v) + if n then + if n + 30 >= time then + local players = c("SMEMBERS", "proxy:" .. key .. ":usersOnline") + for _, player in ipairs(players) do + local server = c("HGET", "player:" .. player, "server") + if server and u(server) == preUppercased then + all[#all + 1] = player + end + end + end + end + key = nil + end +end + +return all