This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using ShrinkNetwork;
|
||||
|
||||
namespace ShrinkNetwork.ServerHost.Framework;
|
||||
|
||||
public sealed class ShrinkDedicatedServerApp
|
||||
{
|
||||
private readonly List<IShrinkServerModule> _modules;
|
||||
private readonly ServerModuleContext _context;
|
||||
|
||||
public ShrinkDedicatedServerApp(ServerHostOptions options, params IShrinkServerModule[] modules)
|
||||
{
|
||||
_modules = modules.ToList();
|
||||
_context = new ServerModuleContext(options, new ServerAuthStore());
|
||||
}
|
||||
|
||||
public ServerModuleContext Context => _context;
|
||||
|
||||
public async UniTask StartAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_context.Options.EnableUnityCodeScan)
|
||||
{
|
||||
var manifest = UnityNetworkCodeScanner.Scan(_context.Options.UnityAssetsPath);
|
||||
UnityNetworkCodeScanner.WriteOutputs(manifest, _context.Options.ScanOutputDirectory);
|
||||
_context.ScanManifest = manifest;
|
||||
}
|
||||
|
||||
var tcpService = CreateService("TCP");
|
||||
var kcpService = CreateService("KCP");
|
||||
|
||||
_context.RegisterService("TCP", tcpService);
|
||||
_context.RegisterService("KCP", kcpService);
|
||||
|
||||
foreach (var module in _modules)
|
||||
{
|
||||
module.ConfigureService(_context, tcpService, "TCP");
|
||||
module.ConfigureService(_context, kcpService, "KCP");
|
||||
}
|
||||
|
||||
tcpService.BindTransport(new TcpServerTransport(System.Net.IPAddress.Any, _context.Options.Port,
|
||||
tlsOptions: BuildTcpTlsOptions()));
|
||||
kcpService.BindTransport(new KcpServerTransport(System.Net.IPAddress.Any, _context.Options.Port, new ShrinkKcpTransportOptions
|
||||
{
|
||||
Interval = 10,
|
||||
UpdateIntervalMs = 10,
|
||||
IdleTimeoutMs = 15000,
|
||||
HandshakeRetryMs = 250,
|
||||
ConnectTimeoutMs = 4000
|
||||
}));
|
||||
|
||||
foreach (var module in _modules)
|
||||
module.StartAsync(_context, cancellationToken).Forget();
|
||||
|
||||
await UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
private ShrinkNetworkService CreateService(string transportName)
|
||||
{
|
||||
var service = new ShrinkNetworkService(new ShrinkJsonNetworkSerializer(),
|
||||
new ShrinkNetworkMessageRegistry(),
|
||||
new ShrinkNetworkRouter());
|
||||
service.MinProtocolVersion = _context.Options.MinProtocolVersion;
|
||||
service.MaxProtocolVersion = _context.Options.MaxProtocolVersion;
|
||||
service.MinSchemaVersion = _context.Options.MinSchemaVersion;
|
||||
service.MaxSchemaVersion = _context.Options.MaxSchemaVersion;
|
||||
service.DisconnectOnProtocolViolation = _context.Options.DisconnectOnProtocolViolation;
|
||||
service.IncomingPacketValidator = (session, packet) => ValidateIncomingPacket(service, session, packet);
|
||||
|
||||
service.OnSessionConnected += session =>
|
||||
{
|
||||
session.SetPeerKind(ShrinkNetworkPeerKind.Client);
|
||||
ShrinkNetworkLogger.Info($"[{transportName}] Client connected: {session.SessionId} {session.RemoteAddress}");
|
||||
};
|
||||
service.OnSessionDisconnected += session =>
|
||||
{
|
||||
_context.AuthStore.Remove(service, session.SessionId);
|
||||
ShrinkNetworkLogger.Info($"[{transportName}] Client disconnected: {session.SessionId}");
|
||||
};
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
private ShrinkIncomingPacketValidationResult ValidateIncomingPacket(
|
||||
ShrinkNetworkService service,
|
||||
ShrinkNetworkSession session,
|
||||
ShrinkNetworkPacket packet)
|
||||
{
|
||||
if (!_context.Options.EnableSessionTokens)
|
||||
return ShrinkIncomingPacketValidationResult.Allow;
|
||||
if (packet.Kind == ShrinkNetworkPacketKind.Response)
|
||||
return ShrinkIncomingPacketValidationResult.Allow;
|
||||
if (string.Equals(packet.Route, AuthServerModule.LoginRoute, StringComparison.Ordinal) ||
|
||||
string.Equals(packet.Route, AuthServerModule.RefreshRoute, StringComparison.Ordinal))
|
||||
return ShrinkIncomingPacketValidationResult.Allow;
|
||||
if (!_context.AuthStore.TryGetState(service, session.SessionId, out _))
|
||||
return ShrinkIncomingPacketValidationResult.Allow;
|
||||
|
||||
if (_context.AuthStore.TryValidateSessionToken(service, session.SessionId, packet.SessionToken, out var authState,
|
||||
out var failureReason))
|
||||
{
|
||||
session.SetSessionToken(authState.SessionToken, authState.SessionTokenExpiresAtUtc);
|
||||
return ShrinkIncomingPacketValidationResult.Allow;
|
||||
}
|
||||
|
||||
return ShrinkIncomingPacketValidationResult.Reject(failureReason,
|
||||
_context.Options.DisconnectOnInvalidSessionToken);
|
||||
}
|
||||
|
||||
private ShrinkTcpTlsOptions? BuildTcpTlsOptions()
|
||||
{
|
||||
if (!_context.Options.EnableTcpTls)
|
||||
return null;
|
||||
|
||||
return new ShrinkTcpTlsOptions
|
||||
{
|
||||
Enabled = true,
|
||||
TargetHost = _context.Options.TcpTlsTargetHost,
|
||||
ServerCertificatePath = _context.Options.TcpTlsCertificatePath,
|
||||
ServerCertificatePassword = _context.Options.TcpTlsCertificatePassword,
|
||||
CheckCertificateRevocation = _context.Options.TcpTlsCheckCertificateRevocation
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user