First thing that actually works! Not fully tested

This commit is contained in:
Jaime Martínez Rincón 2017-09-14 21:14:42 +02:00
parent 22b320274d
commit 3d293b1887
8 changed files with 168 additions and 98 deletions

View File

@ -4,6 +4,7 @@ import com.google.common.reflect.TypeToken;
import com.jaimemartz.playerbalancer.commands.FallbackCommand; import com.jaimemartz.playerbalancer.commands.FallbackCommand;
import com.jaimemartz.playerbalancer.commands.MainCommand; import com.jaimemartz.playerbalancer.commands.MainCommand;
import com.jaimemartz.playerbalancer.commands.ManageCommand; import com.jaimemartz.playerbalancer.commands.ManageCommand;
import com.jaimemartz.playerbalancer.connection.ServerAssignRegistry;
import com.jaimemartz.playerbalancer.listener.*; import com.jaimemartz.playerbalancer.listener.*;
import com.jaimemartz.playerbalancer.manager.NetworkManager; import com.jaimemartz.playerbalancer.manager.NetworkManager;
import com.jaimemartz.playerbalancer.manager.PasteHelper; import com.jaimemartz.playerbalancer.manager.PasteHelper;
@ -181,11 +182,7 @@ public class PlayerBalancer extends Plugin {
sectionManager.flush(); sectionManager.flush();
/* ServerAssignRegistry.getTable().clear();
if (settings.getGeneralProps().isAssignTargets()) {
ServerAssignRegistry.getTable().clear();
}
*/
} }
PlayerLocker.flush(); PlayerLocker.flush();
@ -199,8 +196,10 @@ public class PlayerBalancer extends Plugin {
this.disable(); this.disable();
this.enable(); this.enable();
long ending = System.currentTimeMillis() - starting; if (!failed) {
getLogger().info(String.format("The plugin has been reloaded, took %sms", ending)); long ending = System.currentTimeMillis() - starting;
getLogger().info(String.format("The plugin has been reloaded, took %sms", ending));
}
return !failed; return !failed;
} }

View File

@ -43,6 +43,7 @@ public class FallbackCommand extends Command {
} else if (number > target.getServers().size()) { } else if (number > target.getServers().size()) {
MessageUtils.send(player, messages.getFailureMessage()); MessageUtils.send(player, messages.getFailureMessage());
} else { } else {
//todo improve this!!! javafx.collections.transformation.SortedList?
ServerInfo server = new ArrayList<>(target.getServers()).get(number - 1); ServerInfo server = new ArrayList<>(target.getServers()).get(number - 1);
ConnectionIntent.direct(plugin, player, server, (response, throwable) -> { ConnectionIntent.direct(plugin, player, server, (response, throwable) -> {
//todo something missing //todo something missing

View File

@ -7,7 +7,7 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
//TODO improve this //TODO improve this? maybe?
public class PlayerLocker { public class PlayerLocker {
private static final Set<UUID> storage = Collections.synchronizedSet(new HashSet<UUID>()); private static final Set<UUID> storage = Collections.synchronizedSet(new HashSet<UUID>());

View File

@ -23,7 +23,7 @@ public final class ServerStatus {
this.maximum = maximum; 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) { public boolean isAccessible(PlayerBalancer plugin, ProxiedPlayer player) {
if (maximum == 0) { if (maximum == 0) {
return false; return false;

View File

@ -1,5 +0,0 @@
package com.jaimemartz.playerbalancer.section;
public class SectionLoader {
private final
}

View File

@ -1,6 +1,5 @@
package com.jaimemartz.playerbalancer.section; package com.jaimemartz.playerbalancer.section;
import com.google.common.base.Preconditions;
import com.jaimemartz.playerbalancer.PlayerBalancer; import com.jaimemartz.playerbalancer.PlayerBalancer;
import com.jaimemartz.playerbalancer.settings.props.features.BalancerProps; import com.jaimemartz.playerbalancer.settings.props.features.BalancerProps;
import com.jaimemartz.playerbalancer.settings.props.shared.SectionProps; import com.jaimemartz.playerbalancer.settings.props.shared.SectionProps;
@ -20,9 +19,10 @@ public class SectionManager {
private final PlayerBalancer plugin; private final PlayerBalancer plugin;
private final BalancerProps props; private final BalancerProps props;
private ScheduledTask updateTask; private ScheduledTask updateTask;
private ServerSection principal;
private final Map<String, ServerSection> sections = new HashMap<>(); private final Map<String, ServerSection> sections = Collections.synchronizedMap(new HashMap<>());
private final Map<ServerInfo, ServerSection> servers = new HashMap<>(); private final Map<ServerInfo, ServerSection> servers = Collections.synchronizedMap(new HashMap<>());
public SectionManager(PlayerBalancer plugin) { public SectionManager(PlayerBalancer plugin) {
this.props = plugin.getSettings().getBalancerProps(); this.props = plugin.getSettings().getBalancerProps();
@ -33,18 +33,16 @@ public class SectionManager {
plugin.getLogger().info("Executing section initialization stages, this may take a while..."); plugin.getLogger().info("Executing section initialization stages, this may take a while...");
long starting = System.currentTimeMillis(); long starting = System.currentTimeMillis();
props.getSectionProps().forEach((name, prop) -> { for (Stage stage : stages) {
plugin.getLogger().info(String.format("Construction of section with name \"%s\"", name)); plugin.getLogger().info("Executing stage \"" + stage.title + "\"");
ServerSection object = new ServerSection(name, prop); if (stage instanceof SectionStage) {
sections.put(name, object); props.getSectionProps().forEach((name, props) -> {
}); ((SectionStage) stage).execute(name, props, sections.get(name));
});
Preconditions.checkNotNull(this.getPrincipal(), } else {
"Could not set principal section, there is no section named \"%s\"", ((GlobalStage) stage).execute();
props.getPrincipalSectionName() }
); }
sections.forEach(this::processSection);
long ending = System.currentTimeMillis() - starting; long ending = System.currentTimeMillis() - starting;
plugin.getLogger().info(String.format("A total of %s section(s) have been loaded in %sms", sections.size(), ending)); 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; updateTask = null;
} }
principal = null;
sections.clear(); sections.clear();
servers.clear(); servers.clear();
} }
@ -121,67 +120,119 @@ public class SectionManager {
} }
private final Stage[] stages = { private final Stage[] stages = {
new Stage("Creation") { new SectionStage("Constructing sections") {
@Override @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 @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<ServerInfo> 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<ServerInfo> calculateServers(ServerSection section) { public Set<ServerInfo> calculateServers(ServerSection section) {
Set<ServerInfo> results = new HashSet<>(); Set<ServerInfo> 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(), servers.size(),
section.getProps().getServerEntries(), section.getProps().getServerEntries(),
section.getName() section.getName()
@ -213,7 +264,6 @@ public class SectionManager {
} }
public int calculatePosition(ServerSection section) { public int calculatePosition(ServerSection section) {
ServerSection principal = this.getPrincipal();
ServerSection current = section; ServerSection current = section;
//Calculate above principal //Calculate above principal
@ -244,6 +294,14 @@ public class SectionManager {
return iterations; return iterations;
} }
public ServerSection getPrincipal() {
return principal;
}
public boolean isPrincipal(ServerSection section) {
return principal.equals(section);
}
public boolean isDummy(ServerSection section) { public boolean isDummy(ServerSection section) {
List<String> dummySections = props.getDummySectionNames(); List<String> dummySections = props.getDummySectionNames();
return dummySections.contains(section.getName()); return dummySections.contains(section.getName());
@ -260,31 +318,34 @@ public class SectionManager {
return Optional.ofNullable(res); 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<String, ServerSection> getSections() { public Map<String, ServerSection> getSections() {
return sections; return sections;
} }
private abstract static class Stage { private static class Stage {
private final String title; private final String title;
public Stage(String title) { private Stage(String title) {
this.title = title; this.title = title;
} }
}
public String getTitle() { private static abstract class GlobalStage extends Stage {
return title;a private GlobalStage(String title) {
super(title);
} }
public abstract void execute( 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, SectionProps props,
ServerSection section ServerSection section
) throws RuntimeException; ) throws RuntimeException;

View File

@ -64,7 +64,15 @@ public class ServerSection {
} }
public ProviderType getImplicitProvider() { 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) { public void setExplicitProvider(ProviderType provider) {
@ -96,6 +104,10 @@ public class ServerSection {
return servers; return servers;
} }
public void setServers(Set<ServerInfo> servers) {
this.servers = servers;
}
public boolean isValid() { public boolean isValid() {
return valid; return valid;
} }

View File

@ -2,12 +2,14 @@
# Read the comments, they are a very important part of the configuration # 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 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 # 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 { general {
# IMPORTANT! Set this to true after configuring the plugin! # IMPORTANT! Set this to true after configuring the plugin!
enabled=false enabled=false
# When true, the plugin will check for new servers added to bungee # When true, the plugin will check for new servers added to bungee
# TODO Not done yet
auto-refresh=false auto-refresh=false
# When true, the plugin will reload when you execute /greload # When true, the plugin will reload when you execute /greload
@ -101,7 +103,7 @@ features {
# The principal section is very important for other features # The principal section is very important for other features
# Normally set this to the section that has your main lobbies # 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 # 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 # This affects both the fallback command and kick handler features