Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using XWorld.Server.Gateway;
|
||||
|
||||
namespace XWorld.Server.Gateway.Runner
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
string gamesRoot = GetArg(args, "--gamesRoot") ??
|
||||
Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "Server.Host.Tests", "TestGames"));
|
||||
int port = int.TryParse(GetArg(args, "--port"), out int p) ? p : 5005;
|
||||
int tickMs = int.TryParse(GetArg(args, "--tickMs"), out int t) ? t : 100;
|
||||
long matchTimeoutTicks = long.TryParse(GetArg(args, "--matchTimeoutTicks"), out long mt) ? mt : 150;
|
||||
string devToken = GetArg(args, "--devToken");
|
||||
string advertiseWs = GetArg(args, "--advertiseWs");
|
||||
string advertiseCdn = GetArg(args, "--advertiseCdn");
|
||||
bool lan = Array.Exists(args, a => string.Equals(a, "--lan", StringComparison.OrdinalIgnoreCase));
|
||||
int cdnPort = int.TryParse(GetArg(args, "--cdnPort"), out int cp) ? cp : 15081;
|
||||
// --lan 下若未显式给 CDN 地址,用本机 LAN IP + 约定端口兜底广而告之 CDN 根
|
||||
// (客户端从根派生两套:minigame/<id>/<ver>/ 与 XWorld/<platform>/;advertiseWs 缺省由 GameServerHost 内部用 LanIp 兜底)
|
||||
if (lan && string.IsNullOrEmpty(advertiseCdn))
|
||||
advertiseCdn = $"http://{XWorld.Server.Gateway.LanIp.Resolve()}:{cdnPort}/";
|
||||
|
||||
// 鉴权 opt-in:给了 --authDbPath 才启用账号鉴权(/register、/login、/ws 验 token)。
|
||||
// 密钥优先级:--authSecret(base64) > DB 同目录 auth.key 文件(不存在则生成并持久化)。
|
||||
string authDbPath = GetArg(args, "--authDbPath");
|
||||
string authSecretB64 = GetArg(args, "--authSecret");
|
||||
byte[] authSecret = null;
|
||||
if (!string.IsNullOrEmpty(authDbPath))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(authSecretB64))
|
||||
authSecret = Convert.FromBase64String(authSecretB64);
|
||||
else
|
||||
{
|
||||
string keyPath = Path.Combine(
|
||||
Path.GetDirectoryName(Path.GetFullPath(authDbPath)) ?? ".", "auth.key");
|
||||
if (File.Exists(keyPath))
|
||||
authSecret = Convert.FromBase64String(File.ReadAllText(keyPath).Trim());
|
||||
else
|
||||
{
|
||||
authSecret = System.Security.Cryptography.RandomNumberGenerator.GetBytes(32);
|
||||
File.WriteAllText(keyPath, Convert.ToBase64String(authSecret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var host = new GameServerHost();
|
||||
await host.StartAsync(gamesRoot, tickMs, matchTimeoutTicks: matchTimeoutTicks, listenPort: port,
|
||||
bindAllInterfaces: lan,
|
||||
devDiscoveryToken: devToken, advertiseGatewayUrl: advertiseWs, advertiseResourceBaseUrl: advertiseCdn,
|
||||
authSecret: authSecret, authDbPath: authDbPath);
|
||||
Console.WriteLine("XWorld Gateway smoke server started.");
|
||||
Console.WriteLine(" gamesRoot: " + gamesRoot);
|
||||
Console.WriteLine(" tickMs: " + tickMs + ", matchTimeoutTicks: " + matchTimeoutTicks);
|
||||
Console.WriteLine(" ws: " + host.WsBaseUrl + "/ws?pid=1");
|
||||
if (!string.IsNullOrEmpty(devToken))
|
||||
Console.WriteLine(" dev-discovery: ON (UDP " + host.DevDiscoveryPort + "), advertise ws=" +
|
||||
(string.IsNullOrEmpty(advertiseWs) ? host.WsBaseUrl + "/ws" : advertiseWs) + " cdn=" + advertiseCdn);
|
||||
Console.WriteLine(" auth: " + (authSecret != null ? ("ON (db=" + authDbPath + ", /register /login /ws?token=)") : "OFF (dev ?pid=)"));
|
||||
Console.WriteLine("Press Ctrl+C to stop.");
|
||||
|
||||
using var stop = new CancellationTokenSource();
|
||||
Console.CancelKeyPress += (s, e) =>
|
||||
{
|
||||
e.Cancel = true;
|
||||
stop.Cancel();
|
||||
};
|
||||
|
||||
try { await Task.Delay(Timeout.InfiniteTimeSpan, stop.Token); }
|
||||
catch (OperationCanceledException) { }
|
||||
await host.StopAsync();
|
||||
}
|
||||
|
||||
private static string GetArg(string[] args, string name)
|
||||
{
|
||||
for (int i = 0; i < args.Length - 1; i++)
|
||||
if (string.Equals(args[i], name, StringComparison.OrdinalIgnoreCase))
|
||||
return args[i + 1];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user