diff --git a/CommonCore b/CommonCore index 89b0c14d..aa70f423 160000 --- a/CommonCore +++ b/CommonCore @@ -1 +1 @@ -Subproject commit 89b0c14da664589a7c9699d73bf72028cdf9dd0d +Subproject commit aa70f423d87e9f6534ad2dd1f20a5122179c423f diff --git a/build.gradle b/build.gradle index 789fc216..1d681384 100644 --- a/build.gradle +++ b/build.gradle @@ -96,7 +96,8 @@ dependencies { testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' compileOnly 'de.steamwar:waterfall:RELEASE' - compileOnly 'de.steamwar:persistentbungeecore:RELEASE' + // compileOnly 'de.steamwar:persistentbungeecore:RELEASE' + compileOnly files('libs/persistentbungeecore.jar') implementation("net.dv8tion:JDA:4.4.0_352") { exclude module: 'opus-java' } diff --git a/src/de/steamwar/bungeecore/Node.java b/src/de/steamwar/bungeecore/Node.java index 387a1f05..6d42c3ab 100644 --- a/src/de/steamwar/bungeecore/Node.java +++ b/src/de/steamwar/bungeecore/Node.java @@ -19,6 +19,7 @@ package de.steamwar.bungeecore; +import de.steamwar.bungeecore.listeners.ConnectionListener; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.ProxyServer; @@ -27,6 +28,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.logging.Level; +import java.util.stream.Collectors; public abstract class Node { @@ -49,6 +51,7 @@ public abstract class Node { for(Node node : nodes) { if(node.belowLoadLimit) return node; + ConnectionListener.cleanup(node); } return null; } diff --git a/src/de/steamwar/bungeecore/ServerStarter.java b/src/de/steamwar/bungeecore/ServerStarter.java index 9373b57f..45649a76 100644 --- a/src/de/steamwar/bungeecore/ServerStarter.java +++ b/src/de/steamwar/bungeecore/ServerStarter.java @@ -265,6 +265,8 @@ public class ServerStarter { Subserver subserver = constructor.construct(serverName, port, node.startServer( serverJar, directory, worldDir, worldName, port, xmx, arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new) ), worldCleanup); + Storage.serverToNodeMap.put(subserver, node.getName()); + Storage.nodeToServerMap.computeIfAbsent(node.getName(), s -> new ArrayList<>()).add(subserver); for(ProxiedPlayer p : playersToSend) SubserverSystem.sendPlayer(subserver, p); diff --git a/src/de/steamwar/bungeecore/listeners/ConnectionListener.java b/src/de/steamwar/bungeecore/listeners/ConnectionListener.java index a1b2e82d..69064549 100644 --- a/src/de/steamwar/bungeecore/listeners/ConnectionListener.java +++ b/src/de/steamwar/bungeecore/listeners/ConnectionListener.java @@ -19,10 +19,7 @@ package de.steamwar.bungeecore.listeners; -import de.steamwar.bungeecore.BungeeCore; -import de.steamwar.bungeecore.Message; -import de.steamwar.bungeecore.Servertype; -import de.steamwar.bungeecore.Subserver; +import de.steamwar.bungeecore.*; import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig; import de.steamwar.bungeecore.bot.util.DiscordRanks; import de.steamwar.bungeecore.commands.ChallengeCommand; @@ -32,6 +29,7 @@ import de.steamwar.bungeecore.commands.MsgCommand; import de.steamwar.bungeecore.listeners.mods.Utils; import de.steamwar.bungeecore.sql.SteamwarUser; import de.steamwar.bungeecore.sql.UserGroup; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.AbstractReconnectHandler; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.ClickEvent; @@ -44,6 +42,7 @@ import net.md_5.bungee.api.event.ServerKickEvent; import net.md_5.bungee.event.EventHandler; import java.util.*; +import java.util.concurrent.TimeUnit; public class ConnectionListener extends BasicListener { @@ -141,8 +140,49 @@ public class ConnectionListener extends BasicListener { ModCommand.playerFilterType.remove(e.getPlayer()); } + { + BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> { + Node.forEach(node -> { + if (!node.belowLoadLimit()) cleanup(node); + }); + }, 0, 1, TimeUnit.MINUTES); + } + + private static final Set currentlyCleaning = new HashSet<>(); + + public static void cleanup(Node node) { + synchronized (currentlyCleaning) { + if (currentlyCleaning.contains(node)) return; + currentlyCleaning.add(node); + } + + ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> { + try { + List subservers = Storage.nodeToServerMap.get(node.getName()); + if (subservers == null) return; + Subserver oldest = null; + long oldestTime = Long.MAX_VALUE; + for (Subserver subserver : subservers) { + long time = Storage.timeOfServerEmpty.get(subserver); + if (time < oldestTime) { + oldest = subserver; + oldestTime = time; + } + } + if (oldest == null) return; + oldest.stop(); + } finally { + synchronized (currentlyCleaning) { + currentlyCleaning.remove(node); + } + } + }); + } + @EventHandler public void onServerDisconnect(ServerDisconnectEvent e){ + Storage.timeOfServerEmpty.remove(Subserver.getSubserver(e.getPlayer().getServer().getInfo())); + ServerInfo server = e.getTarget(); Subserver subserver = Subserver.getSubserver(server); if(subserver == null) @@ -150,7 +190,12 @@ public class ConnectionListener extends BasicListener { ProxiedPlayer player = e.getPlayer(); Collection players = server.getPlayers(); - if(players.isEmpty() || (players.size() == 1 && players.contains(player))) - ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), subserver::waitForTermination); + if(players.isEmpty() || (players.size() == 1 && players.contains(player))) { + if (subserver instanceof Bauserver || subserver instanceof Builderserver) { + Storage.timeOfServerEmpty.put(subserver, System.currentTimeMillis()); + } else { + ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), subserver::waitForTermination); + } + } } }