Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/ClientSource/Networking/ChildServerRelay.cs
2023-01-31 18:08:26 +02:00

91 lines
3.1 KiB
C#

using System.Diagnostics;
using System.IO.Pipes;
using System.Linq;
using System.Threading;
namespace Barotrauma.Networking
{
static partial class ChildServerRelay
{
public static Process Process;
public static bool IsProcessAlive => Process is { HasExited: false };
private static bool localHandlesDisposed;
private static AnonymousPipeServerStream writePipe;
private static AnonymousPipeServerStream readPipe;
public static void Start(ProcessStartInfo processInfo)
{
CrashString = null;
CrashReportFilePath = null;
writePipe = new AnonymousPipeServerStream(PipeDirection.Out, System.IO.HandleInheritability.Inheritable);
readPipe = new AnonymousPipeServerStream(PipeDirection.In, System.IO.HandleInheritability.Inheritable);
writeStream = writePipe; readStream = readPipe;
PrivateStart();
processInfo.Arguments += " -pipes " + writePipe.GetClientHandleAsString() + " " + readPipe.GetClientHandleAsString();
try
{
Process = Process.Start(processInfo);
}
catch
{
DebugConsole.ThrowError($"Failed to start ChildServerRelay Process. File: {processInfo.FileName}, arguments: {processInfo.Arguments}");
ForceShutDown();
throw;
}
localHandlesDisposed = false;
}
public static void DisposeLocalHandles()
{
if (localHandlesDisposed) { return; }
writePipe.DisposeLocalCopyOfClientHandle(); readPipe.DisposeLocalCopyOfClientHandle();
localHandlesDisposed = true;
}
public static void AttemptGracefulShutDown(int maxAttempts = 20)
{
status = StatusEnum.RequestedShutDown;
writeManualResetEvent?.Set();
int checks = 0;
while (Process is { HasExited: false })
{
if (checks >= maxAttempts)
{
DebugConsole.AddWarning("Server could not be shut down gracefully");
break;
}
Thread.Sleep(100);
checks++;
}
ForceShutDown();
}
public static void ForceShutDown()
{
Process?.Kill(); Process = null;
PrivateShutDown();
}
public static string CrashString { get; private set; }
public static string CrashReportFilePath { get; private set; }
public static LocalizedString CrashMessage
=> string.IsNullOrEmpty(CrashReportFilePath)
? TextManager.Get("ServerProcessClosed")
: TextManager.GetWithVariable("ServerProcessCrashed", "[reportfilepath]", CrashReportFilePath);
static partial void HandleCrashString(string str)
{
DebugConsole.ThrowError($"The server has crashed: {str}");
CrashReportFilePath = str.Split("||").FirstOrDefault() ?? "servercrashreport.log";
CrashString = str;
}
}
}