101 lines
3.2 KiB
C#
101 lines
3.2 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace CapyLauncher
|
|
{
|
|
public class ServerHost
|
|
{
|
|
Process process;
|
|
bool stopping;
|
|
|
|
public event Action<string> Line;
|
|
public event Action<int, bool> Exited;
|
|
|
|
public string Root { get; }
|
|
public string Exe { get; }
|
|
public bool Running => process != null && !process.HasExited;
|
|
public int Id => process?.Id ?? 0;
|
|
|
|
public ServerHost(string launcherDir)
|
|
{
|
|
Root = FindRoot(launcherDir) ?? launcherDir;
|
|
Exe = new[]
|
|
{
|
|
Path.Combine(launcherDir, "capysr.exe"),
|
|
Path.Combine(Root, "capysr.exe"),
|
|
Path.Combine(Root, "build", "bin", "capysr.exe"),
|
|
}.FirstOrDefault(File.Exists);
|
|
}
|
|
|
|
static string FindRoot(string dir)
|
|
{
|
|
for (int depth = 0; depth < 5 && dir != null; depth++)
|
|
{
|
|
if (File.Exists(Path.Combine(dir, "config", "config.json")))
|
|
return dir;
|
|
dir = Path.GetDirectoryName(dir);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public Process[] Strangers() =>
|
|
Process.GetProcessesByName("capysr").Where(p => p.Id != Id).ToArray();
|
|
|
|
public void Start()
|
|
{
|
|
var info = new ProcessStartInfo(Exe)
|
|
{
|
|
WorkingDirectory = Root,
|
|
UseShellExecute = false,
|
|
CreateNoWindow = true,
|
|
RedirectStandardInput = true,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
StandardOutputEncoding = Encoding.UTF8,
|
|
StandardErrorEncoding = Encoding.UTF8,
|
|
};
|
|
info.EnvironmentVariables["NO_COLOR"] = "1";
|
|
|
|
var started = new Process { StartInfo = info, EnableRaisingEvents = true };
|
|
started.OutputDataReceived += (s, e) => { if (e.Data != null) Line?.Invoke(e.Data); };
|
|
started.ErrorDataReceived += (s, e) => { if (e.Data != null) Line?.Invoke(e.Data); };
|
|
started.Exited += (s, e) =>
|
|
{
|
|
started.WaitForExit();
|
|
bool asked = stopping;
|
|
stopping = false;
|
|
Exited?.Invoke(started.ExitCode, asked);
|
|
};
|
|
stopping = false;
|
|
started.Start();
|
|
started.BeginOutputReadLine();
|
|
started.BeginErrorReadLine();
|
|
process = started;
|
|
}
|
|
|
|
public async Task StopAsync()
|
|
{
|
|
Process running = process;
|
|
if (running == null || running.HasExited)
|
|
return;
|
|
stopping = true;
|
|
try
|
|
{
|
|
running.StandardInput.WriteLine("stop");
|
|
running.StandardInput.Flush();
|
|
}
|
|
catch (Exception) { }
|
|
bool exited = await Task.Run(() => running.WaitForExit(8000));
|
|
if (!exited)
|
|
{
|
|
try { running.Kill(); } catch (Exception) { }
|
|
await Task.Run(() => running.WaitForExit(3000));
|
|
}
|
|
}
|
|
}
|
|
}
|