From 3f417d8ecb6fd00f8fd713e2cce59e24c1e50652 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 2 Oct 2021 19:07:50 +0200 Subject: [PATCH] Cyclic port running to reduce failing server starts Signed-off-by: Lixfel --- .../steamwar/bungeecore/SubserverSystem.java | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/src/de/steamwar/bungeecore/SubserverSystem.java b/src/de/steamwar/bungeecore/SubserverSystem.java index 018c8a33..66ec037d 100644 --- a/src/de/steamwar/bungeecore/SubserverSystem.java +++ b/src/de/steamwar/bungeecore/SubserverSystem.java @@ -29,7 +29,9 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; import java.io.File; import java.net.InetSocketAddress; import java.time.format.DateTimeFormatter; +import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; public class SubserverSystem { private SubserverSystem(){} @@ -39,14 +41,9 @@ public class SubserverSystem { private static final String SERVER_PATH = BACKBONE + "server/"; private static final String EVENT_PATH = BACKBONE + "event/"; - private static final int FIRST_ARENA_PORT; - - static { - if(BungeeCore.EVENT_MODE) - FIRST_ARENA_PORT = 6000; - else - FIRST_ARENA_PORT = 2500; - } + private static final boolean MAIN_SERVER = ProxyServer.getInstance().getConfig().getListeners().stream().anyMatch(info -> ((InetSocketAddress) info.getSocketAddress()).getPort() == 25565); + private static final Portrange bauPorts = MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200); + private static final Portrange arenaPorts = MAIN_SERVER ? new Portrange(3000, 3100) : (BungeeCore.EVENT_MODE ? new Portrange(4000, 5000) : bauPorts); /** * This function starts every arena (even test- and eventarenas). @@ -88,13 +85,13 @@ public class SubserverSystem { public static synchronized Subserver startArena(ArenaMode modus, String map, int eventFightID, int checkSchemID, int prepareSchemID, String serverName, String mapName, UUID player1, UUID player2, boolean ranked){ //Generate missing parameters Node node = eventFightID > 0 ? Node.local : Node.getNode(); - int port = freePort(FIRST_ARENA_PORT); + int port = arenaPorts.freePort(); if(serverName == null){ if(ranked) - serverName = "Ranked" + (port - FIRST_ARENA_PORT); + serverName = "Ranked" + (port - arenaPorts.start); else - serverName = modus.getDisplayName() + (port - FIRST_ARENA_PORT); + serverName = modus.getDisplayName() + (port - arenaPorts.start); } if(mapName == null) mapName = serverName; @@ -159,7 +156,7 @@ public class SubserverSystem { SteamwarUser user = SteamwarUser.get(owner); File directory = new File(SERVER_PATH, serverName); Node node = Node.getNode(); - int port = freePort(4000); + int port = bauPorts.freePort(); new Bauserver(user.getUserName() + "s Bau", owner, port, node.startServer( serverJar, directory, worldDir, worldName, port, xmx, "logPath=" + worldName @@ -213,21 +210,40 @@ public class SubserverSystem { Node.local.execute("cp", "-r", sourcePath, targetPath); } - private static int freePort(int start){ - synchronized (Subserver.getServerList()){ - int port = start; - boolean isFree = false; - while(!isFree){ - port++; - isFree = true; - for(Subserver server : Subserver.getServerList()){ - if(((InetSocketAddress)server.getServer().getSocketAddress()).getPort() == port){ - isFree = false; - break; - } - } + + private static class Portrange { + + private final int start; + private final int end; + private int current; + + private Portrange(int start, int end) { + this.start = start; + this.end = end; + current = start; + } + + private void increment() { + current++; + + if(current == end) + current = start; + } + + private synchronized int freePort() { + Set usedPorts; + + synchronized (Subserver.getServerList()) { + usedPorts = Subserver.getServerList().stream().map(server -> ((InetSocketAddress) server.getServer().getSocketAddress()).getPort()).collect(Collectors.toSet()); } - return port; + + while(usedPorts.contains(current)) { + increment(); + } + + int result = current; + increment(); + return result; } } }