NBloodServerSupervisor/Supervisor/PublicServerManager.cs
2020-01-27 16:25:45 +00:00

91 lines
2.9 KiB
C#

using Common;
using Model;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace Supervisor
{
static class PublicServerManager
{
public static void Start()
{
Thread.Sleep(TimeSpan.FromSeconds(2));
KillOrphanedServers();
Task.Factory.StartNew(() =>
{
while (true)
{
LaunchNewServersWhenNeeded();
Thread.Sleep(TimeSpan.FromSeconds(1));
}
});
}
private static void KillOrphanedServers()
{
foreach (var process in Process.GetProcessesByName("nblood_server"))
{
if (!Program.State.Servers.Values.Any(s => s.ProcessId == process.Id))
{
process.Kill();
}
}
}
private static void LaunchNewServersWhenNeeded()
{
foreach (Mod mod in Constants.SupportedMods.Values)
{
const int maxPlayers = 8;
for (int i = 3; i <= maxPlayers; i++)
{
if (IsNewServerNeeded(i, mod))
{
try
{
var spawnedServer = ProcessSpawner.SpawnServer(i, mod.Name);
int port = spawnedServer.Port;
int processId = spawnedServer.Process.Id;
Program.State.Servers.AddOrUpdate(port, new Server()
{
Port = port,
ProcessId = processId,
MaximumPlayers = i,
CurrentPlayers = 1,
Mod = mod,
},
(prt, server) =>
{
server.ProcessId = processId;
server.MaximumPlayers = i;
server.CurrentPlayers = 1;
server.Mod = mod;
return server;
});
}
catch
{
// No free ports, cannot create process
// Log...
}
}
}
}
}
private static bool IsNewServerNeeded(int i, Mod mod)
{
return !Program.State.Servers.Values.Any(s =>
!s.IsPrivate
&& s.Mod.Name == mod.Name
&& s.MaximumPlayers == i
&& s.CurrentPlayers < s.MaximumPlayers);
}
}
}