110 lines
5.0 KiB
Plaintext
110 lines
5.0 KiB
Plaintext
using System.Reflection;
|
||
using ShrinkNetwork;
|
||
using ShrinkNetwork.ServerHost;
|
||
using ShrinkNetwork.ServerHost.Framework;
|
||
|
||
ShrinkNetworkLogger.InfoHandler = msg => Console.WriteLine(msg);
|
||
ShrinkNetworkLogger.WarningHandler = msg => Console.WriteLine("[Warn] " + msg);
|
||
ShrinkNetworkLogger.ErrorHandler = msg => Console.Error.WriteLine(msg);
|
||
ShrinkNetworkLogger.ExceptionHandler = ex => Console.Error.WriteLine(ex);
|
||
|
||
var config = ServerHostProperties.LoadOrCreate();
|
||
var options = config.Options;
|
||
var modules = DiscoverModules();
|
||
var app = new ShrinkDedicatedServerApp(options, modules);
|
||
|
||
await app.StartAsync();
|
||
|
||
Console.WriteLine("ShrinkNetwork 独立服务器模板已启动。");
|
||
Console.WriteLine($"配置文件:{config.FilePath}");
|
||
Console.WriteLine($"首次生成默认配置:{config.CreatedDefaultFile}");
|
||
foreach (var warning in config.Warnings)
|
||
Console.WriteLine($"[Warn] 配置文件:{warning}");
|
||
Console.WriteLine($"TCP: 0.0.0.0:{options.Port}");
|
||
Console.WriteLine($"KCP: 0.0.0.0:{options.Port}");
|
||
Console.WriteLine($"Unity 扫描输出目录:{options.ScanOutputDirectory}");
|
||
Console.WriteLine($"Unity 资产扫描目录:{options.UnityAssetsPath}");
|
||
Console.WriteLine($"共享口令鉴权已启用:{!string.IsNullOrWhiteSpace(options.SharedAuthToken)}");
|
||
Console.WriteLine($"缺少口令时允许匿名登录:{options.AllowAnonymousWhenAuthTokenMissing}");
|
||
Console.WriteLine($"会话令牌已启用:{options.EnableSessionTokens}");
|
||
Console.WriteLine($"会话令牌 TTL(秒):{options.SessionTokenTtlSeconds}");
|
||
Console.WriteLine($"会话令牌续期窗口(秒):{options.SessionTokenRefreshWindowSeconds}");
|
||
Console.WriteLine($"会话令牌校验失败时断开会话:{options.DisconnectOnInvalidSessionToken}");
|
||
Console.WriteLine($"协议版本范围:{options.MinProtocolVersion}-{options.MaxProtocolVersion}");
|
||
Console.WriteLine($"Schema 版本范围:{options.MinSchemaVersion}-{options.MaxSchemaVersion}");
|
||
Console.WriteLine($"TCP TLS 已启用:{options.EnableTcpTls}");
|
||
if (options.EnableTcpTls)
|
||
{
|
||
Console.WriteLine($"TCP TLS 证书路径:{options.TcpTlsCertificatePath}");
|
||
Console.WriteLine($"TCP TLS SNI/目标主机:{options.TcpTlsTargetHost}");
|
||
}
|
||
if (string.IsNullOrWhiteSpace(options.SharedAuthToken) && !options.AllowAnonymousWhenAuthTokenMissing)
|
||
{
|
||
Console.WriteLine("[Warn] 当前未配置 SHRINK_SERVER_AUTH_TOKEN,登录请求默认会被拒绝。");
|
||
}
|
||
Console.WriteLine("[Info] 配置优先级:代码默认值 < server.properties < 环境变量");
|
||
Console.WriteLine("已加载模块:");
|
||
foreach (var module in modules)
|
||
Console.WriteLine($"- {module.Name}");
|
||
Console.WriteLine("按 Ctrl+C 退出。");
|
||
|
||
using var metricsCts = new CancellationTokenSource();
|
||
if (options.DiagnosticsLogIntervalSeconds > 0)
|
||
_ = RunDiagnosticsLoopAsync(app, options.DiagnosticsLogIntervalSeconds, metricsCts.Token);
|
||
|
||
Console.CancelKeyPress += (_, args) =>
|
||
{
|
||
args.Cancel = true;
|
||
metricsCts.Cancel();
|
||
DumpDiagnostics(app);
|
||
Environment.Exit(0);
|
||
};
|
||
|
||
try
|
||
{
|
||
await Task.Delay(Timeout.Infinite, metricsCts.Token);
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
}
|
||
|
||
static IShrinkServerModule[] DiscoverModules()
|
||
{
|
||
return Assembly.GetExecutingAssembly()
|
||
.GetTypes()
|
||
.Where(type => typeof(IShrinkServerModule).IsAssignableFrom(type))
|
||
.Where(type => !type.IsAbstract && !type.IsInterface)
|
||
.Where(type => type.GetConstructor(Type.EmptyTypes) != null)
|
||
.Select(type => (IShrinkServerModule)Activator.CreateInstance(type)!)
|
||
.OrderBy(module => module.Name, StringComparer.Ordinal)
|
||
.ToArray();
|
||
}
|
||
|
||
static async Task RunDiagnosticsLoopAsync(ShrinkDedicatedServerApp app, int intervalSeconds, CancellationToken cancellationToken)
|
||
{
|
||
while (!cancellationToken.IsCancellationRequested)
|
||
{
|
||
try
|
||
{
|
||
await Task.Delay(TimeSpan.FromSeconds(intervalSeconds), cancellationToken);
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
break;
|
||
}
|
||
|
||
DumpDiagnostics(app);
|
||
}
|
||
}
|
||
|
||
static void DumpDiagnostics(ShrinkDedicatedServerApp app)
|
||
{
|
||
Console.WriteLine("[Metrics] ShrinkNetwork service snapshots:");
|
||
foreach (var pair in app.Context.Services.OrderBy(item => item.Key, StringComparer.OrdinalIgnoreCase))
|
||
{
|
||
var metrics = pair.Value.GetDiagnosticsSnapshot();
|
||
Console.WriteLine(
|
||
$"[Metrics][{pair.Key}] sessions={metrics.CurrentSessions} connected={metrics.SessionsConnected} disconnected={metrics.SessionsDisconnected} sent={metrics.PacketsSent}/{metrics.BytesSent}B recv={metrics.PacketsReceived}/{metrics.BytesReceived}B rpc={metrics.RpcStarted}/{metrics.RpcCompleted} timeout={metrics.RpcTimedOut} canceled={metrics.RpcCanceled} failed={metrics.RpcFailed} proto={metrics.ProtocolViolations} authRejected={metrics.AuthRejectedCount} denied={metrics.PermissionDeniedCount} handlerEx={metrics.HandlerExceptionCount} unknownOpcode={metrics.UnknownOpcodeCount} dispatchMiss={metrics.DispatchMissCount} serialization={metrics.SerializationErrorCount} queueReject={metrics.DispatchQueueRejectedCount}");
|
||
}
|
||
}
|