diff --git a/Ragon.Client/Sources/RagonSession.cs b/Ragon.Client/Sources/RagonSession.cs index befc560..1ee1f59 100644 --- a/Ragon.Client/Sources/RagonSession.cs +++ b/Ragon.Client/Sources/RagonSession.cs @@ -31,11 +31,11 @@ namespace Ragon.Client public void CreateOrJoin(string sceneName, int minPlayers, int maxPlayers) { - var parameters = new RagonRoomPayload() {Scene = sceneName, Min = minPlayers, Max = maxPlayers}; + var parameters = new RagonRoomParameters() {Scene = sceneName, Min = minPlayers, Max = maxPlayers}; CreateOrJoin(parameters); } - public void CreateOrJoin(RagonRoomPayload parameters) + public void CreateOrJoin(RagonRoomParameters parameters) { _buffer.Clear(); _buffer.WriteOperation(RagonOperation.JOIN_OR_CREATE_ROOM); @@ -48,15 +48,15 @@ namespace Ragon.Client public void Create(string sceneName, int minPlayers, int maxPlayers) { - Create(null, new RagonRoomPayload() {Scene = sceneName, Min = minPlayers, Max = maxPlayers}); + Create(null, new RagonRoomParameters() {Scene = sceneName, Min = minPlayers, Max = maxPlayers}); } public void Create(string roomId, string sceneName, int minPlayers, int maxPlayers) { - Create(roomId, new RagonRoomPayload() {Scene = sceneName, Min = minPlayers, Max = maxPlayers}); + Create(roomId, new RagonRoomParameters() {Scene = sceneName, Min = minPlayers, Max = maxPlayers}); } - public void Create(string roomId, RagonRoomPayload parameters) + public void Create(string roomId, RagonRoomParameters parameters) { _buffer.Clear(); _buffer.WriteOperation(RagonOperation.CREATE_ROOM); diff --git a/Ragon.Protocol/Sources/RagonRoomParameters.cs b/Ragon.Protocol/Sources/RagonRoomParameters.cs index 9aa502f..b205173 100644 --- a/Ragon.Protocol/Sources/RagonRoomParameters.cs +++ b/Ragon.Protocol/Sources/RagonRoomParameters.cs @@ -17,7 +17,7 @@ namespace Ragon.Protocol { - public class RagonRoomPayload: IRagonSerializable + public class RagonRoomParameters: IRagonSerializable { public string Scene { get; set; } public int Min { get; set; } diff --git a/Ragon.Relay/Ragon.Relay.csproj b/Ragon.Relay/Ragon.Relay.csproj index fec71fb..23b5632 100644 --- a/Ragon.Relay/Ragon.Relay.csproj +++ b/Ragon.Relay/Ragon.Relay.csproj @@ -28,4 +28,9 @@ + + + + + diff --git a/Ragon.Relay/Sources/Logger/RelayLogger.cs b/Ragon.Relay/Sources/Logger/RelayLogger.cs new file mode 100644 index 0000000..7b6fdaf --- /dev/null +++ b/Ragon.Relay/Sources/Logger/RelayLogger.cs @@ -0,0 +1,40 @@ +using System; +using NLog; +using Ragon.Server.Logging; + +namespace Ragon.Relay; + +public class RelayLogger: IRagonLogger +{ + private Logger _nlogger; + + public RelayLogger(string tag) + { + _nlogger = LogManager.GetLogger(tag); + } + + public void Warning(string message) + { + _nlogger.Warn(message); + } + + public void Info(string message) + { + _nlogger.Info(message); + } + + public void Error(string message) + { + _nlogger.Error(message); + } + + public void Error(Exception ex) + { + _nlogger.Error(ex); + } + + public void Trace(string message) + { + _nlogger.Trace(message); + } +} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Logger/RelayLoggerFactory.cs b/Ragon.Relay/Sources/Logger/RelayLoggerFactory.cs new file mode 100644 index 0000000..758a455 --- /dev/null +++ b/Ragon.Relay/Sources/Logger/RelayLoggerFactory.cs @@ -0,0 +1,11 @@ +using Ragon.Server.Logging; + +namespace Ragon.Relay; + +public class RelayLoggerFactory: IRagonLoggerFactory +{ + public IRagonLogger GetLogger(string tag) + { + return new RelayLogger(tag); + } +} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs b/Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs new file mode 100644 index 0000000..c0d95a2 --- /dev/null +++ b/Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs @@ -0,0 +1,37 @@ +using System; +using Ragon.Server; +using Ragon.Server.Entity; +using Ragon.Server.Plugin; +using Ragon.Server.Room; + +namespace Ragon.Relay; + +public class RelayRoomPlugin: BaseRoomPlugin +{ + public void Tick(float dt) + { + + } + + public void OnAttached() + { + Console.WriteLine("Room attached"); + } + + public void OnDetached() + { + Console.WriteLine("Room detached"); + } + + public bool OnEntityCreate(RagonRoomPlayer creator, RagonEntity entity) + { + Console.WriteLine($"Entity created: {entity.Id}"); + return true; + } + + public bool OnEntityRemove(RagonRoomPlayer destroyer, RagonEntity entity) + { + Console.WriteLine($"Entity destroyed: {entity.Id}"); + return true; + } +} \ No newline at end of file diff --git a/Ragon.Relay/Sources/RelayServerPlugin.cs b/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs similarity index 100% rename from Ragon.Relay/Sources/RelayServerPlugin.cs rename to Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs diff --git a/Ragon.Relay/Sources/Relay.cs b/Ragon.Relay/Sources/Relay.cs index dad3948..40cb86c 100644 --- a/Ragon.Relay/Sources/Relay.cs +++ b/Ragon.Relay/Sources/Relay.cs @@ -14,39 +14,64 @@ * limitations under the License. */ -using NLog; +using System; +using System.IO; +using System.Threading; +using Newtonsoft.Json; using Ragon.Server; using Ragon.Server.ENetServer; -using Ragon.Server.WebSocketServer; using Ragon.Server.IO; +using Ragon.Server.Logging; using Ragon.Server.Plugin; +using Ragon.Server.WebSocketServer; -namespace Ragon.Relay; - -public class Relay +namespace Ragon.Relay { - public void Start() + public class Relay { - var logger = LogManager.GetLogger("Ragon.Relay"); - logger.Info("Relay Application"); - - var configuration = RagonServerConfiguration.Load("relay.config.json"); - var serverType = RagonServerConfiguration.GetServerType(configuration.ServerType); - - INetworkServer networkServer = new ENetServer(); - IServerPlugin plugin = new RelayServerPlugin(); - switch (serverType) + public void Start() { - case ServerType.ENET: - networkServer = new ENetServer(); - break; - case ServerType.WEBSOCKET: - networkServer = new WebSocketServer(); - break; - } + LoggerManager.SetLoggerFactory(new RelayLoggerFactory()); - var relay = new RagonServer(networkServer, plugin, configuration); - logger.Info("Started"); - relay.Start(); + var logger = LoggerManager.GetLogger("Relay"); + logger.Info("Relay Application"); + + var data = File.ReadAllText("relay.config.json"); + var configuration = JsonConvert.DeserializeObject(data); + var serverType = RagonServerConfiguration.GetServerType(configuration.ServerType); + + INetworkServer networkServer = new ENetServer(); + IServerPlugin plugin = new RelayServerPlugin(); + switch (serverType) + { + case ServerType.ENET: + networkServer = new ENetServer(); + break; + case ServerType.WEBSOCKET: + networkServer = new WebSocketServer(); + break; + } + + var serverConfiguration = new RagonServerConfiguration() + { + LimitConnections = configuration.LimitConnections, + LimitRooms = configuration.LimitConnections, + LimitBufferedEvents = configuration.LimitConnections, + LimitPlayersPerRoom = configuration.LimitConnections, + Port = configuration.Port, + Protocol = configuration.Protocol, + ServerKey = configuration.ServerKey, + ServerTickRate = configuration.ServerTickRate, + }; + var relay = new RagonServer(networkServer, plugin, serverConfiguration); + relay.Start(); + while (relay.IsRunning) + { + relay.Tick(); + Thread.Sleep(1); + } + + relay.Dispose(); + } } } \ No newline at end of file diff --git a/Ragon.Relay/Sources/RelayConfiguration.cs b/Ragon.Relay/Sources/RelayConfiguration.cs new file mode 100644 index 0000000..84279a6 --- /dev/null +++ b/Ragon.Relay/Sources/RelayConfiguration.cs @@ -0,0 +1,20 @@ +using System; + +namespace Ragon.Relay +{ + [Serializable] + public struct RelayConfiguration + { + public string ServerKey; + public string ServerType; + public ushort ServerTickRate; + public string Protocol; + public ushort Port; + public int LimitConnections; + public int LimitPlayersPerRoom; + public int LimitRooms; + public int LimitBufferedEvents; + public int LimitUserData; + + } +} \ No newline at end of file diff --git a/Ragon.Relay/Sources/RelayRoomPlugin.cs b/Ragon.Relay/Sources/RelayRoomPlugin.cs deleted file mode 100644 index 245f7b6..0000000 --- a/Ragon.Relay/Sources/RelayRoomPlugin.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using NLog; -using Ragon.Server.Entity; -using Ragon.Server.IO; -using Ragon.Server.Plugin; -using Ragon.Server.Room; - -namespace Ragon.Relay; - -public class RelayRoomPlugin : BaseRoomPlugin -{ - private Logger _logger = LogManager.GetCurrentClassLogger(); - - public override bool OnPlayerJoined(RagonRoomPlayer player) - { - // _logger.Trace($"Player {player.Name}|{player.Connection.Id} joined"); - return false; - } - - public override bool OnPlayerLeaved(RagonRoomPlayer player) - { - // _logger.Trace($"Player {player.Name}|{player.Connection.Id} leaved"); - return false; - } - - public override bool OnData(RagonRoomPlayer player, byte[] data) - { - // _logger.Trace($"Data received from {player.Name}|{player.Connection.Id}"); - - // All Players - // Room.ReplicateData(new Byte[] { 30, 40, 50 }, NetworkChannel.RELIABLE); - // Selected Player - // Room.ReplicateData(new byte[] { 10, 30, 40 }, new List { player }, NetworkChannel.RELIABLE); - - return true; - } -} \ No newline at end of file diff --git a/Ragon.Relay/relay.config.json b/Ragon.Relay/relay.config.json index 55c4b5e..bef71d0 100644 --- a/Ragon.Relay/relay.config.json +++ b/Ragon.Relay/relay.config.json @@ -2,20 +2,11 @@ "serverKey": "defaultkey", "serverType": "enet", "serverTickRate": 30, - "gameProtocol": "1.0.0", + "protocol": "1.0.0", "port": 5000, - "httpPort": 5001, - "httpKey": "defaultkey", "limitConnections": 4095, "limitPlayersPerRoom": 20, "limitRooms": 200, "limitBufferedEvents": 50, - "limitUserData": 1024, - "webHooks": - { - "room-created": "http://127.0.0.1:3000/service/create-room", - "room-removed": "http://127.0.0.1:3000/service/remove-room", - "room-joined": "http://127.0.0.1:3000/service/join-room", - "room-leaved": "http://127.0.0.1:3000/service/leave-room" - } + "limitUserData": 1024 } \ No newline at end of file diff --git a/Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj b/Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj index b81e24d..ac438ef 100644 --- a/Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj +++ b/Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj @@ -9,7 +9,6 @@ - diff --git a/Ragon.Server.ENetServer/Sources/ENetServer.cs b/Ragon.Server.ENetServer/Sources/ENetServer.cs index c0f5a41..e0488b9 100644 --- a/Ragon.Server.ENetServer/Sources/ENetServer.cs +++ b/Ragon.Server.ENetServer/Sources/ENetServer.cs @@ -15,26 +15,24 @@ */ using ENet; -using NLog; using Ragon.Protocol; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.ENetServer { public sealed class ENetServer : INetworkServer { - public Executor Executor => _executor; private readonly Host _host = new(); - private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(ENetServer)); private ENetConnection[] _connections = Array.Empty(); private INetworkListener _listener; private uint _protocol; private ENet.Event _event; - private Executor _executor = new(); - public void Start(INetworkListener listener, NetworkConfiguration configuration) + public void Listen(INetworkListener listener, NetworkConfiguration configuration) { Library.Initialize(); @@ -79,7 +77,7 @@ namespace Ragon.Server.ENetServer { if (!IsValidProtocol(_event.Data)) { - _logger.Warn($"Mismatched protocol Server: {RagonVersion.Parse(_protocol)} Client: {RagonVersion.Parse(_event.Data)}, close connection"); + _logger.Warning($"Mismatched protocol Server: {RagonVersion.Parse(_protocol)} Client: {RagonVersion.Parse(_event.Data)}, close connection"); _event.Peer.DisconnectNow(0); break; } diff --git a/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj b/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj index 4aa8f12..0ba9084 100644 --- a/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj +++ b/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj @@ -7,10 +7,6 @@ net7.0;net6.0 - - - - diff --git a/Ragon.Server/Sources/IO/Executor.cs b/Ragon.Server.WebSocketServer/Sources/Executor/Executor.cs similarity index 100% rename from Ragon.Server/Sources/IO/Executor.cs rename to Ragon.Server.WebSocketServer/Sources/Executor/Executor.cs diff --git a/Ragon.Server/Sources/IO/IExecutor.cs b/Ragon.Server.WebSocketServer/Sources/Executor/IExecutor.cs similarity index 100% rename from Ragon.Server/Sources/IO/IExecutor.cs rename to Ragon.Server.WebSocketServer/Sources/Executor/IExecutor.cs diff --git a/Ragon.Server.WebSocketServer/Sources/WebSocketConnection.cs b/Ragon.Server.WebSocketServer/Sources/WebSocketConnection.cs index 6c02f52..3bac7c2 100644 --- a/Ragon.Server.WebSocketServer/Sources/WebSocketConnection.cs +++ b/Ragon.Server.WebSocketServer/Sources/WebSocketConnection.cs @@ -14,15 +14,15 @@ * limitations under the License. */ -using NLog; using System.Net.WebSockets; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.WebSocketServer; public sealed class WebSocketConnection : INetworkConnection { - private Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(WebSocketConnection)); public ushort Id { get; } public INetworkChannel Reliable { get; private set; } public INetworkChannel Unreliable { get; private set; } diff --git a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs b/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs index 8ab2a46..2558ab4 100644 --- a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs +++ b/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs @@ -16,17 +16,16 @@ using System.Net; using System.Net.WebSockets; -using NLog; using Ragon.Protocol; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.WebSocketServer; public class WebSocketServer : INetworkServer { - public Executor Executor => _executor; - - private ILogger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(WebSocketServer)); + private INetworkListener _networkListener; private Stack _sequencer; private Executor _executor; @@ -67,7 +66,7 @@ public class WebSocketServer : INetworkServer } catch (Exception ex) { - _logger.Warn(ex); + _logger.Error(ex); continue; } @@ -113,6 +112,8 @@ public class WebSocketServer : INetworkServer public void Update() { + _executor.Update(); + Flush(); } @@ -128,7 +129,7 @@ public class WebSocketServer : INetworkServer await conn.Flush(); } - public void Start( + public void Listen( INetworkListener listener, NetworkConfiguration configuration ) diff --git a/Ragon.Server/Ragon.Server.csproj b/Ragon.Server/Ragon.Server.csproj index 3dde34d..835d921 100644 --- a/Ragon.Server/Ragon.Server.csproj +++ b/Ragon.Server/Ragon.Server.csproj @@ -16,11 +16,6 @@ net6.0;net7.0 - - - - - diff --git a/Ragon.Server/Sources/Handler/AuthorizationOperation.cs b/Ragon.Server/Sources/Handler/AuthorizationOperation.cs index e463725..7f1dd8a 100644 --- a/Ragon.Server/Sources/Handler/AuthorizationOperation.cs +++ b/Ragon.Server/Sources/Handler/AuthorizationOperation.cs @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Eduard Kargin + * Copyright 2023 Eduard Kargin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,105 +14,103 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Lobby; -using Ragon.Server.Plugin.Web; +using Ragon.Server.Logging; +using Ragon.Server.Plugin; - -namespace Ragon.Server.Handler; - -public sealed class AuthorizationOperation: BaseOperation +namespace Ragon.Server.Handler { - private Logger _logger = LogManager.GetCurrentClassLogger(); - private readonly RagonWebHookPlugin _webhook; - private readonly RagonContextObserver _observer; - private readonly RagonBuffer _writer; - private readonly RagonServerConfiguration _configuration; - - public AuthorizationOperation( - RagonBuffer reader, - RagonBuffer writer, - RagonWebHookPlugin webhook, - RagonContextObserver observer, - RagonServerConfiguration configuration): base(reader, writer) + public sealed class AuthorizationOperation : BaseOperation { - _webhook = webhook; - _observer = observer; - _writer = writer; - _configuration = configuration; - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - if (context.ConnectionStatus == ConnectionStatus.Authorized) + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(AuthorizationOperation)); + private readonly IServerPlugin _serverPlugin; + private readonly RagonContextObserver _observer; + private readonly RagonServerConfiguration _configuration; + private readonly RagonBuffer _writer; + + public AuthorizationOperation(RagonBuffer reader, + RagonBuffer writer, + IServerPlugin serverPlugin, + RagonContextObserver observer, + RagonServerConfiguration configuration) : base(reader, writer) { - _logger.Warn("Player already authorized!"); - return; + _serverPlugin = serverPlugin; + _configuration = configuration; + _observer = observer; + _writer = writer; } - if (context.ConnectionStatus == ConnectionStatus.InProcess) + public override void Handle(RagonContext context, NetworkChannel channel) { - _logger.Warn("Player already request authorization!"); - return; - } - - var configuration = _configuration; - var key = Reader.ReadString(); - var name = Reader.ReadString(); - var payload = Reader.ReadString(); - - if (key == configuration.ServerKey) - { - if (_webhook.RequestAuthorization(context, payload)) + if (context.ConnectionStatus == ConnectionStatus.Authorized) + { + _logger.Warning("Player already authorized!"); return; - - var lobbyPlayer = new RagonLobbyPlayer(context.Connection, Guid.NewGuid().ToString(), name, payload); - context.SetPlayer(lobbyPlayer); - - Approve(context); + } + + if (context.ConnectionStatus == ConnectionStatus.InProcess) + { + _logger.Warning("Player already request authorization!"); + return; + } + + var configuration = _configuration; + var key = Reader.ReadString(); + var name = Reader.ReadString(); + var payload = Reader.ReadString(); + + if (key == configuration.ServerKey) + { + var authorizeViaWebHook = _serverPlugin.OnAuthorize(new ConnectionRequest() { PeerID = context.Connection.Id }); + if (authorizeViaWebHook) + return; + + var lobbyPlayer = new RagonLobbyPlayer(context.Connection, Guid.NewGuid().ToString(), name, payload); + context.SetPlayer(lobbyPlayer); + + Approve(context); + } + else + { + Reject(context); + } } - else + + public void Approve(RagonContext context) { - Reject(context); + context.ConnectionStatus = ConnectionStatus.Authorized; + + _observer.OnAuthorized(context); + + var playerId = context.LobbyPlayer.Id; + var playerName = context.LobbyPlayer.Name; + var playerPayload = context.LobbyPlayer.Payload; + + _writer.Clear(); + _writer.WriteOperation(RagonOperation.AUTHORIZED_SUCCESS); + _writer.WriteString(playerId); + _writer.WriteString(playerName); + _writer.WriteString(playerPayload); + + var sendData = _writer.ToArray(); + context.Connection.Reliable.Send(sendData); + + _logger.Trace($"Connection {context.Connection.Id} as {playerId}|{context.LobbyPlayer.Name} authorized"); + } + + public void Reject(RagonContext context) + { + _writer.Clear(); + _writer.WriteOperation(RagonOperation.AUTHORIZED_FAILED); + + var sendData = _writer.ToArray(); + + context.Connection.Reliable.Send(sendData); + context.Connection.Close(); + + _logger.Trace($"Connection {context.Connection.Id}"); } } - - public void Approve(RagonContext context) - { - context.ConnectionStatus = ConnectionStatus.Authorized; - - _observer.OnAuthorized(context); - - var playerId = context.LobbyPlayer.Id; - var playerName = context.LobbyPlayer.Name; - var playerPayload = context.LobbyPlayer.Payload; - - _writer.Clear(); - _writer.WriteOperation(RagonOperation.AUTHORIZED_SUCCESS); - _writer.WriteString(playerId); - _writer.WriteString(playerName); - _writer.WriteString(playerPayload); - - var sendData = _writer.ToArray(); - context.Connection.Reliable.Send(sendData); - - _logger.Trace($"Connection {context.Connection.Id} as {playerId}|{context.LobbyPlayer.Name} authorized"); - } - - public void Reject(RagonContext context) - { - _writer.Clear(); - _writer.WriteOperation(RagonOperation.AUTHORIZED_FAILED); - - var sendData = _writer.ToArray(); - - context.Connection.Reliable.Send(sendData); - context.Connection.Close(); - - _logger.Trace($"Connection {context.Connection.Id}"); - } - - } \ No newline at end of file diff --git a/Ragon.Server/Sources/Handler/EntityCreateOperation.cs b/Ragon.Server/Sources/Handler/EntityCreateOperation.cs index 7d5bf36..c93886a 100644 --- a/Ragon.Server/Sources/Handler/EntityCreateOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityCreateOperation.cs @@ -14,17 +14,17 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.Entity; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class EntityCreateOperation : BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); - + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityCreateOperation)); + public EntityCreateOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { } diff --git a/Ragon.Server/Sources/Handler/EntityEventOperation.cs b/Ragon.Server/Sources/Handler/EntityEventOperation.cs index 7227adf..3e2ece5 100644 --- a/Ragon.Server/Sources/Handler/EntityEventOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityEventOperation.cs @@ -14,16 +14,16 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.Event; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class EntityEventOperation : BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityEventOperation)); public EntityEventOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { @@ -37,7 +37,7 @@ public sealed class EntityEventOperation : BaseOperation if (!room.Entities.TryGetValue(entityId, out var ent)) { - _logger.Warn($"Entity not found for event with Id {entityId}"); + _logger.Warning($"Entity not found for event with Id {entityId}"); return; } diff --git a/Ragon.Server/Sources/Handler/EntityOwnershipOperation.cs b/Ragon.Server/Sources/Handler/EntityOwnershipOperation.cs index 9ae4592..4d48a26 100644 --- a/Ragon.Server/Sources/Handler/EntityOwnershipOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityOwnershipOperation.cs @@ -15,15 +15,15 @@ */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class EntityOwnershipOperation : BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityOwnershipOperation)); public EntityOwnershipOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { diff --git a/Ragon.Server/Sources/Handler/EntityRemoveOperation.cs b/Ragon.Server/Sources/Handler/EntityRemoveOperation.cs index 9a45b4b..acb8f82 100644 --- a/Ragon.Server/Sources/Handler/EntityRemoveOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityRemoveOperation.cs @@ -14,16 +14,16 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.Entity; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class EntityDestroyOperation: BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityDestroyOperation)); public EntityDestroyOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { diff --git a/Ragon.Server/Sources/Handler/EntityStateOperation.cs b/Ragon.Server/Sources/Handler/EntityStateOperation.cs index c5fcca3..ac92626 100644 --- a/Ragon.Server/Sources/Handler/EntityStateOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityStateOperation.cs @@ -14,15 +14,15 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class EntityStateOperation: BaseOperation { - private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityStateOperation)); public EntityStateOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { diff --git a/Ragon.Server/Sources/Handler/PlayerUserDataOperation.cs b/Ragon.Server/Sources/Handler/PlayerUserDataOperation.cs index 1ccb83d..36d84d8 100644 --- a/Ragon.Server/Sources/Handler/PlayerUserDataOperation.cs +++ b/Ragon.Server/Sources/Handler/PlayerUserDataOperation.cs @@ -1,15 +1,15 @@ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Lobby; +using Ragon.Server.Logging; namespace Ragon.Server.Handler { public class PlayerUserDataOperation : BaseOperation { - private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(PlayerUserDataOperation)); private readonly int _userDataLimit; - + public PlayerUserDataOperation( RagonBuffer reader, RagonBuffer writer, @@ -23,10 +23,10 @@ namespace Ragon.Server.Handler { if (context.ConnectionStatus == ConnectionStatus.Unauthorized) { - _logger.Warn($"Player {context.Connection.Id} not authorized for this request"); + _logger.Warning($"Player {context.Connection.Id} not authorized for this request"); return; } - + context.UserData.Read(Reader); } } diff --git a/Ragon.Server/Sources/Handler/RoomCreateOperation.cs b/Ragon.Server/Sources/Handler/RoomCreateOperation.cs index 4b39790..4855ac3 100644 --- a/Ragon.Server/Sources/Handler/RoomCreateOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomCreateOperation.cs @@ -14,114 +14,114 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Lobby; +using Ragon.Server.Logging; using Ragon.Server.Plugin; -using Ragon.Server.Plugin.Web; using Ragon.Server.Room; -namespace Ragon.Server.Handler; - -public sealed class RoomCreateOperation : BaseOperation +namespace Ragon.Server.Handler { - private readonly RagonRoomPayload _roomPayload = new(); - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); - private readonly IServerPlugin _serverPlugin; - private readonly RagonWebHookPlugin _ragonWebHookPlugin; - - public RoomCreateOperation(RagonBuffer reader, RagonBuffer writer, IServerPlugin serverPlugin, RagonWebHookPlugin ragonWebHook) : base(reader, writer) + public sealed class RoomCreateOperation : BaseOperation { - _serverPlugin = serverPlugin; - _ragonWebHookPlugin = ragonWebHook; - } + private IRagonLogger _logger = LoggerManager.GetLogger(nameof(RoomCreateOperation)); - public override void Handle(RagonContext context, NetworkChannel channel) - { - if (context.ConnectionStatus == ConnectionStatus.Unauthorized) + private readonly RagonRoomParameters _roomParameters = new(); + private readonly IServerPlugin _serverPlugin; + + public RoomCreateOperation(RagonBuffer reader, RagonBuffer writer, IServerPlugin serverPlugin) : base(reader, + writer) { - _logger.Warn($"Player {context.Connection.Id} not authorized for this request"); - return; + _serverPlugin = serverPlugin; } - var custom = Reader.ReadBool(); - var roomId = Guid.NewGuid().ToString(); - - if (custom) + public override void Handle(RagonContext context, NetworkChannel channel) { - roomId = Reader.ReadString(); - if (context.Lobby.FindRoomById(roomId, out _)) + if (context.ConnectionStatus == ConnectionStatus.Unauthorized) { - Writer.Clear(); - Writer.WriteOperation(RagonOperation.JOIN_FAILED); - Writer.WriteString($"Room with id {roomId} already exists"); - - var sendData = Writer.ToArray(); - context.Connection.Reliable.Send(sendData); - - _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} join failed to room {roomId}, room already exist"); + _logger.Warning($"Player {context.Connection.Id} not authorized for this request"); return; } + + var custom = Reader.ReadBool(); + var roomId = Guid.NewGuid().ToString(); + + if (custom) + { + roomId = Reader.ReadString(); + if (context.Lobby.FindRoomById(roomId, out _)) + { + Writer.Clear(); + Writer.WriteOperation(RagonOperation.JOIN_FAILED); + Writer.WriteString($"Room with id {roomId} already exists"); + + var sendData = Writer.ToArray(); + context.Connection.Reliable.Send(sendData); + + _logger.Trace( + $"Player {context.Connection.Id}|{context.LobbyPlayer.Name} join failed to room {roomId}, room already exist"); + return; + } + } + + _roomParameters.Deserialize(Reader); + + var information = new RoomInformation() + { + Scene = _roomParameters.Scene, + Max = _roomParameters.Max, + Min = _roomParameters.Min, + }; + + var lobbyPlayer = context.LobbyPlayer; + var roomPlayer = new RagonRoomPlayer(context, lobbyPlayer.Id, lobbyPlayer.Name); + + var roomPlugin = _serverPlugin.CreateRoomPlugin(information); + var room = new RagonRoom(roomId, information, roomPlugin); + + room.Plugin.OnAttached(room); + roomPlayer.OnAttached(room); + + context.Scheduler.Run(room); + context.Lobby.Persist(room); + context.SetRoom(room, roomPlayer); + + _logger.Trace( + $"Player {context.Connection.Id}|{context.LobbyPlayer.Name} create room {room.Id} with scene {information.Scene}"); + + JoinSuccess(roomPlayer, room, Writer); + + roomPlugin.OnPlayerJoined(roomPlayer); + + _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} joined to room {room.Id}"); } - _roomPayload.Deserialize(Reader); - - var information = new RoomInformation() + private void JoinSuccess(RagonRoomPlayer player, RagonRoom room, RagonBuffer writer) { - Scene = _roomPayload.Scene, - Max = _roomPayload.Max, - Min = _roomPayload.Min, - }; + writer.Clear(); + writer.WriteOperation(RagonOperation.JOIN_SUCCESS); + writer.WriteString(room.Id); + writer.WriteUShort((ushort)room.PlayerMin); + writer.WriteUShort((ushort)room.PlayerMax); + writer.WriteString(room.Scene); + writer.WriteString(player.Id); + writer.WriteString(room.Owner.Id); - var lobbyPlayer = context.LobbyPlayer; - var roomPlayer = new RagonRoomPlayer(context, lobbyPlayer.Id, lobbyPlayer.Name); + room.UserData.Snapshot(writer); - var roomPlugin = _serverPlugin.CreateRoomPlugin(information); - var room = new RagonRoom(roomId, information, roomPlugin); - - room.Plugin.OnAttached(room); - roomPlayer.OnAttached(room); + writer.WriteUShort((ushort)room.PlayerList.Count); + foreach (var roomPlayer in room.PlayerList) + { + writer.WriteUShort(roomPlayer.Connection.Id); + writer.WriteString(roomPlayer.Id); + writer.WriteString(roomPlayer.Name); - context.Scheduler.Run(room); - context.Lobby.Persist(room); - context.SetRoom(room, roomPlayer); + roomPlayer.Context.UserData.Snapshot(writer); + } - _ragonWebHookPlugin.RoomCreated(context, room, roomPlayer); - - _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} create room {room.Id} with scene {information.Scene}"); - - JoinSuccess(roomPlayer, room, Writer); - - roomPlugin.OnPlayerJoined(roomPlayer); - - _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} joined to room {room.Id}"); - } - - private void JoinSuccess(RagonRoomPlayer player, RagonRoom room, RagonBuffer writer) - { - writer.Clear(); - writer.WriteOperation(RagonOperation.JOIN_SUCCESS); - writer.WriteString(room.Id); - writer.WriteUShort((ushort)room.PlayerMin); - writer.WriteUShort((ushort)room.PlayerMax); - writer.WriteString(room.Scene); - writer.WriteString(player.Id); - writer.WriteString(room.Owner.Id); - - room.UserData.Snapshot(writer); - - writer.WriteUShort((ushort)room.PlayerList.Count); - foreach (var roomPlayer in room.PlayerList) - { - writer.WriteUShort(roomPlayer.Connection.Id); - writer.WriteString(roomPlayer.Id); - writer.WriteString(roomPlayer.Name); - - roomPlayer.Context.UserData.Snapshot(writer); + var sendData = writer.ToArray(); + player.Connection.Reliable.Send(sendData); } - - var sendData = writer.ToArray(); - player.Connection.Reliable.Send(sendData); } } \ No newline at end of file diff --git a/Ragon.Server/Sources/Handler/RoomDataOperation.cs b/Ragon.Server/Sources/Handler/RoomDataOperation.cs index 2c98506..23cbc45 100644 --- a/Ragon.Server/Sources/Handler/RoomDataOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomDataOperation.cs @@ -14,7 +14,6 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; diff --git a/Ragon.Server/Sources/Handler/RoomEventOperation.cs b/Ragon.Server/Sources/Handler/RoomEventOperation.cs index 0f796dd..85082e7 100644 --- a/Ragon.Server/Sources/Handler/RoomEventOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomEventOperation.cs @@ -1,14 +1,15 @@ -using NLog; using Ragon.Protocol; using Ragon.Server.Event; using Ragon.Server.IO; using Ragon.Server.Lobby; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public class RoomEventOperation : BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(RoomEventOperation)); + public RoomEventOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { } @@ -17,7 +18,7 @@ public class RoomEventOperation : BaseOperation { if (context.ConnectionStatus == ConnectionStatus.Unauthorized) { - _logger.Warn($"Player {context.Connection.Id} not authorized for this request"); + _logger.Warning($"Player {context.Connection.Id} not authorized for this request"); return; } diff --git a/Ragon.Server/Sources/Handler/RoomJoinOperation.cs b/Ragon.Server/Sources/Handler/RoomJoinOperation.cs index e00954b..228aec7 100644 --- a/Ragon.Server/Sources/Handler/RoomJoinOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomJoinOperation.cs @@ -14,24 +14,21 @@ * limitations under the License. */ -using NLog; + using Ragon.Protocol; using Ragon.Server.IO; -using Ragon.Server.Plugin.Web; +using Ragon.Server.Logging; using Ragon.Server.Room; namespace Ragon.Server.Handler; public sealed class RoomJoinOperation : BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); - private readonly RagonWebHookPlugin _webHook; + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(RoomJoinOperation)); - public RoomJoinOperation(RagonBuffer reader, RagonBuffer writer, RagonWebHookPlugin plugin) : base(reader, writer) + public RoomJoinOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { - _webHook = plugin; } - public override void Handle(RagonContext context, NetworkChannel channel) { @@ -49,8 +46,6 @@ public sealed class RoomJoinOperation : BaseOperation var player = new RagonRoomPlayer(context, lobbyPlayer.Id, lobbyPlayer.Name); context.SetRoom(existsRoom, player); - _webHook.RoomJoined(context, existsRoom, player); - JoinSuccess(context, existsRoom, Writer); existsRoom.RestoreBufferedEvents(player); diff --git a/Ragon.Server/Sources/Handler/RoomJoinOrCreateOperation.cs b/Ragon.Server/Sources/Handler/RoomJoinOrCreateOperation.cs index 8304bab..2b51ca5 100644 --- a/Ragon.Server/Sources/Handler/RoomJoinOrCreateOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomJoinOrCreateOperation.cs @@ -14,50 +14,46 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Lobby; +using Ragon.Server.Logging; using Ragon.Server.Plugin; -using Ragon.Server.Plugin.Web; using Ragon.Server.Room; namespace Ragon.Server.Handler; public sealed class RoomJoinOrCreateOperation : BaseOperation { - private readonly RagonRoomPayload _roomPayload = new(); - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private IRagonLogger _logger = LoggerManager.GetLogger(nameof(RoomJoinOrCreateOperation)); + + private readonly RagonRoomParameters _roomParameters = new(); private readonly IServerPlugin _serverPlugin; - private readonly RagonWebHookPlugin _ragonWebHookPlugin; - public RoomJoinOrCreateOperation(RagonBuffer reader, RagonBuffer writer, IServerPlugin serverPlugin, RagonWebHookPlugin plugin): base(reader, writer) + public RoomJoinOrCreateOperation(RagonBuffer reader, RagonBuffer writer, IServerPlugin serverPlugin): base(reader, writer) { _serverPlugin = serverPlugin; - _ragonWebHookPlugin = plugin; } public override void Handle(RagonContext context, NetworkChannel channel) { if (context.ConnectionStatus == ConnectionStatus.Unauthorized) { - _logger.Warn("Player not authorized for this request"); + _logger.Warning("Player not authorized for this request"); return; } var roomId = Guid.NewGuid().ToString(); var lobbyPlayer = context.LobbyPlayer; - _roomPayload.Deserialize(Reader); + _roomParameters.Deserialize(Reader); - if (context.Lobby.FindRoomByScene(_roomPayload.Scene, out var existsRoom)) + if (context.Lobby.FindRoomByScene(_roomParameters.Scene, out var existsRoom)) { var player = new RagonRoomPlayer(context, lobbyPlayer.Id, lobbyPlayer.Name); context.SetRoom(existsRoom, player); - _ragonWebHookPlugin.RoomJoined(context, existsRoom, player); - JoinSuccess(player, existsRoom, Writer); existsRoom.RestoreBufferedEvents(player); @@ -68,16 +64,16 @@ public sealed class RoomJoinOrCreateOperation : BaseOperation { var information = new RoomInformation() { - Scene = _roomPayload.Scene, - Max = _roomPayload.Max, - Min = _roomPayload.Min, + Scene = _roomParameters.Scene, + Max = _roomParameters.Max, + Min = _roomParameters.Min, }; var roomPlayer = new RagonRoomPlayer(context, lobbyPlayer.Id, lobbyPlayer.Name); var roomPlugin = _serverPlugin.CreateRoomPlugin(information); var room = new RagonRoom(roomId, information, roomPlugin); - _ragonWebHookPlugin.RoomCreated(context, room, roomPlayer); + _serverPlugin.OnRoomCreate(lobbyPlayer, room); room.Plugin.OnAttached(room); diff --git a/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs b/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs index 3010264..3e08c76 100644 --- a/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs @@ -14,22 +14,18 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; -using Ragon.Server.Plugin; -using Ragon.Server.Plugin.Web; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class RoomLeaveOperation: BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); - private readonly RagonWebHookPlugin _webHook; + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(RoomLeaveOperation)); - public RoomLeaveOperation(RagonBuffer reader, RagonBuffer writer, RagonWebHookPlugin plugin): base(reader, writer) + public RoomLeaveOperation(RagonBuffer reader, RagonBuffer writer): base(reader, writer) { - _webHook = plugin; } public override void Handle(RagonContext context, NetworkChannel channel) @@ -44,8 +40,6 @@ public sealed class RoomLeaveOperation: BaseOperation plugin.OnPlayerLeaved(roomPlayer); room.DetachPlayer(roomPlayer); - _webHook.RoomLeaved(context, room, roomPlayer); - _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} leaved from {room.Id}"); } } diff --git a/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs b/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs index 32e9a2c..498095f 100644 --- a/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -using NLog; using Ragon.Protocol; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class RoomOwnershipOperation : BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(RoomOwnershipOperation)); public RoomOwnershipOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { diff --git a/Ragon.Server/Sources/Handler/RoomUserDataOperation.cs b/Ragon.Server/Sources/Handler/RoomUserDataOperation.cs index d299015..5943e21 100644 --- a/Ragon.Server/Sources/Handler/RoomUserDataOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomUserDataOperation.cs @@ -14,16 +14,16 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Lobby; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public sealed class RoomUserDataOperation : BaseOperation { - private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(RoomUserDataOperation)); private readonly int _userDataLimit; public RoomUserDataOperation( @@ -39,7 +39,7 @@ public sealed class RoomUserDataOperation : BaseOperation { if (context.ConnectionStatus == ConnectionStatus.Unauthorized) { - _logger.Warn($"Player {context.Connection.Id} not authorized for this request"); + _logger.Warning($"Player {context.Connection.Id} not authorized for this request"); return; } diff --git a/Ragon.Server/Sources/Handler/SceneLoadOperation.cs b/Ragon.Server/Sources/Handler/SceneLoadOperation.cs index a8f3498..3d4c40d 100644 --- a/Ragon.Server/Sources/Handler/SceneLoadOperation.cs +++ b/Ragon.Server/Sources/Handler/SceneLoadOperation.cs @@ -14,15 +14,15 @@ * limitations under the License. */ -using NLog; using Ragon.Protocol; using Ragon.Server.IO; +using Ragon.Server.Logging; namespace Ragon.Server.Handler; public class SceneLoadOperation: BaseOperation { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(SceneLoadOperation)); public SceneLoadOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) {} @@ -35,7 +35,7 @@ public class SceneLoadOperation: BaseOperation if (roomOwner.Connection.Id != currentPlayer.Connection.Id) { - _logger.Warn("Only owner can change scene!"); + _logger.Warning("Only owner can change scene!"); return; } diff --git a/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs b/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs index 0c59087..49b53d2 100644 --- a/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs +++ b/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs @@ -14,150 +14,151 @@ * limitations under the License. */ -using NLog; + using Ragon.Protocol; using Ragon.Server.Entity; using Ragon.Server.IO; using Ragon.Server.Lobby; +using Ragon.Server.Logging; using Ragon.Server.Room; -namespace Ragon.Server.Handler; - -public sealed class SceneLoadedOperation : BaseOperation +namespace Ragon.Server.Handler { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); - - public SceneLoadedOperation(RagonBuffer reader, RagonBuffer writer): base(reader, writer) + public sealed class SceneLoadedOperation : BaseOperation { - - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - if (context.ConnectionStatus == ConnectionStatus.Unauthorized) - return; + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(SceneLoadedOperation)); - var owner = context.Room.Owner; - var player = context.RoomPlayer; - var room = context.Room; - if (player.IsLoaded) + public SceneLoadedOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { - _logger.Warn($"Player {player.Name}:{player.Connection.Id} already ready"); - return; } - if (player == owner) + public override void Handle(RagonContext context, NetworkChannel channel) { - var statics = Reader.ReadUShort(); - for (var staticIndex = 0; staticIndex < statics; staticIndex++) + if (context.ConnectionStatus == ConnectionStatus.Unauthorized) + return; + + var owner = context.Room.Owner; + var player = context.RoomPlayer; + var room = context.Room; + if (player.IsLoaded) { - var entityType = Reader.ReadUShort(); - var eventAuthority = (RagonAuthority)Reader.ReadByte(); - var staticId = Reader.ReadUShort(); - var propertiesCount = Reader.ReadUShort(); + _logger.Warning($"Player {player.Name}:{player.Connection.Id} already ready"); + return; + } - var entityParameters = new RagonEntityParameters() + if (player == owner) + { + var statics = Reader.ReadUShort(); + for (var staticIndex = 0; staticIndex < statics; staticIndex++) { - Type = entityType, - Authority = eventAuthority, - AttachId = 0, - StaticId = staticId, - BufferedEvents = context.LimitBufferedEvents, - }; + var entityType = Reader.ReadUShort(); + var eventAuthority = (RagonAuthority)Reader.ReadByte(); + var staticId = Reader.ReadUShort(); + var propertiesCount = Reader.ReadUShort(); - var entity = new RagonEntity(entityParameters); - for (var propertyIndex = 0; propertyIndex < propertiesCount; propertyIndex++) - { - var propertyType = Reader.ReadBool(); - var propertySize = Reader.ReadUShort(); - entity.AddProperty(new RagonProperty(propertySize, propertyType)); + var entityParameters = new RagonEntityParameters() + { + Type = entityType, + Authority = eventAuthority, + AttachId = 0, + StaticId = staticId, + BufferedEvents = context.LimitBufferedEvents, + }; + + var entity = new RagonEntity(entityParameters); + for (var propertyIndex = 0; propertyIndex < propertiesCount; propertyIndex++) + { + var propertyType = Reader.ReadBool(); + var propertySize = Reader.ReadUShort(); + entity.AddProperty(new RagonProperty(propertySize, propertyType)); + } + + var roomPlugin = room.Plugin; + if (!roomPlugin.OnEntityCreate(player, entity)) continue; + + var playerInfo = $"Player {context.Connection.Id}|{context.LobbyPlayer.Name}"; + var entityInfo = $"{entity.Id}:{entity.Type}"; + + _logger.Trace($"{playerInfo} created static entity {entityInfo}"); + + entity.Attach(player); + room.AttachEntity(entity); + player.AttachEntity(entity); } - - var roomPlugin = room.Plugin; - if (!roomPlugin.OnEntityCreate(player, entity)) continue; - - var playerInfo = $"Player {context.Connection.Id}|{context.LobbyPlayer.Name}"; - var entityInfo = $"{entity.Id}:{entity.Type}"; - _logger.Trace($"{playerInfo} created static entity {entityInfo}"); + _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} loaded"); - entity.Attach(player); - room.AttachEntity(entity); - player.AttachEntity(entity); + room.WaitPlayersList.Add(player); + + foreach (var roomPlayer in room.WaitPlayersList) + { + DispatchPlayerJoinExcludePlayer(room, roomPlayer, Writer); + + roomPlayer.SetReady(); + } + + room.UpdateReadyPlayerList(); + + DispatchSnapshot(room, room.WaitPlayersList, Writer); + + room.WaitPlayersList.Clear(); } - - _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} loaded"); - - room.WaitPlayersList.Add(player); - - foreach (var roomPlayer in room.WaitPlayersList) + else if (owner.IsLoaded) { - DispatchPlayerJoinExcludePlayer(room, roomPlayer, Writer); + player.SetReady(); - roomPlayer.SetReady(); + DispatchPlayerJoinExcludePlayer(room, player, Writer); + + room.UpdateReadyPlayerList(); + + DispatchSnapshot(room, new List() { player }, Writer); + + foreach (var entity in room.EntityList) + entity.RestoreBufferedEvents(player, Writer); + } + else + { + _logger.Trace($"Player {player.Connection.Id}|{context.LobbyPlayer.Name} waiting owner of room"); + room.WaitPlayersList.Add(player); } - - room.UpdateReadyPlayerList(); - - DispatchSnapshot(room, room.WaitPlayersList, Writer); - - room.WaitPlayersList.Clear(); } - else if (owner.IsLoaded) + + private void DispatchPlayerJoinExcludePlayer(RagonRoom room, RagonRoomPlayer roomPlayer, RagonBuffer writer) { - player.SetReady(); + writer.Clear(); + writer.WriteOperation(RagonOperation.PLAYER_JOINED); + writer.WriteUShort(roomPlayer.Connection.Id); + writer.WriteString(roomPlayer.Id); + writer.WriteString(roomPlayer.Name); - DispatchPlayerJoinExcludePlayer(room, player, Writer); - - room.UpdateReadyPlayerList(); - - DispatchSnapshot(room, new List() { player }, Writer); - - foreach (var entity in room.EntityList) - entity.RestoreBufferedEvents(player, Writer); + var sendData = writer.ToArray(); + foreach (var awaiter in room.ReadyPlayersList) + { + if (awaiter != roomPlayer) + awaiter.Connection.Reliable.Send(sendData); + } } - else + + private void DispatchSnapshot(RagonRoom room, List receviersList, RagonBuffer writer) { - _logger.Trace($"Player {player.Connection.Id}|{context.LobbyPlayer.Name} waiting owner of room"); - room.WaitPlayersList.Add(player); + writer.Clear(); + writer.WriteOperation(RagonOperation.SNAPSHOT); + + var dynamicEntities = room.DynamicEntitiesList; + var dynamicEntitiesCount = (ushort)dynamicEntities.Count; + writer.WriteUShort(dynamicEntitiesCount); + foreach (var entity in dynamicEntities) + entity.Snapshot(writer); + + var staticEntities = room.StaticEntitiesList; + var staticEntitiesCount = (ushort)staticEntities.Count; + writer.WriteUShort(staticEntitiesCount); + foreach (var entity in staticEntities) + entity.Snapshot(writer); + + var sendData = writer.ToArray(); + foreach (var player in receviersList) + player.Connection.Reliable.Send(sendData); } } - - private void DispatchPlayerJoinExcludePlayer(RagonRoom room, RagonRoomPlayer roomPlayer, RagonBuffer writer) - { - writer.Clear(); - writer.WriteOperation(RagonOperation.PLAYER_JOINED); - writer.WriteUShort(roomPlayer.Connection.Id); - writer.WriteString(roomPlayer.Id); - writer.WriteString(roomPlayer.Name); - - var sendData = writer.ToArray(); - foreach (var awaiter in room.ReadyPlayersList) - { - if (awaiter != roomPlayer) - awaiter.Connection.Reliable.Send(sendData); - } - } - - private void DispatchSnapshot(RagonRoom room, List receviersList, RagonBuffer writer) - { - writer.Clear(); - writer.WriteOperation(RagonOperation.SNAPSHOT); - - var dynamicEntities = room.DynamicEntitiesList; - var dynamicEntitiesCount = (ushort)dynamicEntities.Count; - writer.WriteUShort(dynamicEntitiesCount); - foreach (var entity in dynamicEntities) - entity.Snapshot(writer); - - var staticEntities = room.StaticEntitiesList; - var staticEntitiesCount = (ushort)staticEntities.Count; - writer.WriteUShort(staticEntitiesCount); - foreach (var entity in staticEntities) - entity.Snapshot(writer); - - var sendData = writer.ToArray(); - foreach (var player in receviersList) - player.Connection.Reliable.Send(sendData); - } } \ No newline at end of file diff --git a/Ragon.Server/Sources/Http/RagonHttpServer.cs b/Ragon.Server/Sources/Http/RagonHttpServer.cs deleted file mode 100644 index 13525f8..0000000 --- a/Ragon.Server/Sources/Http/RagonHttpServer.cs +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using NLog; -using System.Net; -using System.Text.Json; -using Ragon.Server.IO; -using Ragon.Server.Plugin; - -namespace Ragon.Server.Http; - -public class RagonHttpServer -{ - private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); - private readonly IExecutor _executor; - private readonly IServerPlugin _serverPlugin; - private HttpListener _httpListener; - private CancellationTokenSource _cancellationTokenSource; - - public RagonHttpServer(IExecutor executor, IServerPlugin serverPlugin) - { - _serverPlugin = serverPlugin; - _executor = executor; - } - - public async void StartAccept(CancellationToken cancellationToken) - { - while (!cancellationToken.IsCancellationRequested) - { - var context = await _httpListener.GetContextAsync(); - - if (context.Request.HttpMethod != "POST") - { - context.Response.StatusCode = 404; - context.Response.ContentLength64 = 0; - context.Response.Close(); - } - - var request = context.Request; - var reader = new StreamReader(request.InputStream, request.ContentEncoding); - var rawJson = await reader.ReadToEndAsync(); - var httpCommand = JsonDocument.Parse(rawJson); - if (httpCommand != null) - { - try - { - var command = httpCommand.RootElement.GetProperty("command"); - var payload = httpCommand.RootElement.GetProperty("payload"); - - if (_serverPlugin.OnCommand(command.GetString() ?? "none", payload.GetRawText())) - { - context.Response.StatusCode = 200; - context.Response.ContentLength64 = 0; - context.Response.Close(); - } - else - { - context.Response.StatusCode = 403; - context.Response.ContentLength64 = 0; - context.Response.Close(); - } - } - catch (Exception ex) - { - _logger.Error(ex); - - context.Response.StatusCode = 505; - context.Response.ContentLength64 = 0; - context.Response.Close(); - } - - continue; - } - - context.Response.StatusCode = 403; - context.Response.ContentLength64 = 0; - context.Response.Close(); - } - } - - public void Start(RagonServerConfiguration configuration) - { - _cancellationTokenSource = new CancellationTokenSource(); - _logger.Info($"Listen at http://0.0.0.0:{configuration.HttpPort}/"); - - _httpListener = new HttpListener(); - _httpListener.Prefixes.Add($"http://127.0.0.1:{configuration.HttpPort}/"); - _httpListener.Start(); - - _executor.Run(() => StartAccept(_cancellationTokenSource.Token), TaskCreationOptions.LongRunning); - } - - public void Stop() - { - _cancellationTokenSource.Cancel(); - _httpListener.Stop(); - } -} \ No newline at end of file diff --git a/Ragon.Server/Sources/IO/INetworkServer.cs b/Ragon.Server/Sources/IO/INetworkServer.cs index f1f6054..84027ef 100644 --- a/Ragon.Server/Sources/IO/INetworkServer.cs +++ b/Ragon.Server/Sources/IO/INetworkServer.cs @@ -18,9 +18,8 @@ namespace Ragon.Server.IO; public interface INetworkServer { - public Executor Executor { get; } public void Stop(); public void Update(); public void Broadcast(byte[] data, NetworkChannel channel); - public void Start(INetworkListener listener, NetworkConfiguration configuration); + public void Listen(INetworkListener listener, NetworkConfiguration configuration); } \ No newline at end of file diff --git a/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs b/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs index a2e2ea6..9291f7b 100644 --- a/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs +++ b/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs @@ -15,7 +15,7 @@ */ using System.Diagnostics.CodeAnalysis; -using NLog; +using Ragon.Server.Logging; using Ragon.Server.Room; namespace Ragon.Server.Lobby; @@ -23,7 +23,7 @@ namespace Ragon.Server.Lobby; public class LobbyInMemory : IRagonLobby { private readonly List _rooms = new(); - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(LobbyInMemory)); public IReadOnlyList Rooms => _rooms.AsReadOnly(); @@ -35,7 +35,7 @@ public class LobbyInMemory : IRagonLobby { if (existRagonRoom.PlayerCount >= existRagonRoom.PlayerMax) { - _logger.Warn($"Room with id {roomId} fulfilled"); + _logger.Warning($"Room with id {roomId} fulfilled"); room = default; return false; @@ -58,7 +58,7 @@ public class LobbyInMemory : IRagonLobby { if (existsRoom.PlayerCount >= existsRoom.PlayerMax) { - _logger.Warn($"Room with scene {sceneName} fulfilled"); + _logger.Warning($"Room with scene {sceneName} fulfilled"); room = default; return false; diff --git a/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs b/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs index 0311f5c..2d3ef3b 100644 --- a/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs +++ b/Ragon.Server/Sources/Plugin/BaseServerPlugin.cs @@ -18,39 +18,68 @@ using Ragon.Server.IO; using Ragon.Server.Lobby; using Ragon.Server.Room; -namespace Ragon.Server.Plugin; - -public class BaseServerPlugin: IServerPlugin +namespace Ragon.Server.Plugin { - public IRagonServer Server { get; protected set; } - - public virtual void OnAttached(IRagonServer server) + public class ConnectionRequest { - Server = server; + public int PeerID { get; set; } + + public void Approve() + { + } + + public void Reject() + { + } } - public virtual void OnDetached() + public class BaseServerPlugin : IServerPlugin { - - } + public IRagonServer Server { get; protected set; } - public virtual bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room) - { - return true; - } + public virtual void OnAttached(IRagonServer server) + { + Server = server; + } - public virtual bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room) - { - return true; - } + public virtual void OnDetached() + { - public virtual bool OnCommand(string command, string payload) - { - return true; - } + } - public virtual IRoomPlugin CreateRoomPlugin(RoomInformation information) - { - return new BaseRoomPlugin(); + public virtual bool OnAuthorize(ConnectionRequest request) + { + return false; + } + + public virtual bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room) + { + return true; + } + + public virtual bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room) + { + return true; + } + + public bool OnRoomJoined(RagonRoomPlayer player, RagonRoom room) + { + return true; + } + + public bool OnRoomLeaved(RagonRoomPlayer player, RagonRoom room) + { + return true; + } + + public virtual bool OnCommand(string command, string payload) + { + return true; + } + + public virtual IRoomPlugin CreateRoomPlugin(RoomInformation information) + { + return new BaseRoomPlugin(); + } } } \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/IServerPlugin.cs b/Ragon.Server/Sources/Plugin/IServerPlugin.cs index eaf5fce..2df2717 100644 --- a/Ragon.Server/Sources/Plugin/IServerPlugin.cs +++ b/Ragon.Server/Sources/Plugin/IServerPlugin.cs @@ -14,18 +14,21 @@ * limitations under the License. */ -using Ragon.Server.Http; using Ragon.Server.Lobby; using Ragon.Server.Room; -namespace Ragon.Server.Plugin; - -public interface IServerPlugin +namespace Ragon.Server.Plugin { - void OnAttached(IRagonServer server); - void OnDetached(); - bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room); - bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room); - bool OnCommand(string command, string payload); - IRoomPlugin CreateRoomPlugin(RoomInformation information); + public interface IServerPlugin + { + void OnAttached(IRagonServer server); + void OnDetached(); + bool OnAuthorize(ConnectionRequest request); + bool OnRoomCreate(RagonLobbyPlayer player, RagonRoom room); + bool OnRoomRemove(RagonLobbyPlayer player, RagonRoom room); + bool OnRoomJoined(RagonRoomPlayer player, RagonRoom room); + bool OnRoomLeaved(RagonRoomPlayer player, RagonRoom room); + bool OnCommand(string command, string payload); + IRoomPlugin CreateRoomPlugin(RoomInformation information); + } } \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/Dto/PlayerDto.cs b/Ragon.Server/Sources/Plugin/Web/Dto/PlayerDto.cs deleted file mode 100644 index faf07cd..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Dto/PlayerDto.cs +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using Ragon.Server.Room; - -namespace Ragon.Server.Plugin.Web; - -[Serializable] -public class PlayerDto -{ - public string Id { get; set;} - public string Name { get; set; } - - public PlayerDto(RagonRoomPlayer ragonRoomPlayer) - { - Id = ragonRoomPlayer.Id; - Name = ragonRoomPlayer.Name; - } -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/Dto/RoomDto.cs b/Ragon.Server/Sources/Plugin/Web/Dto/RoomDto.cs deleted file mode 100644 index a500fef..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Dto/RoomDto.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using Ragon.Server.Room; - -namespace Ragon.Server.Plugin.Web; - -[Serializable] -public class RoomDto -{ - public string Id { get; set;} - public int PlayerMin { get; set; } - public int PlayerMax { get; set; } - public int PlayerCount { get; set; } - public PlayerDto[] Players { get; set; } - - public RoomDto(RagonRoom room) - { - Id = room.Id; - PlayerMin = room.PlayerMin; - PlayerMax = room.PlayerMax; - PlayerCount = room.PlayerCount; - - Players = room.PlayerList.Select(p => new PlayerDto(p)).ToArray(); - } -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/RagonWebHookPlugin.cs b/Ragon.Server/Sources/Plugin/Web/RagonWebHookPlugin.cs deleted file mode 100644 index c1d6f4f..0000000 --- a/Ragon.Server/Sources/Plugin/Web/RagonWebHookPlugin.cs +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2023-2024 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System.Net; -using System.Net.Http.Json; -using System.Text; -using Newtonsoft.Json; -using Ragon.Protocol; -using Ragon.Server.Handler; -using Ragon.Server.Lobby; -using Ragon.Server.Room; - -namespace Ragon.Server.Plugin.Web; - -public class RagonWebHookPlugin -{ - private Dictionary _webHooks; - - private IRagonServer _server; - private HttpClient _httpClient; - - public RagonWebHookPlugin(IRagonServer server, RagonServerConfiguration configuration) - { - _webHooks = new Dictionary(configuration.WebHooks); - _httpClient = new HttpClient(); - _server = server; - } - - public bool RequestAuthorization(RagonContext context, string payload) - { - if (_webHooks.TryGetValue("authorization-request", out var value)) - { - var httpContent = new StringContent(payload, Encoding.UTF8, "application/json"); - var executor = context.Executor; - executor.Run(async () => - { - var authorizationOperation = (AuthorizationOperation) _server.ResolveHandler(RagonOperation.AUTHORIZE); - var response = await _httpClient.PostAsync(new Uri(value), httpContent); - if (response.StatusCode != HttpStatusCode.OK) - { - authorizationOperation.Reject(context); - return; - } - - var content = await response.Content.ReadAsStringAsync(); - var authorizationResponse = JsonConvert.DeserializeObject(content); - if (authorizationResponse != null) - { - var lobbyPlayer = new RagonLobbyPlayer(context.Connection, authorizationResponse.Id, authorizationResponse.Name, authorizationResponse.Payload); - - context.SetPlayer(lobbyPlayer); - authorizationOperation.Approve(context); - } - else - { - authorizationOperation.Reject(context); - } - }); - return true; - } - - return false; - } - - public void RoomCreated(RagonContext context, RagonRoom room, RagonRoomPlayer player) - { - if (_webHooks.TryGetValue("room-created", out var value) && !string.IsNullOrEmpty(value)) - { - var request = new RoomCreatedRequest() - { - Room = new RoomDto(room), - Player = new PlayerDto(player) - }; - var content = JsonContent.Create(request); - var executor = context.Executor; - executor.Run(() => _httpClient.PostAsync(new Uri(value), content, CancellationToken.None)); - } - } - - public void RoomRemoved(RagonContext context, RagonRoom ragonRoom) - { - if (_webHooks.TryGetValue("room-removed", out var value) && !string.IsNullOrEmpty(value)) - { - var request = new RoomRemovedRequest() - { - Room = new RoomDto(ragonRoom) - }; - var content = JsonContent.Create(request); - var executor = context.Executor; - executor.Run(() => _httpClient.PostAsync(new Uri(value), content, CancellationToken.None)); - } - } - - public void RoomJoined(RagonContext context, RagonRoom existsRoom, RagonRoomPlayer player) - { - if (_webHooks.TryGetValue("room-joined", out var value) && !string.IsNullOrEmpty(value)) - { - var request = new RoomJoinedRequest() - { - Room = new RoomDto(existsRoom), - Player = new PlayerDto(player) - }; - var content = JsonContent.Create(request); - var executor = context.Executor; - executor.Run(() => _httpClient.PostAsync(new Uri(value), content, CancellationToken.None)); - } - } - - public void RoomLeaved(RagonContext context, RagonRoom room, RagonRoomPlayer roomPlayer) - { - if (_webHooks.TryGetValue("room-leaved", out var value) && !string.IsNullOrEmpty(value)) - { - var request = new RoomLeavedRequest() - { - Room = new RoomDto(room), - Player = new PlayerDto(roomPlayer) - }; - var content = JsonContent.Create(request); - var executor = context.Executor; - executor.Run(() => _httpClient.PostAsync(new Uri(value), content, CancellationToken.None)); - } - } -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/Request/AuthorizationRequest.cs b/Ragon.Server/Sources/Plugin/Web/Request/AuthorizationRequest.cs deleted file mode 100644 index 66c89f0..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Request/AuthorizationRequest.cs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Ragon.Server.Plugin.Web; - -[Serializable] -public class AuthorizationRequest -{ - public string Name; - public string Token; -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/Request/RoomCreatedRequest.cs b/Ragon.Server/Sources/Plugin/Web/Request/RoomCreatedRequest.cs deleted file mode 100644 index e398551..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Request/RoomCreatedRequest.cs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Ragon.Server.Plugin.Web; - -[Serializable] -public class RoomCreatedRequest -{ - public RoomDto Room { get; set; } - public PlayerDto Player { get; set; } -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/Request/RoomJoinedRequest.cs b/Ragon.Server/Sources/Plugin/Web/Request/RoomJoinedRequest.cs deleted file mode 100644 index 420b387..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Request/RoomJoinedRequest.cs +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Ragon.Server.Plugin.Web; - -public class RoomJoinedRequest -{ - public RoomDto Room { get; set; } - public PlayerDto Player { get; set; } -} diff --git a/Ragon.Server/Sources/Plugin/Web/Request/RoomLeavedRequest.cs b/Ragon.Server/Sources/Plugin/Web/Request/RoomLeavedRequest.cs deleted file mode 100644 index 7914ed7..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Request/RoomLeavedRequest.cs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Ragon.Server.Plugin.Web; - -[Serializable] -public class RoomLeavedRequest -{ - public RoomDto Room { get; set; } - public PlayerDto Player { get; set; } -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/Request/RoomRemovedRequest.cs b/Ragon.Server/Sources/Plugin/Web/Request/RoomRemovedRequest.cs deleted file mode 100644 index 5d4af96..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Request/RoomRemovedRequest.cs +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -namespace Ragon.Server.Plugin.Web; - -[Serializable] -public class RoomRemovedRequest -{ - public RoomDto Room { get; set; } -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Plugin/Web/Response/AuthorizationResponse.cs b/Ragon.Server/Sources/Plugin/Web/Response/AuthorizationResponse.cs deleted file mode 100644 index 459ec53..0000000 --- a/Ragon.Server/Sources/Plugin/Web/Response/AuthorizationResponse.cs +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 Eduard Kargin - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace Ragon.Server.Plugin.Web; - -[Serializable] -public class AuthorizationResponse -{ - public string Id; - public string Name; - public string Payload; -} \ No newline at end of file diff --git a/Ragon.Server/Sources/RagonContext.cs b/Ragon.Server/Sources/RagonContext.cs index 245549c..aa168c2 100644 --- a/Ragon.Server/Sources/RagonContext.cs +++ b/Ragon.Server/Sources/RagonContext.cs @@ -26,8 +26,6 @@ public class RagonContext { public ConnectionStatus ConnectionStatus { get; set; } public INetworkConnection Connection { get; } - public IExecutor Executor { get; private set; } - public int LimitBufferedEvents { get; private set; } public IRagonLobby Lobby { get; private set; } public RagonLobbyPlayer? LobbyPlayer { get; private set; } public RagonRoom Room { get; private set; } @@ -35,9 +33,10 @@ public class RagonContext public RagonData UserData { get; private set; } public RagonScheduler Scheduler { get; private set; } + public int LimitBufferedEvents { get; private set; } + public RagonContext( INetworkConnection connection, - IExecutor executor, IRagonLobby lobby, RagonScheduler scheduler, int limitBufferedEvents) @@ -45,7 +44,6 @@ public class RagonContext ConnectionStatus = ConnectionStatus.Unauthorized; LimitBufferedEvents = limitBufferedEvents; Connection = connection; - Executor = executor; Lobby = lobby; Scheduler = scheduler; UserData = new RagonData(); diff --git a/Ragon.Server/Sources/RagonServer.cs b/Ragon.Server/Sources/RagonServer.cs index 465f0af..b759b4c 100644 --- a/Ragon.Server/Sources/RagonServer.cs +++ b/Ragon.Server/Sources/RagonServer.cs @@ -15,30 +15,27 @@ */ using System.Diagnostics; -using NLog; using Ragon.Protocol; using Ragon.Server.Handler; -using Ragon.Server.Http; using Ragon.Server.IO; using Ragon.Server.Lobby; +using Ragon.Server.Logging; using Ragon.Server.Plugin; -using Ragon.Server.Plugin.Web; using Ragon.Server.Time; namespace Ragon.Server; public class RagonServer : IRagonServer, INetworkListener { - private readonly Logger _logger = LogManager.GetCurrentClassLogger(); + private const string ServerVersion = "1.4.0"; + + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(RagonServer)); private readonly INetworkServer _server; private readonly BaseOperation[] _handlers; private readonly IRagonLobby _lobby; private readonly IServerPlugin _serverPlugin; private readonly Thread _dedicatedThread; - private readonly Executor _executor; private readonly RagonServerConfiguration _configuration; - private readonly RagonWebHookPlugin _webhooks; - private readonly RagonHttpServer _httpServer; private readonly RagonBuffer _reader; private readonly RagonBuffer _writer; private readonly RagonScheduler _scheduler; @@ -47,6 +44,9 @@ public class RagonServer : IRagonServer, INetworkListener private readonly Stopwatch _timer; private readonly RagonLobbyDispatcher _lobbySerializer; private readonly long _tickRate = 0; + private bool _isRunning = false; + + public bool IsRunning => _isRunning; public RagonServer( INetworkServer server, @@ -54,7 +54,6 @@ public class RagonServer : IRagonServer, INetworkListener RagonServerConfiguration configuration) { _server = server; - _executor = _server.Executor; _configuration = configuration; _serverPlugin = plugin; _contextsByConnection = new Dictionary(); @@ -62,10 +61,6 @@ public class RagonServer : IRagonServer, INetworkListener _lobby = new LobbyInMemory(); _lobbySerializer = new RagonLobbyDispatcher(_lobby); _scheduler = new RagonScheduler(); - _webhooks = new RagonWebHookPlugin(this, configuration); - _dedicatedThread = new Thread(Execute); - _dedicatedThread.IsBackground = true; - _httpServer = new RagonHttpServer(_executor, plugin); _reader = new RagonBuffer(); _writer = new RagonBuffer(); _tickRate = 1000 / _configuration.ServerTickRate; @@ -80,11 +75,11 @@ public class RagonServer : IRagonServer, INetworkListener _serverPlugin.OnAttached(this); _handlers = new BaseOperation[byte.MaxValue]; - _handlers[(byte)RagonOperation.AUTHORIZE] = new AuthorizationOperation(_reader, _writer, _webhooks, contextObserver, configuration); - _handlers[(byte)RagonOperation.JOIN_OR_CREATE_ROOM] = new RoomJoinOrCreateOperation(_reader, _writer, plugin, _webhooks); - _handlers[(byte)RagonOperation.CREATE_ROOM] = new RoomCreateOperation(_reader, _writer, plugin, _webhooks); - _handlers[(byte)RagonOperation.JOIN_ROOM] = new RoomJoinOperation(_reader, _writer, _webhooks); - _handlers[(byte)RagonOperation.LEAVE_ROOM] = new RoomLeaveOperation(_reader, _writer, _webhooks); + _handlers[(byte)RagonOperation.AUTHORIZE] = new AuthorizationOperation(_reader, _writer, _serverPlugin, contextObserver, configuration); + _handlers[(byte)RagonOperation.JOIN_OR_CREATE_ROOM] = new RoomJoinOrCreateOperation(_reader, _writer, plugin); + _handlers[(byte)RagonOperation.CREATE_ROOM] = new RoomCreateOperation(_reader, _writer, plugin); + _handlers[(byte)RagonOperation.JOIN_ROOM] = new RoomJoinOperation(_reader, _writer); + _handlers[(byte)RagonOperation.LEAVE_ROOM] = new RoomLeaveOperation(_reader, _writer); _handlers[(byte)RagonOperation.LOAD_SCENE] = new SceneLoadOperation(_reader, _writer); _handlers[(byte)RagonOperation.SCENE_LOADED] = new SceneLoadedOperation(_reader, _writer); _handlers[(byte)RagonOperation.CREATE_ENTITY] = new EntityCreateOperation(_reader, _writer); @@ -98,51 +93,43 @@ public class RagonServer : IRagonServer, INetworkListener _handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomDataOperation(_reader, _writer); _handlers[(byte)RagonOperation.ROOM_DATA_UPDATED] = new RoomUserDataOperation(_reader, _writer, _configuration.LimitUserData); _handlers[(byte)RagonOperation.PLAYER_DATA_UPDATED] = new PlayerUserDataOperation(_reader, _writer, _configuration.LimitUserData); - - _logger.Trace($"Server Tick Rate: {_configuration.ServerTickRate}"); } - - public void Execute() + public void Tick() { - _timer.Start(); - while (true) + if (_timer.ElapsedMilliseconds > _tickRate * 2) { - if (_timer.ElapsedMilliseconds > _tickRate * 2) - { - _logger.Warn($"Slow perfomance: {_timer.ElapsedMilliseconds}"); - } - - if (_timer.ElapsedMilliseconds > _tickRate) - { - _timer.Restart(); - _scheduler.Update(_tickRate); - - SendTimestamp(); - } - - _executor.Update(); - _server.Update(); - Thread.Sleep(1); + _logger.Warning($"Slow performance: {_timer.ElapsedMilliseconds}"); } + + if (_timer.ElapsedMilliseconds > _tickRate) + { + _timer.Restart(); + _scheduler.Update(_timer.ElapsedMilliseconds / 1000.0f); + + SendTimestamp(); + } + + _server.Update(); } public void Start(bool executeInDedicatedThread = false) { + CopyrightInfo(); + var networkConfiguration = new NetworkConfiguration() { LimitConnections = _configuration.LimitConnections, - Protocol = RagonVersion.Parse(_configuration.GameProtocol), + Protocol = RagonVersion.Parse(_configuration.Protocol), Address = "0.0.0.0", Port = _configuration.Port, }; - _httpServer.Start(_configuration); - _server.Start(this, networkConfiguration); + _server.Listen(this, networkConfiguration); + _serverPlugin.OnAttached(this); - if (executeInDedicatedThread) - _dedicatedThread.Start(); - else - Execute(); + _timer.Start(); + + _isRunning = true; } public void Dispose() @@ -154,7 +141,7 @@ public class RagonServer : IRagonServer, INetworkListener public void OnConnected(INetworkConnection connection) { - var context = new RagonContext(connection, _executor, _lobby, _scheduler, _configuration.LimitBufferedEvents); + var context = new RagonContext(connection, _lobby, _scheduler, _configuration.LimitBufferedEvents); _logger.Trace($"Connected: {connection.Id}"); _contextsByConnection.Add(connection.Id, context); @@ -168,8 +155,8 @@ public class RagonServer : IRagonServer, INetworkListener if (room != null) { room.DetachPlayer(context.RoomPlayer); - if (_lobby.RemoveIfEmpty(room)) - _webhooks.RoomRemoved(context, room); + + _lobby.RemoveIfEmpty(room); } _logger.Trace($"Disconnected: {connection.Id}"); @@ -297,4 +284,14 @@ public class RagonServer : IRagonServer, INetworkListener { return _contextsByPlayerId.TryGetValue(playerId, out var context) ? context.LobbyPlayer : null; } + + private void CopyrightInfo() + { + _logger.Info($"Ragon Server Version: {ServerVersion}"); + _logger.Info($"Machine Name: {Environment.MachineName}"); + _logger.Info($"OS: {Environment.OSVersion}"); + _logger.Info($"Processors: {Environment.ProcessorCount}"); + _logger.Info($"Runtime Version: {Environment.Version}"); + _logger.Info($"Server Tick Rate: {_configuration.ServerTickRate}"); + } } \ No newline at end of file diff --git a/Ragon.Server/Sources/RagonServerConfiguration.cs b/Ragon.Server/Sources/RagonServerConfiguration.cs index 3e1e3d2..67eb681 100644 --- a/Ragon.Server/Sources/RagonServerConfiguration.cs +++ b/Ragon.Server/Sources/RagonServerConfiguration.cs @@ -14,9 +14,6 @@ * limitations under the License. */ -using Newtonsoft.Json; -using NLog; - namespace Ragon.Server; public enum ServerType @@ -29,50 +26,20 @@ public enum ServerType public struct RagonServerConfiguration { public string ServerKey; - public string ServerType; public ushort ServerTickRate; - public string GameProtocol; + public string Protocol; public ushort Port; - public ushort HttpPort; - public string HttpKey; public int LimitConnections; public int LimitPlayersPerRoom; public int LimitRooms; public int LimitBufferedEvents; public int LimitUserData; - public Dictionary WebHooks; - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - private static readonly string ServerVersion = "1.3.2"; private static Dictionary _serverTypes = new Dictionary() { - {"enet", Server.ServerType.ENET}, - {"websocket", Server.ServerType.WEBSOCKET} + { "enet", Server.ServerType.ENET }, + { "websocket", Server.ServerType.WEBSOCKET } }; - - public static RagonServerConfiguration Load(string filePath) - { - CopyrightInfo(); - - var data = File.ReadAllText(filePath); - var configuration = JsonConvert.DeserializeObject(data); - return configuration; - } - - private static void CopyrightInfo() - { - Logger.Info($"Server Version: {ServerVersion}"); - Logger.Info($"Machine Name: {Environment.MachineName}"); - Logger.Info($"OS: {Environment.OSVersion}"); - Logger.Info($"Processors: {Environment.ProcessorCount}"); - Logger.Info($"Runtime Version: {Environment.Version}"); - Logger.Info("=================================="); - Logger.Info(@" ___ _ ___ ___ _ _ "); - Logger.Info(@" | _ \ /_\ / __|/ _ \| \| |"); - Logger.Info(@" | / / _ \ (_ | (_) | .` |"); - Logger.Info(@" |_|_\/_/ \_\___|\___/|_|\_|"); - Logger.Info("=================================="); - } - + public static ServerType GetServerType(string type) => _serverTypes[type]; } \ No newline at end of file