From 16b8d3a062d9847efa23eee8d1579018cc3f4203 Mon Sep 17 00:00:00 2001 From: Edmand46 Date: Sat, 30 Jul 2022 14:07:48 +0400 Subject: [PATCH] feat: replication level --- Ragon.Common/Protocol/RagonOperation.cs | 1 + Ragon/Sources/Game/GameRoom.cs | 41 +++++++--------- Ragon/Sources/Game/GameThread.cs | 21 ++++---- Ragon/Sources/Lobby/Lobby.cs | 64 +++++++++++++++++-------- Ragon/Sources/Room/RoomManager.cs | 16 +++++++ 5 files changed, 86 insertions(+), 57 deletions(-) diff --git a/Ragon.Common/Protocol/RagonOperation.cs b/Ragon.Common/Protocol/RagonOperation.cs index d486d5c..adc1480 100644 --- a/Ragon.Common/Protocol/RagonOperation.cs +++ b/Ragon.Common/Protocol/RagonOperation.cs @@ -7,6 +7,7 @@ namespace Ragon.Common AUTHORIZED_FAILED, JOIN_OR_CREATE_ROOM, + CREATE_ROOM, JOIN_ROOM, LEAVE_ROOM, OWNERSHIP_CHANGED, diff --git a/Ragon/Sources/Game/GameRoom.cs b/Ragon/Sources/Game/GameRoom.cs index 9b9a50f..318bb2a 100755 --- a/Ragon/Sources/Game/GameRoom.cs +++ b/Ragon/Sources/Game/GameRoom.cs @@ -94,8 +94,6 @@ namespace Ragon.Core _allPlayers = _players.Select(p => p.Key).ToArray(); _readyPlayers = _players.Where(p => p.Value.IsLoaded).Select(p => p.Key).ToArray(); - var isOwnershipChange = player.PeerId == _owner; - { _plugin.OnPlayerLeaved(player); @@ -114,34 +112,12 @@ namespace Ragon.Core Broadcast(_readyPlayers, sendData); } - if (_allPlayers.Length > 0 && isOwnershipChange) - { - var newRoomOwnerId = _allPlayers[0]; - var newRoomOwner = _players[newRoomOwnerId]; - - _owner = newRoomOwnerId; - - { - _plugin.OnOwnershipChanged(newRoomOwner); - - _serializer.Clear(); - _serializer.WriteOperation(RagonOperation.OWNERSHIP_CHANGED); - _serializer.WriteString(newRoomOwner.Id); - - var sendData = _serializer.ToArray(); - Broadcast(_readyPlayers, sendData); - } - } - _entitiesAll = _entities.Values.ToArray(); } } - public void ProcessEvent(uint peerId, ReadOnlySpan rawData) + public void ProcessEvent(uint peerId, RagonOperation operation, ReadOnlySpan payloadRawData) { - var operation = (RagonOperation) rawData[0]; - var payloadRawData = rawData.Slice(1, rawData.Length - 1); - _serializer.Clear(); _serializer.FromSpan(ref payloadRawData); @@ -193,6 +169,21 @@ namespace Ragon.Core Broadcast(_readyPlayers, sendData, DeliveryType.Reliable); break; } + case RagonOperation.LOAD_SCENE: + { + var sceneName = _serializer.ReadString(); + _readyPlayers = Array.Empty(); + _entitiesAll = Array.Empty(); + _entities.Clear(); + + _serializer.Clear(); + _serializer.WriteOperation(RagonOperation.LOAD_SCENE); + _serializer.WriteString(sceneName); + + var sendData = _serializer.ToArray(); + Broadcast(_allPlayers, sendData, DeliveryType.Reliable); + break; + } case RagonOperation.REPLICATE_EVENT: { var evntId = _serializer.ReadUShort(); diff --git a/Ragon/Sources/Game/GameThread.cs b/Ragon/Sources/Game/GameThread.cs index 7ea3d6a..e718a6f 100755 --- a/Ragon/Sources/Game/GameThread.cs +++ b/Ragon/Sources/Game/GameThread.cs @@ -1,7 +1,7 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Threading; +using Ragon.Common; using ENet; using NLog; @@ -29,10 +29,10 @@ namespace Ragon.Core var authorizationProvider = factory.CreateAuthorizationProvider(configuration); var dispatcher = new Dispatcher(); _dispatcherInternal = dispatcher; - + ThreadDispatcher = dispatcher; Server = new ENetServer(this); - + _deltaTime = 1000.0f / configuration.SendRate; _roomManager = new RoomManager(factory, this); @@ -69,7 +69,7 @@ namespace Ragon.Core while (true) { Server.Process(); - + _dispatcherInternal.Process(); var elapsedMilliseconds = _gameLoopTimer.ElapsedMilliseconds; @@ -109,14 +109,13 @@ namespace Ragon.Core evnt.Packet.CopyTo(dataRaw); var data = new ReadOnlySpan(dataRaw); + var operation = (RagonOperation) data[0]; + var payload = data.Slice(1, data.Length - 1); + if (_roomManager.RoomsBySocket.TryGetValue(peerId, out var room)) - { - room.ProcessEvent(peerId, data); - } - else - { - _lobby.ProcessEvent(peerId, data); - } + room.ProcessEvent(peerId, operation, payload); + + _lobby.ProcessEvent(peerId, operation, payload); } catch (Exception exception) { diff --git a/Ragon/Sources/Lobby/Lobby.cs b/Ragon/Sources/Lobby/Lobby.cs index 618c7f8..7f610fd 100644 --- a/Ragon/Sources/Lobby/Lobby.cs +++ b/Ragon/Sources/Lobby/Lobby.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using NLog; using Ragon.Common; namespace Ragon.Core; public class Lobby : ILobby { + private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); private readonly RagonSerializer _serializer; private readonly RoomManager _roomManager; private readonly AuthorizationManager _authorizationManager; @@ -19,30 +21,50 @@ public class Lobby : ILobby _authorizationManager = new AuthorizationManager(provider, gameThread, this, _serializer); } - public void ProcessEvent(uint peerId, ReadOnlySpan data) + public void ProcessEvent(uint peerId, RagonOperation op, ReadOnlySpan payload) { - var op = (RagonOperation) data[0]; - var payload = data.Slice(1, data.Length - 1); - _serializer.Clear(); _serializer.FromSpan(ref payload); + if (op == RagonOperation.AUTHORIZE) + { + var key = _serializer.ReadString(); + var playerName = _serializer.ReadString(); + var protocol = _serializer.ReadByte(); + _authorizationManager.OnAuthorization(peerId, key, playerName, protocol); + return; + } + + var player = _authorizationManager.GetPlayer(peerId); + if (player == null) + { + _logger.Warn($"Peer not authorized {peerId} trying to {op}"); + return; + } + switch (op) { - case RagonOperation.AUTHORIZE: - { - var key = _serializer.ReadString(); - var playerName = _serializer.ReadString(); - var protocol = _serializer.ReadByte(); - _authorizationManager.OnAuthorization(peerId, key, playerName, protocol); - break; - } case RagonOperation.JOIN_ROOM: { var roomId = _serializer.ReadString(); - var player = _authorizationManager.GetPlayer(peerId); - if (player != null) - _roomManager.Join(player, roomId, Array.Empty()); + + if (_roomManager.RoomsBySocket.ContainsKey(peerId)) + _roomManager.Left(player, Array.Empty()); + + _roomManager.Join(player, roomId, Array.Empty()); + + break; + } + case RagonOperation.CREATE_ROOM: + { + var min = _serializer.ReadUShort(); + var max = _serializer.ReadUShort(); + var map = _serializer.ReadString(); + + if (_roomManager.RoomsBySocket.ContainsKey(peerId)) + _roomManager.Left(player, Array.Empty()); + + _roomManager.Create(player, map, min, max, Array.Empty()); break; } case RagonOperation.JOIN_OR_CREATE_ROOM: @@ -50,16 +72,16 @@ public class Lobby : ILobby var min = _serializer.ReadUShort(); var max = _serializer.ReadUShort(); var map = _serializer.ReadString(); - var player = _authorizationManager.GetPlayer(peerId); - if (player != null) - _roomManager.JoinOrCreate(player, map, min, max, Array.Empty()); + + if (_roomManager.RoomsBySocket.ContainsKey(peerId)) + _roomManager.Left(player, Array.Empty()); + + _roomManager.JoinOrCreate(player, map, min, max, Array.Empty()); break; } case RagonOperation.LEAVE_ROOM: { - var player = _authorizationManager.GetPlayer(peerId); - if (player != null) - _roomManager.Left(player, Array.Empty()); + _roomManager.Left(player, Array.Empty()); break; } } diff --git a/Ragon/Sources/Room/RoomManager.cs b/Ragon/Sources/Room/RoomManager.cs index c35144c..dd4e385 100644 --- a/Ragon/Sources/Room/RoomManager.cs +++ b/Ragon/Sources/Room/RoomManager.cs @@ -40,6 +40,20 @@ public class RoomManager } } + public void Create(Player player, string map, int min, int max, byte[] payload) + { + var plugin = _factory.CreatePlugin(map); + if (plugin == null) + throw new NullReferenceException($"Plugin for map {map} is null"); + + var room = new GameRoom(_gameThread, plugin, map, min, max); + room.Joined(player, payload); + room.Start(); + + _roomsBySocket.Add(player.PeerId, room); + _rooms.Add(room); + } + public void JoinOrCreate(Player player, string map, int min, int max, byte[] payload) { if (_rooms.Count > 0) @@ -77,6 +91,8 @@ public class RoomManager room.Stop(); _rooms.Remove(room); } + + _gameThread.Server.Send(player.PeerId, new byte[] { (byte) RagonOperation.LEAVE_ROOM }, DeliveryType.Reliable); } }