Files

87 lines
2.7 KiB
C#

using System.Globalization;
namespace FakeGameServer;
internal enum FakeMode
{
Normal,
NoReady,
FailOnStart,
CrashAfterReady,
IgnoreStop,
IgnoreAll,
}
internal sealed record FakeSettings(
FakeMode Mode,
int StartupMs,
int StopMs,
int CrashAfterMs,
int CrashExitCode,
bool StdinEofStopsServer)
{
public static FakeSettings FromEnvironment()
{
var mode = Enum.TryParse<FakeMode>(Env("FAKE_MODE"), true, out var parsed) ? parsed : FakeMode.Normal;
return new FakeSettings(
mode,
EnvInt("FAKE_STARTUP_MS", 500),
EnvInt("FAKE_STOP_MS", 200),
EnvInt("FAKE_CRASH_AFTER_MS", 300),
EnvInt("FAKE_CRASH_EXIT_CODE", 0),
string.Equals(Env("FAKE_STDIN_EOF"), "stop", StringComparison.OrdinalIgnoreCase));
}
private static string? Env(string name) => Environment.GetEnvironmentVariable(name);
private static int EnvInt(string name, int fallback) =>
int.TryParse(Env(name), NumberStyles.Integer, CultureInfo.InvariantCulture, out var value)
? value
: fallback;
}
internal sealed record CommandLine(string? DataPath, int? Port, string? SetConfig)
{
// Flags that take a value. Like the real game, the next token is taken as the value
// when there is no "=", even if that token is another flag.
private static readonly HashSet<string> ValueOptions = new(StringComparer.OrdinalIgnoreCase)
{
"dataPath", "port", "setconfig", "withconfig", "logPath", "ip", "maxclients",
};
public static CommandLine Parse(string[] args)
{
var values = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
if (!arg.StartsWith("--", StringComparison.Ordinal))
{
continue;
}
var body = arg[2..];
var eq = body.IndexOf('=', StringComparison.Ordinal);
if (eq >= 0)
{
values[body[..eq]] = body[(eq + 1)..];
}
else if (ValueOptions.Contains(body) && i + 1 < args.Length)
{
values[body] = args[++i];
}
else
{
values[body] = null;
}
}
values.TryGetValue("dataPath", out var dataPath);
values.TryGetValue("setconfig", out var setConfig);
values.TryGetValue("port", out var portText);
int? port = int.TryParse(portText, NumberStyles.None, CultureInfo.InvariantCulture, out var n) ? n : null;
return new CommandLine(dataPath, port, setConfig);
}
}