diff --git a/src/main/java/com/jaimemartz/playerbalancer/PlayerBalancer.java b/src/main/java/com/jaimemartz/playerbalancer/PlayerBalancer.java index f32c751..4d1d713 100644 --- a/src/main/java/com/jaimemartz/playerbalancer/PlayerBalancer.java +++ b/src/main/java/com/jaimemartz/playerbalancer/PlayerBalancer.java @@ -4,6 +4,7 @@ import com.google.common.reflect.TypeToken; import com.jaimemartz.playerbalancer.commands.FallbackCommand; import com.jaimemartz.playerbalancer.commands.MainCommand; import com.jaimemartz.playerbalancer.commands.ManageCommand; +import com.jaimemartz.playerbalancer.connection.ServerAssignRegistry; import com.jaimemartz.playerbalancer.listener.*; import com.jaimemartz.playerbalancer.manager.NetworkManager; import com.jaimemartz.playerbalancer.manager.PasteHelper; @@ -181,11 +182,7 @@ public class PlayerBalancer extends Plugin { sectionManager.flush(); - /* - if (settings.getGeneralProps().isAssignTargets()) { - ServerAssignRegistry.getTable().clear(); - } - */ + ServerAssignRegistry.getTable().clear(); } PlayerLocker.flush(); @@ -199,8 +196,10 @@ public class PlayerBalancer extends Plugin { this.disable(); this.enable(); - long ending = System.currentTimeMillis() - starting; - getLogger().info(String.format("The plugin has been reloaded, took %sms", ending)); + if (!failed) { + long ending = System.currentTimeMillis() - starting; + getLogger().info(String.format("The plugin has been reloaded, took %sms", ending)); + } return !failed; } diff --git a/src/main/java/com/jaimemartz/playerbalancer/commands/FallbackCommand.java b/src/main/java/com/jaimemartz/playerbalancer/commands/FallbackCommand.java index c8d253a..48dbe91 100644 --- a/src/main/java/com/jaimemartz/playerbalancer/commands/FallbackCommand.java +++ b/src/main/java/com/jaimemartz/playerbalancer/commands/FallbackCommand.java @@ -43,6 +43,7 @@ public class FallbackCommand extends Command { } else if (number > target.getServers().size()) { MessageUtils.send(player, messages.getFailureMessage()); } else { + //todo improve this!!! javafx.collections.transformation.SortedList? ServerInfo server = new ArrayList<>(target.getServers()).get(number - 1); ConnectionIntent.direct(plugin, player, server, (response, throwable) -> { //todo something missing diff --git a/src/main/java/com/jaimemartz/playerbalancer/manager/PlayerLocker.java b/src/main/java/com/jaimemartz/playerbalancer/manager/PlayerLocker.java index c9add2f..8342d1e 100644 --- a/src/main/java/com/jaimemartz/playerbalancer/manager/PlayerLocker.java +++ b/src/main/java/com/jaimemartz/playerbalancer/manager/PlayerLocker.java @@ -7,7 +7,7 @@ import java.util.HashSet; import java.util.Set; import java.util.UUID; -//TODO improve this +//TODO improve this? maybe? public class PlayerLocker { private static final Set storage = Collections.synchronizedSet(new HashSet()); diff --git a/src/main/java/com/jaimemartz/playerbalancer/ping/ServerStatus.java b/src/main/java/com/jaimemartz/playerbalancer/ping/ServerStatus.java index 6194add..60b4d8d 100644 --- a/src/main/java/com/jaimemartz/playerbalancer/ping/ServerStatus.java +++ b/src/main/java/com/jaimemartz/playerbalancer/ping/ServerStatus.java @@ -23,7 +23,7 @@ public final class ServerStatus { this.maximum = maximum; } - //TODO improve this (set from the pinger if accessible or not) + //TODO improve this (set from the pinger if accessible or not) maybe? public boolean isAccessible(PlayerBalancer plugin, ProxiedPlayer player) { if (maximum == 0) { return false; diff --git a/src/main/java/com/jaimemartz/playerbalancer/section/SectionLoader.java b/src/main/java/com/jaimemartz/playerbalancer/section/SectionLoader.java deleted file mode 100644 index 9e99bad..0000000 --- a/src/main/java/com/jaimemartz/playerbalancer/section/SectionLoader.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.jaimemartz.playerbalancer.section; - -public class SectionLoader { - private final -} diff --git a/src/main/java/com/jaimemartz/playerbalancer/section/SectionManager.java b/src/main/java/com/jaimemartz/playerbalancer/section/SectionManager.java index 864b731..6da761e 100644 --- a/src/main/java/com/jaimemartz/playerbalancer/section/SectionManager.java +++ b/src/main/java/com/jaimemartz/playerbalancer/section/SectionManager.java @@ -1,6 +1,5 @@ package com.jaimemartz.playerbalancer.section; -import com.google.common.base.Preconditions; import com.jaimemartz.playerbalancer.PlayerBalancer; import com.jaimemartz.playerbalancer.settings.props.features.BalancerProps; import com.jaimemartz.playerbalancer.settings.props.shared.SectionProps; @@ -20,9 +19,10 @@ public class SectionManager { private final PlayerBalancer plugin; private final BalancerProps props; private ScheduledTask updateTask; + private ServerSection principal; - private final Map sections = new HashMap<>(); - private final Map servers = new HashMap<>(); + private final Map sections = Collections.synchronizedMap(new HashMap<>()); + private final Map servers = Collections.synchronizedMap(new HashMap<>()); public SectionManager(PlayerBalancer plugin) { this.props = plugin.getSettings().getBalancerProps(); @@ -33,18 +33,16 @@ public class SectionManager { plugin.getLogger().info("Executing section initialization stages, this may take a while..."); long starting = System.currentTimeMillis(); - props.getSectionProps().forEach((name, prop) -> { - plugin.getLogger().info(String.format("Construction of section with name \"%s\"", name)); - ServerSection object = new ServerSection(name, prop); - sections.put(name, object); - }); - - Preconditions.checkNotNull(this.getPrincipal(), - "Could not set principal section, there is no section named \"%s\"", - props.getPrincipalSectionName() - ); - - sections.forEach(this::processSection); + for (Stage stage : stages) { + plugin.getLogger().info("Executing stage \"" + stage.title + "\""); + if (stage instanceof SectionStage) { + props.getSectionProps().forEach((name, props) -> { + ((SectionStage) stage).execute(name, props, sections.get(name)); + }); + } else { + ((GlobalStage) stage).execute(); + } + } long ending = System.currentTimeMillis() - starting; plugin.getLogger().info(String.format("A total of %s section(s) have been loaded in %sms", sections.size(), ending)); @@ -71,6 +69,7 @@ public class SectionManager { updateTask = null; } + principal = null; sections.clear(); servers.clear(); } @@ -121,67 +120,119 @@ public class SectionManager { } private final Stage[] stages = { - new Stage("Creation") { + new SectionStage("Constructing sections") { @Override - public void execute(SectionProps props, ServerSection section) throws RuntimeException { - + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + ServerSection object = new ServerSection(name, props); + sections.put(name, object); } }, - new Stage("") { + new GlobalStage("Processing principal section") { @Override - public void execute(SectionProps props, ServerSection section) throws RuntimeException { + public void execute() { + principal = sections.get(props.getPrincipalSectionName()); + if (principal == null) { + throw new IllegalArgumentException(String.format( + "Could not set principal section, there is no section called \"%s\"", + props.getPrincipalSectionName() + )); + } + } + }, + new SectionStage("Processing parents") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + if (props.getParentName() != null) { + ServerSection parent = getByName(props.getParentName()); + if (principal.equals(section) && parent == null) { + throw new IllegalArgumentException(String.format( + "The section \"%s\" has an invalid parent set", + section.getName() + )); + } else { + section.setParent(parent); + } + } + } + }, + new SectionStage("Validating parents") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + ServerSection parent = section.getParent(); + if (parent != null && parent.getParent() == section) { + throw new IllegalStateException(String.format( + "The sections \"%s\" and \"%s\" are parents of each other", + section.getName(), + parent.getName() + )); + } + } + }, + new SectionStage("Validating providers") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + if (props.getProvider() == null) { + ServerSection current = section.getParent(); + if (current != null) { + while (current.getExplicitProvider() == null) { + current = current.getParent(); + } + plugin.getLogger().info(String.format( + "The section \"%s\" inherits the provider from the section \"%s\"", + section.getName(), + current.getName() + )); + + section.setInherited(true); + } + } else { + section.setInherited(false); + } + } + }, + new SectionStage("Calculating positions") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + section.setPosition(calculatePosition(section)); + } + }, + new SectionStage("Resolving servers") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + section.setServers(calculateServers(section)); + } + }, + new SectionStage("Section server processing") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + if (props.getServerName() != null) { + FakeServer server = new FakeServer(section); + section.setServer(server); + plugin.getSectionManager().register(server, section); + FixedAdapter.getFakeServers().put(server.getName(), server); + plugin.getProxy().getServers().put(server.getName(), server); + } + } + }, + new SectionStage("Section command processing") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + if (props.getCommand() != null) { + SectionCommand command = new SectionCommand(plugin, props.getCommand(), section); + section.setCommand(command); + plugin.getProxy().getPluginManager().registerCommand(plugin, command); + } + } + }, + new SectionStage("Finishing loading sections") { + @Override + public void execute(String name, SectionProps props, ServerSection section) throws RuntimeException { + section.setValid(true); } } }; - public void processSection(String sectionName, ServerSection section) throws RuntimeException { - plugin.getLogger().info(String.format("Loading section with name \"%s\"", sectionName)); - - Optional.ofNullable(section.getProps().getParentName()).ifPresent(parentName -> { - ServerSection parent = getByName(parentName); - if (parent == null) { - throw new IllegalArgumentException(String.format("The section \"%s\" has an invalid parent set", sectionName)); - } else { - section.setParent(parent); - } - }); - - Optional.ofNullable(section.getParent()).ifPresent(parent -> { - if (parent.getProps().getParentName().equals(sectionName)) { - throw new IllegalStateException(String.format("The sections \"%s\" and \"%s\" are parents of each other", - sectionName, - section.getParent().getName() - )); - } - }); - - Set servers = calculateServers(section); - section.getServers().addAll(servers); - - //TODO Load sections - - section.setPosition(calculatePosition(section)); - - Optional.ofNullable(section.getProps().getServerName()).ifPresent(serverName -> { - FakeServer server = new FakeServer(section); - section.setServer(server); - - plugin.getSectionManager().register(server, section); - FixedAdapter.getFakeServers().put(server.getName(), server); - plugin.getProxy().getServers().put(server.getName(), server); - }); - - Optional.ofNullable(section.getProps().getCommand()).ifPresent(props -> { - SectionCommand command = new SectionCommand(plugin, props, section); - section.setCommand(command); - - plugin.getProxy().getPluginManager().registerCommand(plugin, command); - }); - - section.setValid(true); - } - public Set calculateServers(ServerSection section) { Set results = new HashSet<>(); @@ -203,7 +254,7 @@ public class SectionManager { } }); - plugin.getLogger().info(String.format("Recognized %s server(s) out of %s entries on the section \"%s\"", + plugin.getLogger().info(String.format("Recognized %s server(s) out of %s in the section \"%s\"", servers.size(), section.getProps().getServerEntries(), section.getName() @@ -213,7 +264,6 @@ public class SectionManager { } public int calculatePosition(ServerSection section) { - ServerSection principal = this.getPrincipal(); ServerSection current = section; //Calculate above principal @@ -244,6 +294,14 @@ public class SectionManager { return iterations; } + public ServerSection getPrincipal() { + return principal; + } + + public boolean isPrincipal(ServerSection section) { + return principal.equals(section); + } + public boolean isDummy(ServerSection section) { List dummySections = props.getDummySectionNames(); return dummySections.contains(section.getName()); @@ -260,31 +318,34 @@ public class SectionManager { return Optional.ofNullable(res); } - //todo maybe store this as a variable? - public ServerSection getPrincipal() { - return getByName(props.getPrincipalSectionName()); - } - - public boolean isPrincipal(ServerSection section) { - return getPrincipal().equals(section); - } - public Map getSections() { return sections; } - private abstract static class Stage { + private static class Stage { private final String title; - public Stage(String title) { + private Stage(String title) { this.title = title; } + } - public String getTitle() { - return title;a + private static abstract class GlobalStage extends Stage { + private GlobalStage(String title) { + super(title); } public abstract void execute( + ) throws RuntimeException; + } + + private static abstract class SectionStage extends Stage { + private SectionStage(String title) { + super(title); + } + + public abstract void execute( + String name, SectionProps props, ServerSection section ) throws RuntimeException; diff --git a/src/main/java/com/jaimemartz/playerbalancer/section/ServerSection.java b/src/main/java/com/jaimemartz/playerbalancer/section/ServerSection.java index f90b225..aa924d2 100644 --- a/src/main/java/com/jaimemartz/playerbalancer/section/ServerSection.java +++ b/src/main/java/com/jaimemartz/playerbalancer/section/ServerSection.java @@ -64,7 +64,15 @@ public class ServerSection { } public ProviderType getImplicitProvider() { - return inherited ? parent.getImplicitProvider() : props.getProvider(); + if (inherited) { + return parent.getImplicitProvider(); + } else { + return props.getProvider(); + } + } + + public ProviderType getExplicitProvider() { + return props.getProvider(); } public void setExplicitProvider(ProviderType provider) { @@ -96,6 +104,10 @@ public class ServerSection { return servers; } + public void setServers(Set servers) { + this.servers = servers; + } + public boolean isValid() { return valid; } diff --git a/src/main/resources/default.conf b/src/main/resources/default.conf index ee7b94b..8094f5b 100644 --- a/src/main/resources/default.conf +++ b/src/main/resources/default.conf @@ -2,12 +2,14 @@ # Read the comments, they are a very important part of the configuration # To get support send me a private message with a description of the problem and the config file # To easily paste the config file (and other relevant files) use the command /balancer paste +# If the plugin has issues loading the configuration, try putting quotes around text general { # IMPORTANT! Set this to true after configuring the plugin! enabled=false # When true, the plugin will check for new servers added to bungee + # TODO Not done yet auto-refresh=false # When true, the plugin will reload when you execute /greload @@ -101,7 +103,7 @@ features { # The principal section is very important for other features # Normally set this to the section that has your main lobbies - principal-section=test + principal-section="general-lobbies" # When a player is not in any section, the player will go to the principal section # This affects both the fallback command and kick handler features