From 10466a9464789bf6b3a939c014ef2cc5d907baf6 Mon Sep 17 00:00:00 2001 From: Tux Date: Sat, 18 Apr 2015 10:13:02 -0400 Subject: [PATCH] Add exempted IP addresses (closes #19) and refactored configuration. --- .../minecraft/redisbungee/DataManager.java | 6 +-- .../minecraft/redisbungee/RedisBungee.java | 47 +++++++++---------- .../minecraft/redisbungee/RedisBungeeAPI.java | 4 +- .../redisbungee/RedisBungeeCommands.java | 2 +- .../redisbungee/RedisBungeeConfiguration.java | 45 ++++++++++++++++++ .../redisbungee/RedisBungeeListener.java | 8 +++- src/main/resources/example_config.yml | 14 ++++-- 7 files changed, 88 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConfiguration.java diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/DataManager.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/DataManager.java index f096a99..5971297 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/DataManager.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/DataManager.java @@ -80,7 +80,7 @@ public class DataManager implements Listener { ProxiedPlayer player = plugin.getProxy().getPlayer(uuid); if (player != null) - return plugin.getServerId(); + return RedisBungee.getConfiguration().getServerId(); String server = proxyCache.get(uuid); @@ -165,7 +165,7 @@ public class DataManager implements Listener { plugin.getLogger().info("I found a funny number for when " + uuid + " was last online!"); boolean found = false; for (String proxyId : plugin.getServerIds()) { - if (proxyId.equals(plugin.getServerId())) continue; + if (proxyId.equals(RedisBungee.getConfiguration().getServerId())) continue; if (tmpRsc.sismember("proxy:" + proxyId + ":usersOnline", uuid.toString())) { found = true; break; @@ -225,7 +225,7 @@ public class DataManager implements Listener { String source = jsonObject.get("source").getAsString(); - if (source.equals(plugin.getServerId())) + if (source.equals(RedisBungee.getConfiguration().getServerId())) return; DataManagerMessage.Action action = DataManagerMessage.Action.valueOf(jsonObject.get("action").getAsString()); diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java index 3bf3ef1..12b1609 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungee.java @@ -16,6 +16,7 @@ import com.imaginarycode.minecraft.redisbungee.util.UUIDFetcher; import com.imaginarycode.minecraft.redisbungee.util.UUIDTranslator; import com.squareup.okhttp.Dispatcher; import com.squareup.okhttp.OkHttpClient; +import lombok.AccessLevel; import lombok.Getter; import lombok.NonNull; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -45,17 +46,17 @@ import static com.google.common.base.Preconditions.checkArgument; * The only function of interest is {@link #getApi()}, which exposes some functions in this class. */ public final class RedisBungee extends Plugin { - private static Configuration configuration; @Getter private static Gson gson = new Gson(); private static RedisBungeeAPI api; + @Getter(AccessLevel.PACKAGE) private static PubSubListener psl = null; @Getter private JedisPool pool; @Getter private UUIDTranslator uuidTranslator; - @Getter - private String serverId; + @Getter(AccessLevel.PACKAGE) + private static RedisBungeeConfiguration configuration; @Getter private DataManager dataManager; @Getter @@ -77,10 +78,6 @@ public final class RedisBungee extends Plugin { return api; } - static Configuration getConfiguration() { - return configuration; - } - static PubSubListener getPubSubListener() { return psl; } @@ -114,7 +111,7 @@ public final class RedisBungee extends Plugin { getLogger().log(Level.SEVERE, "Unable to fetch all server IDs", e); if (jedis != null) pool.returnBrokenResource(jedis); - return Collections.singletonList(serverId); + return Collections.singletonList(configuration.getServerId()); } finally { pool.returnResource(jedis); } @@ -164,15 +161,12 @@ public final class RedisBungee extends Plugin { } final Set getPlayers() { - ImmutableSet.Builder setBuilder = ImmutableSet.builder().addAll(getLocalPlayers()); + ImmutableSet.Builder setBuilder = ImmutableSet.builder(); if (pool != null) { Jedis rsc = pool.getResource(); try { List keys = new ArrayList<>(); for (String i : getServerIds()) { - if (i.equals(serverId)) - continue; - keys.add("proxy:" + i + ":usersOnline"); } if (!keys.isEmpty()) { @@ -236,7 +230,7 @@ public final class RedisBungee extends Plugin { if (pool != null) { Jedis tmpRsc = pool.getResource(); try { - tmpRsc.hset("heartbeats", serverId, String.valueOf(System.nanoTime())); + tmpRsc.hset("heartbeats", configuration.getServerId(), String.valueOf(System.nanoTime())); } finally { pool.returnResource(tmpRsc); } @@ -247,7 +241,7 @@ public final class RedisBungee extends Plugin { public void run() { Jedis rsc = pool.getResource(); try { - rsc.hset("heartbeats", serverId, String.valueOf(System.nanoTime())); + rsc.hset("heartbeats", configuration.getServerId(), String.valueOf(System.nanoTime())); } catch (JedisConnectionException e) { // Redis server has disappeared! getLogger().log(Level.SEVERE, "Unable to update heartbeat - did your Redis server go away?", e); @@ -259,7 +253,7 @@ public final class RedisBungee extends Plugin { } }, 0, 3, TimeUnit.SECONDS); dataManager = new DataManager(this); - if (configuration.getBoolean("register-bungee-commands", true)) { + if (configuration.isRegisterBungeeCommands()) { getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.GlistCommand(this)); getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.FindCommand(this)); getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.LastSeenCommand(this)); @@ -270,7 +264,7 @@ public final class RedisBungee extends Plugin { getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.ServerIds()); getProxy().getPluginManager().registerCommand(this, new RedisBungeeCommands.PlayerProxyCommand(this)); api = new RedisBungeeAPI(this); - getProxy().getPluginManager().registerListener(this, new RedisBungeeListener(this)); + getProxy().getPluginManager().registerListener(this, new RedisBungeeListener(this, configuration.getExemptAddresses())); getProxy().getPluginManager().registerListener(this, dataManager); psl = new PubSubListener(); getProxy().getScheduler().runAsync(this, psl); @@ -280,14 +274,14 @@ public final class RedisBungee extends Plugin { Jedis tmpRsc = pool.getResource(); try { Set players = new HashSet<>(getLocalPlayersAsUuidStrings()); - Set redisCollection = tmpRsc.smembers("proxy:" + serverId + ":usersOnline"); + Set redisCollection = tmpRsc.smembers("proxy:" + configuration.getServerId() + ":usersOnline"); for (String member : redisCollection) { if (!players.contains(member)) { // Are they simply on a different proxy? boolean found = false; for (String proxyId : getServerIds()) { - if (proxyId.equals(serverId)) continue; + if (proxyId.equals(configuration.getServerId())) continue; if (tmpRsc.sismember("proxy:" + proxyId + ":usersOnline", member)) { // Just clean up the set. found = true; @@ -298,7 +292,7 @@ public final class RedisBungee extends Plugin { RedisUtil.cleanUpPlayer(member, tmpRsc); getLogger().warning("Player found in set that was not found locally and globally: " + member); } else { - tmpRsc.srem("proxy:" + serverId + ":usersOnline", member); + tmpRsc.srem("proxy:" + configuration.getServerId() + ":usersOnline", member); getLogger().warning("Player found in set that was not found locally, but is on another proxy: " + member); } } @@ -310,7 +304,7 @@ public final class RedisBungee extends Plugin { // Player not online according to Redis but not BungeeCord. Fire another consumer event. getLogger().warning("Player " + player + " is on the proxy but not in Redis."); - tmpRsc.sadd("proxy:" + serverId + ":usersOnline", player); + tmpRsc.sadd("proxy:" + configuration.getServerId() + ":usersOnline", player); } } finally { pool.returnResource(tmpRsc); @@ -343,9 +337,9 @@ public final class RedisBungee extends Plugin { Jedis tmpRsc = pool.getResource(); try { - tmpRsc.hdel("heartbeats", serverId); - if (tmpRsc.scard("proxy:" + serverId + ":usersOnline") > 0) { - Set players = tmpRsc.smembers("proxy:" + serverId + ":usersOnline"); + tmpRsc.hdel("heartbeats", configuration.getServerId()); + if (tmpRsc.scard("proxy:" + configuration.getServerId() + ":usersOnline") > 0) { + Set players = tmpRsc.smembers("proxy:" + configuration.getServerId() + ":usersOnline"); for (String member : players) RedisUtil.cleanUpPlayer(member, tmpRsc); } @@ -372,12 +366,12 @@ public final class RedisBungee extends Plugin { } } - configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(file); + final Configuration configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(file); final String redisServer = configuration.getString("redis-server", "localhost"); final int redisPort = configuration.getInt("redis-port", 6379); String redisPassword = configuration.getString("redis-password"); - serverId = configuration.getString("server-id"); + String serverId = configuration.getString("server-id"); if (redisPassword != null && (redisPassword.isEmpty() || redisPassword.equals("none"))) { redisPassword = null; @@ -439,6 +433,7 @@ public final class RedisBungee extends Plugin { httpClient.setDispatcher(dispatcher); NameFetcher.setHttpClient(httpClient); UUIDFetcher.setHttpClient(httpClient); + RedisBungee.configuration = new RedisBungeeConfiguration(RedisBungee.this.getPool(), configuration); return null; } }); @@ -481,7 +476,7 @@ public final class RedisBungee extends Plugin { try { rsc = pool.getResource(); jpsh = new JedisPubSubHandler(); - rsc.subscribe(jpsh, "redisbungee-" + serverId, "redisbungee-allservers", "redisbungee-data"); + rsc.subscribe(jpsh, "redisbungee-" + configuration.getServerId(), "redisbungee-allservers", "redisbungee-data"); } catch (JedisException | ClassCastException ignored) { } } diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java index 9e11ecf..69776ff 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java @@ -35,7 +35,7 @@ public class RedisBungeeAPI { this.plugin = plugin; this.reservedChannels = ImmutableList.of( "redisbungee-allservers", - "redisbungee-" + plugin.getServerId(), + "redisbungee-" + RedisBungee.getConfiguration().getServerId(), "redisbungee-data" ); } @@ -197,7 +197,7 @@ public class RedisBungeeAPI { * @since 0.2.5 */ public final String getServerId() { - return plugin.getServerId(); + return RedisBungee.getConfiguration().getServerId(); } /** diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeCommands.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeCommands.java index a41fa00..cf56640 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeCommands.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeCommands.java @@ -56,7 +56,7 @@ class RedisBungeeCommands { BaseComponent[] playersOnline = new ComponentBuilder("").color(ChatColor.YELLOW).append(String.valueOf(count)) .append(" player(s) are currently online.").create(); if (args.length > 0 && args[0].equals("showall")) { - if (RedisBungee.getConfiguration().getBoolean("canonical-glist", true)) { + if (RedisBungee.getConfiguration().isCanonicalGlist()) { Multimap serverToPlayers = RedisBungee.getApi().getServerToPlayers(); Multimap human = HashMultimap.create(); for (Map.Entry entry : serverToPlayers.entries()) { diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConfiguration.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConfiguration.java new file mode 100644 index 0000000..51a1cb2 --- /dev/null +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeConfiguration.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2013 tuxed + * This work is free. You can redistribute it and/or modify it under the + * terms of the Do What The Fuck You Want To Public License, Version 2, + * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. + */ +package com.imaginarycode.minecraft.redisbungee; + +import com.google.common.collect.ImmutableList; +import com.google.common.net.InetAddresses; +import lombok.Getter; +import net.md_5.bungee.config.Configuration; +import redis.clients.jedis.JedisPool; + +import java.net.InetAddress; +import java.util.List; + +public class RedisBungeeConfiguration { + @Getter + private final JedisPool pool; + @Getter + private final String serverId; + @Getter + private final boolean registerBungeeCommands; + @Getter + private final boolean canonicalGlist; + @Getter + private final List exemptAddresses; + + public RedisBungeeConfiguration(JedisPool pool, Configuration configuration) { + this.pool = pool; + this.serverId = configuration.getString("server-id"); + this.registerBungeeCommands = configuration.getBoolean("register-bungee-commands", true); + this.canonicalGlist = configuration.getBoolean("canonical-glist", true); + + List stringified = configuration.getStringList("exempt-ip-addresses"); + ImmutableList.Builder addressBuilder = ImmutableList.builder(); + + for (String s : stringified) { + addressBuilder.add(InetAddresses.forString(s)); + } + + this.exemptAddresses = addressBuilder.build(); + } +} diff --git a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java index 3b77b5f..9962b94 100644 --- a/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java +++ b/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java @@ -24,6 +24,7 @@ import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventPriority; import redis.clients.jedis.Jedis; +import java.net.InetAddress; import java.util.*; import java.util.concurrent.Callable; @@ -35,6 +36,7 @@ public class RedisBungeeListener implements Listener { .color(ChatColor.GRAY) .create(); private final RedisBungee plugin; + private final List exemptAddresses; @EventHandler public void onPlayerConnect(final PostLoginEvent event) { @@ -54,7 +56,7 @@ public class RedisBungeeListener implements Listener { jedis.hset("player:" + event.getPlayer().getUniqueId().toString(), "online", "0"); jedis.hset("player:" + event.getPlayer().getUniqueId().toString(), "ip", event.getPlayer().getAddress().getAddress().getHostAddress()); plugin.getUuidTranslator().persistInfo(event.getPlayer().getName(), event.getPlayer().getUniqueId(), jedis); - jedis.hset("player:" + event.getPlayer().getUniqueId().toString(), "proxy", plugin.getServerId()); + jedis.hset("player:" + event.getPlayer().getUniqueId().toString(), "proxy", RedisBungee.getConfiguration().getServerId()); jedis.publish("redisbungee-data", RedisBungee.getGson().toJson(new DataManager.DataManagerMessage<>( event.getPlayer().getUniqueId(), DataManager.DataManagerMessage.Action.JOIN, new DataManager.LoginPayload(event.getPlayer().getAddress().getAddress())))); @@ -98,6 +100,10 @@ public class RedisBungeeListener implements Listener { @EventHandler(priority = EventPriority.LOWEST) public void onPing(final ProxyPingEvent event) { + if (exemptAddresses.contains(event.getConnection().getAddress().getAddress())) { + return; + } + event.registerIntent(plugin); plugin.getProxy().getScheduler().runAsync(plugin, new Runnable() { @Override diff --git a/src/main/resources/example_config.yml b/src/main/resources/example_config.yml index 4725b7d..0e52b1e 100644 --- a/src/main/resources/example_config.yml +++ b/src/main/resources/example_config.yml @@ -1,6 +1,6 @@ # RedisBungee configuration file. # PLEASE READ THE WIKI: http://minecraft.imaginarycode.com/ - + # The Redis server you use. # Get Redis from http://redis.io/ redis-server: 127.0.0.1 @@ -11,10 +11,10 @@ redis-password: "" # The default is 8. This setting should be left as-is unless you have some wildly # inefficient plugins or a lot of players. max-redis-connections: 8 - + # An identifier for this BungeeCord instance. server-id: iluvbungee - + # Whether or not RedisBungee should install its version of regular BungeeCord commands. # Often, the RedisBungee commands are desired, but in some cases someone may wish to # override the commands using another plugin. @@ -25,6 +25,10 @@ server-id: iluvbungee # Please note that with build 787+, most commands overridden by RedisBungee were moved to # modules, and these must be disabled or overridden yourself. register-bungee-commands: true - + # Whether or not /glist showall output should match vanilla BungeeCord. -canonical-glist: true \ No newline at end of file +canonical-glist: true + +# A list of IP addresses for which RedisBungee will not modify the response for, useful for automatic +# restart scripts. +exempt-ip-addresses: [] \ No newline at end of file