From a3b9aced7f7b587854f3b241fdd89f1950db04ec Mon Sep 17 00:00:00 2001 From: Jaime Martinez Rincon Date: Mon, 9 Jan 2017 22:04:15 +0100 Subject: [PATCH] Implemented PM-API and added an option to print info about the geolocation checks --- pom.xml | 2 +- .../lobbybalancer/LobbyBalancer.java | 7 ++ .../configuration/ConfigEntries.java | 1 + .../connection/ConnectionIntent.java | 8 +- .../connection/ProviderType.java | 10 ++- .../listener/PluginMessageListener.java | 80 ++++++++++++++++++- .../lobbybalancer/section/SectionManager.java | 9 +++ .../lobbybalancer/section/ServerSection.java | 52 ++++++++---- src/main/resources/config.yml | 26 ++++-- 9 files changed, 165 insertions(+), 30 deletions(-) diff --git a/pom.xml b/pom.xml index d6a9350..76a8579 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.jaimemartz lobbybalancer - 2.0 + 2.0.1 LobbyBalancer diff --git a/src/main/java/me/jaimemartz/lobbybalancer/LobbyBalancer.java b/src/main/java/me/jaimemartz/lobbybalancer/LobbyBalancer.java index b34a13d..3eaf5dd 100644 --- a/src/main/java/me/jaimemartz/lobbybalancer/LobbyBalancer.java +++ b/src/main/java/me/jaimemartz/lobbybalancer/LobbyBalancer.java @@ -1,5 +1,6 @@ package me.jaimemartz.lobbybalancer; +import com.google.gson.Gson; import com.imaginarycode.minecraft.redisbungee.RedisBungee; import me.jaimemartz.faucet.ConfigFactory; import me.jaimemartz.lobbybalancer.commands.BackwardCommand; @@ -29,6 +30,7 @@ public class LobbyBalancer extends Plugin { public static final String NONCE_ID = "%%__NONCE__%%"; private boolean failed = false; + private Gson gson; private ConfigFactory factory; private PingManager pingManager; @@ -40,6 +42,7 @@ public class LobbyBalancer extends Plugin { @Override public void onEnable() { instance = this; + gson = new Gson(); if (factory == null) { factory = new ConfigFactory(this); factory.register(0, "config.yml"); @@ -199,6 +202,10 @@ public class LobbyBalancer extends Plugin { return true; } + public Gson getGson() { + return gson; + } + public GeolocationManager getGeolocationManager() { return geolocationManager; } diff --git a/src/main/java/me/jaimemartz/lobbybalancer/configuration/ConfigEntries.java b/src/main/java/me/jaimemartz/lobbybalancer/configuration/ConfigEntries.java index a57e959..1d4d1ac 100644 --- a/src/main/java/me/jaimemartz/lobbybalancer/configuration/ConfigEntries.java +++ b/src/main/java/me/jaimemartz/lobbybalancer/configuration/ConfigEntries.java @@ -21,6 +21,7 @@ public class ConfigEntries implements ConfigEntryHolder { public static final ConfigEntry> SERVER_CHECK_MARKER_MOTDS = new ConfigEntry<>(0, "settings.server_check.marker-motds", Arrays.asList("Server is not accessible", "Gamemode has already started")); public static final ConfigEntry GEOLOCATION_ENABLED = new ConfigEntry<>(0, "settings.geolocation.enabled", true); + public static final ConfigEntry GEOLOCATION_PRINT_INFO = new ConfigEntry<>(0, "settings.geolocation.print-info", true); public static final ConfigEntry RECONNECT_KICK_ENABLED = new ConfigEntry<>(0, "settings.reconnect-kick.enabled", true); public static final ConfigEntry RECONNECT_KICK_INVERTED = new ConfigEntry<>(0, "settings.reconnect-kick.inverted", false); diff --git a/src/main/java/me/jaimemartz/lobbybalancer/connection/ConnectionIntent.java b/src/main/java/me/jaimemartz/lobbybalancer/connection/ConnectionIntent.java index 40ec750..7d55f94 100644 --- a/src/main/java/me/jaimemartz/lobbybalancer/connection/ConnectionIntent.java +++ b/src/main/java/me/jaimemartz/lobbybalancer/connection/ConnectionIntent.java @@ -12,7 +12,7 @@ import java.util.ArrayList; import java.util.List; public abstract class ConnectionIntent { - public ConnectionIntent(LobbyBalancer plugin, ProxiedPlayer player, ServerSection section) { + protected ConnectionIntent(LobbyBalancer plugin, ProxiedPlayer player, ServerSection section) { ServerInfo target = this.findTarget(plugin, player, section); Messager msgr = new Messager(player); @@ -44,12 +44,12 @@ public abstract class ConnectionIntent { servers.addAll(section.getServers()); while (intents-- >= 1) { - ServerInfo target = provider.requestTarget(plugin, section, servers, player); - if (target == null) continue; - if (servers.size() == 0) return null; if (servers.size() == 1) return servers.get(0); + ServerInfo target = provider.requestTarget(plugin, section, servers, player); + if (target == null) continue; + ServerStatus status = plugin.getPingManager().getStatus(target); if (status.isAccessible()) { return target; diff --git a/src/main/java/me/jaimemartz/lobbybalancer/connection/ProviderType.java b/src/main/java/me/jaimemartz/lobbybalancer/connection/ProviderType.java index 89eb8e9..d32a5f2 100644 --- a/src/main/java/me/jaimemartz/lobbybalancer/connection/ProviderType.java +++ b/src/main/java/me/jaimemartz/lobbybalancer/connection/ProviderType.java @@ -43,9 +43,17 @@ public enum ProviderType { CountryResponse countryResponse = plugin.getGeolocationManager().getReader().country(address); Country country = countryResponse.getCountry(); + if (ConfigEntries.GEOLOCATION_PRINT_INFO.get()) { + plugin.getLogger().info(String.format( + "Player Address: \"%s\", Country Name: \"%s\"", + address.toString(), + country.getName() + )); + } + for (String name : rule.getKeys()) { List countries = rule.getStringList(name); - if (countries.contains(country.getName().toUpperCase())) { + if (countries.contains(country.getName())) { ServerInfo server = plugin.getProxy().getServerInfo(name); if (server != null) { return server; diff --git a/src/main/java/me/jaimemartz/lobbybalancer/listener/PluginMessageListener.java b/src/main/java/me/jaimemartz/lobbybalancer/listener/PluginMessageListener.java index bb496ec..253c117 100644 --- a/src/main/java/me/jaimemartz/lobbybalancer/listener/PluginMessageListener.java +++ b/src/main/java/me/jaimemartz/lobbybalancer/listener/PluginMessageListener.java @@ -3,11 +3,15 @@ package me.jaimemartz.lobbybalancer.listener; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import me.jaimemartz.lobbybalancer.LobbyBalancer; +import me.jaimemartz.lobbybalancer.connection.ConnectionIntent; +import me.jaimemartz.lobbybalancer.section.ServerSection; import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.Server; import net.md_5.bungee.api.event.PluginMessageEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; +import org.json.JSONObject; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; @@ -27,16 +31,88 @@ public class PluginMessageListener implements Listener { String request = in.readUTF(); ServerInfo sender = ((Server) event.getSender()).getInfo(); switch (request) { - default: { + case "Connect": { + if (event.getReceiver() instanceof ProxiedPlayer) { + ProxiedPlayer player = (ProxiedPlayer) event.getReceiver(); + ServerSection section = plugin.getSectionManager().getByName(in.readUTF()); + + if (section == null) { + return; + } + + new ConnectionIntent(plugin, player, section) { + @Override + public void connect(ServerInfo server) { + player.connect(server); + } + }; + } + break; + } + + case "ConnectOther": { + ProxiedPlayer player = plugin.getProxy().getPlayer(in.readUTF()); + if (player == null) { + return; + } + + ServerSection section = plugin.getSectionManager().getByName(in.readUTF()); + if (section == null) { + return; + } + + new ConnectionIntent(plugin, player, section) { + @Override + public void connect(ServerInfo server) { + player.connect(server); + } + }; + break; + } + + case "GetSectionByName": { ByteArrayOutputStream stream = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(stream); + ServerSection section = plugin.getSectionManager().getByName(in.readUTF()); + if (section == null) { + return; + } + try { - out.writeUTF("The plugin message api for LobbyBalancer is not ready yet, it will be implemented in a future version"); + String output = plugin.getGson().toJson(section); + out.writeUTF(output); } catch (IOException e) { e.printStackTrace(); } + sender.sendData("LobbyBalancer", stream.toByteArray()); + break; + } + + case "GetSectionByServer": { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(stream); + + ServerInfo server = plugin.getProxy().getServerInfo(in.readUTF()); + if (server == null) { + return; + } + + ServerSection section = plugin.getSectionManager().getByServer(server); + if (section == null) { + return; + } + + try { + String output = plugin.getGson().toJson(section); + out.writeUTF(output); + } catch (IOException e) { + e.printStackTrace(); + } + + sender.sendData("LobbyBalancer", stream.toByteArray()); + break; } } } diff --git a/src/main/java/me/jaimemartz/lobbybalancer/section/SectionManager.java b/src/main/java/me/jaimemartz/lobbybalancer/section/SectionManager.java index a59af7b..b047ae4 100644 --- a/src/main/java/me/jaimemartz/lobbybalancer/section/SectionManager.java +++ b/src/main/java/me/jaimemartz/lobbybalancer/section/SectionManager.java @@ -10,6 +10,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class SectionManager { + private ServerSection principal; private final LobbyBalancer plugin; private final Map sectionStorage = new ConcurrentHashMap<>(); private final Map sectionServers = new ConcurrentHashMap<>(); @@ -97,4 +98,12 @@ public class SectionManager { public boolean hasSection(String name) { return sectionStorage.containsKey(name); } + + public ServerSection getPrincipal() { + return principal; + } + + protected void setPrincipal(ServerSection principal) { + this.principal = principal; + } } diff --git a/src/main/java/me/jaimemartz/lobbybalancer/section/ServerSection.java b/src/main/java/me/jaimemartz/lobbybalancer/section/ServerSection.java index 5f1f806..9870e63 100644 --- a/src/main/java/me/jaimemartz/lobbybalancer/section/ServerSection.java +++ b/src/main/java/me/jaimemartz/lobbybalancer/section/ServerSection.java @@ -1,5 +1,6 @@ package me.jaimemartz.lobbybalancer.section; +import com.google.gson.annotations.Expose; import me.jaimemartz.lobbybalancer.LobbyBalancer; import me.jaimemartz.lobbybalancer.connection.ProviderType; import me.jaimemartz.lobbybalancer.utils.AdapterFix; @@ -15,16 +16,34 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ServerSection { - private final String name; private final Configuration section; private final SectionManager manager; + @Expose + private final String name; + + @Expose private boolean principal; + + @Expose private ServerSection parent; + + @Expose + private boolean inherit = false; + + @Expose private List servers; + + @Expose private ProviderType provider; + + @Expose private ServerInfo server; + + @Expose private SectionCommand command; + + @Expose private boolean valid = false; ServerSection(String name, Configuration section, SectionManager manager) { @@ -37,6 +56,14 @@ public class ServerSection { void preInit(LobbyBalancer plugin) { principal = section.getBoolean("principal", false); + if (principal) { + ServerSection section = manager.getPrincipal(); + if (section != null) { + throw new IllegalStateException(String.format("The section \"%s\" is already principal", section.getName())); + } else { + manager.setPrincipal(this); + } + } if (ConfigUtils.isSet(section, "parent")) { if (principal) { throw new IllegalStateException(String.format("The principal section \"%s\" has a parent set", name)); @@ -84,14 +111,6 @@ public class ServerSection { throw new IllegalStateException(String.format("The section \"%s\" and \"%s\" are parents of each other", this.name, parent.name)); } - if (principal) { - manager.getSections().forEach((name, section) -> { - if (section.isPrincipal() && section != this) { - throw new IllegalStateException(String.format("The section \"%s\" is already principal", section.getName())); - } - }); - } - if (ConfigUtils.isSet(section, "provider")) { try { provider = ProviderType.valueOf(section.getString("provider").toUpperCase()); @@ -118,23 +137,24 @@ public class ServerSection { sect = sect.parent; } - LobbyBalancer.printStartupInfo("The section \"%s\" inherits the provider from parent section \"%s\"", this.name, sect.name); + LobbyBalancer.printStartupInfo("The section \"%s\" inherits the provider from the section \"%s\"", this.name, sect.name); provider = sect.provider; + inherit = true; } if (provider == null) { throw new IllegalStateException(String.format("The section \"%s\" does not have a provider", name)); } - if (ConfigUtils.isSet(section, "server")) { + if (ConfigUtils.isSet(section, "section-server")) { int port = (int) Math.floor(Math.random() * (0xFFFF + 1)); - ServerInfo server = plugin.getProxy().constructServerInfo("@" + section.getString("server"), new InetSocketAddress("0.0.0.0", port), String.format("Server of Section %s", name), false); + server = plugin.getProxy().constructServerInfo("@" + section.getString("section-server"), new InetSocketAddress("0.0.0.0", port), String.format("Server of Section %s", name), false); plugin.getSectionManager().register(server, this); AdapterFix.addFakeServer(server); } - if (ConfigUtils.isSet(section, "command")) { - Configuration other = section.getSection("command"); + if (ConfigUtils.isSet(section, "section-command")) { + Configuration other = section.getSection("section-command"); String name = other.getString("name"); String permission = other.getString("permission"); @@ -171,6 +191,10 @@ public class ServerSection { return provider; } + public boolean isProviderInherit() { + return inherit; + } + public ServerInfo getServer() { return server; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 219b0f8..edc86c5 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -39,7 +39,7 @@ settings: # The descriptions that mark a server as non accessible marker-motds: ["Server is not accessible", "Gamemode has already started"] - # This will connect the players to a server + # This will connect the player to a server of the parent of the section the player is kicked from reconnect-kick: enabled: true @@ -61,8 +61,10 @@ settings: # Override the behavior with rules rules: {} + # This will connect the player to a server of the parent of the section the player is currently on backward-command: enabled: true + name: 'backward' aliases: ['lobby', 'hub', 'back'] permission: '' @@ -80,7 +82,15 @@ settings: # WARNING: In testing stage geolocation: enabled: false - rules: {} + + # This prints info every time the plugin checks the country of a player (while being used) + print-info: true + + # The rules for the LOCALIZED provider, every section using it has to have a rule + rules: + practice: + 'EUPractice': ["Country1", "Country2"] + 'USPractice': ["Country3", "Country4"] # This will reload the plugin everytime you execute /greload auto-reload: true @@ -106,29 +116,29 @@ sections: general-lobbies: principal: true provider: RANDOM - server: 'general-lobbies' + section-server: 'general-lobbies' servers: ["Lobby1", "Lobby2", "Lobby3"] eggwars-lobbies: parent: 'general-lobbies' - server: 'eggwars-lobbies' + section-server: 'eggwars-lobbies' servers: ["EWLobby1", "EWLobby2", "EWLobby3"] eggwars-games: provider: FILLER parent: 'eggwars-lobbies' servers: ["EW1", "EW2", "EW3", "EW4", "EW5"] - command: + section-command: name: 'playeggwars' permission: '' aliases: [] skywars-lobbies: parent: 'general-lobbies' - server: 'skywars-lobbies' + section-server: 'skywars-lobbies' servers: ["SWLobby1", "SWLobby2", "SWLobby3"] skywars-games: provider: FILLER parent: 'skywars-lobbies' servers: ["SW1", "SW2", "SW3", "SW4", "SW5"] - command: + section-command: name: 'playskywars' permission: '' aliases: [] @@ -136,7 +146,7 @@ sections: provider: LOCALIZED parent: 'general-lobbies' servers: ["EUPractice", "USPractice"] - command: + section-command: name: 'practice' permission: '' aliases: ["rektnoobs"] \ No newline at end of file