Add command for printing live servers through monitor

This commit is contained in:
Kenny Goodin 2017-11-25 20:31:58 -05:00 committed by Alexander Meech
parent b5ea6f1240
commit 4b552f0317
2 changed files with 258 additions and 159 deletions

View File

@ -12,6 +12,11 @@
<name>ServerMonitor</name> <name>ServerMonitor</name>
<artifactId>mineplex-servermonitor</artifactId> <artifactId>mineplex-servermonitor</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.jline>2.12</version.jline>
</properties>
<dependencies> <dependencies>
<dependency> <dependency>
@ -28,6 +33,12 @@
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
</dependency> </dependency>
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
<version>${version.jline}</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -16,11 +16,15 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Optional;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.logging.FileHandler; import java.util.logging.FileHandler;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.craftbukkit.libs.com.google.common.base.Throwables;
import org.fusesource.jansi.AnsiConsole;
import mineplex.core.common.util.NautHashMap; import mineplex.core.common.util.NautHashMap;
import mineplex.serverdata.Region; import mineplex.serverdata.Region;
import mineplex.serverdata.commands.RestartCommand; import mineplex.serverdata.commands.RestartCommand;
@ -32,9 +36,11 @@ import mineplex.serverdata.servers.DedicatedServerSorter;
import mineplex.serverdata.servers.ServerManager; import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository; import mineplex.serverdata.servers.ServerRepository;
import jline.console.ConsoleReader;
public class ServerMonitor public class ServerMonitor
{ {
private static ServerRepository _repository = null; private static volatile ServerRepository _repository = null;
private static StatusHistoryRepository _historyRepository = null; private static StatusHistoryRepository _historyRepository = null;
private static int _count = 0; private static int _count = 0;
private static HashSet<ProcessRunner> _processes = new HashSet<ProcessRunner>(); private static HashSet<ProcessRunner> _processes = new HashSet<ProcessRunner>();
@ -42,18 +48,18 @@ public class ServerMonitor
private static Collection<MinecraftServer> _serverStatuses = null; private static Collection<MinecraftServer> _serverStatuses = null;
private static Collection<ServerGroup> _serverGroups = null; private static Collection<ServerGroup> _serverGroups = null;
private static Map<String, ServerGroup> _serverGroupMap = null; private static Map<String, ServerGroup> _serverGroupMap = null;
private static List<DedicatedServer> _dedicatedServers = null; private static volatile List<DedicatedServer> _dedicatedServers = null;
private static HashSet<String> _deadServers = new HashSet<String>(); private static HashSet<String> _deadServers = new HashSet<String>();
private static HashSet<String> _delayedKill = new HashSet<String>(); private static HashSet<String> _delayedKill = new HashSet<String>();
private static HashSet<String> _laggyServers = new HashSet<String>(); private static HashSet<String> _laggyServers = new HashSet<String>();
private static SimpleDateFormat _dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); private static volatile SimpleDateFormat _dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
private static Logger _logger = Logger.getLogger("ServerMonitor"); private static volatile Logger _logger = Logger.getLogger("ServerMonitor");
private static Timer _timer = new Timer(); private static Timer _timer = new Timer();
private static int _totalPlayers = 0; private static int _totalPlayers = 0;
private static Region _region; private static Region _region;
private static boolean _debug = false; private static boolean _debug = false;
public static void main (String args[]) public static void main (String args[])
@ -75,7 +81,7 @@ public class ServerMonitor
_repository = ServerManager.getServerRepository(_region); // Fetches and connects to server repo _repository = ServerManager.getServerRepository(_region); // Fetches and connects to server repo
_historyRepository = new StatusHistoryRepository(); _historyRepository = new StatusHistoryRepository();
File logFile = new File("monitor.log"); File logFile = new File("monitor.log");
if (!logFile.exists()) if (!logFile.exists())
{ {
try try
@ -87,7 +93,7 @@ public class ServerMonitor
e1.printStackTrace(); e1.printStackTrace();
} }
} }
try try
{ {
FileHandler fileHandler = new FileHandler("monitor.log", true); FileHandler fileHandler = new FileHandler("monitor.log", true);
@ -99,9 +105,53 @@ public class ServerMonitor
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
AnsiConsole.systemInstall();
ConsoleReader reader = new ConsoleReader();
reader.setExpandEvents(false);
String command;
while ((command = reader.readLine(">")) != null)
{
if (command.contains("printservers"))
{
String[] parts = command.split(" ");
String serverGroup = "";
if (parts.length > 1)
{
serverGroup = parts[1];
}
printServersCommand(serverGroup);
}
else if (command.equals("help"))
{
log("Commands:");
log("printservers (server-group) - prints all servers if no server group is"
+ "supplied, or all servers of a given group if a server group is supplied.");
}
else
{
log("No command " + command + " found.");
}
}
}
catch (Exception e)
{
log(Throwables.getStackTraceAsString(e));
}
}
}).start();
HashMap<String, Entry<String, Long>> serverTracker = new HashMap<String, Entry<String, Long>>(); HashMap<String, Entry<String, Long>> serverTracker = new HashMap<String, Entry<String, Long>>();
while (true) while (true)
{ {
try try
@ -110,22 +160,22 @@ public class ServerMonitor
_serverStatuses = _repository.getServerStatuses(); _serverStatuses = _repository.getServerStatuses();
_serverGroups = _repository.getServerGroups(_serverStatuses); _serverGroups = _repository.getServerGroups(_serverStatuses);
_serverGroupMap = new HashMap<String, ServerGroup>(); _serverGroupMap = new HashMap<String, ServerGroup>();
_dedicatedServers = new ArrayList<DedicatedServer>(_repository.getDedicatedServers()); _dedicatedServers = Collections.synchronizedList(new ArrayList<>(_repository.getDedicatedServers()));
calculateTotalPlayers(); calculateTotalPlayers();
killDeadServers(); killDeadServers();
double totalCPU = 0.0; double totalCPU = 0.0;
double totalRAM = 0.0; double totalRAM = 0.0;
double availableCPU = 0.0; double availableCPU = 0.0;
double availableRAM = 0.0; double availableRAM = 0.0;
for (DedicatedServer server : _dedicatedServers) for (DedicatedServer server : _dedicatedServers)
{ {
totalCPU += server.getAvailableCpu(); totalCPU += server.getAvailableCpu();
totalRAM += server.getAvailableRam(); totalRAM += server.getAvailableRam();
} }
for (MinecraftServer minecraftServer : _serverStatuses) for (MinecraftServer minecraftServer : _serverStatuses)
{ {
if (!ignoreServer(minecraftServer.getGroup())) if (!ignoreServer(minecraftServer.getGroup()))
@ -133,12 +183,12 @@ public class ServerMonitor
if (minecraftServer.getMotd().contains("Finished") || (minecraftServer.getGroup().equalsIgnoreCase("UltraHardcore") && minecraftServer.getMotd().contains("Restarting") && minecraftServer.getPlayerCount() == 0)) if (minecraftServer.getMotd().contains("Finished") || (minecraftServer.getGroup().equalsIgnoreCase("UltraHardcore") && minecraftServer.getMotd().contains("Restarting") && minecraftServer.getPlayerCount() == 0))
{ {
killServer(minecraftServer.getName(), minecraftServer.getPublicAddress(), minecraftServer.getPlayerCount(), "[KILLED] [FINISHED] " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress(), true); killServer(minecraftServer.getName(), minecraftServer.getPublicAddress(), minecraftServer.getPlayerCount(), "[KILLED] [FINISHED] " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress(), true);
handleUserServerGroup(_serverGroupMap.get(minecraftServer.getGroup())); handleUserServerGroup(_serverGroupMap.get(minecraftServer.getGroup()));
continue; continue;
} }
} }
for (DedicatedServer server : _dedicatedServers) for (DedicatedServer server : _dedicatedServers)
{ {
if (_serverGroupMap.containsKey(minecraftServer.getGroup()) && minecraftServer.getPublicAddress().equalsIgnoreCase(server.getPrivateAddress())) if (_serverGroupMap.containsKey(minecraftServer.getGroup()) && minecraftServer.getPublicAddress().equalsIgnoreCase(server.getPrivateAddress()))
@ -148,11 +198,11 @@ public class ServerMonitor
} }
} }
} }
if (_count % 15 == 0) if (_count % 15 == 0)
{ {
_badServers.clear(); _badServers.clear();
for (DedicatedServer serverData : _dedicatedServers) for (DedicatedServer serverData : _dedicatedServers)
{ {
if (isServerOffline(serverData)) if (isServerOffline(serverData))
@ -161,14 +211,14 @@ public class ServerMonitor
_badServers.put(serverData.getName(), true); _badServers.put(serverData.getName(), true);
} }
} }
log(_badServers.size() + " bad servers."); log(_badServers.size() + " bad servers.");
} }
for (Iterator<DedicatedServer> iterator = _dedicatedServers.iterator(); iterator.hasNext();) for (Iterator<DedicatedServer> iterator = _dedicatedServers.iterator(); iterator.hasNext();)
{ {
DedicatedServer serverData = iterator.next(); DedicatedServer serverData = iterator.next();
if (_badServers.containsKey(serverData.getName())) if (_badServers.containsKey(serverData.getName()))
iterator.remove(); iterator.remove();
else else
@ -177,12 +227,12 @@ public class ServerMonitor
availableRAM += serverData.getAvailableRam(); availableRAM += serverData.getAvailableRam();
} }
} }
double usedCpuPercent = Math.round((1 - availableCPU / totalCPU) * 10000.0) / 100.0; double usedCpuPercent = Math.round((1 - availableCPU / totalCPU) * 10000.0) / 100.0;
double usedRamPercent = Math.round((1 - availableRAM / totalRAM) * 10000.0) / 100.0; double usedRamPercent = Math.round((1 - availableRAM / totalRAM) * 10000.0) / 100.0;
log("Using " + usedCpuPercent + "% of available CPU (" + availableCPU + " Free) and " + usedRamPercent + "% of available RAM (" + availableRAM / 1000 + "GB Free)"); log("Using " + usedCpuPercent + "% of available CPU (" + availableCPU + " Free) and " + usedRamPercent + "% of available RAM (" + availableRAM / 1000 + "GB Free)");
try try
{ {
_historyRepository.saveDedicatedServerStats(_dedicatedServers); _historyRepository.saveDedicatedServerStats(_dedicatedServers);
@ -196,19 +246,19 @@ public class ServerMonitor
{ {
ex.printStackTrace(); ex.printStackTrace();
} }
if (_count == 0) if (_count == 0)
{ {
for (Iterator<ServerGroup> groupStatusIterator = _serverGroups.iterator(); groupStatusIterator.hasNext();) for (Iterator<ServerGroup> groupStatusIterator = _serverGroups.iterator(); groupStatusIterator.hasNext();)
{ {
ServerGroup groupStatus = groupStatusIterator.next(); ServerGroup groupStatus = groupStatusIterator.next();
if (groupStatus.getServerType().equalsIgnoreCase("Player")) if (groupStatus.getServerType().equalsIgnoreCase("Player"))
{ {
_repository.removeServerGroup(groupStatus); _repository.removeServerGroup(groupStatus);
_serverGroupMap.remove(groupStatus.getName()); _serverGroupMap.remove(groupStatus.getName());
groupStatusIterator.remove(); groupStatusIterator.remove();
System.out.println("Removed MPS : " + groupStatus.getName()); System.out.println("Removed MPS : " + groupStatus.getName());
} }
if (groupStatus.getServerType().equalsIgnoreCase("Community")) if (groupStatus.getServerType().equalsIgnoreCase("Community"))
@ -216,19 +266,19 @@ public class ServerMonitor
_repository.removeServerGroup(groupStatus); _repository.removeServerGroup(groupStatus);
_serverGroupMap.remove(groupStatus.getName()); _serverGroupMap.remove(groupStatus.getName());
groupStatusIterator.remove(); groupStatusIterator.remove();
System.out.println("Removed MCS : " + groupStatus.getName()); System.out.println("Removed MCS : " + groupStatus.getName());
} }
} }
} }
for (ServerGroup groupStatus : _serverGroups) for (ServerGroup groupStatus : _serverGroups)
{ {
if (ignoreServer(groupStatus.getName())) if (ignoreServer(groupStatus.getName()))
continue; continue;
NautHashMap<Integer, MinecraftServer> serverMap = new NautHashMap<Integer, MinecraftServer>(); NautHashMap<Integer, MinecraftServer> serverMap = new NautHashMap<Integer, MinecraftServer>();
for (Iterator<MinecraftServer> serverIterator = groupStatus.getServers().iterator(); serverIterator.hasNext();) for (Iterator<MinecraftServer> serverIterator = groupStatus.getServers().iterator(); serverIterator.hasNext();)
{ {
try try
@ -236,7 +286,7 @@ public class ServerMonitor
MinecraftServer server = serverIterator.next(); MinecraftServer server = serverIterator.next();
String[] nameArgs = server.getName().split("-"); String[] nameArgs = server.getName().split("-");
int serverNum = Integer.parseInt(nameArgs[nameArgs.length - 1]); int serverNum = Integer.parseInt(nameArgs[nameArgs.length - 1]);
if (serverMap.containsKey(serverNum)) if (serverMap.containsKey(serverNum))
{ {
killServer(server.getName(), server.getPublicAddress(), server.getPlayerCount(), "[KILLED] [DUPLICATE] " + server.getName() + ":" + server.getPublicAddress(), true); killServer(server.getName(), server.getPublicAddress(), server.getPlayerCount(), "[KILLED] [DUPLICATE] " + server.getName() + ":" + server.getPublicAddress(), true);
@ -253,19 +303,19 @@ public class ServerMonitor
} }
} }
} }
HashSet<String> onlineServers = new HashSet<String>(); HashSet<String> onlineServers = new HashSet<String>();
HashSet<String> laggyServers = new HashSet<String>(); HashSet<String> laggyServers = new HashSet<String>();
laggyServers.addAll(_laggyServers); laggyServers.addAll(_laggyServers);
_laggyServers.clear(); _laggyServers.clear();
for (MinecraftServer minecraftServer : _serverStatuses) for (MinecraftServer minecraftServer : _serverStatuses)
{ {
if (ignoreServer(minecraftServer.getGroup())) if (ignoreServer(minecraftServer.getGroup()))
continue; continue;
onlineServers.add(minecraftServer.getName()); onlineServers.add(minecraftServer.getName());
if (minecraftServer.getTps() <= 17) if (minecraftServer.getTps() <= 17)
{ {
if (minecraftServer.getTps() <= 10) if (minecraftServer.getTps() <= 10)
@ -285,27 +335,27 @@ public class ServerMonitor
log("[Performance] " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress() + "] Running poorly at " + minecraftServer.getTps() + " TPS"); log("[Performance] " + minecraftServer.getName() + ":" + minecraftServer.getPublicAddress() + "] Running poorly at " + minecraftServer.getTps() + " TPS");
} }
} }
for (Iterator<Entry<String, Entry<String, Long>>> iterator = serverTracker.entrySet().iterator(); iterator.hasNext();) for (Iterator<Entry<String, Entry<String, Long>>> iterator = serverTracker.entrySet().iterator(); iterator.hasNext();)
{ {
Entry<String, Entry<String, Long>> entry = iterator.next(); Entry<String, Entry<String, Long>> entry = iterator.next();
if (onlineServers.contains(entry.getKey())) if (onlineServers.contains(entry.getKey()))
iterator.remove(); iterator.remove();
else if (System.currentTimeMillis() - entry.getValue().getValue() > 35000) else if (System.currentTimeMillis() - entry.getValue().getValue() > 35000)
{ {
String serverName = entry.getKey(); String serverName = entry.getKey();
String serverAddress = entry.getValue().getKey(); String serverAddress = entry.getValue().getKey();
killServer(serverName, serverAddress, 0, "[KILLED] [SLOW-STARTUP] " + serverName + ":" + serverAddress, true); killServer(serverName, serverAddress, 0, "[KILLED] [SLOW-STARTUP] " + serverName + ":" + serverAddress, true);
iterator.remove(); iterator.remove();
} }
} }
for (ServerGroup serverGroup : _serverGroups) for (ServerGroup serverGroup : _serverGroups)
{ {
if (ignoreServer(serverGroup.getName())) if (ignoreServer(serverGroup.getName()))
continue; continue;
try try
{ {
handleGroupChanges(serverTracker, serverGroup, false); handleGroupChanges(serverTracker, serverGroup, false);
@ -316,9 +366,9 @@ public class ServerMonitor
log("Can't handle group changes for " + serverGroup.getName()); log("Can't handle group changes for " + serverGroup.getName());
} }
} }
int processWaits = 0; int processWaits = 0;
while (_processes.size() > 0) while (_processes.size() > 0)
{ {
try try
@ -326,16 +376,16 @@ public class ServerMonitor
for (Iterator<ProcessRunner> iterator = _processes.iterator(); iterator.hasNext();) for (Iterator<ProcessRunner> iterator = _processes.iterator(); iterator.hasNext();)
{ {
ProcessRunner pr = iterator.next(); ProcessRunner pr = iterator.next();
try try
{ {
pr.join(100); pr.join(100);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
if (pr.isDone()) if (pr.isDone())
iterator.remove(); iterator.remove();
} }
@ -344,48 +394,48 @@ public class ServerMonitor
{ {
ex.printStackTrace(); ex.printStackTrace();
} }
if (_processes.size() > 0) if (_processes.size() > 0)
{ {
try try
{ {
log("Sleeping while processes run..."); log("Sleeping while processes run...");
Thread.sleep(6000); Thread.sleep(6000);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
} }
if (processWaits >= 5) if (processWaits >= 5)
{ {
log("Killing stale processes."); log("Killing stale processes.");
for (Iterator<ProcessRunner> iterator = _processes.iterator(); iterator.hasNext();) for (Iterator<ProcessRunner> iterator = _processes.iterator(); iterator.hasNext();)
{ {
iterator.next().abort(); iterator.next().abort();
iterator.remove(); iterator.remove();
} }
_processes.clear(); _processes.clear();
} }
processWaits++; processWaits++;
} }
processWaits = 0; processWaits = 0;
try try
{ {
log("Natural sleep."); log("Natural sleep.");
Thread.sleep(10000); Thread.sleep(10000);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
_count++; _count++;
} }
catch (Exception ex) catch (Exception ex)
@ -408,40 +458,41 @@ public class ServerMonitor
{ {
HashSet<String> deadServers = new HashSet<String>(); HashSet<String> deadServers = new HashSet<String>();
deadServers.addAll(_deadServers); deadServers.addAll(_deadServers);
_deadServers.clear(); _deadServers.clear();
for (final MinecraftServer deadServer : _repository.getDeadServers()) for (final MinecraftServer deadServer : _repository.getDeadServers())
{ {
if (deadServer.getUptime() <= 10 || ignoreServer(deadServer.getGroup())) if (deadServer.getUptime() <= 10 || ignoreServer(deadServer.getGroup()))
continue; continue;
try try
{ {
if (_count == 0 || deadServers.contains(deadServer.getName())) if (_count == 0 || deadServers.contains(deadServer.getName()))
{ {
if (_count != 0) if (_count != 0)
copyServerLog(deadServer); copyServerLog(deadServer);
killServer(deadServer.getName(), deadServer.getPublicAddress(), deadServer.getPlayerCount(), "[KILLED] [DEAD] " + deadServer.getName() + ":" + deadServer.getPublicAddress(), true); killServer(deadServer.getName(), deadServer.getPublicAddress(), deadServer.getPlayerCount(), "[KILLED] [DEAD] " + deadServer.getName() + ":" + deadServer.getPublicAddress(), true);
handleUserServerGroup(_serverGroupMap.get(deadServer.getGroup())); handleUserServerGroup(_serverGroupMap.get(deadServer.getGroup()));
} }
else if (!_delayedKill.contains(deadServer.getName())) else if (!_delayedKill.contains(deadServer.getName()))
{ {
startTimingReport(deadServer); startTimingReport(deadServer);
_timer.schedule(new TimerTask() _timer.schedule(new TimerTask()
{ {
public void run() @Override
public void run()
{ {
_deadServers.add(deadServer.getName()); _deadServers.add(deadServer.getName());
_delayedKill.remove(deadServer.getName()); _delayedKill.remove(deadServer.getName());
stopTimingReport(deadServer); stopTimingReport(deadServer);
log("[IMPENDING DEATH] : " + deadServer.getName() + ":" + deadServer.getPublicAddress()); log("[IMPENDING DEATH] : " + deadServer.getName() + ":" + deadServer.getPublicAddress());
} }
}, 20 * 1000); }, 20 * 1000);
_delayedKill.add(deadServer.getName()); _delayedKill.add(deadServer.getName());
} }
} }
@ -463,7 +514,7 @@ public class ServerMonitor
System.out.println("Removed ServerGroup : " + serverGroup.getName()); System.out.println("Removed ServerGroup : " + serverGroup.getName());
} }
} }
private static void calculateTotalPlayers() private static void calculateTotalPlayers()
{ {
for (ServerGroup serverGroup : _serverGroups) for (ServerGroup serverGroup : _serverGroups)
@ -471,7 +522,7 @@ public class ServerMonitor
_serverGroupMap.put(serverGroup.getName(), serverGroup); _serverGroupMap.put(serverGroup.getName(), serverGroup);
_totalPlayers += serverGroup.getPlayerCount(); _totalPlayers += serverGroup.getPlayerCount();
} }
log("Total Players : " + _totalPlayers); log("Total Players : " + _totalPlayers);
} }
@ -490,13 +541,13 @@ public class ServerMonitor
if (serverGroup.getName().equalsIgnoreCase("Lobby")) if (serverGroup.getName().equalsIgnoreCase("Lobby"))
{ {
if (_region == Region.EU) if (_region == Region.EU)
{ {
requiredTotal = 10; requiredTotal = 10;
requiredJoinable = 10; requiredJoinable = 10;
} }
int availableSlots = serverGroup.getMaxPlayerCount() - serverGroup.getPlayerCount(); int availableSlots = serverGroup.getMaxPlayerCount() - serverGroup.getPlayerCount();
if (availableSlots < 1000) if (availableSlots < 1000)
{ {
serversToAdd = Math.max(1, (1000 - availableSlots) / serverGroup.getMaxPlayers()); serversToAdd = Math.max(1, (1000 - availableSlots) / serverGroup.getMaxPlayers());
@ -509,12 +560,12 @@ public class ServerMonitor
{ {
serversToRestart = Math.min(joinableServers - requiredJoinable, joinableServers - requiredTotal); serversToRestart = Math.min(joinableServers - requiredJoinable, joinableServers - requiredTotal);
serversToRestart = Math.min(serversToRestart, (availableSlots - 1000) / 80); serversToRestart = Math.min(serversToRestart, (availableSlots - 1000) / 80);
if (serversToRestart <= 5) if (serversToRestart <= 5)
serversToRestart = 0; serversToRestart = 0;
} }
} }
else if (serverGroup.getName().equalsIgnoreCase("Halloween")) else if (serverGroup.getName().equalsIgnoreCase("Halloween"))
{ {
@ -533,10 +584,10 @@ public class ServerMonitor
else if (serverGroup.getName().equalsIgnoreCase("UltraHardcore")) else if (serverGroup.getName().equalsIgnoreCase("UltraHardcore"))
{ {
int maxUHC = Math.max(1, _totalPlayers / 6000); int maxUHC = Math.max(1, _totalPlayers / 6000);
if (serversToAdd > 0) if (serversToAdd > 0)
serversToAdd = maxUHC - joinableServers; serversToAdd = maxUHC - joinableServers;
if (joinableServers > maxUHC) if (joinableServers > maxUHC)
serversToKill = maxUHC - joinableServers; serversToKill = maxUHC - joinableServers;
} }
@ -544,7 +595,7 @@ public class ServerMonitor
{ {
return; return;
} }
// KILL, CLEAN, THEN ADD // KILL, CLEAN, THEN ADD
while (serversToKill > 0) while (serversToKill > 0)
{ {
@ -553,16 +604,16 @@ public class ServerMonitor
killServer(emptyServer, "[KILLED] [EXCESS] " + emptyServer.getName() + ":" + emptyServer.getPublicAddress()); killServer(emptyServer, "[KILLED] [EXCESS] " + emptyServer.getName() + ":" + emptyServer.getPublicAddress());
serversToKill--; serversToKill--;
} }
while (serversToAdd > 0) while (serversToAdd > 0)
{ {
serverNum = serverGroup.generateUniqueId(serverNum + 1); serverNum = serverGroup.generateUniqueId(serverNum + 1);
while (_deadServers.contains(serverGroup.getPrefix() + "-" + serverNum)) while (_deadServers.contains(serverGroup.getPrefix() + "-" + serverNum))
{ {
serverNum = serverGroup.generateUniqueId(serverNum + 1); serverNum = serverGroup.generateUniqueId(serverNum + 1);
} }
Collections.sort(_dedicatedServers, new DedicatedServerSorter()); Collections.sort(_dedicatedServers, new DedicatedServerSorter());
DedicatedServer bestServer = getBestDedicatedServer(_dedicatedServers, serverGroup); DedicatedServer bestServer = getBestDedicatedServer(_dedicatedServers, serverGroup);
@ -579,14 +630,14 @@ public class ServerMonitor
startServer(bestServer, serverGroup, serverNum, free); startServer(bestServer, serverGroup, serverNum, free);
serverTracker.put(serverGroup.getPrefix() + "-" + serverNum, new AbstractMap.SimpleEntry<String, Long>(bestServer.getPublicAddress(), System.currentTimeMillis())); serverTracker.put(serverGroup.getPrefix() + "-" + serverNum, new AbstractMap.SimpleEntry<String, Long>(bestServer.getPublicAddress(), System.currentTimeMillis()));
} }
serversToAdd--; serversToAdd--;
} }
List<MinecraftServer> servers = new ArrayList<MinecraftServer>(); List<MinecraftServer> servers = new ArrayList<MinecraftServer>();
servers.addAll(serverGroup.getServers()); servers.addAll(serverGroup.getServers());
Collections.sort(servers, new ServerSorter()); Collections.sort(servers, new ServerSorter());
while (serversToRestart > 0) while (serversToRestart > 0)
{ {
MinecraftServer server = servers.get(servers.size() - serversToRestart); MinecraftServer server = servers.get(servers.size() - serversToRestart);
@ -600,26 +651,27 @@ public class ServerMonitor
{ {
if (_debug) if (_debug)
return; return;
String cmd = "/home/mineplex/easyRemoteKillServer.sh"; String cmd = "/home/mineplex/easyRemoteKillServer.sh";
ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, serverAddress, serverName}); ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, serverAddress, serverName});
pr.start(new GenericRunnable<Boolean>() pr.start(new GenericRunnable<Boolean>()
{ {
public void run(Boolean error) @Override
public void run(Boolean error)
{ {
MinecraftServer server = null; MinecraftServer server = null;
if (!error) if (!error)
{ {
server = _repository.getServerStatus(serverName); server = _repository.getServerStatus(serverName);
if (server != null) if (server != null)
{ {
_repository.removeServerStatus(server); _repository.removeServerStatus(server);
} }
} }
if (announce) if (announce)
{ {
if (error) if (error)
@ -629,17 +681,17 @@ public class ServerMonitor
} }
} }
}); });
try try
{ {
pr.join(50); pr.join(50);
} }
catch (InterruptedException e1) catch (InterruptedException e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
if (!pr.isDone()) if (!pr.isDone())
_processes.add(pr); _processes.add(pr);
} }
@ -647,31 +699,31 @@ public class ServerMonitor
private static boolean isServerOffline(DedicatedServer serverData) private static boolean isServerOffline(DedicatedServer serverData)
{ {
boolean success = false; boolean success = false;
if (_debug) if (_debug)
return false; return false;
Process process = null; Process process = null;
String cmd = "/home/mineplex/isServerOnline.sh"; String cmd = "/home/mineplex/isServerOnline.sh";
ProcessBuilder processBuilder = new ProcessBuilder(new String[] {"/bin/sh", cmd, serverData.getPublicAddress()}); ProcessBuilder processBuilder = new ProcessBuilder(new String[] {"/bin/sh", cmd, serverData.getPublicAddress()});
try try
{ {
process = processBuilder.start(); process = processBuilder.start();
process.waitFor(); process.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream())); BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = reader.readLine(); String line = reader.readLine();
while(line != null) while(line != null)
{ {
success = line.equals("Success"); success = line.equals("Success");
line=reader.readLine(); line=reader.readLine();
} }
} }
catch (Exception e1) catch (Exception e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
@ -686,10 +738,10 @@ public class ServerMonitor
private static DedicatedServer getBestDedicatedServer(Collection<DedicatedServer> dedicatedServers, ServerGroup serverGroup) private static DedicatedServer getBestDedicatedServer(Collection<DedicatedServer> dedicatedServers, ServerGroup serverGroup)
{ {
DedicatedServer bestServer = null; DedicatedServer bestServer = null;
for (DedicatedServer serverData : dedicatedServers) for (DedicatedServer serverData : dedicatedServers)
{ {
if (serverData.getAvailableRam() > serverGroup.getRequiredRam() if (serverData.getAvailableRam() > serverGroup.getRequiredRam()
&& serverData.getAvailableCpu() > serverGroup.getRequiredCpu()) && serverData.getAvailableCpu() > serverGroup.getRequiredCpu())
{ {
if (bestServer == null || serverData.getServerCount(serverGroup) < bestServer.getServerCount(serverGroup)) if (bestServer == null || serverData.getServerCount(serverGroup) < bestServer.getServerCount(serverGroup))
@ -698,7 +750,7 @@ public class ServerMonitor
} }
} }
} }
return bestServer; return bestServer;
} }
@ -706,18 +758,19 @@ public class ServerMonitor
{ {
killServer(serverToKill.getName(), serverToKill.getPublicAddress(), serverToKill.getPlayerCount(), message, true); killServer(serverToKill.getName(), serverToKill.getPublicAddress(), serverToKill.getPlayerCount(), message, true);
} }
private static void startTimingReport(final MinecraftServer server) private static void startTimingReport(final MinecraftServer server)
{ {
if (_debug) if (_debug)
return; return;
String cmd = "/home/mineplex/remoteStartTiming.sh"; String cmd = "/home/mineplex/remoteStartTiming.sh";
ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() }); ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() });
pr.start(new GenericRunnable<Boolean>() pr.start(new GenericRunnable<Boolean>()
{ {
public void run(Boolean error) @Override
public void run(Boolean error)
{ {
if (error) if (error)
log("[TIMING START] Errored " + server.getName() + "(" + server.getPublicAddress() + ")"); log("[TIMING START] Errored " + server.getName() + "(" + server.getPublicAddress() + ")");
@ -726,31 +779,32 @@ public class ServerMonitor
} }
}); });
try try
{ {
pr.join(100); pr.join(100);
} }
catch (InterruptedException e1) catch (InterruptedException e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
if (!pr.isDone()) if (!pr.isDone())
_processes.add(pr); _processes.add(pr);
} }
private static void stopTimingReport(final MinecraftServer server) private static void stopTimingReport(final MinecraftServer server)
{ {
if (_debug) if (_debug)
return; return;
String cmd = "/home/mineplex/remoteStopTiming.sh"; String cmd = "/home/mineplex/remoteStopTiming.sh";
ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() }); ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() });
pr.start(new GenericRunnable<Boolean>() pr.start(new GenericRunnable<Boolean>()
{ {
public void run(Boolean error) @Override
public void run(Boolean error)
{ {
if (error) if (error)
log("[TIMING PASTE] Errored " + server.getName() + "(" + server.getPublicAddress() + ")"); log("[TIMING PASTE] Errored " + server.getName() + "(" + server.getPublicAddress() + ")");
@ -759,31 +813,32 @@ public class ServerMonitor
} }
}); });
try try
{ {
pr.join(100); pr.join(100);
} }
catch (InterruptedException e1) catch (InterruptedException e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
if (!pr.isDone()) if (!pr.isDone())
_processes.add(pr); _processes.add(pr);
} }
private static void copyServerLog(final MinecraftServer server) private static void copyServerLog(final MinecraftServer server)
{ {
if (_debug) if (_debug)
return; return;
String cmd = "/home/mineplex/easyRemoteCopyLog.sh"; String cmd = "/home/mineplex/easyRemoteCopyLog.sh";
ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() }); ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, server.getPublicAddress(), server.getName() });
pr.start(new GenericRunnable<Boolean>() pr.start(new GenericRunnable<Boolean>()
{ {
public void run(Boolean error) @Override
public void run(Boolean error)
{ {
if (error) if (error)
log("[COPY LOG] Errored " + server.getName() + "(" + server.getPublicAddress() + ")"); log("[COPY LOG] Errored " + server.getName() + "(" + server.getPublicAddress() + ")");
@ -792,34 +847,35 @@ public class ServerMonitor
} }
}); });
try try
{ {
pr.join(100); pr.join(100);
} }
catch (InterruptedException e1) catch (InterruptedException e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
if (!pr.isDone()) if (!pr.isDone())
_processes.add(pr); _processes.add(pr);
} }
private static void startServer(final DedicatedServer serverSpace, final ServerGroup serverGroup, final int serverNum, final boolean free) private static void startServer(final DedicatedServer serverSpace, final ServerGroup serverGroup, final int serverNum, final boolean free)
{ {
if (_debug) if (_debug)
return; return;
String cmd = "/home/mineplex/easyRemoteStartServerCustom.sh"; String cmd = "/home/mineplex/easyRemoteStartServerCustom.sh";
final String groupPrefix = serverGroup.getPrefix(); final String groupPrefix = serverGroup.getPrefix();
final String serverName = serverSpace.getName(); final String serverName = serverSpace.getName();
final String serverAddress = serverSpace.getPublicAddress(); final String serverAddress = serverSpace.getPublicAddress();
ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, serverAddress, serverSpace.getPrivateAddress(), (serverGroup.getPortSection() + serverNum) + "", serverGroup.getRequiredRam() + "", serverGroup.getWorldZip(), serverGroup.getPlugin(), serverGroup.getConfigPath(), serverGroup.getName(), serverGroup.getPrefix() + "-" + serverNum, serverSpace.isUsRegion() ? "true" : "false", serverGroup.getAddNoCheat() + "", serverGroup.getAddWorldEdit() + "" }); ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, serverAddress, serverSpace.getPrivateAddress(), (serverGroup.getPortSection() + serverNum) + "", serverGroup.getRequiredRam() + "", serverGroup.getWorldZip(), serverGroup.getPlugin(), serverGroup.getConfigPath(), serverGroup.getName(), serverGroup.getPrefix() + "-" + serverNum, serverSpace.isUsRegion() ? "true" : "false", serverGroup.getAddNoCheat() + "", serverGroup.getAddWorldEdit() + "" });
pr.start(new GenericRunnable<Boolean>() pr.start(new GenericRunnable<Boolean>()
{ {
public void run(Boolean error) @Override
public void run(Boolean error)
{ {
if (error) if (error)
log("[" + serverName + ":" + serverAddress + " Free Resources; CPU " + serverSpace.getAvailableCpu() + " RAM " + serverSpace.getAvailableRam() + "MB] Errored " + serverName + "(" + groupPrefix+ "-" + serverNum + (free ? "-FREE" : "") + ")"); log("[" + serverName + ":" + serverAddress + " Free Resources; CPU " + serverSpace.getAvailableCpu() + " RAM " + serverSpace.getAvailableRam() + "MB] Errored " + serverName + "(" + groupPrefix+ "-" + serverNum + (free ? "-FREE" : "") + ")");
@ -828,36 +884,68 @@ public class ServerMonitor
} }
}); });
try try
{ {
pr.join(100); pr.join(100);
} }
catch (InterruptedException e1) catch (InterruptedException e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
serverSpace.incrementServerCount(serverGroup); serverSpace.incrementServerCount(serverGroup);
if (!pr.isDone()) if (!pr.isDone())
_processes.add(pr); _processes.add(pr);
} }
private static void printServersCommand(String serverGroup)
{
// grab servers
Collection<MinecraftServer> servers = _repository.getServerStatuses();
// remove entries not within the target server group, if one is supplied
if (!serverGroup.isEmpty())
{
servers.removeIf(s -> !s.getGroup().equalsIgnoreCase(serverGroup));
}
List<MinecraftServer> serverList = new ArrayList<>(servers);
Collections.sort(serverList,
(a, b) -> Integer.compare(b.getPlayerCount(), a.getPlayerCount()));
serverList.forEach(server ->
{
Optional<DedicatedServer> opt = getDediStatusFromAddress(server.getPublicAddress());
String dediName = opt.map(dedi -> dedi.getName()).orElse("???");
String fmt = "%s: %s (%s players online), open slots: %s, free ram: %sMB";
log(String.format(fmt, server.getName(), dediName, server.getPlayerCount(),
server.getMaxPlayerCount() - server.getPlayerCount(), server.getRam()));
});
}
private static Optional<DedicatedServer> getDediStatusFromAddress(String address)
{
return _dedicatedServers.stream().filter(dedi -> dedi.getPrivateAddress().equals(address))
.findFirst();
}
private static boolean ignoreServer(String serverGroupName) private static boolean ignoreServer(String serverGroupName)
{ {
return serverGroupName.equalsIgnoreCase("Testing") || serverGroupName.equalsIgnoreCase("Clans"); return serverGroupName.equalsIgnoreCase("Testing") || serverGroupName.equalsIgnoreCase("Clans");
} }
private static void log(String message) private static void log(String message)
{ {
log(message, false); log(message, false);
} }
private static void log(String message, boolean fileOnly) private static void log(String message, boolean fileOnly)
{ {
_logger.info("[" + _dateFormat.format(new Date()) + "] " + message); _logger.info("[" + _dateFormat.format(new Date()) + "] " + message);
if (!fileOnly) if (!fileOnly)
System.out.println("[" + _dateFormat.format(new Date()) + "] " + message); System.out.println("[" + _dateFormat.format(new Date()) + "] " + message);
} }