The principal sections now can have parents and fallback principal

Making the plugin more flexible
Added checks for the file pasting
Added version checking of the configuration version
This commit is contained in:
Jaime Martinez Rincon 2017-01-12 22:48:38 +01:00
parent a95268530a
commit d5741c16a2
12 changed files with 83 additions and 65 deletions

View File

@ -3,16 +3,16 @@ 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.RegressCommand;
import me.jaimemartz.lobbybalancer.commands.MainCommand;
import me.jaimemartz.lobbybalancer.commands.RegressCommand;
import me.jaimemartz.lobbybalancer.configuration.ConfigEntries;
import me.jaimemartz.lobbybalancer.connection.ServerAssignRegistry;
import me.jaimemartz.lobbybalancer.listener.*;
import me.jaimemartz.lobbybalancer.ping.PingManager;
import me.jaimemartz.lobbybalancer.section.SectionManager;
import me.jaimemartz.lobbybalancer.manager.AdapterFix;
import me.jaimemartz.lobbybalancer.manager.GeolocationManager;
import me.jaimemartz.lobbybalancer.manager.PlayerLocker;
import me.jaimemartz.lobbybalancer.ping.PingManager;
import me.jaimemartz.lobbybalancer.section.SectionManager;
import me.jaimemartz.lobbybalancer.utils.DigitUtils;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
@ -29,11 +29,10 @@ public class LobbyBalancer extends Plugin {
public static final String USER_ID = "%%__USER__%%";
public static final String RESOURCE_ID = "%%__RESOURCE__%%";
public static final String NONCE_ID = "%%__NONCE__%%";
private static final int LAST_VER_CONFIG_UPDATE = 20200;
public static final int LAST_CONFIG_UPDATE_VER = 20200;
private final Gson gson = new Gson();
private boolean failed = false;
private Gson gson;
private ConfigFactory factory;
private PingManager pingManager;
@ -45,7 +44,6 @@ public class LobbyBalancer extends Plugin {
@Override
public void onEnable() {
instance = this;
gson = new Gson();
if (factory == null) {
factory = new ConfigFactory(this);
@ -53,26 +51,28 @@ public class LobbyBalancer extends Plugin {
factory.submit(ConfigEntries.class);
}
factory.load(0, true);
int configVersion = DigitUtils.getDigits(ConfigEntries.CONFIG_VERSION.get(), 5);
if (configVersion < LAST_CONFIG_UPDATE_VER) {
throw new IllegalStateException("Your config is outdated, please reset it and configure it again");
} else {
this.enable();
}
this.enable();
}
private void enable() {
factory.load(0, true);
mainCommand = new MainCommand(this);
getProxy().getPluginManager().registerCommand(this, mainCommand);
if (ConfigEntries.AUTO_RELOAD_ENABLED.get()) {
reloadListener = new ProxyReloadListener(this);
getProxy().getPluginManager().registerListener(this, reloadListener);
String text = ConfigEntries.CONFIG_VERSION.get();
int configVersion = DigitUtils.getDigits(text, 5);
if (configVersion < LAST_VER_CONFIG_UPDATE) {
failed = true;
throw new IllegalStateException("Your config is outdated, please reset it and configure it again");
}
if (ConfigEntries.PLUGIN_ENABLED.get()) {
if (ConfigEntries.AUTO_RELOAD_ENABLED.get()) {
reloadListener = new ProxyReloadListener(this);
getProxy().getPluginManager().registerListener(this, reloadListener);
}
if (ConfigEntries.CHECK_UPDATES_ENABLED.get()) {
try {
new BungeeUpdater(this, 10788);
@ -112,7 +112,7 @@ public class LobbyBalancer extends Plugin {
}
if (ConfigEntries.GEOLOCATION_ENABLED.get()) {
LobbyBalancer.printStartupInfo("The geolocation feature has not been tested in depth");
printStartupInfo("The geolocation feature has not been tested in depth");
try {
geolocationManager = new GeolocationManager(this);
} catch (IOException e) {
@ -140,15 +140,15 @@ public class LobbyBalancer extends Plugin {
getProxy().getPluginManager().unregisterCommand(mainCommand);
mainCommand = null;
if (ConfigEntries.AUTO_RELOAD_ENABLED.get()) {
getProxy().getPluginManager().unregisterListener(reloadListener);
reloadListener = null;
}
if (ConfigEntries.PLUGIN_ENABLED.get()) {
//Do not try to do anything if the plugin has not loaded correctly
if (hasFailed()) return;
if (ConfigEntries.AUTO_RELOAD_ENABLED.get()) {
getProxy().getPluginManager().unregisterListener(reloadListener);
reloadListener = null;
}
if (ConfigEntries.SERVER_CHECK_ENABLED.get()) {
pingManager.stop();
}
@ -185,7 +185,6 @@ public class LobbyBalancer extends Plugin {
long starting = System.currentTimeMillis();
this.disable();
factory.load(0, true);
this.enable();
long ending = System.currentTimeMillis() - starting;

View File

@ -4,8 +4,8 @@ import me.jaimemartz.faucet.Messager;
import me.jaimemartz.lobbybalancer.LobbyBalancer;
import me.jaimemartz.lobbybalancer.configuration.ConfigEntries;
import me.jaimemartz.lobbybalancer.connection.ConnectionIntent;
import me.jaimemartz.lobbybalancer.section.ServerSection;
import me.jaimemartz.lobbybalancer.manager.PlayerLocker;
import me.jaimemartz.lobbybalancer.section.ServerSection;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.config.ServerInfo;
@ -13,7 +13,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.config.Configuration;
import java.util.concurrent.*;
import java.util.concurrent.Callable;
public class RegressCommand extends Command {
private final LobbyBalancer plugin;

View File

@ -18,6 +18,8 @@ import java.net.InetAddress;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import static me.jaimemartz.lobbybalancer.LobbyBalancer.getPlayerCount;
public enum ProviderType {
NONE(0, "Returns no server") {
@Override
@ -75,7 +77,7 @@ public enum ProviderType {
ServerInfo target = null;
for (ServerInfo server : list) {
int count = LobbyBalancer.getPlayerCount(server);
int count = getPlayerCount(server);
if (count < min) {
min = count;
@ -97,7 +99,7 @@ public enum ProviderType {
public ServerInfo requestTarget(LobbyBalancer plugin, ServerSection section, List<ServerInfo> list, ProxiedPlayer player) {
for (ServerInfo server : list) {
ServerStatus status = plugin.getPingManager().getStatus(server);
if (LobbyBalancer.getPlayerCount(server) < status.getMaximumPlayers()) {
if (getPlayerCount(server) < status.getMaximumPlayers()) {
return server;
}
}
@ -113,7 +115,7 @@ public enum ProviderType {
for (ServerInfo server : list) {
ServerStatus status = plugin.getPingManager().getStatus(server);
int count = LobbyBalancer.getPlayerCount(server);
int count = getPlayerCount(server);
if (count > max && count <= status.getMaximumPlayers()) {
max = count;

View File

@ -11,7 +11,6 @@ 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;

View File

@ -5,8 +5,8 @@ import me.jaimemartz.lobbybalancer.LobbyBalancer;
import me.jaimemartz.lobbybalancer.configuration.ConfigEntries;
import me.jaimemartz.lobbybalancer.connection.ConnectionIntent;
import me.jaimemartz.lobbybalancer.connection.ServerAssignRegistry;
import me.jaimemartz.lobbybalancer.section.ServerSection;
import me.jaimemartz.lobbybalancer.manager.PlayerLocker;
import me.jaimemartz.lobbybalancer.section.ServerSection;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;

View File

@ -16,6 +16,9 @@ import net.md_5.bungee.event.EventPriority;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import static me.jaimemartz.lobbybalancer.LobbyBalancer.checkSendMessage;
import static me.jaimemartz.lobbybalancer.LobbyBalancer.printStartupInfo;
public class ServerKickListener implements Listener {
private final LobbyBalancer plugin;
@ -39,6 +42,8 @@ public class ServerKickListener implements Listener {
}
ServerSection section = plugin.getSectionManager().getByServer(from);
//Section the player is going to be reconnected
Callable<ServerSection> task = () -> {
if (section != null) {
if ((ConfigEntries.RECONNECT_KICK_IGNORED_SECTIONS.get()).contains(section.getName())) {
@ -51,9 +56,6 @@ public class ServerKickListener implements Listener {
if (target == null) {
target = section.getParent();
if (target == null) {
return null;
}
}
AtomicBoolean matches = new AtomicBoolean(false);
@ -69,12 +71,12 @@ public class ServerKickListener implements Listener {
matches.set(!matches.get());
}
if (matches.get()) {
return target;
if (ConfigEntries.RECONNECT_KICK_PRINT_INFO.get()) {
printStartupInfo(String.format("Kick Reason: \"%s\", Found Match: %s", TextComponent.toPlainText(event.getKickReasonComponent()), matches));
}
if (ConfigEntries.RECONNECT_KICK_PRINT_INFO.get()) {
LobbyBalancer.printStartupInfo(String.format("Kick Reason: \"%s\", Found Match: %s", TextComponent.toPlainText(event.getKickReasonComponent()), matches.get()));
if (matches.get()) {
return target;
}
} else {
if (ConfigEntries.FALLBACK_PRINCIPAL_ENABLED.get()) {
@ -90,6 +92,8 @@ public class ServerKickListener implements Listener {
new ConnectionIntent(plugin, player, target) {
@Override
public void connect(ServerInfo server) {
checkSendMessage(player, ConfigEntries.RECONNECT_KICK_MESSAGE.get().replace("{from}", from.getName()).replace("{to}", server.getName()).replace("{reason}", TextComponent.toPlainText(event.getKickReasonComponent())));
event.setCancelled(true);
event.setCancelServer(server);
}

View File

@ -16,6 +16,8 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import static me.jaimemartz.lobbybalancer.LobbyBalancer.printStartupInfo;
public class GeolocationManager {
private final DatabaseReader reader;
@ -31,7 +33,7 @@ public class GeolocationManager {
File database = new File(dir, "GeoLite2-Country.mmdb");
if (!database.exists()) {
LobbyBalancer.printStartupInfo("Downloading database");
printStartupInfo("Downloading database");
URL url = new URL("http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz");
try (ReadableByteChannel rbc = Channels.newChannel(url.openStream())) {
try (FileOutputStream fos = new FileOutputStream(packed)) {
@ -39,7 +41,7 @@ public class GeolocationManager {
}
}
LobbyBalancer.printStartupInfo("Unpacking database");
printStartupInfo("Unpacking database");
byte[] buffer = new byte[1024];
try (GZIPInputStream in = new GZIPInputStream(new FileInputStream(packed))) {
try (FileOutputStream out = new FileOutputStream(database)) {
@ -50,12 +52,12 @@ public class GeolocationManager {
}
}
LobbyBalancer.printStartupInfo("Deleting packed archive, success: " + (packed.delete() ? "yes" : "no"));
printStartupInfo("Deleting packed archive, success: " + (packed.delete() ? "yes" : "no"));
} else {
LobbyBalancer.printStartupInfo("Database exists, no need to download again");
printStartupInfo("Database exists, no need to download again");
}
LobbyBalancer.printStartupInfo("Initializing database");
printStartupInfo("Initializing database");
reader = new DatabaseReader.Builder(database).withCache(new CHMCache()).build();
}

View File

@ -21,6 +21,10 @@ public enum PasteHelper {
@Override
public String paste(Plugin plugin) throws Exception {
File file = new File(plugin.getDataFolder(), "config.yml");
if (!file.exists()) {
return "File does not exist";
}
PastebinPaste paste = new PastebinPaste();
paste.setPasteTitle("{name} ({version} on {bungee_version}) Configuration"
.replace("{name}", plugin.getDescription().getName())
@ -42,6 +46,10 @@ public enum PasteHelper {
@Override
public String paste(Plugin plugin) throws Exception {
File file = new File(plugin.getDataFolder().getParentFile().getParentFile(), "config.yml");
if (!file.exists()) {
return "File does not exist";
}
PastebinPaste paste = new PastebinPaste();
paste.setPasteTitle("{name} ({version}) Configuration"
.replace("{name}", plugin.getProxy().getName())
@ -62,6 +70,10 @@ public enum PasteHelper {
@Override
public String paste(Plugin plugin) throws Exception {
File file = new File(plugin.getDataFolder().getParentFile().getParentFile(), "proxy.log.0");
if (!file.exists()) {
return "File does not exist";
}
PastebinPaste paste = new PastebinPaste();
paste.setPasteTitle("{name} ({version}) Last Logs"
.replace("{name}", plugin.getProxy().getName())
@ -80,7 +92,6 @@ public enum PasteHelper {
};
private String link;
private ScheduledTask task = null;
public void send(Plugin plugin, CommandSender sender, String message) {
try {

View File

@ -9,6 +9,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static me.jaimemartz.lobbybalancer.LobbyBalancer.printStartupInfo;
public class PingManager {
private final LobbyBalancer plugin;
private boolean stopped = true;
@ -26,7 +28,7 @@ public class PingManager {
}
stopped = false;
tactic = PingTacticType.valueOf((ConfigEntries.SERVER_CHECK_MODE.get()).toUpperCase());
LobbyBalancer.printStartupInfo(String.format("Starting the ping task, the interval is %s", ConfigEntries.SERVER_CHECK_INTERVAL.get()));
printStartupInfo(String.format("Starting the ping task, the interval is %s", ConfigEntries.SERVER_CHECK_INTERVAL.get()));
task = plugin.getProxy().getScheduler().schedule(plugin, () -> {
for (ServerInfo server : plugin.getProxy().getServers().values()) {
if (stopped) break;

View File

@ -9,6 +9,8 @@ import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static me.jaimemartz.lobbybalancer.LobbyBalancer.printStartupInfo;
public class SectionManager {
private ServerSection principal;
private final LobbyBalancer plugin;
@ -20,40 +22,40 @@ public class SectionManager {
}
public void load() throws RuntimeException {
LobbyBalancer.printStartupInfo("Loading sections from the config, this may take a while...");
printStartupInfo("Loading sections from the config, this may take a while...");
long starting = System.currentTimeMillis();
Configuration sections = plugin.getConfig().getSection("sections");
sections.getKeys().forEach(name -> {
LobbyBalancer.printStartupInfo("Construction of section with name \"%s\"", name);
printStartupInfo("Construction of section with name \"%s\"", name);
Configuration section = sections.getSection(name);
ServerSection object = new ServerSection(name, section, this);
sectionStorage.put(name, object);
});
sectionStorage.forEach((name, section) -> {
LobbyBalancer.printStartupInfo("Pre-Initialization of section with name \"%s\"", name);
printStartupInfo("Pre-Initialization of section with name \"%s\"", name);
section.preInit(plugin);
});
sectionStorage.forEach((name, section) -> {
LobbyBalancer.printStartupInfo("Initialization of section with name \"%s\"", name);
printStartupInfo("Initialization of section with name \"%s\"", name);
section.load(plugin);
});
sectionStorage.forEach((name, section) -> {
LobbyBalancer.printStartupInfo("Post-Initialization of section with name \"%s\"", name);
printStartupInfo("Post-Initialization of section with name \"%s\"", name);
section.postInit(plugin);
});
AdapterFix.inject(plugin.getProxy());
long ending = System.currentTimeMillis() - starting;
LobbyBalancer.printStartupInfo("A total of %s section(s) have been loaded in %sms", sectionStorage.size(), ending);
printStartupInfo("A total of %s section(s) have been loaded in %sms", sectionStorage.size(), ending);
}
public void flush() {
LobbyBalancer.printStartupInfo("Flushing section storage because of plugin shutdown");
printStartupInfo("Flushing section storage because of plugin shutdown");
sectionStorage.forEach((key, value) -> {
value.setValid(false);
@ -77,7 +79,7 @@ public class SectionManager {
throw new IllegalArgumentException(String.format("The server \"%s\" is already in the section \"%s\"", server.getName(), other.getName()));
}
LobbyBalancer.printStartupInfo("Registering server \"%s\" to section \"%s\"", server.getName(), section.getName());
printStartupInfo("Registering server \"%s\" to section \"%s\"", server.getName(), section.getName());
sectionServers.put(server, section);
}
@ -95,10 +97,6 @@ public class SectionManager {
return Collections.unmodifiableMap(sectionStorage);
}
public boolean hasSection(String name) {
return sectionStorage.containsKey(name);
}
public ServerSection getPrincipal() {
return principal;
}

View File

@ -14,6 +14,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static me.jaimemartz.lobbybalancer.LobbyBalancer.printStartupInfo;
public class ServerSection {
private transient final Configuration section;
private transient final SectionManager manager;
@ -46,17 +48,15 @@ public class ServerSection {
manager.setPrincipal(this);
}
}
if (ConfigUtils.isSet(section, "parent")) {
if (principal) {
throw new IllegalStateException(String.format("The principal section \"%s\" has a parent set", name));
}
if (ConfigUtils.isSet(section, "parent")) {
parent = manager.getByName(section.getString("parent"));
if (parent == null) {
throw new IllegalArgumentException(String.format("The section \"%s\" has an invalid parent set", name));
}
} else {
//Principal sections do not necessarily must have a parent section
if (!principal) {
throw new IllegalArgumentException(String.format("The section \"%s\" does not have a parent set", name));
}
@ -69,7 +69,7 @@ public class ServerSection {
plugin.getProxy().getServers().forEach((key, value) -> {
Matcher matcher = pattern.matcher(key);
if (matcher.matches()) {
LobbyBalancer.printStartupInfo("Found a match with \"%s\" for entry \"%s\"", key, entry);
printStartupInfo("Found a match with \"%s\" for entry \"%s\"", key, entry);
servers.add(value);
manager.register(server, this);
matches.set(true);
@ -81,7 +81,7 @@ public class ServerSection {
}
});
LobbyBalancer.printStartupInfo("Recognized %s server(s) out of %s entries", servers.size(), section.getStringList("servers").size());
printStartupInfo("Recognized %s server(s) out of %s entries", servers.size(), section.getStringList("servers").size());
} else {
throw new IllegalArgumentException(String.format("The section \"%s\" does not have any servers set", name));
}
@ -119,7 +119,7 @@ public class ServerSection {
sect = sect.parent;
}
LobbyBalancer.printStartupInfo("The section \"%s\" inherits the provider from the section \"%s\"", this.name, sect.name);
printStartupInfo("The section \"%s\" inherits the provider from the section \"%s\"", this.name, sect.name);
provider = sect.provider;
inherit = true;
}

View File

@ -9,6 +9,7 @@ public class DigitUtils {
if (builder.length() >= digits) {
break;
}
builder.append(character);
}
}