Merge branch 'master' into Patron

This commit is contained in:
John Gross
2019-09-19 11:34:09 -07:00
7 changed files with 111 additions and 14 deletions

View File

@@ -17,6 +17,6 @@ if (!(Test-Path $steamCMDPath)) {
}
cd "$steamData"
& "$steamCMDPath/steamcmd.exe" "+login anonymous" "+force_install_dir $steamData" "+app_update 298740 -beta publictest -betapassword nt8WuDw9kdvE validate" "+quit"
& "$steamCMDPath/steamcmd.exe" "+login anonymous" "+force_install_dir $steamData" "+app_update 298740 validate" "+quit"
popd

View File

@@ -254,6 +254,7 @@ quit";
private void HandleException(object sender, UnhandledExceptionEventArgs e)
{
_server.FatalException = true;
var ex = (Exception)e.ExceptionObject;
LogException(ex);
if (MyFakes.ENABLE_MINIDUMP_SENDING)

View File

@@ -63,7 +63,7 @@ namespace Torch.Server
// Breaks on Windows Server 2019
if (!new ComputerInfo().OSFullName.Contains("Server 2019") && !Environment.UserInteractive)
{
using (var service = new TorchService())
using (var service = new TorchService(args))
ServiceBase.Run(service);
return;
}

View File

@@ -50,6 +50,8 @@ namespace Torch.Server
private int _players;
private MultiplayerManagerDedicated _multiplayerManagerDedicated;
internal bool FatalException { get; set; }
/// <inheritdoc />
public TorchServer(TorchConfig config = null)
{
@@ -232,10 +234,16 @@ namespace Torch.Server
private static void CheckServerResponding(object state)
{
var server = (TorchServer)state;
var mre = new ManualResetEvent(false);
((TorchServer)state).Invoke(() => mre.Set());
server.Invoke(() => mre.Set());
if (!mre.WaitOne(TimeSpan.FromSeconds(Instance.Config.TickTimeout)))
{
if (server.FatalException)
{
server._watchdog.Dispose();
return;
}
#if DEBUG
Log.Error(
$"Server watchdog detected that the server was frozen for at least {((TorchServer) state).Config.TickTimeout} seconds.");

View File

@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceProcess;
using System.Threading;
using NLog;
using Torch.API;
@@ -12,12 +14,14 @@ namespace Torch.Server
{
class TorchService : ServiceBase
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
public const string Name = "Torch (SEDS)";
private TorchServer _server;
private Initializer _initializer;
private string[] _args;
public TorchService()
public TorchService(string[] args)
{
_args = args;
var workingDir = new FileInfo(typeof(TorchService).Assembly.Location).Directory.ToString();
Directory.SetCurrentDirectory(workingDir);
_initializer = new Initializer(workingDir);
@@ -29,19 +33,21 @@ namespace Torch.Server
}
/// <inheritdoc />
protected override void OnStart(string[] args)
protected override void OnStart(string[] _)
{
base.OnStart(args);
base.OnStart(_args);
_initializer.Initialize(args);
_initializer.Initialize(_args);
_initializer.Run();
}
/// <inheritdoc />
protected override void OnStop()
{
_server.Stop();
base.OnStop();
var mre = new ManualResetEvent(false);
Task.Run(() => _initializer.Server.Stop());
if (!mre.WaitOne(TimeSpan.FromMinutes(1)))
Process.GetCurrentProcess().Kill();
}
}
}

View File

@@ -29,6 +29,8 @@ namespace Torch.Commands
{
private static bool _restartPending = false;
private static bool _cancelRestart = false;
private bool _stopPending = false;
private bool _cancelStop = false;
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
[Command("whatsmyip")]
@@ -154,9 +156,25 @@ namespace Torch.Commands
}
[Command("stop", "Stops the server.")]
public void Stop(bool save = true)
public void Stop(bool save = true, int countdownSeconds = 0)
{
Context.Respond("Stopping server.");
if (_stopPending)
{
Context.Respond("A stop is already pending.");
return;
}
_stopPending = true;
Task.Run(() =>
{
var countdown = StopCountdown(countdownSeconds, save).GetEnumerator();
while (countdown.MoveNext())
{
Thread.Sleep(1000);
}
});
/*Context.Respond("Stopping server.");
if (save)
DoSave()?.ContinueWith((a, mod) =>
{
@@ -165,7 +183,7 @@ namespace Torch.Commands
torch.Stop();
}, this, TaskContinuationOptions.RunContinuationsAsynchronously);
else
Context.Torch.Stop();
Context.Torch.Stop();*/
}
[Command("restart", "Restarts the server.")]
@@ -205,6 +223,69 @@ namespace Torch.Commands
Context.Respond("A restart is not pending.");
}
[Command("stop cancel", "Cancel a pending stop.")]
public void CancelStop()
{
if (_restartPending)
_cancelStop = true;
else
Context.Respond("Server Stop is not pending.");
}
private IEnumerable StopCountdown(int countdown, bool save)
{
for (var i = countdown; i >= 0; i--)
{
if (_cancelStop)
{
Context.Torch.CurrentSession.Managers.GetManager<IChatManagerClient>()
.SendMessageAsSelf($"Stop cancelled.");
_stopPending = false;
_cancelStop = false;
yield break;
}
if (i >= 60 && i % 60 == 0)
{
Context.Torch.CurrentSession.Managers.GetManager<IChatManagerClient>()
.SendMessageAsSelf($"Stopping server in {i / 60} minute{Pluralize(i / 60)}.");
yield return null;
}
else if (i > 0)
{
if (i < 11)
Context.Torch.CurrentSession.Managers.GetManager<IChatManagerClient>()
.SendMessageAsSelf($"Stopping server in {i} second{Pluralize(i)}.");
yield return null;
}
else
{
if (save)
{
Log.Info("Saving game before stop.");
Context.Torch.CurrentSession.Managers.GetManager<IChatManagerClient>()
.SendMessageAsSelf($"Saving game before stop.");
DoSave()?.ContinueWith((a, mod) =>
{
ITorchBase torch = (mod as CommandModule)?.Context?.Torch;
Debug.Assert(torch != null);
torch.Stop();
}, this, TaskContinuationOptions.RunContinuationsAsynchronously);
}
else
{
Log.Info("Stopping server.");
Context.Torch.Invoke(() => Context.Torch.Stop());
}
yield break;
}
}
}
private IEnumerable RestartCountdown(int countdown, bool save)
{
for (var i = countdown; i >= 0; i--)

View File

@@ -199,7 +199,8 @@ namespace Torch
}
MyRenderProxy.Initialize(renderer);
MyRenderProfiler.SetAutocommit(false);
MyRenderProfiler.InitMemoryHack("MainEntryPoint");
//This broke services?
//MyRenderProfiler.InitMemoryHack("MainEntryPoint");
}
// Loads object builder serializers. Intuitive, right?