Rework SubServers.Bungee's app lifecycle

SubServers.Bungee now puts code in 2 new places to better load/unload it's data.

When supported, this should give it better compatabilty with ordanary plugins. Also, it no longer has to 'shutdown' to handle /greload. Isn't that neat?
This commit is contained in:
ME1312 2021-02-06 23:53:03 -05:00
parent 25fff82af6
commit 3dea3b67d0
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
20 changed files with 230 additions and 269 deletions

View File

@ -30,13 +30,13 @@
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId> <artifactId>GalaxiUtil</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId> <artifactId>GalaxiEngine</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -26,14 +26,6 @@ public interface BungeeAPI {
return ((BungeeCommon) ProxyServer.getInstance()).api.run(); return ((BungeeCommon) ProxyServer.getInstance()).api.run();
} }
/**
* Adds a SubAPI Listener
*
* @param enable An Event that will be called when SubAPI is ready
* @param disable An Event that will be called before SubAPI is disabled (your plugin should reset it's values in case this is a hard-reset instead of a shutdown)
*/
void addListener(Runnable enable, Runnable disable);
/** /**
* Get the number of players on this network across all known proxies * Get the number of players on this network across all known proxies
* *

View File

@ -19,7 +19,6 @@ public class Logger {
* @param prefix Prefix * @param prefix Prefix
* @return Logger * @return Logger
*/ */
@SuppressWarnings("deprecation")
public static java.util.logging.Logger get(String prefix) { public static java.util.logging.Logger get(String prefix) {
if (!existing.keySet().contains(prefix)) { if (!existing.keySet().contains(prefix)) {
java.util.logging.Logger log = Util.getDespiteException(() -> Util.reflect(Class.forName("net.ME1312.Galaxi.Library.Log.Logger").getDeclaredMethod("toPrimitive"), java.util.logging.Logger log = Util.getDespiteException(() -> Util.reflect(Class.forName("net.ME1312.Galaxi.Library.Log.Logger").getDeclaredMethod("toPrimitive"),
@ -29,23 +28,14 @@ public class Logger {
log = java.util.logging.Logger.getAnonymousLogger(); log = java.util.logging.Logger.getAnonymousLogger();
log.setUseParentHandlers(false); log.setUseParentHandlers(false);
log.addHandler(new Handler() { log.addHandler(new Handler() {
private boolean open = true;
@Override @Override
public void publish(LogRecord record) { public void publish(LogRecord record) {
if (open)
BungeeCommon.getInstance().getLogger().log(record.getLevel(), prefix + " > " + record.getMessage(), record.getParameters()); BungeeCommon.getInstance().getLogger().log(record.getLevel(), prefix + " > " + record.getMessage(), record.getParameters());
} }
@Override @Override
public void flush() { public void flush() {}
public void close() {}
}
@Override
public void close() throws SecurityException {
open = false;
}
}); });
} }
existing.put(prefix, log); existing.put(prefix, log);

View File

@ -30,14 +30,14 @@
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId> <artifactId>GalaxiUtil</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>compile</scope> <scope>compile</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId> <artifactId>GalaxiEngine</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -465,13 +465,11 @@ public abstract class Host implements ExtraDataHandler {
*/ */
public boolean destroy() { public boolean destroy() {
try { try {
List<String> subservers = new ArrayList<String>(); String[] subservers = getSubServers().keySet().toArray(new String[0]);
subservers.addAll(getSubServers().keySet());
for (String server : subservers) { for (String server : subservers) {
forceRemoveSubServer(server); forceRemoveSubServer(server);
} }
subservers.clear();
getCreator().terminate(); getCreator().terminate();
getCreator().waitFor(); getCreator().waitFor();
return true; return true;

View File

@ -124,9 +124,9 @@ public class InternalHost extends Host {
server.stop(); server.stop();
server.waitFor(); server.waitFor();
} }
servers.remove(name.toLowerCase());
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(server.getAddress().getPort())) if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(server.getAddress().getPort()))
UPnP.closePortTCP(server.getAddress().getPort()); UPnP.closePortTCP(server.getAddress().getPort());
servers.remove(name.toLowerCase());
return true; return true;
} else return false; } else return false;
} }

View File

@ -1,19 +1,23 @@
package net.ME1312.SubServers.Bungee.Library.Compatibility; package net.ME1312.SubServers.Bungee.Library.Compatibility;
import net.ME1312.Galaxi.Library.Callback.ExceptionRunnable;
import net.ME1312.Galaxi.Library.Util; import net.ME1312.Galaxi.Library.Util;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.PluginDescription; import net.md_5.bungee.api.plugin.PluginDescription;
import java.io.File; import java.io.File;
import java.io.IOException;
public final class Plugin extends net.md_5.bungee.api.plugin.Plugin { public final class Plugin extends net.md_5.bungee.api.plugin.Plugin {
private static final PluginDescription description = new PluginDescription(); private static final PluginDescription description = new PluginDescription();
private final boolean invalid; private final ExceptionRunnable enable;
private final Runnable disable;
@Deprecated @Deprecated
public Plugin() { public Plugin() {
this.invalid = true; enable = null;
disable = null;
} }
private static PluginDescription describe() { private static PluginDescription describe() {
@ -25,9 +29,10 @@ public final class Plugin extends net.md_5.bungee.api.plugin.Plugin {
return description; return description;
} }
public Plugin(ProxyServer proxy) { public Plugin(ProxyServer proxy, ExceptionRunnable enable, Runnable disable) {
super(proxy, describe()); super(proxy, describe());
this.invalid = false; this.enable = enable;
this.disable = disable;
// 2020 BungeeCord builds don't run init(), but future builds may uncomment that line. We wouldn't want to repeat ourselves. // 2020 BungeeCord builds don't run init(), but future builds may uncomment that line. We wouldn't want to repeat ourselves.
if (getDescription() == null) Util.isException(() -> Util.reflect(net.md_5.bungee.api.plugin.Plugin.class.getDeclaredMethod("init", ProxyServer.class, PluginDescription.class), this, proxy, description)); if (getDescription() == null) Util.isException(() -> Util.reflect(net.md_5.bungee.api.plugin.Plugin.class.getDeclaredMethod("init", ProxyServer.class, PluginDescription.class), this, proxy, description));
@ -35,6 +40,17 @@ public final class Plugin extends net.md_5.bungee.api.plugin.Plugin {
@Override @Override
public void onEnable() { public void onEnable() {
if (invalid) throw new IllegalStateException("SubServers.Bungee does not run as a plugin, but a wrapper. For more information on how to install, please visit this page: https://github.com/ME1312/SubServers-2/wiki/Install"); if (enable == null) {
throw new IllegalStateException("SubServers.Bungee does not run as a plugin, but a wrapper. For more information on how to install, please visit this page: https://github.com/ME1312/SubServers-2/wiki/Install");
} else try {
enable.run();
} catch (Throwable e) {
e.printStackTrace();
}
}
@Override
public void onDisable() {
if (disable != null) disable.run();
} }
} }

View File

@ -28,9 +28,7 @@ import java.util.*;
* SubAPI Class * SubAPI Class
*/ */
public final class SubAPI implements BungeeAPI { public final class SubAPI implements BungeeAPI {
LinkedList<Runnable> enableListeners = new LinkedList<Runnable>();
LinkedList<Runnable> reloadListeners = new LinkedList<Runnable>(); LinkedList<Runnable> reloadListeners = new LinkedList<Runnable>();
LinkedList<Runnable> disableListeners = new LinkedList<Runnable>();
private static HashMap<String, Object> knownSignatures = new HashMap<String, Object>(); private static HashMap<String, Object> knownSignatures = new HashMap<String, Object>();
boolean ready = false; boolean ready = false;
private final SubProxy plugin; private final SubProxy plugin;
@ -63,25 +61,11 @@ public final class SubAPI implements BungeeAPI {
} }
/** /**
* Adds a SubAPI Listener * Adds a SubAPI Reload Listener
* *
* @param enable An Event that will be called when SubAPI is ready
* @param disable An Event that will be called before SubAPI is disabled (your plugin should reset it's values in case this is a hard-reset instead of a shutdown)
*/
public void addListener(Runnable enable, Runnable disable) {
if (enable != null) enableListeners.add(enable);
if (disable != null) disableListeners.add(disable);
}
/**
* Adds a SubAPI Listener
*
* @param enable An Event that will be called when SubAPI is ready
* @param reload An Event that will be called after SubAPI is soft-reloaded * @param reload An Event that will be called after SubAPI is soft-reloaded
* @param disable An Event that will be called before SubAPI is disabled (your plugin should reset it's values in case this is a hard-reset instead of a shutdown)
*/ */
public void addListener(Runnable enable, Runnable reload, Runnable disable) { public void addListener(Runnable reload) {
addListener(enable, disable);
if (reload != null) reloadListeners.add(reload); if (reload != null) reloadListeners.add(reload);
} }

View File

@ -121,16 +121,27 @@ public final class SubCommand extends CommandX {
} catch (Exception e) {} } catch (Exception e) {}
}, "SubServers.Bungee::Update_Check").start(); }, "SubServers.Bungee::Update_Check").start();
} else if (args[0].equalsIgnoreCase("reload")) { } else if (args[0].equalsIgnoreCase("reload")) {
new Thread(() -> {
if (args.length > 1) { if (args.length > 1) {
switch (args[1].toLowerCase()) { switch (args[1].toLowerCase()) {
case "*": case "*":
case "all": case "all":
case "hard":
case "system": case "system":
case "bungee":
case "bungeecord":
case "subdata": case "subdata":
case "network": case "network":
plugin.getPluginManager().dispatchCommand(ConsoleCommandSender.getInstance(), "greload"); plugin.stopListeners();
plugin.getLogger().info("Closing player connections");
for (ProxiedPlayer player : plugin.getPlayers()) {
Util.isException(() -> player.disconnect(plugin.getTranslation("restart")));
}
plugin.shutdown();
case "soft":
case "bungee":
case "bungeecord":
case "plugin":
case "plugins":
plugin.getPluginManager().dispatchCommand(sender, "greload");
break; break;
case "host": case "host":
case "hosts": case "hosts":
@ -167,6 +178,7 @@ public final class SubCommand extends CommandX {
e.printStackTrace(); e.printStackTrace();
} }
} }
}, "SubServers.Bungee::Reload_Command_Handler").start();
} else if (args[0].equalsIgnoreCase("list")) { } else if (args[0].equalsIgnoreCase("list")) {
String div = ChatColor.RESET + ", "; String div = ChatColor.RESET + ", ";
int i = 0; int i = 0;
@ -830,7 +842,7 @@ public final class SubCommand extends CommandX {
" Help: /sub help", " Help: /sub help",
" List: /sub list", " List: /sub list",
" Version: /sub version", " Version: /sub version",
" Reload: /sub reload [all|config|templates]", " Reload: /sub reload [hard|bungee|servers|templates]",
" Info: /sub info [proxy|host|group|server|player] <Name>", " Info: /sub info [proxy|host|group|server|player] <Name>",
" Start Server: /sub start <Subservers>", " Start Server: /sub start <Subservers>",
" Restart Server: /sub restart <Subservers>", " Restart Server: /sub restart <Subservers>",
@ -987,12 +999,12 @@ public final class SubCommand extends CommandX {
} else if (!(sender instanceof ProxiedPlayer) && (args[0].equals("reload") || args[0].equals("restore"))) { } else if (!(sender instanceof ProxiedPlayer) && (args[0].equals("reload") || args[0].equals("restore"))) {
if (args[0].equals("reload")) { if (args[0].equals("reload")) {
List<String> list = new ArrayList<String>(), List<String> list = new ArrayList<String>(),
completes = Arrays.asList("all", "config", "templates"); completes = Arrays.asList("hard", "bungee", "servers", "templates");
if (args.length == 2) { if (args.length == 2) {
for (String complete : completes) { for (String complete : completes) {
if (complete.toLowerCase().startsWith(last)) list.add(Last + complete.substring(last.length())); if (complete.toLowerCase().startsWith(last)) list.add(Last + complete.substring(last.length()));
} }
return new ContainedPair<>((list.size() <= 0)?plugin.api.getLang("SubServers", "Command.Generic.Unknown").replace("$str$", args[0]):null, list); return new ContainedPair<>(null, list);
} else { } else {
return new ContainedPair<>(null, Collections.emptyList()); return new ContainedPair<>(null, Collections.emptyList());
} }

View File

@ -11,7 +11,6 @@ import net.ME1312.SubData.Server.ClientHandler;
import net.ME1312.SubData.Server.Encryption.AES; import net.ME1312.SubData.Server.Encryption.AES;
import net.ME1312.SubData.Server.Encryption.DHE; import net.ME1312.SubData.Server.Encryption.DHE;
import net.ME1312.SubData.Server.Encryption.RSA; import net.ME1312.SubData.Server.Encryption.RSA;
import net.ME1312.SubData.Server.Library.DataSize;
import net.ME1312.SubData.Server.SubDataClient; import net.ME1312.SubData.Server.SubDataClient;
import net.ME1312.SubData.Server.SubDataServer; import net.ME1312.SubData.Server.SubDataServer;
import net.ME1312.SubServers.Bungee.Event.SubRemoveProxyEvent; import net.ME1312.SubServers.Bungee.Event.SubRemoveProxyEvent;
@ -47,6 +46,7 @@ import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.*; import net.md_5.bungee.api.event.*;
import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.PluginManager;
import net.md_5.bungee.connection.InitialHandler; import net.md_5.bungee.connection.InitialHandler;
import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventHandler;
@ -62,6 +62,7 @@ import java.security.SecureRandom;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Handler;
/** /**
* Main Plugin Class * Main Plugin Class
@ -241,8 +242,9 @@ public final class SubProxy extends BungeeCommon implements Listener {
api.addHostDriver(net.ME1312.SubServers.Bungee.Host.Internal.InternalHost.class, "virtual"); api.addHostDriver(net.ME1312.SubServers.Bungee.Host.Internal.InternalHost.class, "virtual");
api.addHostDriver(net.ME1312.SubServers.Bungee.Host.External.ExternalHost.class, "network"); api.addHostDriver(net.ME1312.SubServers.Bungee.Host.External.ExternalHost.class, "network");
plugin = Util.getDespiteException(() -> new Plugin(this), null); plugin = Util.getDespiteException(() -> new Plugin(this, this::reload, this::shutdown), null);
if (plugin == null) Logger.get("SubServers").warning("Could not initialize plugin object emulation"); if (plugin == null) Logger.get("SubServers").warning("Could not initialize plugin object emulation");
else Util.isException(() -> Util.<LinkedHashMap<String, net.md_5.bungee.api.plugin.Plugin>>reflect(PluginManager.class.getDeclaredField("plugins"), getPluginManager()).put(null, plugin));
getPluginManager().registerListener(plugin, this); getPluginManager().registerListener(plugin, this);
@ -292,21 +294,21 @@ public final class SubProxy extends BungeeCommon implements Listener {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void startListeners() { public void startListeners() {
try { try {
reload(); if (posted || !api.ready) reload();
if (UPnP.isUPnPAvailable()) { if (UPnP.isUPnPAvailable()) {
if (config.get().getMap("Settings").getMap("UPnP", new ObjectMap<String>()).getBoolean("Forward-Proxy", true)) for (ListenerInfo listener : getConfig().getListeners()) { if (config.get().getMap("Settings").getMap("UPnP", new ObjectMap<String>()).getBoolean("Forward-Proxy", true)) for (ListenerInfo listener : getConfig().getListeners()) {
UPnP.openPortTCP(listener.getHost().getPort()); UPnP.openPortTCP(listener.getHost().getPort());
} }
} else { } else {
getLogger().warning("UPnP is currently unavailable. Ports may not be automatically forwarded on this device."); getLogger().warning("UPnP service is unavailable. SubServers can't port-forward for you from this device.");
} }
super.startListeners(); super.startListeners();
if (!posted) { if (!posted) {
post();
posted = true; posted = true;
post();
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -429,16 +431,7 @@ public final class SubProxy extends BungeeCommon implements Listener {
int subservers = 0; int subservers = 0;
Logger.get("SubServers").info(((status)?"Rel":"L")+"oading SubServers..."); Logger.get("SubServers").info(((status)?"Rel":"L")+"oading SubServers...");
if (!posted) Runtime.getRuntime().addShutdownHook(new Thread(() -> { if (!posted) Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown, "SubServers.Bungee::System_Shutdown"));
if (running) {
Logger.get("SubServers").info("Received request from system to shutdown");
try {
shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "SubServers.Bungee::System_Shutdown"));
running = true; running = true;
List<String> autorun = new LinkedList<String>(); List<String> autorun = new LinkedList<String>();
for (String name : this.servers.get().getMap("Servers").getKeys()) { for (String name : this.servers.get().getMap("Servers").getKeys()) {
@ -605,7 +598,8 @@ public final class SubProxy extends BungeeCommon implements Listener {
} }
int plugins = 0; int plugins = 0;
List<Runnable> listeners = (status)?api.reloadListeners:api.enableListeners; if (status) {
List<Runnable> listeners = api.reloadListeners;
if (listeners.size() > 0) { if (listeners.size() > 0) {
Logger.get("SubServers").info(((status)?"Rel":"L")+"oading SubAPI Plugins..."); Logger.get("SubServers").info(((status)?"Rel":"L")+"oading SubAPI Plugins...");
for (Runnable obj : listeners) { for (Runnable obj : listeners) {
@ -618,7 +612,6 @@ public final class SubProxy extends BungeeCommon implements Listener {
} }
} }
if (status) {
for (Host host : api.getHosts().values()) if (host instanceof ClientHandler && ((ClientHandler) host).getSubData()[0] != null) ((SubDataClient) ((ClientHandler) host).getSubData()[0]).sendPacket(new PacketOutExReload(null)); for (Host host : api.getHosts().values()) if (host instanceof ClientHandler && ((ClientHandler) host).getSubData()[0] != null) ((SubDataClient) ((ClientHandler) host).getSubData()[0]).sendPacket(new PacketOutExReload(null));
for (Server server : api.getServers().values()) if (server.getSubData()[0] != null) ((SubDataClient) server.getSubData()[0]).sendPacket(new PacketOutExReload(null)); for (Server server : api.getServers().values()) if (server.getSubData()[0] != null) ((SubDataClient) server.getSubData()[0]).sendPacket(new PacketOutExReload(null));
} }
@ -733,23 +726,6 @@ public final class SubProxy extends BungeeCommon implements Listener {
} }
} }
}, TimeUnit.SECONDS.toMillis(rpec_s), TimeUnit.SECONDS.toMillis(rpec_i)); }, TimeUnit.SECONDS.toMillis(rpec_s), TimeUnit.SECONDS.toMillis(rpec_i));
new Timer("SubServers.Bungee::Garbo_Collector").schedule(new TimerTask() {
@Override
public void run() {
long start = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
System.gc();
Timer timer = new Timer("SubServers.Bungee::Garbo_Collector_Result");
timer.schedule(new TimerTask() {
@Override
public void run() {
long end = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
Logger.get("SGC").info("Cleared " + (start - end) + " bytes of extremely useless memory data. Now using " + end + " bytes.");
if (subdata != null) Logger.get("SDD").info(subdata.getClients().size() + " SubData channels are open.");
timer.cancel();
}
}, TimeUnit.MINUTES.toMillis(1));
}
}, TimeUnit.HOURS.toMillis(1), TimeUnit.HOURS.toMillis(1));
} }
/** /**
@ -759,57 +735,49 @@ public final class SubProxy extends BungeeCommon implements Listener {
*/ */
@Override @Override
public void stopListeners() { public void stopListeners() {
try { if (running) {
legServers.clear(); legServers.clear();
legServers.putAll(getServersCopy()); legServers.putAll(getServersCopy());
if (api.disableListeners.size() > 0) {
Logger.get("SubServers").info("Resetting SubAPI Plugins...");
for (Runnable listener : api.disableListeners) {
try {
listener.run();
} catch (Throwable e) {
new InvocationTargetException(e, "Problem disabling plugin").printStackTrace();
}
}
}
shutdown();
subdata.close();
for (ListenerInfo listener : getConfig().getListeners()) {
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(listener.getHost().getPort())) UPnP.closePortTCP(listener.getHost().getPort());
}
} catch (Exception e) {
e.printStackTrace();
}
ListenerInfo[] listeners = getConfig().getListeners().toArray(new ListenerInfo[0]);
super.stopListeners(); super.stopListeners();
} private void shutdown() throws Exception {
if (UPnP.isUPnPAvailable()) {
for (ListenerInfo listener : listeners) {
if (UPnP.isMappedTCP(listener.getHost().getPort())) UPnP.closePortTCP(listener.getHost().getPort());
}
}
}
} protected void shutdown() {
if (running) {
api.ready = false; api.ready = false;
Logger.get("SubServers").info("Resetting Hosts and Server Data"); Logger.get("SubServers").info("Stopping hosted servers");
List<String> hosts = new ArrayList<String>(); String[] hosts = this.hosts.keySet().toArray(new String[0]);
hosts.addAll(this.hosts.keySet());
for (String host : hosts) { for (String host : hosts) {
api.forceRemoveHost(host); api.forceRemoveHost(host);
} }
Logger.get("SubServers").info("Removing dynamic data");
running = false; running = false;
this.hosts.clear();
exServers.clear(); exServers.clear();
this.hosts.clear();
for (String proxy : proxies.keySet()) { String[] proxies = this.proxies.keySet().toArray(new String[0]);
getPluginManager().callEvent(new SubRemoveProxyEvent(proxies.get(proxy))); for (String proxy : proxies) {
} getPluginManager().callEvent(new SubRemoveProxyEvent(this.proxies.get(proxy)));
proxies.clear();
for (ListenerInfo listener : getConfig().getListeners()) {
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(listener.getHost().getPort())) UPnP.closePortTCP(listener.getHost().getPort());
} }
this.proxies.clear();
rPlayerLinkS.clear(); rPlayerLinkS.clear();
rPlayerLinkP.clear(); rPlayerLinkP.clear();
rPlayers.clear(); rPlayers.clear();
try {
subdata.close();
Thread.sleep(500);
} catch (InterruptedException | IOException e) {}
}
} }
String getNewSignature() { String getNewSignature() {

View File

@ -48,7 +48,7 @@
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId> <artifactId>GalaxiUtil</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>compile</scope> <scope>compile</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>

View File

@ -20,7 +20,7 @@
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId> <artifactId>GalaxiUtil</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -30,7 +30,7 @@
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId> <artifactId>GalaxiUtil</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>compile</scope> <scope>compile</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>

View File

@ -45,12 +45,12 @@ public final class ConsolePlugin extends Plugin implements Listener {
e.printStackTrace(); e.printStackTrace();
} }
SubAPI.getInstance().addListener(null, new Runnable() { SubAPI.getInstance().addListener(new Runnable() {
@Override @Override
public void run() { public void run() {
reload(); reload();
} }
}, null); });
} }
private void reload() { private void reload() {

View File

@ -20,7 +20,7 @@
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId> <artifactId>GalaxiEngine</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>compile</scope> <scope>compile</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>

View File

@ -224,14 +224,18 @@ public final class ExHost {
updcount++; updcount++;
} }
} }
if (updcount > 0) log.info.println("SubServers.Host v" + updversion + " is available. You are " + updcount + " version" + ((updcount == 1)?"":"s") + " behind."); if (updcount > 0) {
log.info.println("SubServers.Host v" + updversion + " is available. You are " + updcount + " version" + ((updcount == 1)?"":"s") + " behind.");
return true;
}
} catch (Exception e) {} } catch (Exception e) {}
return false;
}); });
engine.start(this::stop); engine.start(this::stop);
if (!UPnP.isUPnPAvailable()) { if (!UPnP.isUPnPAvailable()) {
log.warn.println("UPnP is currently unavailable. Ports may not be automatically forwarded on this device."); log.warn.println("UPnP service is unavailable. SubServers can't port-forward for you from this device.");
} }
} catch (Exception e) { } catch (Exception e) {
if (engine == null) { if (engine == null) {
@ -289,19 +293,19 @@ public final class ExHost {
private void stop() { private void stop() {
if (running) { if (running) {
log.info.println("Shutting down..."); log.info.println("Stopping hosted servers");
String[] subservers = servers.keySet().toArray(new String[0]);
List<String> subservers = new ArrayList<String>(); for (String name : subservers) {
subservers.addAll(servers.keySet()); SubServerImpl server = servers.get(name);
server.stop();
for (String server : subservers) {
servers.get(server).stop();
try { try {
servers.get(server).waitFor(); server.waitFor();
} catch (Exception e) { } catch (Exception e) {
log.error.println(e); log.error.println(e);
} }
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(servers.get(server).getPort())) UPnP.closePortTCP(servers.get(server).getPort()); servers.remove(name);
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(server.getPort())) UPnP.closePortTCP(server.getPort());
} }
servers.clear(); servers.clear();

View File

@ -30,14 +30,14 @@
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiUtil</artifactId> <artifactId>GalaxiUtil</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>compile</scope> <scope>compile</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.ME1312.Galaxi</groupId> <groupId>net.ME1312.Galaxi</groupId>
<artifactId>GalaxiEngine</artifactId> <artifactId>GalaxiEngine</artifactId>
<version>21w04a</version> <version>21w06a</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -268,7 +268,7 @@ public final class ExProxy extends BungeeCommon implements Listener {
new Timer("SubServers.Sync::RemotePlayer_Error_Checking").schedule(new TimerTask() { new Timer("SubServers.Sync::RemotePlayer_Error_Checking").schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
if (api.getSubDataNetwork()[0] != null && !api.getSubDataNetwork()[0].isClosed()) { if (api.getName() != null && api.getSubDataNetwork()[0] != null && !api.getSubDataNetwork()[0].isClosed()) {
api.getProxy(api.getName(), proxy -> { api.getProxy(api.getName(), proxy -> {
synchronized (rPlayers) { synchronized (rPlayers) {
ArrayList<CachedPlayer> add = new ArrayList<CachedPlayer>(); ArrayList<CachedPlayer> add = new ArrayList<CachedPlayer>();
@ -376,7 +376,7 @@ public final class ExProxy extends BungeeCommon implements Listener {
@Override @Override
public void stopListeners() { public void stopListeners() {
try { try {
Logger.get("SubServers").info("Resetting Server Data"); Logger.get("SubServers").info("Removing synced data");
servers.clear(); servers.clear();
reconnect = false; reconnect = false;
@ -389,8 +389,10 @@ public final class ExProxy extends BungeeCommon implements Listener {
subdata.clear(); subdata.clear();
subdata.put(0, null); subdata.put(0, null);
if (UPnP.isUPnPAvailable()) {
for (ListenerInfo listener : getConfig().getListeners()) { for (ListenerInfo listener : getConfig().getListeners()) {
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(listener.getHost().getPort())) UPnP.closePortTCP(listener.getHost().getPort()); if (UPnP.isMappedTCP(listener.getHost().getPort())) UPnP.closePortTCP(listener.getHost().getPort());
}
} }
rPlayerLinkS.clear(); rPlayerLinkS.clear();

View File

@ -20,8 +20,6 @@ import java.util.*;
* SubAPI Class * SubAPI Class
*/ */
public final class SubAPI extends ClientAPI implements BungeeAPI { public final class SubAPI extends ClientAPI implements BungeeAPI {
LinkedList<Runnable> enableListeners = new LinkedList<Runnable>();
LinkedList<Runnable> disableListeners = new LinkedList<Runnable>();
private final ExProxy plugin; private final ExProxy plugin;
private static SubAPI api; private static SubAPI api;
String name; String name;
@ -52,17 +50,6 @@ public final class SubAPI extends ClientAPI implements BungeeAPI {
return plugin; return plugin;
} }
/**
* Adds a SubAPI Listener
*
* @param enable An Event that will be called when SubAPI is ready
* @param disable An Event that will be called before SubAPI is disabled (your plugin should reset it's values in case this is a hard-reset instead of a shutdown)
*/
public void addListener(Runnable enable, Runnable disable) {
if (enable != null) enableListeners.add(enable);
if (disable != null) disableListeners.add(disable);
}
/** /**
* Get the Proxy Name * Get the Proxy Name
* *

View File

@ -1463,6 +1463,9 @@ public final class SubCommand extends CommandX {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void execute(CommandSender sender, String[] args) { public void execute(CommandSender sender, String[] args) {
if (plugin.lang == null) {
throw new IllegalStateException("There are no lang options available at this time");
} else {
if (sender instanceof ProxiedPlayer) { if (sender instanceof ProxiedPlayer) {
if (args.length > 0) { if (args.length > 0) {
Map<String, ServerImpl> servers = plugin.servers; Map<String, ServerImpl> servers = plugin.servers;
@ -1498,6 +1501,7 @@ public final class SubCommand extends CommandX {
sender.sendMessage(plugin.api.getLang("SubServers", "Command.Generic.Player-Only")); sender.sendMessage(plugin.api.getLang("SubServers", "Command.Generic.Player-Only"));
} }
} }
}
/** /**
* Suggest command arguments * Suggest command arguments
@ -1507,7 +1511,7 @@ public final class SubCommand extends CommandX {
* @return The validator's response and list of possible arguments * @return The validator's response and list of possible arguments
*/ */
public Pair<String, List<String>> suggestArguments(CommandSender sender, String[] args) { public Pair<String, List<String>> suggestArguments(CommandSender sender, String[] args) {
if (args.length <= 1) { if (plugin.lang != null && args.length <= 1) {
String last = (args.length > 0)?args[args.length - 1].toLowerCase():""; String last = (args.length > 0)?args[args.length - 1].toLowerCase():"";
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
if (last.length() == 0) { if (last.length() == 0) {
@ -1557,6 +1561,9 @@ public final class SubCommand extends CommandX {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void execute(CommandSender sender, String[] args) { public void execute(CommandSender sender, String[] args) {
if (plugin.lang == null) {
throw new IllegalStateException("There are no lang options available at this time");
} else {
List<String> messages = new LinkedList<String>(); List<String> messages = new LinkedList<String>();
int players = 0; int players = 0;
for (ServerImpl server : plugin.servers.values()) { for (ServerImpl server : plugin.servers.values()) {
@ -1581,3 +1588,4 @@ public final class SubCommand extends CommandX {
} }
} }
} }
}