diff --git a/src/de/steamwar/bungeecore/LoadEvaluation.java b/src/de/steamwar/bungeecore/LoadEvaluation.java new file mode 100644 index 00000000..d1785af1 --- /dev/null +++ b/src/de/steamwar/bungeecore/LoadEvaluation.java @@ -0,0 +1,92 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bungeecore; + +import java.io.*; + +public class LoadEvaluation { + private LoadEvaluation(){} + + private static final File meminfo = new File("/proc/meminfo"); + + public static double getRamPercentage() { + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(meminfo)))) { + String memTotal = bufferedReader.readLine().replaceAll(" +", " "); + bufferedReader.readLine(); + String memAvailable = bufferedReader.readLine().replaceAll(" +", " "); + + long memTotalLong = getNumber(memTotal); + long memAvailableLong = getNumber(memAvailable); + return (memTotalLong - memAvailableLong) / (double) memTotalLong; + } catch (IOException e) { + return 1D; + } + } + + public static double getRemoteRamPercentage() { + try { + Process process = new ProcessBuilder("ssh lx cat /proc/meminfo").start(); + process.waitFor(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); + String memTotal = bufferedReader.readLine().replaceAll(" +", " "); + bufferedReader.readLine(); + String memAvailable = bufferedReader.readLine().replaceAll(" +", " "); + + long memTotalLong = getNumber(memTotal); + long memAvailableLong = getNumber(memAvailable); + return (memTotalLong - memAvailableLong) / (double) memTotalLong; + } catch (IOException e) { + return 1D; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return 1D; + } + } + + public static double getCPULoad() { + try { + Process process = new ProcessBuilder("cat <(grep 'cpu ' /proc/stat) <(sleep 1 && grep 'cpu ' /proc/stat) | awk -v RS=\"\" '{printf \"%.2f\\n\", ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'").start(); + process.waitFor(); + return Double.parseDouble(new BufferedReader(new InputStreamReader(process.getInputStream())).readLine()); + } catch (IOException e) { + return 1D; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return 1D; + } + } + + public static double getRemoteCPULoad() { + try { + Process process = new ProcessBuilder("ssh lx cat <(grep 'cpu ' /proc/stat) <(sleep 1 && grep 'cpu ' /proc/stat) | awk -v RS=\"\" '{printf \"%.2f\\n\", ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'").start(); + process.waitFor(); + return Double.parseDouble(new BufferedReader(new InputStreamReader(process.getInputStream())).readLine()); + } catch (IOException e) { + return 1D; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return 1D; + } + } + + private static long getNumber(String s) { + return Long.parseLong(s.split(" ")[1]); + } +} diff --git a/src/de/steamwar/bungeecore/SubserverSystem.java b/src/de/steamwar/bungeecore/SubserverSystem.java index 2812eb33..3498008a 100644 --- a/src/de/steamwar/bungeecore/SubserverSystem.java +++ b/src/de/steamwar/bungeecore/SubserverSystem.java @@ -118,8 +118,10 @@ public class SubserverSystem { Thread.currentThread().interrupt(); } + File directory = new File(SERVER_PATH, modus.getFolder()); List cmd = serverStartCommand( modus.serverJar(), + directory, worldDir, mapName, port, @@ -135,7 +137,7 @@ public class SubserverSystem { //Start server ProcessBuilder process = new ProcessBuilder(cmd); - process.directory(new File(SERVER_PATH, modus.getFolder())); + process.directory(directory); String finalMapName = mapName; if(eventFightID == -1) @@ -185,8 +187,10 @@ public class SubserverSystem { copyBauweltIfRequired(p, prototype, worldFolder + worldName); int port = freePort(4000); + File directory = new File(SERVER_PATH, serverName); List cmd = serverStartCommand( serverJar, + directory, worldDir, worldName, port, @@ -195,7 +199,7 @@ public class SubserverSystem { //Start server ProcessBuilder process = new ProcessBuilder(cmd); - process.directory(new File(SERVER_PATH, serverName)); + process.directory(directory); new Bauserver(user.getUserName() + "s Bau", owner, port, process, () -> {}).sendPlayer(p); } @@ -231,9 +235,20 @@ public class SubserverSystem { new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bau addmember " + p.getName())); } - private static List serverStartCommand(String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams){ + private static List serverStartCommand(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams){ List cmd = new ArrayList<>(); boolean jdk11 = serverJar.contains("1.15.2"); + + if(!steamwarStartAvailible() && lixfelStartAvailible()){ + cmd.add("ssh"); + cmd.add("-L"); + cmd.add(port + ":localhost:" + port); + cmd.add("lx"); + cmd.add("cd"); + cmd.add(directory.getPath()); + cmd.add(";"); + } + if(jdk11) cmd.add("/usr/lib/jvm/java-11-openjdk-amd64/bin/java"); else @@ -259,6 +274,14 @@ public class SubserverSystem { return cmd; } + private static boolean steamwarStartAvailible(){ + return LoadEvaluation.getCPULoad() < 0.8 && LoadEvaluation.getRamPercentage() < 0.8; + } + + private static boolean lixfelStartAvailible(){ + return LoadEvaluation.getRemoteCPULoad() < 0.8 && LoadEvaluation.getRemoteRamPercentage() < 0.8; + } + private static boolean bauRunning(ProxiedPlayer p, UUID owner){ for(Subserver subserver : Subserver.getServerList()){ if(subserver.getType() == Servertype.BAUSERVER && ((Bauserver)subserver).getOwner().equals(owner)){