From 5bf1881f81ddd598dbbcc8bba7b7d749021c898e Mon Sep 17 00:00:00 2001 From: edmand46 Date: Tue, 7 May 2024 22:42:45 +0300 Subject: [PATCH] feat: room properties ready, player properties wip --- .../Sources/Handler/PlayerDataHandler.cs | 13 ----- .../Sources/Handler/PlayerUserDataHandler.cs | 32 ++++++++++ .../Sources/Handler/RoomDataHandler.cs | 58 +++++++++++++++---- .../Sources/Handler/RoomEventHandler.cs | 2 +- .../Sources/Handler/RoomRawDataHandler.cs | 56 ------------------ .../Sources/Handler/RoomUserDataHandler.cs | 22 +++++++ .../Sources/Listener/IRagonListener.cs | 5 +- .../Listener/IRagonPlayerUserDataListener.cs | 22 +++++++ .../Listener/IRagonRoomUserDataListener.cs | 6 ++ Ragon.Client/Sources/RagonClient.cs | 20 ++++++- Ragon.Client/Sources/RagonListenerList.cs | 24 ++++++++ Ragon.Client/Sources/RagonPlayer.cs | 8 +-- Ragon.Client/Sources/RagonRoom.cs | 40 ++++++++----- Ragon.Client/Sources/RagonUserData.cs | 54 +++++++++++++++++ Ragon.Protocol/Sources/RagonOperation.cs | 4 +- .../Sources/Handler/AuthorizationOperation.cs | 1 + ...ration.cs => PlayerPropertiesOperation.cs} | 10 ++-- .../Sources/Handler/RoomDataOperation.cs | 22 +++++-- ...peration.cs => RoomPropertiesOperation.cs} | 33 +++++------ Ragon.Server/Sources/RagonContext.cs | 2 - Ragon.Server/Sources/RagonServer.cs | 33 +++++++++-- Ragon.Server/Sources/Room/RagonRoom.cs | 15 +---- 22 files changed, 325 insertions(+), 157 deletions(-) delete mode 100644 Ragon.Client/Sources/Handler/PlayerDataHandler.cs create mode 100644 Ragon.Client/Sources/Handler/PlayerUserDataHandler.cs delete mode 100644 Ragon.Client/Sources/Handler/RoomRawDataHandler.cs create mode 100644 Ragon.Client/Sources/Handler/RoomUserDataHandler.cs create mode 100644 Ragon.Client/Sources/Listener/IRagonPlayerUserDataListener.cs create mode 100644 Ragon.Client/Sources/Listener/IRagonRoomUserDataListener.cs create mode 100644 Ragon.Client/Sources/RagonUserData.cs rename Ragon.Server/Sources/Handler/{PlayerDataOperation.cs => PlayerPropertiesOperation.cs} (68%) rename Ragon.Server/Sources/Handler/{RoomRawDataOperation.cs => RoomPropertiesOperation.cs} (57%) diff --git a/Ragon.Client/Sources/Handler/PlayerDataHandler.cs b/Ragon.Client/Sources/Handler/PlayerDataHandler.cs deleted file mode 100644 index 8031337..0000000 --- a/Ragon.Client/Sources/Handler/PlayerDataHandler.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ragon.Protocol; - -namespace Ragon.Client -{ - - public class PlayerDataHandler: IHandler - { - public void Handle(RagonBuffer reader) - { - - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Handler/PlayerUserDataHandler.cs b/Ragon.Client/Sources/Handler/PlayerUserDataHandler.cs new file mode 100644 index 0000000..4d96a20 --- /dev/null +++ b/Ragon.Client/Sources/Handler/PlayerUserDataHandler.cs @@ -0,0 +1,32 @@ +using Ragon.Protocol; + +namespace Ragon.Client +{ + + internal class PlayerUserDataHandler: IHandler + { + private RagonPlayerCache _playerCache; + private RagonListenerList _listenerList; + + public PlayerUserDataHandler( + RagonPlayerCache playerCache, + RagonListenerList listenerList + ) + { + _playerCache = playerCache; + _listenerList = listenerList; + } + public void Handle(RagonBuffer reader) + { + var playerPeerId = reader.ReadUShort(); + var player = _playerCache.GetPlayerByPeer(playerPeerId); + + if (player != null) + { + player.UserData.Read(reader); + + _listenerList.OnPlayerUserData(); + } + } + } +} \ No newline at end of file diff --git a/Ragon.Client/Sources/Handler/RoomDataHandler.cs b/Ragon.Client/Sources/Handler/RoomDataHandler.cs index f46a19e..21eb0c7 100644 --- a/Ragon.Client/Sources/Handler/RoomDataHandler.cs +++ b/Ragon.Client/Sources/Handler/RoomDataHandler.cs @@ -1,20 +1,56 @@ +/* + * 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.Protocol; -namespace Ragon.Client +namespace Ragon.Client; + +internal class RoomDataHandler: IHandler { - public class RoomDataHandler: IHandler + private readonly RagonListenerList _listeners; + private readonly RagonPlayerCache _playerCache; + + public RoomDataHandler( + RagonPlayerCache playerCache, + RagonListenerList listeners) { - private readonly RagonClient _client; - public RoomDataHandler(RagonClient client) + _playerCache = playerCache; + _listeners = listeners; + } + + public void Handle(RagonBuffer reader) + { + var rawData = reader.RawData; + var peerId = (ushort)(rawData[1] + (rawData[2] << 8)); + var player = _playerCache.GetPlayerByPeer(peerId); + + if (player == null) { - _client = client; + RagonLog.Error($"Player with peerId:{peerId} not found"); + + _playerCache.Dump(); + return; } - public void Handle(RagonBuffer reader) - { - var len = reader.ReadUShort(); - - _client.Room?.Data(reader); - } + var headerSize = 3; + var payload = new byte[rawData.Length - headerSize]; + + Array.Copy(rawData, headerSize, payload, 0, payload.Length); + + _listeners.OnData(player, payload); } } \ No newline at end of file diff --git a/Ragon.Client/Sources/Handler/RoomEventHandler.cs b/Ragon.Client/Sources/Handler/RoomEventHandler.cs index ff3b1a6..d3a7a6a 100644 --- a/Ragon.Client/Sources/Handler/RoomEventHandler.cs +++ b/Ragon.Client/Sources/Handler/RoomEventHandler.cs @@ -50,6 +50,6 @@ public class RoomEventHandler : IHandler if (player.IsLocal && executionMode == RagonReplicationMode.LocalAndServer) return; - _client.Room.Event(eventCode, player, buffer); + _client.Room.HandleEvent(eventCode, player, buffer); } } \ No newline at end of file diff --git a/Ragon.Client/Sources/Handler/RoomRawDataHandler.cs b/Ragon.Client/Sources/Handler/RoomRawDataHandler.cs deleted file mode 100644 index bb4ebe4..0000000 --- a/Ragon.Client/Sources/Handler/RoomRawDataHandler.cs +++ /dev/null @@ -1,56 +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.Protocol; - -namespace Ragon.Client; - -internal class RoomRawDataHandler: IHandler -{ - private readonly RagonListenerList _listeners; - private readonly RagonPlayerCache _playerCache; - - public RoomRawDataHandler( - RagonPlayerCache playerCache, - RagonListenerList listeners) - { - _playerCache = playerCache; - _listeners = listeners; - } - - public void Handle(RagonBuffer reader) - { - var rawData = reader.RawData; - var peerId = (ushort)(rawData[1] + (rawData[2] << 8)); - var player = _playerCache.GetPlayerByPeer(peerId); - - if (player == null) - { - RagonLog.Error($"Player with peerId:{peerId} not found"); - - _playerCache.Dump(); - return; - } - - var headerSize = 3; - var payload = new byte[rawData.Length - headerSize]; - - Array.Copy(rawData, headerSize, payload, 0, payload.Length); - - _listeners.OnData(player, payload); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Handler/RoomUserDataHandler.cs b/Ragon.Client/Sources/Handler/RoomUserDataHandler.cs new file mode 100644 index 0000000..7ae89eb --- /dev/null +++ b/Ragon.Client/Sources/Handler/RoomUserDataHandler.cs @@ -0,0 +1,22 @@ +using Ragon.Protocol; + +namespace Ragon.Client +{ + internal class RoomUserDataHandler: IHandler + { + private readonly RagonClient _client; + private readonly RagonListenerList _listenerList; + public RoomUserDataHandler(RagonClient client, RagonListenerList listenerList) + { + _client = client; + _listenerList = listenerList; + } + + public void Handle(RagonBuffer reader) + { + _client.Room?.HandleProperties(reader); + + _listenerList.OnRoomUserData(); + } + } +} \ No newline at end of file diff --git a/Ragon.Client/Sources/Listener/IRagonListener.cs b/Ragon.Client/Sources/Listener/IRagonListener.cs index 8b55a16..0a30589 100644 --- a/Ragon.Client/Sources/Listener/IRagonListener.cs +++ b/Ragon.Client/Sources/Listener/IRagonListener.cs @@ -25,7 +25,10 @@ namespace Ragon.Client IRagonSceneListener, IRagonOwnershipChangedListener, IRagonPlayerJoinListener, - IRagonPlayerLeftListener + IRagonPlayerLeftListener, + IRagonRoomListListener, + IRagonRoomUserDataListener, + IRagonPlayerUserDataListener { } diff --git a/Ragon.Client/Sources/Listener/IRagonPlayerUserDataListener.cs b/Ragon.Client/Sources/Listener/IRagonPlayerUserDataListener.cs new file mode 100644 index 0000000..a0d4f77 --- /dev/null +++ b/Ragon.Client/Sources/Listener/IRagonPlayerUserDataListener.cs @@ -0,0 +1,22 @@ +/* + * 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.Client; + +public interface IRagonPlayerUserDataListener +{ + void OnPlayerUserDataUpdated(RagonClient client, RagonPlayer player); +} \ No newline at end of file diff --git a/Ragon.Client/Sources/Listener/IRagonRoomUserDataListener.cs b/Ragon.Client/Sources/Listener/IRagonRoomUserDataListener.cs new file mode 100644 index 0000000..04b62bd --- /dev/null +++ b/Ragon.Client/Sources/Listener/IRagonRoomUserDataListener.cs @@ -0,0 +1,6 @@ +namespace Ragon.Client; + +public interface IRagonRoomUserDataListener +{ + public void OnUserDataUpdated(RagonClient client); +} \ No newline at end of file diff --git a/Ragon.Client/Sources/RagonClient.cs b/Ragon.Client/Sources/RagonClient.cs index c593c74..248d416 100644 --- a/Ragon.Client/Sources/RagonClient.cs +++ b/Ragon.Client/Sources/RagonClient.cs @@ -121,8 +121,9 @@ namespace Ragon.Client _handlers[(byte)RagonOperation.REPLICATE_ROOM_EVENT] = new RoomEventHandler(this, _playerCache); _handlers[(byte)RagonOperation.SNAPSHOT] = new SnapshotHandler(this, _listeners, _entityCache, _playerCache, _entityListener); _handlers[(byte)RagonOperation.TIMESTAMP_SYNCHRONIZATION] = new TimestampHandler(this); - _handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomRawDataHandler(_playerCache, _listeners); + _handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomDataHandler(_playerCache, _listeners); _handlers[(byte)RagonOperation.ROOM_LIST_UPDATED] = new RoomListHandler(_session, _listeners); + _handlers[(byte)RagonOperation.ROOM_PROPERTIES_UPDATED] = new RoomUserDataHandler(this, _listeners); var protocolRaw = RagonVersion.Parse(protocol); _connection.Connect(address, port, protocolRaw); @@ -148,6 +149,7 @@ namespace Ragon.Client _entityCache.WriteState(_writeBuffer); SendTimestamp(); + SendProperties(); } _stats.Update(_connection.BytesSent, _connection.BytesReceived, _connection.Ping, dt); @@ -231,6 +233,22 @@ namespace Ragon.Client _writeBuffer.Write(value.Int0, 32); _writeBuffer.Write(value.Int1, 32); } + + private void SendProperties() + { + if (_room == null) return; + + var props = _room.UserData; + if (!props.Dirty) return; + + _writeBuffer.Clear(); + _writeBuffer.WriteOperation(RagonOperation.ROOM_PROPERTIES_UPDATED); + + _room.UserData.Write(_writeBuffer); + + var sendData = _writeBuffer.ToArray(); + _connection.Reliable.Send(sendData); + } private void OnConnected() { diff --git a/Ragon.Client/Sources/RagonListenerList.cs b/Ragon.Client/Sources/RagonListenerList.cs index c7c6053..8bfe7b3 100644 --- a/Ragon.Client/Sources/RagonListenerList.cs +++ b/Ragon.Client/Sources/RagonListenerList.cs @@ -33,6 +33,7 @@ namespace Ragon.Client private readonly List _playerLeftListeners = new(); private readonly List _dataListeners = new(); private readonly List _roomListListeners = new(); + private readonly List _roomUserDataListeners = new(); private readonly List _delayedActions = new(); public RagonListenerList(RagonClient client) @@ -51,6 +52,7 @@ namespace Ragon.Client _ownershipChangedListeners.Add(listener); _playerJoinListeners.Add(listener); _playerLeftListeners.Add(listener); + _roomUserDataListeners.Add(listener); } public void Remove(IRagonListener listener) @@ -66,6 +68,7 @@ namespace Ragon.Client _ownershipChangedListeners.Remove(listener); _playerJoinListeners.Remove(listener); _playerLeftListeners.Remove(listener); + _roomUserDataListeners.Remove(listener); }); } @@ -137,6 +140,11 @@ namespace Ragon.Client _roomListListeners.Add(listener); } + public void Add(IRagonRoomUserDataListener listener) + { + _roomUserDataListeners.Add(listener); + } + public void Remove(IRagonDataListener listener) { _delayedActions.Add(() => _dataListeners.Remove(listener)); @@ -197,6 +205,11 @@ namespace Ragon.Client _delayedActions.Add(() => _roomListListeners.Remove(listener)); } + public void Remove(IRagonRoomUserDataListener listener) + { + _delayedActions.Add(() => _roomUserDataListeners.Remove(listener)); + } + public void OnAuthorizationSuccess(string playerId, string playerName, string payload) { foreach (var listener in _authorizationListeners) @@ -280,5 +293,16 @@ namespace Ragon.Client foreach (var listListener in _roomListListeners) listListener.OnRoomListUpdate(roomInfos); } + + public void OnRoomUserData() + { + foreach (var userDataListener in _roomUserDataListeners) + userDataListener.OnUserDataUpdated(_client); + } + + public void OnPlayerUserData() + { + + } } } \ No newline at end of file diff --git a/Ragon.Client/Sources/RagonPlayer.cs b/Ragon.Client/Sources/RagonPlayer.cs index 023d467..f1cf3da 100644 --- a/Ragon.Client/Sources/RagonPlayer.cs +++ b/Ragon.Client/Sources/RagonPlayer.cs @@ -26,7 +26,7 @@ namespace Ragon.Client public ushort PeerId { get; set; } public bool IsRoomOwner { get; set; } public bool IsLocal { get; set; } - public byte[] Data { get; private set; } + public RagonUserData UserData { get; private set; } public RagonPlayer(ushort peerId, string playerId, string name, bool isRoomOwner, bool isLocal) { @@ -35,11 +35,7 @@ namespace Ragon.Client IsLocal = isLocal; Name = name; Id = playerId; - } - - public void SetData(byte[] data) - { - Data = data; + UserData = new RagonUserData(); } } } \ No newline at end of file diff --git a/Ragon.Client/Sources/RagonRoom.cs b/Ragon.Client/Sources/RagonRoom.cs index ef1806f..1a5a0ac 100644 --- a/Ragon.Client/Sources/RagonRoom.cs +++ b/Ragon.Client/Sources/RagonRoom.cs @@ -18,7 +18,7 @@ using Ragon.Protocol; namespace Ragon.Client { - public class RagonRoom: IDisposable + public class RagonRoom : IDisposable { private class EventSubscription : IDisposable { @@ -46,7 +46,7 @@ namespace Ragon.Client _callback = null!; } } - + private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer); private readonly RagonClient _client; @@ -54,20 +54,25 @@ namespace Ragon.Client private readonly RagonEntityCache _entityCache; private readonly RagonPlayerCache _playerCache; private readonly RoomParameters _parameters; - private readonly Dictionary _properties = new(); - + private readonly RagonUserData _userData; + public string Id => _parameters.RoomId; public int MinPlayers => _parameters.Min; public int MaxPlayers => _parameters.Max; public string Scene => _scene.Name; - + public IReadOnlyList Players => _playerCache.Players; public RagonPlayer Local => _playerCache.Local; public RagonPlayer Owner => _playerCache.Owner; + public RagonUserData UserData => _userData; private readonly Dictionary _events = new Dictionary(); - private readonly Dictionary>> _localListeners = new Dictionary>>(); - private readonly Dictionary>> _listeners = new Dictionary>>(); + + private readonly Dictionary>> _localListeners = + new Dictionary>>(); + + private readonly Dictionary>> _listeners = + new Dictionary>>(); public RagonRoom(RagonClient client, RagonEntityCache entityCache, @@ -80,6 +85,7 @@ namespace Ragon.Client _entityCache = entityCache; _playerCache = playerCache; _scene = scene; + _userData = new RagonUserData(); } internal void Cleanup() @@ -93,7 +99,7 @@ namespace Ragon.Client _scene.Update(sceneName); } - internal void Event(ushort eventCode, RagonPlayer caller, RagonBuffer buffer) + internal void HandleEvent(ushort eventCode, RagonPlayer caller, RagonBuffer buffer) { if (_events.TryGetValue(eventCode, out var evnt)) evnt?.Invoke(caller, buffer); @@ -101,23 +107,23 @@ namespace Ragon.Client RagonLog.Warn($"Handler event on entity {Id} with eventCode {eventCode} not defined"); } - internal void Data(RagonBuffer buffer) + internal void HandleProperties(RagonBuffer buffer) { - + _userData.Read(buffer); } - + public IDisposable OnEvent(Action callback) where TEvent : IRagonEvent, new() { var t = new TEvent(); var eventCode = _client.Event.GetEventCode(t); var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData); - + if (!_listeners.TryGetValue(eventCode, out var callbacks)) { callbacks = new List>(); _listeners.Add(eventCode, callbacks); } - + if (!_localListeners.TryGetValue(eventCode, out var localCallbacks)) { localCallbacks = new List>(); @@ -144,8 +150,12 @@ namespace Ragon.Client public void LoadScene(string sceneName) => _scene.Load(sceneName); public void SceneLoaded() => _scene.SceneLoaded(); - public void ReplicateEvent(TEvent evnt, RagonTarget target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); - public void ReplicateEvent(TEvent evnt, RagonPlayer target, RagonReplicationMode mode) where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); + public void ReplicateEvent(TEvent evnt, RagonTarget target, RagonReplicationMode mode) + where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); + + public void ReplicateEvent(TEvent evnt, RagonPlayer target, RagonReplicationMode mode) + where TEvent : IRagonEvent, new() => _scene.ReplicateEvent(evnt, target, mode); + public void ReplicateData(byte[] data, bool reliable = false) => _scene.ReplicateData(data, reliable); public void CreateEntity(RagonEntity entity) => CreateEntity(entity, null); diff --git a/Ragon.Client/Sources/RagonUserData.cs b/Ragon.Client/Sources/RagonUserData.cs new file mode 100644 index 0000000..44ca2d6 --- /dev/null +++ b/Ragon.Client/Sources/RagonUserData.cs @@ -0,0 +1,54 @@ +using Ragon.Protocol; + +namespace Ragon.Client +{ + public class RagonUserData + { + public byte[] this[string key] + { + get => _properties[key]; + set + { + _properties[key] = value; + + _dirty = true; + } + } + public bool Dirty => _dirty; + + private bool _dirty = false; + private readonly Dictionary _properties = new(); + + public RagonUserData() + { + } + + internal void Read(RagonBuffer buffer) + { + _properties.Clear(); + + var len = buffer.ReadUShort(); + for (int i = 0; i < len; i++) + { + var key = buffer.ReadString(); + var valueSize = buffer.ReadUShort(); + var value = buffer.ReadBytes(valueSize); + + _properties[key] = value; + } + } + + internal void Write(RagonBuffer buffer) + { + buffer.WriteUShort((ushort)_properties.Count); + foreach (var property in _properties) + { + buffer.WriteString(property.Key); + buffer.WriteUShort((ushort) property.Value.Length); + buffer.WriteBytes(property.Value); + } + + _dirty = false; + } + } +} \ No newline at end of file diff --git a/Ragon.Protocol/Sources/RagonOperation.cs b/Ragon.Protocol/Sources/RagonOperation.cs index f5a9960..2efbeae 100644 --- a/Ragon.Protocol/Sources/RagonOperation.cs +++ b/Ragon.Protocol/Sources/RagonOperation.cs @@ -45,7 +45,7 @@ namespace Ragon.Protocol TRANSFER_ENTITY_OWNERSHIP = 24, TIMESTAMP_SYNCHRONIZATION = 25, ROOM_LIST_UPDATED = 26, - PLAYER_DATA_UPDATED = 27, - ROOM_DATA_UPDATED = 28, + PLAYER_PROPERTIES_UPDATED = 27, + ROOM_PROPERTIES_UPDATED = 28, } } \ No newline at end of file diff --git a/Ragon.Server/Sources/Handler/AuthorizationOperation.cs b/Ragon.Server/Sources/Handler/AuthorizationOperation.cs index 791944f..4bd37f3 100644 --- a/Ragon.Server/Sources/Handler/AuthorizationOperation.cs +++ b/Ragon.Server/Sources/Handler/AuthorizationOperation.cs @@ -41,6 +41,7 @@ public sealed class AuthorizationOperation: BaseOperation _webhook = webhook; _observer = observer; _writer = writer; + _configuration = configuration; } public override void Handle(RagonContext context, NetworkChannel channel) diff --git a/Ragon.Server/Sources/Handler/PlayerDataOperation.cs b/Ragon.Server/Sources/Handler/PlayerPropertiesOperation.cs similarity index 68% rename from Ragon.Server/Sources/Handler/PlayerDataOperation.cs rename to Ragon.Server/Sources/Handler/PlayerPropertiesOperation.cs index b9229b6..32b055b 100644 --- a/Ragon.Server/Sources/Handler/PlayerDataOperation.cs +++ b/Ragon.Server/Sources/Handler/PlayerPropertiesOperation.cs @@ -5,11 +5,11 @@ using Ragon.Server.Lobby; namespace Ragon.Server.Handler { - public class PlayerDataOperation : BaseOperation + public class PlayerPropertiesOperation : BaseOperation { private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); - public PlayerDataOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) + public PlayerPropertiesOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { } @@ -20,10 +20,8 @@ namespace Ragon.Server.Handler _logger.Warn($"Player {context.Connection.Id} not authorized for this request"); return; } - - var playerDataLen = Reader.ReadUShort(); - var playerData = Reader.ReadBytes(playerDataLen); - + + var playerData = Reader.ReadBytes(Reader.Capacity); context.UserData.Data = playerData; } } diff --git a/Ragon.Server/Sources/Handler/RoomDataOperation.cs b/Ragon.Server/Sources/Handler/RoomDataOperation.cs index 4efc960..9d35986 100644 --- a/Ragon.Server/Sources/Handler/RoomDataOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomDataOperation.cs @@ -14,6 +14,7 @@ * limitations under the License. */ +using NLog; using Ragon.Protocol; using Ragon.Server.IO; @@ -27,11 +28,22 @@ public sealed class RoomDataOperation : BaseOperation public override void Handle(RagonContext context, NetworkChannel channel) { - var playerDataLen = Reader.ReadUShort(); - var playerData = Reader.ReadBytes(playerDataLen); - + var player = context.RoomPlayer; var room = context.Room; - if (room != null) - room.UserData.Data = playerData; + + var data = Reader.RawData; + var dataSize = data.Length - 1; + var headerSize = 3; + var size = headerSize + dataSize; + var sendData = new byte[size]; + var peerId = player.Connection.Id; + + sendData[0] = (byte)RagonOperation.REPLICATE_RAW_DATA; + sendData[1] = (byte)peerId; + sendData[2] = (byte)(peerId >> 8); + + Array.Copy(data, 1, sendData, headerSize, dataSize); + + room.Broadcast(sendData, channel); } } \ No newline at end of file diff --git a/Ragon.Server/Sources/Handler/RoomRawDataOperation.cs b/Ragon.Server/Sources/Handler/RoomPropertiesOperation.cs similarity index 57% rename from Ragon.Server/Sources/Handler/RoomRawDataOperation.cs rename to Ragon.Server/Sources/Handler/RoomPropertiesOperation.cs index 134c89b..c1b3119 100644 --- a/Ragon.Server/Sources/Handler/RoomRawDataOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomPropertiesOperation.cs @@ -17,33 +17,30 @@ using NLog; using Ragon.Protocol; using Ragon.Server.IO; +using Ragon.Server.Lobby; namespace Ragon.Server.Handler; -public sealed class RoomRawDataOperation : BaseOperation +public sealed class RoomPropertiesOperation : BaseOperation { - public RoomRawDataOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) + private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); + + public RoomPropertiesOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) { } public override void Handle(RagonContext context, NetworkChannel channel) { - var player = context.RoomPlayer; + if (context.ConnectionStatus == ConnectionStatus.Unauthorized) + { + _logger.Warn($"Player {context.Connection.Id} not authorized for this request"); + return; + } + + var roomData = Reader.ReadBytes(Reader.Capacity); + var room = context.Room; - - var data = Reader.RawData; - var dataSize = data.Length - 1; - var headerSize = 3; - var size = headerSize + dataSize; - var sendData = new byte[size]; - var peerId = player.Connection.Id; - - sendData[0] = (byte)RagonOperation.REPLICATE_RAW_DATA; - sendData[1] = (byte)peerId; - sendData[2] = (byte)(peerId >> 8); - - Array.Copy(data, 1, sendData, headerSize, dataSize); - - room.Broadcast(sendData, channel); + if (room != null) + room.UserData.Data = roomData; } } \ No newline at end of file diff --git a/Ragon.Server/Sources/RagonContext.cs b/Ragon.Server/Sources/RagonContext.cs index 3559002..26a60c3 100644 --- a/Ragon.Server/Sources/RagonContext.cs +++ b/Ragon.Server/Sources/RagonContext.cs @@ -32,9 +32,7 @@ public class RagonContext public RagonLobbyPlayer? LobbyPlayer { get; private set; } public RagonRoom? Room { get; private set; } public RagonRoomPlayer? RoomPlayer { get; private set; } - public RagonData UserData { get; private set; } - public RagonScheduler Scheduler { get; private set; } public RagonContext( diff --git a/Ragon.Server/Sources/RagonServer.cs b/Ragon.Server/Sources/RagonServer.cs index f387552..68f877f 100644 --- a/Ragon.Server/Sources/RagonServer.cs +++ b/Ragon.Server/Sources/RagonServer.cs @@ -74,7 +74,8 @@ public class RagonServer : IRagonServer, INetworkListener var contextObserver = new RagonContextObserver(_contextsByPlayerId); _scheduler.Run(new RagonActionTimer(SendRoomList, 1.0f)); - _scheduler.Run(new RagonActionTimer(SendUserData, 0.2f)); + _scheduler.Run(new RagonActionTimer(SendPlayerProperties, 1.0f)); + _scheduler.Run(new RagonActionTimer(SendRoomProperties, 1.0f)); _serverPlugin.OnAttached(this); @@ -94,9 +95,9 @@ public class RagonServer : IRagonServer, INetworkListener _handlers[(byte)RagonOperation.TRANSFER_ENTITY_OWNERSHIP] = new EntityOwnershipOperation(_reader, _writer); _handlers[(byte)RagonOperation.TIMESTAMP_SYNCHRONIZATION] = new TimestampSyncOperation(_reader, _writer); _handlers[(byte)RagonOperation.REPLICATE_ROOM_EVENT] = new RoomEventOperation(_reader, _writer); - _handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomRawDataOperation(_reader, _writer); - _handlers[(byte)RagonOperation.ROOM_DATA_UPDATED] = new RoomDataOperation(_reader, _writer); - _handlers[(byte)RagonOperation.PLAYER_DATA_UPDATED] = new PlayerDataOperation(_reader, _writer); + _handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomDataOperation(_reader, _writer); + _handlers[(byte)RagonOperation.ROOM_PROPERTIES_UPDATED] = new RoomPropertiesOperation(_reader, _writer); + _handlers[(byte)RagonOperation.PLAYER_PROPERTIES_UPDATED] = new PlayerPropertiesOperation(_reader, _writer); _logger.Trace($"Server Tick Rate: {_configuration.ServerTickRate}"); } @@ -247,19 +248,39 @@ public class RagonServer : IRagonServer, INetworkListener } } - public void SendUserData() + public void SendPlayerProperties() { foreach (var (_, value) in _contextsByPlayerId) { if (value.UserData.IsDirty) { _writer.Clear(); - _writer.WriteOperation(RagonOperation.PLAYER_DATA_UPDATED); + _writer.WriteOperation(RagonOperation.PLAYER_PROPERTIES_UPDATED); _writer.WriteUShort(value.Connection.Id); _writer.WriteBytes(value.UserData.Data); var sendData = _writer.ToArray(); _server.Broadcast(sendData, NetworkChannel.RELIABLE); + + value.UserData.IsDirty = false; + } + } + } + + public void SendRoomProperties() + { + foreach (var room in _lobby.Rooms) + { + if (room.UserData.IsDirty) + { + _writer.Clear(); + _writer.WriteOperation(RagonOperation.ROOM_PROPERTIES_UPDATED); + _writer.WriteBytes(room.UserData.Data); + + var sendData = _writer.ToArray(); + _server.Broadcast(sendData, NetworkChannel.RELIABLE); + + room.UserData.IsDirty = false; } } } diff --git a/Ragon.Server/Sources/Room/RagonRoom.cs b/Ragon.Server/Sources/Room/RagonRoom.cs index 7a5ea9a..1ab0399 100644 --- a/Ragon.Server/Sources/Room/RagonRoom.cs +++ b/Ragon.Server/Sources/Room/RagonRoom.cs @@ -68,6 +68,7 @@ public class RagonRoom : IRagonRoom, IRagonAction _entitiesDirtySet = new HashSet(); + UserData = new RagonData(Array.Empty()); Writer = new RagonBuffer(); } @@ -110,20 +111,6 @@ public class RagonRoom : IRagonRoom, IRagonAction foreach (var roomPlayer in ReadyPlayersList) roomPlayer.Connection.Unreliable.Send(sendData); } - - if (UserData.IsDirty) - { - Writer.Clear(); - Writer.WriteOperation(RagonOperation.ROOM_DATA_UPDATED); - Writer.WriteUShort((ushort)UserData.Data.Length); - Writer.WriteBytes(UserData.Data); - - var sendData = Writer.ToArray(); - foreach (var roomPlayer in ReadyPlayersList) - roomPlayer.Connection.Reliable.Send(sendData); - - UserData.IsDirty = false; - } } public void AttachPlayer(RagonRoomPlayer player)