From 7cf1353869fe6fe5016956d69db589f2aa1cf284 Mon Sep 17 00:00:00 2001 From: edmand46 Date: Sun, 19 May 2024 11:28:36 +0300 Subject: [PATCH] feat: improved server plugin api --- .../Sources/Plugin/RelayServerPlugin.cs | 42 ++++++++-------- Ragon.Relay/Sources/Relay.cs | 2 + Ragon.Relay/Sources/RelayConfiguration.cs | 1 - .../Sources/WebSocketServer.cs | 2 +- .../Sources/Handler/AuthorizationOperation.cs | 17 ++++--- .../Sources/Handler/RoomJoinOperation.cs | 1 - Ragon.Server/Sources/IRagonServer.cs | 4 +- .../Sources/Plugin/BaseServerPlugin.cs | 50 +++++++++++++++++-- Ragon.Server/Sources/RagonServer.cs | 18 +++---- 9 files changed, 92 insertions(+), 45 deletions(-) diff --git a/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs b/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs index 710d727..03b8593 100644 --- a/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs +++ b/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs @@ -3,28 +3,30 @@ using Newtonsoft.Json; using Ragon.Server; using Ragon.Server.Plugin; -namespace Ragon.Relay; - -public class RelayServerPlugin: BaseServerPlugin +namespace Ragon.Relay { - public override bool OnCommand(string command, string payload) - { - Console.WriteLine(command); - if (command == "kick-player") - { - var commandPayload = JsonConvert.DeserializeObject(payload); - var player = Server.GetPlayerById(commandPayload.Id); - if (player != null) - player.Connection.Close(); - else - Console.WriteLine($"Player not found with Id {commandPayload.Id}"); - } - - return true; - } - public override IRoomPlugin CreateRoomPlugin(RoomInformation information) + public class RelayServerPlugin : BaseServerPlugin { - return new RelayRoomPlugin(); + public override bool OnCommand(string command, string payload) + { + Console.WriteLine(command); + if (command == "kick-player") + { + var commandPayload = JsonConvert.DeserializeObject(payload); + var player = Server.GetContextById(commandPayload.Id); + if (player != null) + player.Connection.Close(); + else + Console.WriteLine($"Player not found with Id {commandPayload.Id}"); + } + + return true; + } + + public override IRoomPlugin CreateRoomPlugin(RoomInformation information) + { + return new RelayRoomPlugin(); + } } } \ No newline at end of file diff --git a/Ragon.Relay/Sources/Relay.cs b/Ragon.Relay/Sources/Relay.cs index 40cb86c..67fa59d 100644 --- a/Ragon.Relay/Sources/Relay.cs +++ b/Ragon.Relay/Sources/Relay.cs @@ -42,6 +42,7 @@ namespace Ragon.Relay INetworkServer networkServer = new ENetServer(); IServerPlugin plugin = new RelayServerPlugin(); + switch (serverType) { case ServerType.ENET: @@ -63,6 +64,7 @@ namespace Ragon.Relay ServerKey = configuration.ServerKey, ServerTickRate = configuration.ServerTickRate, }; + var relay = new RagonServer(networkServer, plugin, serverConfiguration); relay.Start(); while (relay.IsRunning) diff --git a/Ragon.Relay/Sources/RelayConfiguration.cs b/Ragon.Relay/Sources/RelayConfiguration.cs index 84279a6..ac2510a 100644 --- a/Ragon.Relay/Sources/RelayConfiguration.cs +++ b/Ragon.Relay/Sources/RelayConfiguration.cs @@ -15,6 +15,5 @@ namespace Ragon.Relay public int LimitRooms; public int LimitBufferedEvents; public int LimitUserData; - } } \ No newline at end of file diff --git a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs b/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs index 2558ab4..351429e 100644 --- a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs +++ b/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs @@ -41,7 +41,7 @@ public class WebSocketServer : INetworkServer _activeConnections = new List(); _executor = new Executor(); } - + public async void StartAccept(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) diff --git a/Ragon.Server/Sources/Handler/AuthorizationOperation.cs b/Ragon.Server/Sources/Handler/AuthorizationOperation.cs index 7f1dd8a..b5cb4f7 100644 --- a/Ragon.Server/Sources/Handler/AuthorizationOperation.cs +++ b/Ragon.Server/Sources/Handler/AuthorizationOperation.cs @@ -26,12 +26,14 @@ namespace Ragon.Server.Handler { private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(AuthorizationOperation)); private readonly IServerPlugin _serverPlugin; + private readonly IRagonServer _server; private readonly RagonContextObserver _observer; private readonly RagonServerConfiguration _configuration; private readonly RagonBuffer _writer; public AuthorizationOperation(RagonBuffer reader, RagonBuffer writer, + IRagonServer server, IServerPlugin serverPlugin, RagonContextObserver observer, RagonServerConfiguration configuration) : base(reader, writer) @@ -40,6 +42,7 @@ namespace Ragon.Server.Handler _configuration = configuration; _observer = observer; _writer = writer; + _server = server; } public override void Handle(RagonContext context, NetworkChannel channel) @@ -63,14 +66,12 @@ namespace Ragon.Server.Handler if (key == configuration.ServerKey) { - var authorizeViaWebHook = _serverPlugin.OnAuthorize(new ConnectionRequest() { PeerID = context.Connection.Id }); - if (authorizeViaWebHook) + var authorizeViaPlugin = _serverPlugin.OnAuthorize(new ConnectionRequest(_server, context.Connection.Id, payload)); + if (authorizeViaPlugin) return; - var lobbyPlayer = new RagonLobbyPlayer(context.Connection, Guid.NewGuid().ToString(), name, payload); - context.SetPlayer(lobbyPlayer); - - Approve(context); + var id = Guid.NewGuid().ToString(); + Approve(context, new ConnectionResponse(id, name, payload)); } else { @@ -78,8 +79,10 @@ namespace Ragon.Server.Handler } } - public void Approve(RagonContext context) + public void Approve(RagonContext context, ConnectionResponse result) { + var lobbyPlayer = new RagonLobbyPlayer(context.Connection, result.Id, result.Name, result.Payload); + context.SetPlayer(lobbyPlayer); context.ConnectionStatus = ConnectionStatus.Authorized; _observer.OnAuthorized(context); diff --git a/Ragon.Server/Sources/Handler/RoomJoinOperation.cs b/Ragon.Server/Sources/Handler/RoomJoinOperation.cs index 228aec7..94f8a4b 100644 --- a/Ragon.Server/Sources/Handler/RoomJoinOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomJoinOperation.cs @@ -49,7 +49,6 @@ public sealed class RoomJoinOperation : BaseOperation JoinSuccess(context, existsRoom, Writer); existsRoom.RestoreBufferedEvents(player); - existsRoom.Plugin.OnPlayerJoined(player); _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} joined to {existsRoom.Id}"); diff --git a/Ragon.Server/Sources/IRagonServer.cs b/Ragon.Server/Sources/IRagonServer.cs index 967de96..428e874 100644 --- a/Ragon.Server/Sources/IRagonServer.cs +++ b/Ragon.Server/Sources/IRagonServer.cs @@ -24,6 +24,6 @@ namespace Ragon.Server; public interface IRagonServer { BaseOperation ResolveHandler(RagonOperation operation); - RagonLobbyPlayer? GetPlayerByConnection(INetworkConnection connection); - RagonLobbyPlayer? GetPlayerById(string id); + public RagonContext? GetContextByConnectionId(ushort peerId); + public RagonContext? GetContextById(string playerId); } \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs b/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs index 2d3ef3b..41af001 100644 --- a/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs +++ b/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs @@ -14,6 +14,8 @@ * limitations under the License. */ +using Ragon.Protocol; +using Ragon.Server.Handler; using Ragon.Server.IO; using Ragon.Server.Lobby; using Ragon.Server.Room; @@ -22,17 +24,58 @@ namespace Ragon.Server.Plugin { public class ConnectionRequest { - public int PeerID { get; set; } - - public void Approve() + public ConnectionRequest( + IRagonServer server, + ushort connectionId, + string payload + ) { + _server = server; + PeerID = connectionId; + Payload = payload; + } + + public ushort PeerID { get; private set; } + public string Payload { get; private set; } + + private readonly IRagonServer _server; + + public void Approve(string id, string name, string payload) + { + var ctx = _server.GetContextByConnectionId(PeerID); + if (ctx == null) + return; + + var operation = (AuthorizationOperation)_server.ResolveHandler(RagonOperation.AUTHORIZE); + operation.Approve(ctx, new ConnectionResponse(id, name, payload)); } public void Reject() { + var ctx = _server.GetContextByConnectionId(PeerID); + if (ctx == null) + return; + + var operation = (AuthorizationOperation)_server.ResolveHandler(RagonOperation.AUTHORIZE); + operation.Reject(ctx); } } + public class ConnectionResponse + { + public string Id { get; } + public string Name { get; } + public string Payload { get; } + + public ConnectionResponse(string id, string name, string payload) + { + Id = id; + Name = name; + Payload = payload; + } + } + + public class BaseServerPlugin : IServerPlugin { public IRagonServer Server { get; protected set; } @@ -44,7 +87,6 @@ namespace Ragon.Server.Plugin public virtual void OnDetached() { - } public virtual bool OnAuthorize(ConnectionRequest request) diff --git a/Ragon.Server/Sources/RagonServer.cs b/Ragon.Server/Sources/RagonServer.cs index c81f5d8..c8a174a 100644 --- a/Ragon.Server/Sources/RagonServer.cs +++ b/Ragon.Server/Sources/RagonServer.cs @@ -34,7 +34,6 @@ public class RagonServer : IRagonServer, INetworkListener private readonly BaseOperation[] _handlers; private readonly IRagonLobby _lobby; private readonly IServerPlugin _serverPlugin; - private readonly Thread _dedicatedThread; private readonly RagonServerConfiguration _configuration; private readonly RagonBuffer _reader; private readonly RagonBuffer _writer; @@ -75,7 +74,7 @@ public class RagonServer : IRagonServer, INetworkListener _serverPlugin.OnAttached(this); _handlers = new BaseOperation[byte.MaxValue]; - _handlers[(byte)RagonOperation.AUTHORIZE] = new AuthorizationOperation(_reader, _writer, _serverPlugin, contextObserver, configuration); + _handlers[(byte)RagonOperation.AUTHORIZE] = new AuthorizationOperation(_reader, _writer, this, _serverPlugin, contextObserver, configuration); _handlers[(byte)RagonOperation.JOIN_OR_CREATE_ROOM] = new RoomJoinOrCreateOperation(_reader, _writer, plugin, _configuration); _handlers[(byte)RagonOperation.CREATE_ROOM] = new RoomCreateOperation(_reader, _writer, plugin, _configuration); _handlers[(byte)RagonOperation.JOIN_ROOM] = new RoomJoinOperation(_reader, _writer); @@ -136,7 +135,6 @@ public class RagonServer : IRagonServer, INetworkListener { _serverPlugin.OnDetached(); _server.Stop(); - _dedicatedThread.Interrupt(); } public void OnConnected(INetworkConnection connection) @@ -158,6 +156,7 @@ public class RagonServer : IRagonServer, INetworkListener _lobby.RemoveIfEmpty(room); } + _contextsByPlayerId.Remove(context.LobbyPlayer.Id); _logger.Trace($"Disconnected: {connection.Id}"); } @@ -177,7 +176,8 @@ public class RagonServer : IRagonServer, INetworkListener room.DetachPlayer(context.RoomPlayer); _lobby.RemoveIfEmpty(room); } - + _contextsByPlayerId.Remove(context.LobbyPlayer.Id); + _logger.Trace($"Timeout: {connection.Id}|{context.LobbyPlayer.Name}|{context.LobbyPlayer.Id}"); } else @@ -274,15 +274,15 @@ public class RagonServer : IRagonServer, INetworkListener { return _handlers[(byte)operation]; } - - public RagonLobbyPlayer? GetPlayerByConnection(INetworkConnection connection) + + public RagonContext? GetContextByConnectionId(ushort peerId) { - return _contextsByConnection.TryGetValue(connection.Id, out var context) ? context.LobbyPlayer : null; + return _contextsByConnection.TryGetValue(peerId, out var context) ? context : null; } - public RagonLobbyPlayer? GetPlayerById(string playerId) + public RagonContext? GetContextById(string playerId) { - return _contextsByPlayerId.TryGetValue(playerId, out var context) ? context.LobbyPlayer : null; + return _contextsByPlayerId.TryGetValue(playerId, out var context) ? context : null; } private void CopyrightInfo()