Merge branch 'master' into Patron
This commit is contained in:
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -49,6 +49,8 @@ namespace Torch.Server
|
||||
private Timer _watchdog;
|
||||
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.");
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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.")]
|
||||
@@ -204,6 +222,69 @@ namespace Torch.Commands
|
||||
else
|
||||
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)
|
||||
{
|
||||
|
@@ -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?
|
||||
|
Reference in New Issue
Block a user