From edf90b39c44c1ffc5afc4d83a57c9b8de00c1076 Mon Sep 17 00:00:00 2001 From: edmand46 Date: Sun, 3 Nov 2024 11:36:58 +0300 Subject: [PATCH] wip --- .../Ragon.Client.Property.csproj | 13 - Ragon.Client.Property/Sources/RagonBool.cs | 61 ---- Ragon.Client.Property/Sources/RagonFloat.cs | 105 ------ Ragon.Client.Property/Sources/RagonInt.cs | 88 ----- .../Sources/RagonQuaternion.cs | 77 ---- Ragon.Client.Property/Sources/RagonString.cs | 69 ---- Ragon.Client.Property/Sources/RagonVector3.cs | 331 ------------------ Ragon.Client/Ragon.Client.csproj | 1 + .../Sources/Handler/PlayerLeftHandler.cs | 1 + Ragon.Client/Sources/RagonClient.cs | 4 +- Ragon.Client/Sources/RagonEventCache.cs | 2 + .../Replication/Compressor/Extensions.cs | 27 -- .../Replication/Compressor/FloatCompressor.cs | 57 --- .../Replication/Compressor/IntCompressor.cs | 44 --- .../Sources/Replication/Entity/RagonEntity.cs | 310 ---------------- .../Replication/Entity/RagonEntityState.cs | 77 ---- .../Replication/Entity/RagonPayload.cs | 49 --- .../Replication/Entity/RagonProperty.cs | 146 -------- .../Handler/EntityCreateHandler.cs | 69 ---- .../Replication/Handler/EntityEventHandler.cs | 56 --- .../Handler/EntityOwnershipHandler.cs | 60 ---- .../Handler/EntityRemoveHandler.cs | 39 --- .../Replication/Handler/EntityStateHandler.cs | 39 --- .../Replication/Handler/LoadSceneHandler.cs | 45 --- .../Replication/Handler/SnapshotHandler.cs | 116 ------ .../Replication/IRagonEntityListener.cs | 22 -- .../Sources/Replication/IRagonPayload.cs | 26 -- .../Replication/IRagonSceneCollector.cs | 22 -- .../Sources/Replication/RagonEntityCache.cs | 257 -------------- .../Sources/Replication/RagonScene.cs | 119 ------- Ragon.Relay/Ragon.Relay.csproj | 3 +- .../Sources/Command/KickPlayerCommand.cs | 6 - Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs | 15 - .../Sources/Plugin/RelayServerPlugin.cs | 14 - Ragon.Relay/Sources/Relay.cs | 5 +- .../Replication/Entity/IRagonEntity.cs | 16 - .../Replication/Entity/IRagonEntityState.cs | 8 - .../Sources/Replication/Entity/RagonEntity.cs | 246 ------------- .../Replication/Entity/RagonEntityCache.cs | 53 --- .../Entity/RagonEntityParameters.cs | 28 -- .../Replication/Entity/RagonEntityState.cs | 78 ----- .../Replication/Entity/RagonPayload.cs | 40 --- .../Replication/Entity/RagonProperty.cs | 78 ----- .../Handler/EntityCreateOperation.cs | 80 ----- .../Handler/EntityEventOperation.cs | 63 ---- .../Handler/EntityOwnershipOperation.cs | 75 ---- .../Handler/EntityRemoveOperation.cs | 55 --- .../Handler/EntityStateOperation.cs | 50 --- .../Replication/Handler/SceneLoadOperation.cs | 52 --- .../Handler/SceneLoadedOperation.cs | 167 --------- .../Sources/Replication/ReplicationRoom.cs | 136 ------- .../Sources/Transport/ENet}/ENetConnection.cs | 2 +- .../Transport/ENet}/ENetReliableChannel.cs | 12 +- .../Sources/Transport/ENet/ENetServer.cs | 141 ++++++++ .../Transport/ENet}/ENetUnreliableChannel.cs | 8 +- .../Transport/WebSocket}/Executor/Executor.cs | 7 +- .../WebSocket}/WebSocketConnection.cs | 3 + .../WebSocket}/WebSocketReliableChannel.cs | 5 +- .../Transport/WebSocket}/WebSocketServer.cs | 5 +- .../Ragon.Server.ENetServer.csproj | 28 -- Ragon.Server.ENetServer/Sources/ENetServer.cs | 141 -------- .../Ragon.Server.WebSocketServer.csproj | 4 + .../Sources/Executor/IExecutor.cs | 22 -- Ragon.Server/Sources/Data/RagonData.cs | 2 +- Ragon.Server/Sources/Event/RagonEvent.cs | 6 +- .../Sources/Handler/RoomDataOperation.cs | 3 +- .../Sources/Handler/RoomLeaveOperation.cs | 1 + .../Sources/Handler/RoomOwnershipOperation.cs | 1 + Ragon.Server/Sources/IO/INetworkChannel.cs | 2 +- .../Sources/Lobby/RagonLobbyDispatcher.cs | 2 +- .../Sources/Lobby/RagonLobbyInMemory.cs | 5 + .../Sources/Lobby/RagonLobbyPlayer.cs | 1 - Ragon.Server/Sources/RagonContext.cs | 2 +- Ragon.Server/Sources/RagonServer.cs | 8 +- Ragon.Tests/{Connection.cs => Tests.cs} | 31 +- Ragon.Tests/Utilities/FakeNetwork.cs | 3 +- .../Utilities/FakeServerNetworkChannel.cs | 2 +- Ragon.Tests/Utilities/FakeSocket.cs | 4 + Ragon.sln | 12 - 79 files changed, 233 insertions(+), 3830 deletions(-) delete mode 100644 Ragon.Client.Property/Ragon.Client.Property.csproj delete mode 100644 Ragon.Client.Property/Sources/RagonBool.cs delete mode 100644 Ragon.Client.Property/Sources/RagonFloat.cs delete mode 100644 Ragon.Client.Property/Sources/RagonInt.cs delete mode 100644 Ragon.Client.Property/Sources/RagonQuaternion.cs delete mode 100644 Ragon.Client.Property/Sources/RagonString.cs delete mode 100644 Ragon.Client.Property/Sources/RagonVector3.cs delete mode 100644 Ragon.Client/Sources/Replication/Compressor/Extensions.cs delete mode 100644 Ragon.Client/Sources/Replication/Compressor/FloatCompressor.cs delete mode 100644 Ragon.Client/Sources/Replication/Compressor/IntCompressor.cs delete mode 100644 Ragon.Client/Sources/Replication/Entity/RagonEntity.cs delete mode 100644 Ragon.Client/Sources/Replication/Entity/RagonEntityState.cs delete mode 100644 Ragon.Client/Sources/Replication/Entity/RagonPayload.cs delete mode 100644 Ragon.Client/Sources/Replication/Entity/RagonProperty.cs delete mode 100644 Ragon.Client/Sources/Replication/Handler/EntityCreateHandler.cs delete mode 100644 Ragon.Client/Sources/Replication/Handler/EntityEventHandler.cs delete mode 100644 Ragon.Client/Sources/Replication/Handler/EntityOwnershipHandler.cs delete mode 100644 Ragon.Client/Sources/Replication/Handler/EntityRemoveHandler.cs delete mode 100644 Ragon.Client/Sources/Replication/Handler/EntityStateHandler.cs delete mode 100644 Ragon.Client/Sources/Replication/Handler/LoadSceneHandler.cs delete mode 100644 Ragon.Client/Sources/Replication/Handler/SnapshotHandler.cs delete mode 100644 Ragon.Client/Sources/Replication/IRagonEntityListener.cs delete mode 100644 Ragon.Client/Sources/Replication/IRagonPayload.cs delete mode 100644 Ragon.Client/Sources/Replication/IRagonSceneCollector.cs delete mode 100644 Ragon.Client/Sources/Replication/RagonEntityCache.cs delete mode 100644 Ragon.Client/Sources/Replication/RagonScene.cs delete mode 100644 Ragon.Relay/Sources/Command/KickPlayerCommand.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/IRagonEntity.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/IRagonEntityState.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/RagonEntity.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/RagonEntityCache.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/RagonEntityParameters.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/RagonEntityState.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/RagonPayload.cs delete mode 100644 Ragon.Relay/Sources/Replication/Entity/RagonProperty.cs delete mode 100644 Ragon.Relay/Sources/Replication/Handler/EntityCreateOperation.cs delete mode 100644 Ragon.Relay/Sources/Replication/Handler/EntityEventOperation.cs delete mode 100644 Ragon.Relay/Sources/Replication/Handler/EntityOwnershipOperation.cs delete mode 100644 Ragon.Relay/Sources/Replication/Handler/EntityRemoveOperation.cs delete mode 100644 Ragon.Relay/Sources/Replication/Handler/EntityStateOperation.cs delete mode 100644 Ragon.Relay/Sources/Replication/Handler/SceneLoadOperation.cs delete mode 100644 Ragon.Relay/Sources/Replication/Handler/SceneLoadedOperation.cs delete mode 100644 Ragon.Relay/Sources/Replication/ReplicationRoom.cs rename {Ragon.Server.ENetServer/Sources => Ragon.Relay/Sources/Transport/ENet}/ENetConnection.cs (97%) rename {Ragon.Server.ENetServer/Sources => Ragon.Relay/Sources/Transport/ENet}/ENetReliableChannel.cs (87%) create mode 100644 Ragon.Relay/Sources/Transport/ENet/ENetServer.cs rename {Ragon.Server.ENetServer/Sources => Ragon.Relay/Sources/Transport/ENet}/ENetUnreliableChannel.cs (88%) rename {Ragon.Server.WebSocketServer/Sources => Ragon.Relay/Sources/Transport/WebSocket}/Executor/Executor.cs (91%) rename {Ragon.Server.WebSocketServer/Sources => Ragon.Relay/Sources/Transport/WebSocket}/WebSocketConnection.cs (96%) rename {Ragon.Server.WebSocketServer/Sources => Ragon.Relay/Sources/Transport/WebSocket}/WebSocketReliableChannel.cs (91%) rename {Ragon.Server.WebSocketServer/Sources => Ragon.Relay/Sources/Transport/WebSocket}/WebSocketServer.cs (97%) delete mode 100644 Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj delete mode 100644 Ragon.Server.ENetServer/Sources/ENetServer.cs delete mode 100644 Ragon.Server.WebSocketServer/Sources/Executor/IExecutor.cs rename Ragon.Tests/{Connection.cs => Tests.cs} (60%) create mode 100644 Ragon.Tests/Utilities/FakeSocket.cs diff --git a/Ragon.Client.Property/Ragon.Client.Property.csproj b/Ragon.Client.Property/Ragon.Client.Property.csproj deleted file mode 100644 index d0ebad4..0000000 --- a/Ragon.Client.Property/Ragon.Client.Property.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - net7.0 - enable - enable - - - - - - - diff --git a/Ragon.Client.Property/Sources/RagonBool.cs b/Ragon.Client.Property/Sources/RagonBool.cs deleted file mode 100644 index 73f36e1..0000000 --- a/Ragon.Client.Property/Sources/RagonBool.cs +++ /dev/null @@ -1,61 +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 Ragon.Client.Replication; -using Ragon.Protocol; - -namespace Ragon.Client.Property -{ - [Serializable] - public class RagonBool : RagonProperty - { - public bool Value - { - get => _value; - set - { - _value = value; - - MarkAsChanged(); - } - } - - private bool _value; - - public RagonBool( - bool initialValue, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _value = initialValue; - SetFixedSize(1); - } - - public override void Serialize(RagonBuffer buffer) - { - buffer.WriteBool(_value); - } - - public override void Deserialize(RagonBuffer buffer) - { - _value = buffer.ReadBool(); - - InvokeChanged(); - } - } -} \ No newline at end of file diff --git a/Ragon.Client.Property/Sources/RagonFloat.cs b/Ragon.Client.Property/Sources/RagonFloat.cs deleted file mode 100644 index c5e0c9c..0000000 --- a/Ragon.Client.Property/Sources/RagonFloat.cs +++ /dev/null @@ -1,105 +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 Ragon.Client.Replication; -using Ragon.Protocol; - -namespace Ragon.Client -{ - [Serializable] - public class RagonFloat : RagonProperty - { - public float Value - { - get => _value; - set - { - _value = value; - - if (_value < _min) - _value = _min; - else if (_value > _max) - _value = _max; - - MarkAsChanged(); - } - } - - private float _value; - private float _min; - private float _max; - private int _requiredBits; - private float _precision; - private uint _mask; - - public RagonFloat( - float initialValue, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _value = initialValue; - _min = -1024.0f; - _max = 1024.0f; - _precision = 0.01f; - - _requiredBits = DeBruijn.Log2((uint)((_max - _min) * (1.0f / _precision) + 0.5f)) + 1; - _mask = (uint)((1L << _requiredBits) - 1); - - SetFixedSize(_requiredBits); - } - - public RagonFloat( - float initialValue, - float min = -1024.0f, - float max = 1024.0f, - float precision = 0.01f, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _value = initialValue; - _min = min; - _max = max; - _precision = precision; - - _requiredBits = DeBruijn.Log2((uint)((_max - _min) * (1.0f / _precision) + 0.5f)) + 1; - _mask = (uint)((1L << _requiredBits) - 1); - - SetFixedSize(_requiredBits); - } - - public override void Serialize(RagonBuffer buffer) - { - var compressedValue = (uint)((_value - _min) * (1f / _precision) + 0.5f) & _mask; - buffer.Write(compressedValue, _requiredBits); - } - - public override void Deserialize(RagonBuffer buffer) - { - var compressedValue = buffer.Read(_requiredBits); - _value = compressedValue * _precision + _min; - - if (_value < _min) - _value = _min; - else if (_value > _max) - _value = _max; - - InvokeChanged(); - } - } -} \ No newline at end of file diff --git a/Ragon.Client.Property/Sources/RagonInt.cs b/Ragon.Client.Property/Sources/RagonInt.cs deleted file mode 100644 index 23a6acf..0000000 --- a/Ragon.Client.Property/Sources/RagonInt.cs +++ /dev/null @@ -1,88 +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 Ragon.Client.Replication; -using Ragon.Protocol; - -namespace Ragon.Client.Property -{ - [Serializable] - public class RagonInt : RagonProperty - { - public int Value - { - get => _value; - set - { - _value = value; - MarkAsChanged(); - } - } - - private int _min; - private int _max; - private int _requiredBits; - private int _value; - - public RagonInt( - int initialValue, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _value = initialValue; - _min = -1000; - _max = 1000; - - _max = Math.Max(Math.Abs(_min), Math.Abs(_max)); - _requiredBits = Bits.Compute(_max); - - SetFixedSize(_requiredBits); - } - - public RagonInt( - int initialValue, - int min = -1000, - int max = 1000, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _value = initialValue; - _min = min; - _max = max; - - _requiredBits = Bits.Compute(_max); - - SetFixedSize(_requiredBits); - } - - public override void Serialize(RagonBuffer buffer) - { - uint compressedValue = (uint)((_value << 1) ^ (_value >> 31)); - buffer.Write(compressedValue, _requiredBits); - } - - public override void Deserialize(RagonBuffer buffer) - { - var compressedValue = buffer.Read(_requiredBits); - _value = (int)((compressedValue >> 1) ^ -(int)(compressedValue & 1)); - - InvokeChanged(); - } - } -} \ No newline at end of file diff --git a/Ragon.Client.Property/Sources/RagonQuaternion.cs b/Ragon.Client.Property/Sources/RagonQuaternion.cs deleted file mode 100644 index 10cb6f9..0000000 --- a/Ragon.Client.Property/Sources/RagonQuaternion.cs +++ /dev/null @@ -1,77 +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.Numerics; -using Ragon.Client.Compressor; -using Ragon.Client.Replication; -using Ragon.Protocol; - -namespace Ragon.Client.Property; - -public class RagonQuaternion : RagonProperty -{ - private Quaternion _value; - - public Quaternion Value - { - get => _value; - set - { - _value = value; - - MarkAsChanged(); - } - } - - private readonly FloatCompressor _compressor; - - public RagonQuaternion(bool invokeLocal = false, int priority = 0) : base(priority, invokeLocal) - { - _compressor = new FloatCompressor(-1.0f, 1f, 0.01f); - - SetFixedSize(_compressor.RequiredBits * 4); - } - - public override void Serialize(RagonBuffer buffer) - { - var compressedX = _compressor.Compress(_value.X); - var compressedY = _compressor.Compress(_value.Y); - var compressedZ = _compressor.Compress(_value.Z); - var compressedW = _compressor.Compress(_value.W); - - buffer.Write(compressedX, _compressor.RequiredBits); - buffer.Write(compressedY, _compressor.RequiredBits); - buffer.Write(compressedZ, _compressor.RequiredBits); - buffer.Write(compressedW, _compressor.RequiredBits); - } - - public override void Deserialize(RagonBuffer buffer) - { - var compressedX = buffer.Read(_compressor.RequiredBits); - var compressedY = buffer.Read(_compressor.RequiredBits); - var compressedZ = buffer.Read(_compressor.RequiredBits); - var compressedW = buffer.Read(_compressor.RequiredBits); - - var x = _compressor.Decompress(compressedX); - var y = _compressor.Decompress(compressedY); - var z = _compressor.Decompress(compressedZ); - var w = _compressor.Decompress(compressedW); - - _value = new Quaternion(x, y, z, w); - - InvokeChanged(); - } -} \ No newline at end of file diff --git a/Ragon.Client.Property/Sources/RagonString.cs b/Ragon.Client.Property/Sources/RagonString.cs deleted file mode 100644 index 301c497..0000000 --- a/Ragon.Client.Property/Sources/RagonString.cs +++ /dev/null @@ -1,69 +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.Text; -using Ragon.Client.Replication; -using Ragon.Protocol; - -namespace Ragon.Client.Property -{ - [Serializable] - public class RagonString : RagonProperty - { - public string Value - { - get => _value; - set - { - _value = value; - - MarkAsChanged(); - } - } - - private string _value; - private readonly UTF8Encoding _utf8Encoding = new UTF8Encoding(false, true); - - public RagonString( - string initialValue, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _value = initialValue; - } - - public override void Serialize(RagonBuffer buffer) - { - var data = _utf8Encoding.GetBytes(_value); - var len = (uint) data.Length; - - buffer.Write(len, 16); - buffer.WriteBytes(data); - } - - public override void Deserialize(RagonBuffer buffer) - { - var len = (int) buffer.Read(16); - var data = buffer.ReadBytes(len); - - _value = _utf8Encoding.GetString(data); - - InvokeChanged(); - } - } -} \ No newline at end of file diff --git a/Ragon.Client.Property/Sources/RagonVector3.cs b/Ragon.Client.Property/Sources/RagonVector3.cs deleted file mode 100644 index 7bd1895..0000000 --- a/Ragon.Client.Property/Sources/RagonVector3.cs +++ /dev/null @@ -1,331 +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; -using System.Numerics; -using Ragon.Client.Compressor; -using Ragon.Client.Replication; -using Ragon.Protocol; - -namespace Ragon.Client.Property -{ - [Serializable] - public enum RagonAxis - { - XYZ, - XY, - YZ, - XZ, - X, - Y, - Z - } - - [Serializable] - public class RagonVector3 : RagonProperty - { - private Vector3 _value; - - public Vector3 Value - { - get => _value; - set - { - _value = value; - - MarkAsChanged(); - } - } - - private RagonAxis _axis; - private FloatCompressor _compressorX; - private FloatCompressor _compressorY; - private FloatCompressor _compressorZ; - - - public RagonVector3( - RagonAxis axis = RagonAxis.XYZ, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _axis = axis; - - var defaultCompressor = new FloatCompressor(-1024.0f, 1024f, 0.01f); - - _compressorX = defaultCompressor; - _compressorY = defaultCompressor; - _compressorZ = defaultCompressor; - - switch (_axis) - { - case RagonAxis.XYZ: - SetFixedSize(_compressorX.RequiredBits + _compressorY.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.XY: - SetFixedSize(_compressorX.RequiredBits + _compressorY.RequiredBits); - break; - case RagonAxis.XZ: - SetFixedSize(_compressorX.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.YZ: - SetFixedSize(_compressorY.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.X: - SetFixedSize(_compressorX.RequiredBits); - break; - case RagonAxis.Y: - SetFixedSize(_compressorY.RequiredBits); - break; - case RagonAxis.Z: - SetFixedSize(_compressorZ.RequiredBits); - break; - } - } - - public RagonVector3( - Vector3 initialValue, - RagonAxis axis = RagonAxis.XYZ, - float min = -1024.0f, - float max = 1024.0f, - float precision = 0.1f, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _value = initialValue; - _axis = axis; - - var defaultCompressor = new FloatCompressor(min, max, precision); - - _compressorX = defaultCompressor; - _compressorY = defaultCompressor; - _compressorZ = defaultCompressor; - - switch (_axis) - { - case RagonAxis.XYZ: - SetFixedSize(_compressorX.RequiredBits + _compressorY.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.XY: - SetFixedSize(_compressorX.RequiredBits + _compressorY.RequiredBits); - break; - case RagonAxis.XZ: - SetFixedSize(_compressorX.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.YZ: - SetFixedSize(_compressorY.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.X: - SetFixedSize(_compressorX.RequiredBits); - break; - case RagonAxis.Y: - SetFixedSize(_compressorY.RequiredBits); - break; - case RagonAxis.Z: - SetFixedSize(_compressorZ.RequiredBits); - break; - } - } - - public RagonVector3( - RagonAxis axis = RagonAxis.XYZ, - FloatCompressor compressorX = null, - FloatCompressor compressorY = null, - FloatCompressor compressorZ = null, - bool invokeLocal = true, - int priority = 0 - ) : base(priority, invokeLocal) - { - _axis = axis; - - var defaultCompressor = new FloatCompressor(-1024.0f, 1024f, 0.01f); - - _compressorX = defaultCompressor; - _compressorY = defaultCompressor; - _compressorZ = defaultCompressor; - - if (compressorX != null) - _compressorX = compressorX; - - if (compressorY != null) - _compressorY = compressorY; - - if (compressorZ != null) - _compressorZ = compressorZ; - - switch (_axis) - { - case RagonAxis.XYZ: - SetFixedSize(_compressorX.RequiredBits + _compressorY.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.XY: - SetFixedSize(_compressorX.RequiredBits + _compressorY.RequiredBits); - break; - case RagonAxis.XZ: - SetFixedSize(_compressorX.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.YZ: - SetFixedSize(_compressorY.RequiredBits + _compressorZ.RequiredBits); - break; - case RagonAxis.X: - SetFixedSize(_compressorX.RequiredBits); - break; - case RagonAxis.Y: - SetFixedSize(_compressorY.RequiredBits); - break; - case RagonAxis.Z: - SetFixedSize(_compressorZ.RequiredBits); - break; - } - } - - public override void Serialize(RagonBuffer buffer) - { - switch (_axis) - { - case RagonAxis.XYZ: - { - var compressedX = _compressorX.Compress(_value.X); - var compressedY = _compressorY.Compress(_value.Y); - var compressedZ = _compressorZ.Compress(_value.Z); - - buffer.Write(compressedX, _compressorX.RequiredBits); - buffer.Write(compressedY, _compressorY.RequiredBits); - buffer.Write(compressedZ, _compressorZ.RequiredBits); - } - break; - case RagonAxis.XY: - { - var compressedX = _compressorX.Compress(_value.X); - var compressedY = _compressorY.Compress(_value.Y); - - buffer.Write(compressedX, _compressorX.RequiredBits); - buffer.Write(compressedY, _compressorY.RequiredBits); - } - break; - case RagonAxis.XZ: - { - var compressedX = _compressorX.Compress(_value.X); - var compressedZ = _compressorZ.Compress(_value.Z); - - buffer.Write(compressedX, _compressorX.RequiredBits); - buffer.Write(compressedZ, _compressorZ.RequiredBits); - break; - } - - case RagonAxis.YZ: - { - var compressedY = _compressorY.Compress(_value.Y); - var compressedZ = _compressorZ.Compress(_value.Z); - - buffer.Write(compressedY, _compressorY.RequiredBits); - buffer.Write(compressedZ, _compressorZ.RequiredBits); - break; - } - case RagonAxis.X: - { - var compressedX = _compressorX.Compress(_value.X); - - buffer.Write(compressedX, _compressorX.RequiredBits); - break; - } - case RagonAxis.Y: - { - var compressedY = _compressorY.Compress(_value.Y); - - buffer.Write(compressedY, _compressorY.RequiredBits); - break; - } - case RagonAxis.Z: - { - var compressedZ = _compressorZ.Compress(_value.Z); - - buffer.Write(compressedZ, _compressorZ.RequiredBits); - break; - } - } - } - - public override void Deserialize(RagonBuffer buffer) - { - switch (_axis) - { - case RagonAxis.XYZ: - { - var compressedX = buffer.Read(_compressorX.RequiredBits); - var compressedY = buffer.Read(_compressorY.RequiredBits); - var compressedZ = buffer.Read(_compressorZ.RequiredBits); - - _value.X = _compressorX.Decompress(compressedX); - _value.Y = _compressorY.Decompress(compressedY); - _value.Z = _compressorZ.Decompress(compressedZ); - break; - } - case RagonAxis.XY: - { - var compressedX = buffer.Read(_compressorX.RequiredBits); - var compressedY = buffer.Read(_compressorY.RequiredBits); - - _value.X = _compressorX.Decompress(compressedX); - _value.Z = _compressorY.Decompress(compressedY); - break; - } - case RagonAxis.XZ: - { - var compressedX = buffer.Read(_compressorX.RequiredBits); - var compressedZ = buffer.Read(_compressorZ.RequiredBits); - - _value.X = _compressorX.Decompress(compressedX); - _value.Z = _compressorZ.Decompress(compressedZ); - break; - } - case RagonAxis.YZ: - { - var compressedY = buffer.Read(_compressorY.RequiredBits); - var compressedZ = buffer.Read(_compressorZ.RequiredBits); - - _value.Y = _compressorY.Decompress(compressedY); - _value.Z = _compressorZ.Decompress(compressedZ); - break; - } - case RagonAxis.X: - { - var compressedX = buffer.Read(_compressorX.RequiredBits); - - _value.X = _compressorX.Decompress(compressedX); - break; - } - case RagonAxis.Y: - { - var compressedY = buffer.Read(_compressorY.RequiredBits); - - _value.Y = _compressorY.Decompress(compressedY); - break; - } - case RagonAxis.Z: - { - var compressedZ = buffer.Read(_compressorZ.RequiredBits); - - _value.Z = _compressorZ.Decompress(compressedZ); - break; - } - } - - InvokeChanged(); - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Ragon.Client.csproj b/Ragon.Client/Ragon.Client.csproj index 8b107bd..6f8e9d9 100644 --- a/Ragon.Client/Ragon.Client.csproj +++ b/Ragon.Client/Ragon.Client.csproj @@ -1,3 +1,4 @@ + diff --git a/Ragon.Client/Sources/Handler/PlayerLeftHandler.cs b/Ragon.Client/Sources/Handler/PlayerLeftHandler.cs index 49e588a..d396b25 100644 --- a/Ragon.Client/Sources/Handler/PlayerLeftHandler.cs +++ b/Ragon.Client/Sources/Handler/PlayerLeftHandler.cs @@ -50,6 +50,7 @@ internal class PlayerLeftHandler : IHandler toDeleteIds[i] = entityId; } + // var emptyPayload = new RagonPayload(0); // foreach (var id in toDeleteIds) // _entityCache.OnDestroy(id, emptyPayload); diff --git a/Ragon.Client/Sources/RagonClient.cs b/Ragon.Client/Sources/RagonClient.cs index 7c25f09..59832af 100644 --- a/Ragon.Client/Sources/RagonClient.cs +++ b/Ragon.Client/Sources/RagonClient.cs @@ -22,7 +22,7 @@ namespace Ragon.Client { private readonly INetworkConnection _connection; private readonly NetworkStatistics _stats; - + private IHandler[] _handlers; private RagonStream _readBuffer; private RagonStream _writeBuffer; @@ -99,7 +99,7 @@ namespace Ragon.Client public void Disconnect() { _status = RagonStatus.DISCONNECTED; - _room.Cleanup(); + _room?.Cleanup(); _connection.Disconnect(); OnDisconnected(RagonDisconnect.MANUAL); diff --git a/Ragon.Client/Sources/RagonEventCache.cs b/Ragon.Client/Sources/RagonEventCache.cs index 5b213a8..7853fd4 100644 --- a/Ragon.Client/Sources/RagonEventCache.cs +++ b/Ragon.Client/Sources/RagonEventCache.cs @@ -26,11 +26,13 @@ public class RagonEventCache public ushort GetEventCode(TEvent _) where TEvent : IRagonEvent { var type = typeof(TEvent); + if (!_eventsRegistryByType.TryGetValue(type, out var eventCode)) { RagonLog.Error($"Event with type {type} not registered"); return 0; } + return eventCode; } diff --git a/Ragon.Client/Sources/Replication/Compressor/Extensions.cs b/Ragon.Client/Sources/Replication/Compressor/Extensions.cs deleted file mode 100644 index 3b3fcfc..0000000 --- a/Ragon.Client/Sources/Replication/Compressor/Extensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Ragon.Client.Compressor; -using Ragon.Protocol; - -namespace Ragon.Client.Utils; - -public static class CompressorExtension -{ - public static float Read(this FloatCompressor compressor, RagonBuffer buffer) - { - return compressor.Decompress(buffer.Read(compressor.RequiredBits)); - } - - public static void Write(this FloatCompressor compressor, RagonBuffer buffer, float value) - { - buffer.Write(compressor.Compress(value), compressor.RequiredBits); - } - - public static float Read(this IntCompressor compressor, RagonBuffer buffer) - { - return compressor.Decompress(buffer.Read(compressor.RequiredBits)); - } - - public static void Write(this IntCompressor compressor, RagonBuffer buffer, int value) - { - buffer.Write(compressor.Compress(value), compressor.RequiredBits); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Compressor/FloatCompressor.cs b/Ragon.Client/Sources/Replication/Compressor/FloatCompressor.cs deleted file mode 100644 index 7bd0491..0000000 --- a/Ragon.Client/Sources/Replication/Compressor/FloatCompressor.cs +++ /dev/null @@ -1,57 +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 Ragon.Protocol; - -namespace Ragon.Client.Compressor; - -public class FloatCompressor -{ - public float Min { get; private set; } - public float Max { get; private set; } - public float Precision { get; private set; } - public int RequiredBits { get; private set; } - - private uint _mask; - - public FloatCompressor(float min = -1024.0f, float max = 1024.0f, float precision = 0.01f) - { - Min = min; - Max = max; - Precision = precision; - RequiredBits = DeBruijn.Log2((uint)((Max - Min) * (1f / Precision) + 0.5f)) + 1; - - _mask = (uint)((1L << RequiredBits) - 1); - } - - public uint Compress(float value) - { - return (uint)((value - Min) * 1f / Precision + 0.5f) & _mask; - } - - public float Decompress(uint value) - { - var result = value * Precision + Min; - - if (result < Min) - result = Min; - else if (result > Max) - result = Max; - - return result; - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Compressor/IntCompressor.cs b/Ragon.Client/Sources/Replication/Compressor/IntCompressor.cs deleted file mode 100644 index f379911..0000000 --- a/Ragon.Client/Sources/Replication/Compressor/IntCompressor.cs +++ /dev/null @@ -1,44 +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 Ragon.Protocol; - -namespace Ragon.Client.Compressor; - -public class IntCompressor -{ - public int Min { get; private set; } - public int Max { get; private set; } - public int RequiredBits { get; private set; } - - public IntCompressor(int min = -1000, int max = 1000) - { - Min = min; - Max = max; - RequiredBits = Bits.Compute(Max); - } - - public uint Compress(int value) - { - return (uint)((value << 1) ^ (value >> 31));; - } - - public int Decompress(uint value) - { - return (int)((value >> 1) ^ -(int)(value & 1)); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Entity/RagonEntity.cs b/Ragon.Client/Sources/Replication/Entity/RagonEntity.cs deleted file mode 100644 index b37e891..0000000 --- a/Ragon.Client/Sources/Replication/Entity/RagonEntity.cs +++ /dev/null @@ -1,310 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication -{ - public sealed class RagonEntity : IDisposable - { - private class EventSubscription : IDisposable - { - private List> _callbacks; - private List> _localCallbacks; - private Action _callback; - - public EventSubscription( - List> callbacks, - List> localCallbacks, - Action callback) - { - _callbacks = callbacks; - _localCallbacks = localCallbacks; - _callback = callback; - } - - public void Dispose() - { - _callbacks?.Remove(_callback); - _localCallbacks?.Remove(_callback); - - _callbacks = null!; - _localCallbacks = null!; - _callback = null!; - } - } - - private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer); - - private RagonClient _client; - - public ushort Id { get; private set; } - public ushort Type { get; private set; } - - public RagonAuthority Authority { get; private set; } - public RagonPlayer Owner { get; private set; } - public RagonEntityState State { get; private set; } - - public bool IsStatic => SceneId > 0; - public bool IsReplicated { get; private set; } - public bool IsAttached { get; private set; } - public bool HasAuthority { get; private set; } - - public event Action Attached; - public event Action Detached; - public event Action OwnershipChanged; - - internal bool PropertiesChanged => _propertiesChanged; - internal ushort SceneId => _sceneId; - - private readonly ushort _sceneId; - private bool _propertiesChanged; - - private RagonPayload _spawnPayload; - private RagonPayload _destroyPayload; - - private readonly Dictionary _events = new(); - private readonly Dictionary>> _localListeners = new(); - private readonly Dictionary>> _listeners = new(); - - public RagonEntity(ushort type = 0, ushort sceneId = 0, bool replicated = true) - { - State = new RagonEntityState(this); - Type = type; - IsReplicated = replicated; - - _spawnPayload = new RagonPayload(0); - _destroyPayload = new RagonPayload(0); - _sceneId = sceneId; - } - - internal void Attach() - { - IsAttached = true; - - Attached?.Invoke(this); - } - - public void SetReplication(bool enabled) - { - IsReplicated = enabled; - } - - internal void Detach(RagonPayload payload) - { - _destroyPayload = payload; - - Detached?.Invoke(); - } - - internal T GetPayload(RagonPayload data) where T : IRagonPayload, new() - { - var payload = new T(); - if (data.Size <= 0) return payload; - - var buffer = new RagonBuffer(); - - // data.Write(buffer); - - // payload.Deserialize(buffer); - - return payload; - } - - public void Prepare( - RagonClient client, - ushort entityId, - ushort entityType, - bool hasAuthority, - RagonPlayer player, - RagonPayload payload - ) - { - Type = entityType; - Id = entityId; - HasAuthority = hasAuthority; - - _client = client; - _spawnPayload = payload; - - Owner = player; - } - - public T GetAttachPayload() where T : IRagonPayload, new() - { - return GetPayload(_spawnPayload); - } - - public T GetDetachPayload() where T : IRagonPayload, new() - { - return GetPayload(_destroyPayload); - } - - public void ReplicateEvent(TEvent evnt, RagonPlayer target, RagonReplicationMode replicationMode) - where TEvent : IRagonEvent, new() - { - if (!IsAttached) - { - RagonLog.Error("Entity not attached"); - return; - } - - var evntId = _client.Event.GetEventCode(evnt); - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); - buffer.WriteUShort(Id); - buffer.WriteUShort(evntId); - buffer.WriteByte((byte)replicationMode); - buffer.WriteByte((byte)RagonTarget.Player); - buffer.WriteUShort(target.PeerId); - - evnt.Serialize(buffer); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - public void ReplicateEvent( - TEvent evnt, - RagonTarget target = RagonTarget.All, - RagonReplicationMode replicationMode = RagonReplicationMode.Server) - where TEvent : IRagonEvent, new() - { - if (!IsAttached) - { - RagonLog.Error("Entity not attached"); - return; - } - - var eventCode = _client.Event.GetEventCode(evnt); - if (target != RagonTarget.ExceptOwner) - { - if (replicationMode == RagonReplicationMode.Local) - { - var localListeners = _localListeners[eventCode]; - foreach (var listener in localListeners) - listener.Invoke(_client.Room.Local, evnt); - return; - } - - if (replicationMode == RagonReplicationMode.LocalAndServer) - { - var localListeners = _localListeners[eventCode]; - foreach (var listener in localListeners) - listener.Invoke(_client.Room.Local, evnt); - } - } - - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); - buffer.WriteUShort(Id); - buffer.WriteUShort(eventCode); - buffer.WriteByte((byte)replicationMode); - buffer.WriteByte((byte)target); - - evnt.Serialize(buffer); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - 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>(); - _localListeners.Add(eventCode, localCallbacks); - } - - callbacks.Add(action); - localCallbacks.Add(action); - - if (!_events.ContainsKey(eventCode)) - { - _events.Add(eventCode, (player, serializer) => - { - // t.Deserialize(serializer); - - foreach (var callbackListener in callbacks) - callbackListener.Invoke(player, t); - }); - } - - return new EventSubscription(callbacks, localCallbacks, action); - } - - internal void Write(RagonBuffer buffer) - { - buffer.WriteUShort(Id); - - State.WriteState(buffer); - - _propertiesChanged = false; - } - - internal void Read(RagonBuffer buffer) - { - State.ReadState(buffer); - } - - internal void Event(ushort eventCode, RagonPlayer caller, RagonBuffer buffer) - { - if (!IsReplicated) return; - - if (_events.TryGetValue(eventCode, out var evnt)) - evnt?.Invoke(caller, buffer); - else - RagonLog.Warn($"Handler event on entity {Id} with eventCode {eventCode} not defined"); - } - - internal void TrackChangedProperty(RagonProperty property) - { - _propertiesChanged = true; - } - - public void OnOwnershipChanged(RagonPlayer player) - { - var prevOwner = Owner; - - Owner = player; - HasAuthority = player.IsLocal; - - OwnershipChanged?.Invoke(prevOwner, player); - } - - public void Dispose() - { - _events.Clear(); - _listeners.Clear(); - _localListeners.Clear(); - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Entity/RagonEntityState.cs b/Ragon.Client/Sources/Replication/Entity/RagonEntityState.cs deleted file mode 100644 index 64d17de..0000000 --- a/Ragon.Client/Sources/Replication/Entity/RagonEntityState.cs +++ /dev/null @@ -1,77 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -public sealed class RagonEntityState -{ - private List _properties; - private RagonEntity _entity; - - public RagonEntityState(RagonEntity entity) - { - _entity = entity; - _properties = new List(6); - } - - public void AddProperty(RagonProperty property) - { - _properties.Add(property); - - property.AssignEntity(_entity); - } - - internal void WriteInfo(RagonBuffer buffer) - { - buffer.WriteUShort((ushort)_properties.Count); - foreach (var property in _properties) - { - buffer.WriteBool(property.IsFixed); - buffer.WriteUShort((ushort)property.Size); - } - } - - internal void ReadState(RagonBuffer buffer) - { - foreach (var property in _properties) - { - var changed = buffer.ReadBool(); - if (changed) - property.Read(buffer); - } - } - - internal void WriteState(RagonBuffer buffer) - { - foreach (var prop in _properties) - { - if (prop.IsDirty) - { - buffer.WriteBool(true); - prop.Write(buffer); - prop.Flush(); - } - else - { - prop.AddTick(); - buffer.WriteBool(false); - } - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Entity/RagonPayload.cs b/Ragon.Client/Sources/Replication/Entity/RagonPayload.cs deleted file mode 100644 index d98c86e..0000000 --- a/Ragon.Client/Sources/Replication/Entity/RagonPayload.cs +++ /dev/null @@ -1,49 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -public class RagonPayload -{ - public static RagonPayload Empty = new RagonPayload(0); - - private byte[] _data = new byte[128]; - private readonly int _size = 0; - - public RagonPayload(int capacity) - { - _size = capacity; - } - public int Size => _size; - - public void Read(RagonStream buffer) - { - _data = buffer.ReadBinary(_size); - } - - public void Write(RagonStream buffer) - { - buffer.WriteBinary(_data); - } - - public override string ToString() - { - return $"Payload Size: {_size}"; - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Entity/RagonProperty.cs b/Ragon.Client/Sources/Replication/Entity/RagonProperty.cs deleted file mode 100644 index c2016ca..0000000 --- a/Ragon.Client/Sources/Replication/Entity/RagonProperty.cs +++ /dev/null @@ -1,146 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication -{ - [Serializable] - public class RagonProperty - { - public string Name => _name; - public RagonEntity Entity => _entity; - - public event Action Changed; - public bool IsDirty => _dirty && _ticks >= _priority; - public bool IsFixed => _fixed; - public int Size => _size; - - private RagonBuffer _propertyBuffer; - private RagonEntity _entity; - private bool _dirty; - private int _size; - private int _ticks; - private int _priority; - private bool _fixed; - private string _name; - - protected bool InvokeLocal; - - protected RagonProperty(int priority, bool invokeLocal) - { - _size = 0; - _priority = priority; - _fixed = false; - _propertyBuffer = new RagonBuffer(); - - InvokeLocal = invokeLocal; - } - - public void SetName(string name) - { - _name = name; - } - - protected void SetFixedSize(int size) - { - _size = size; - _fixed = true; - } - - protected void InvokeChanged() - { - if (_entity.HasAuthority) - return; - - Changed?.Invoke(); - } - - protected void MarkAsChanged() - { - if (InvokeLocal) - Changed?.Invoke(); - - if (_dirty || _entity == null) - return; - - _dirty = true; - _entity.TrackChangedProperty(this); - } - - internal void Flush() - { - _dirty = false; - _ticks = 0; - } - - internal void AddTick() - { - _ticks++; - } - - internal void AssignEntity(RagonEntity ent) - { - _entity = ent; - - Changed?.Invoke(); - } - - internal void Write(RagonBuffer buffer) - { - _propertyBuffer.Clear(); - - if (_fixed) - { - Serialize(_propertyBuffer); - - buffer.CopyFrom(_propertyBuffer, _size); - return; - } - - Serialize(_propertyBuffer); - - var propertySize = (ushort)_propertyBuffer.WriteOffset; - buffer.WriteUShort(propertySize); - buffer.CopyFrom(_propertyBuffer, propertySize); - } - - internal void Read(RagonBuffer buffer) - { - _propertyBuffer.Clear(); - - if (_fixed) - { - buffer.ToBuffer(_propertyBuffer, _size); - - Deserialize(_propertyBuffer); - return; - } - - var propSize = buffer.ReadUShort(); - buffer.ToBuffer(_propertyBuffer, propSize); - Deserialize(_propertyBuffer); - } - - public virtual void Serialize(RagonBuffer buffer) - { - } - - public virtual void Deserialize(RagonBuffer buffer) - { - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Handler/EntityCreateHandler.cs b/Ragon.Client/Sources/Replication/Handler/EntityCreateHandler.cs deleted file mode 100644 index 595cf5a..0000000 --- a/Ragon.Client/Sources/Replication/Handler/EntityCreateHandler.cs +++ /dev/null @@ -1,69 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -internal class EntityCreateHandler -{ - private readonly RagonClient _client; - private readonly RagonPlayerCache _playerCache; - private readonly RagonEntityCache _entityCache; - private readonly IRagonEntityListener _entityListener; - - public EntityCreateHandler( - RagonClient client, - RagonPlayerCache playerCache, - RagonEntityCache entityCache, - IRagonEntityListener entityListener - ) - { - _client = client; - _entityCache = entityCache; - _playerCache = playerCache; - _entityListener = entityListener; - } - - public void Handle(RagonStream reader) - { - var attachId = reader.ReadUShort(); - var entityType = reader.ReadUShort(); - var entityId = reader.ReadUShort(); - var ownerId = reader.ReadUShort(); - var player = _playerCache.GetPlayerByPeer(ownerId); - // var payload = new RagonPayload(reader.Capacity); - // payload.Read(reader); - - if (player == null) - { - RagonLog.Warn($"Owner {ownerId}|{player.Name} not found in players"); - - _playerCache.Dump(); - return; - } - - var hasAuthority = _playerCache.Local.Id == player.Id; - var entity = _entityCache.TryGetEntity(attachId, entityType, 0, entityId, hasAuthority, out var hasCreated); - - // entity.Prepare(_client, entityId, entityType, hasAuthority, player, payload); - - if (hasCreated) - _entityListener.OnEntityCreated(entity); - - entity.Attach(); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Handler/EntityEventHandler.cs b/Ragon.Client/Sources/Replication/Handler/EntityEventHandler.cs deleted file mode 100644 index 4008260..0000000 --- a/Ragon.Client/Sources/Replication/Handler/EntityEventHandler.cs +++ /dev/null @@ -1,56 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -internal class EntityEventHandler -{ - private readonly RagonPlayerCache _playerCache; - private readonly RagonEntityCache _entityCache; - - public EntityEventHandler( - RagonPlayerCache playerCache, - RagonEntityCache entityCache - ) - { - _playerCache = playerCache; - _entityCache = entityCache; - } - - public void Handle(RagonBuffer reader) - { - var eventCode = reader.ReadUShort(); - var peerId = reader.ReadUShort(); - var executionMode = (RagonReplicationMode)reader.ReadByte(); - var entityId = reader.ReadUShort(); - - var player = _playerCache.GetPlayerByPeer(peerId); - if (player == null) - { - RagonLog.Error($"Player with peerId:{peerId} not found as owner of event with code:{eventCode}"); - - _playerCache.Dump(); - return; - } - - if (player.IsLocal && executionMode == RagonReplicationMode.LocalAndServer) - return; - - _entityCache.OnEvent(player, entityId, eventCode, reader); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Handler/EntityOwnershipHandler.cs b/Ragon.Client/Sources/Replication/Handler/EntityOwnershipHandler.cs deleted file mode 100644 index 8b0da29..0000000 --- a/Ragon.Client/Sources/Replication/Handler/EntityOwnershipHandler.cs +++ /dev/null @@ -1,60 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -internal class EntityOwnershipHandler -{ - private readonly RagonListenerList _listenerList; - private readonly RagonPlayerCache _playerCache; - private readonly RagonEntityCache _entityCache; - - public EntityOwnershipHandler( - RagonListenerList listenerList, - RagonPlayerCache playerCache, - RagonEntityCache entityCache) - { - _listenerList = listenerList; - _playerCache = playerCache; - _entityCache = entityCache; - } - - public void Handle(RagonBuffer reader) - { - var newOwnerId = reader.ReadUShort(); - var entities = reader.ReadUShort(); - - var player = _playerCache.GetPlayerByPeer(newOwnerId); - if (player == null) - { - RagonLog.Error($"Player with Id:{newOwnerId} not found in cache"); - - _playerCache.Dump(); - return; - } - - for (var i = 0; i < entities; i++) - { - var entityId = reader.ReadUShort(); - _entityCache.OnOwnershipChanged(player, entityId); - - RagonLog.Trace("Entity changed owner: " + entityId); - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Handler/EntityRemoveHandler.cs b/Ragon.Client/Sources/Replication/Handler/EntityRemoveHandler.cs deleted file mode 100644 index 5219066..0000000 --- a/Ragon.Client/Sources/Replication/Handler/EntityRemoveHandler.cs +++ /dev/null @@ -1,39 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -internal class EntityRemoveHandler -{ - private readonly RagonEntityCache _entityCache; - - public EntityRemoveHandler(RagonEntityCache entityCache) - { - _entityCache = entityCache; - } - - public void Handle(RagonBuffer reader) - { - var entityId = reader.ReadUShort(); - // var payload = new RagonPayload(reader.Capacity); - // payload.Read(reader); - - // _entityCache.OnDestroy(entityId, payload); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Handler/EntityStateHandler.cs b/Ragon.Client/Sources/Replication/Handler/EntityStateHandler.cs deleted file mode 100644 index 3a78941..0000000 --- a/Ragon.Client/Sources/Replication/Handler/EntityStateHandler.cs +++ /dev/null @@ -1,39 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -internal class StateEntityHandler -{ - private readonly RagonEntityCache _entityCache; - - public StateEntityHandler(RagonEntityCache entityCache) - { - _entityCache = entityCache; - } - - public void Handle(RagonBuffer reader) - { - var entitiesCount = reader.ReadUShort(); - for (var i = 0; i < entitiesCount; i++) - { - var entityId = reader.ReadUShort(); - _entityCache.OnState(entityId, reader); - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Handler/LoadSceneHandler.cs b/Ragon.Client/Sources/Replication/Handler/LoadSceneHandler.cs deleted file mode 100644 index 05a87e2..0000000 --- a/Ragon.Client/Sources/Replication/Handler/LoadSceneHandler.cs +++ /dev/null @@ -1,45 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -internal class SceneLoadHandler -{ - private readonly RagonClient _client; - private readonly RagonListenerList _listenerList; - - public SceneLoadHandler( - RagonClient ragonClient, - RagonListenerList listenerList - ) - { - _client = ragonClient; - _listenerList = listenerList; - } - - public void Handle(RagonBuffer reader) - { - var sceneName = reader.ReadString(); - var room = _client.Room; - - room.Cleanup(); - room.Update(sceneName); - - // _listenerList.OnSceneRequest(sceneName); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/Handler/SnapshotHandler.cs b/Ragon.Client/Sources/Replication/Handler/SnapshotHandler.cs deleted file mode 100644 index e6a31fd..0000000 --- a/Ragon.Client/Sources/Replication/Handler/SnapshotHandler.cs +++ /dev/null @@ -1,116 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -internal class SnapshotHandler -{ - private readonly IRagonEntityListener _entityListener; - private readonly RagonClient _client; - private readonly RagonListenerList _listenerList; - private readonly RagonEntityCache _entityCache; - private readonly RagonPlayerCache _playerCache; - - public SnapshotHandler( - RagonClient ragonClient, - RagonListenerList listenerList, - RagonEntityCache entityCache, - RagonPlayerCache playerCache, - IRagonEntityListener entityListener - ) - { - _client = ragonClient; - _entityListener = entityListener; - _listenerList = listenerList; - _entityCache = entityCache; - _playerCache = playerCache; - } - - public void Handle(RagonBuffer buffer) - { - var entities = new List(); - var dynamicEntities = buffer.ReadUShort(); - RagonLog.Trace("Dynamic Entities: " + dynamicEntities); - for (var i = 0; i < dynamicEntities; i++) - { - var entityType = buffer.ReadUShort(); - var entityId = buffer.ReadUShort(); - var ownerPeerId = buffer.ReadUShort(); - var payloadSize = buffer.ReadUShort(); - - var player = _playerCache.GetPlayerByPeer(ownerPeerId); - if (player == null) - { - RagonLog.Error($"Player not found with peerId: {ownerPeerId}"); - - _playerCache.Dump(); - return; - } - - var hasAuthority = _playerCache.Local.Id == player.Id; - var entity = _entityCache.TryGetEntity(0, entityType, 0, entityId, hasAuthority, out _); - var payload = RagonPayload.Empty; - if (payloadSize > 0) - { - // payload = new RagonPayload(payloadSize); - // payload.Read(buffer); - } - - entity.Prepare(_client, entityId, entityType, hasAuthority, player, payload); - - _entityListener.OnEntityCreated(entity); - - entity.Read(buffer); - - entities.Add(entity); - } - - var staticEntities = buffer.ReadUShort(); - RagonLog.Trace("Scene Entities: " + staticEntities); - for (var i = 0; i < staticEntities; i++) - { - var entityType = buffer.ReadUShort(); - var entityId = buffer.ReadUShort(); - var staticId = buffer.ReadUShort(); - var ownerPeerId = buffer.ReadUShort(); - var payloadSize = buffer.ReadUShort(); - - var player = _playerCache.GetPlayerByPeer(ownerPeerId); - if (player == null) - { - RagonLog.Error($"Player not found with peerId: {ownerPeerId}"); - - _playerCache.Dump(); - return; - } - - var hasAuthority = _playerCache.Local.Id == player.Id; - var entity = _entityCache.TryGetEntity(0, entityType, staticId, entityId, hasAuthority, out _); - - entity.Prepare(_client, entityId, entityType, hasAuthority, player, RagonPayload.Empty); - entity.Read(buffer); - - entities.Add(entity); - } - - foreach (var entity in entities) - entity.Attach(); - - // _listenerList.OnSceneLoaded(); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/IRagonEntityListener.cs b/Ragon.Client/Sources/Replication/IRagonEntityListener.cs deleted file mode 100644 index ade945f..0000000 --- a/Ragon.Client/Sources/Replication/IRagonEntityListener.cs +++ /dev/null @@ -1,22 +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. - */ - -namespace Ragon.Client.Replication; - -public interface IRagonEntityListener -{ - public void OnEntityCreated(RagonEntity entity); -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/IRagonPayload.cs b/Ragon.Client/Sources/Replication/IRagonPayload.cs deleted file mode 100644 index 83ec452..0000000 --- a/Ragon.Client/Sources/Replication/IRagonPayload.cs +++ /dev/null @@ -1,26 +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 Ragon.Protocol; - -namespace Ragon.Client -{ - public interface IRagonPayload - { - public void Serialize(RagonStream buffer); - public void Deserialize(RagonStream buffer); - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/IRagonSceneCollector.cs b/Ragon.Client/Sources/Replication/IRagonSceneCollector.cs deleted file mode 100644 index 7ed453d..0000000 --- a/Ragon.Client/Sources/Replication/IRagonSceneCollector.cs +++ /dev/null @@ -1,22 +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. - */ - -namespace Ragon.Client.Replication; - -public interface IRagonSceneCollector -{ - public RagonEntity[] Collect(); -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/RagonEntityCache.cs b/Ragon.Client/Sources/Replication/RagonEntityCache.cs deleted file mode 100644 index 1ee2662..0000000 --- a/Ragon.Client/Sources/Replication/RagonEntityCache.cs +++ /dev/null @@ -1,257 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -public sealed class RagonEntityCache -{ - private readonly List _entityList = new(); - private readonly Dictionary _entityMap = new(); - private readonly Dictionary _pendingEntities = new(); - private readonly Dictionary _sceneEntities = new(); - - private readonly RagonClient _client; - private readonly IRagonSceneCollector _sceneCollector; - private readonly RagonPlayerCache _playerCache; - - private int _localEntitiesCounter = 0; - - public RagonEntityCache( - RagonClient client, - RagonPlayerCache playerCache, - IRagonSceneCollector sceneCollector - ) - { - _client = client; - _sceneCollector = sceneCollector; - _playerCache = playerCache; - } - - public bool TryGetEntity(ushort id, out RagonEntity entity) - { - return _entityMap.TryGetValue(id, out entity); - } - - public void Create(RagonEntity entity, RagonPayload spawnPayload) - { - var attachId = (ushort)(_playerCache.Local.PeerId + _localEntitiesCounter++); - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.CREATE_ENTITY); - buffer.WriteUShort(attachId); - buffer.WriteUShort(entity.Type); - buffer.WriteByte((byte)entity.Authority); - - // entity.State.WriteInfo(buffer); - - spawnPayload?.Write(buffer); - - _pendingEntities.Add(attachId, entity); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - public void Transfer(RagonEntity entity, RagonPlayer player) - { - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.TRANSFER_ENTITY_OWNERSHIP); - buffer.WriteUShort(entity.Id); - buffer.WriteUShort(player.PeerId); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - public void Destroy(RagonEntity entity, RagonPayload destroyPayload) - { - if (!entity.IsAttached && !entity.HasAuthority) - { - RagonLog.Warn("Can't destroy object"); - return; - } - - entity.SetReplication(false); - - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REMOVE_ENTITY); - buffer.WriteUShort(entity.Id); - - destroyPayload?.Write(buffer); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - internal void WriteState(RagonBuffer buffer) - { - var changedEntities = 0u; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_STATE); - - var offset = buffer.WriteOffset; - buffer.Write(0, 16); - - foreach (var ent in _entityList) - { - if (!ent.IsAttached || - !ent.IsReplicated || - !ent.PropertiesChanged) continue; - - ent.Write(buffer); - - changedEntities++; - } - - if (changedEntities <= 0) return; - - buffer.Write(changedEntities, 16, offset); - - var data = buffer.ToArray(); - _client.Unreliable.Send(data); - } - - internal void WriteScene(RagonBuffer buffer) - { - _sceneEntities.Clear(); - - var entities = _sceneCollector.Collect(); - buffer.WriteUShort((ushort)entities.Length); - foreach (var entity in entities) - { - buffer.WriteUShort(entity.Type); - buffer.WriteByte((byte)entity.Authority); - buffer.WriteUShort(entity.SceneId); - - entity.State.WriteInfo(buffer); - - _sceneEntities.Add(entity.SceneId, entity); - } - } - - internal void CacheScene() - { - _sceneEntities.Clear(); - - var entities = _sceneCollector.Collect(); - foreach (var entity in entities) - _sceneEntities.Add(entity.SceneId, entity); - } - - internal void Cleanup() - { - var payload = new RagonPayload(0); - foreach (var ent in _entityList) - ent.Detach(payload); - - _entityMap.Clear(); - _entityList.Clear(); - } - - internal RagonEntity TryGetEntity(ushort attachId, ushort entityType, ushort sceneId, ushort entityId, bool hasAuthority, out bool hasCreated) - { - if (sceneId > 0) - { - if (_sceneEntities.TryGetValue(sceneId, out var sceneEntity)) - { - _entityMap.Add(entityId, sceneEntity); - - if (hasAuthority) - _entityList.Add(sceneEntity); - - hasCreated = false; - - return sceneEntity; - } - } - - if (_pendingEntities.TryGetValue(attachId, out var pendingEntity) && hasAuthority) - { - _pendingEntities.Remove(attachId); - _entityMap.Add(entityId, pendingEntity); - _entityList.Add(pendingEntity); - - hasCreated = false; - - return pendingEntity; - } - - var entity = new RagonEntity(entityType, sceneId); - - _entityMap.Add(entityId, entity); - - if (hasAuthority) - _entityList.Add(entity); - - hasCreated = true; - - return entity; - } - - - internal void OnDestroy(ushort entityId, RagonPayload payload) - { - if (_entityMap.TryGetValue(entityId, out var entity)) - { - _entityMap.Remove(entityId); - _entityList.Remove(entity); - - entity.Detach(payload); - entity.Dispose(); - } - } - - internal void OnState(ushort entityId, RagonBuffer buffer) - { - if (_entityMap.TryGetValue(entityId, out var entity)) - entity.Read(buffer); - else - RagonLog.Warn($"Entity {entityId} not found!"); - } - - internal void OnEvent(RagonPlayer player, ushort entityId, ushort eventCode, RagonBuffer buffer) - { - if (_entityMap.TryGetValue(entityId, out var entity)) - entity.Event(eventCode, player, buffer); - else - RagonLog.Warn($"Entity {entityId} not found!"); - } - - internal void OnOwnershipChanged(RagonPlayer player, ushort entityId) - { - if (_entityMap.TryGetValue(entityId, out var entity)) - { - if (player.IsLocal) - _entityList.Add(entity); - else - _entityList.Remove(entity); - - entity.OnOwnershipChanged(player); - } - else - { - RagonLog.Warn($"Entity {entityId} not found!"); - } - } -} \ No newline at end of file diff --git a/Ragon.Client/Sources/Replication/RagonScene.cs b/Ragon.Client/Sources/Replication/RagonScene.cs deleted file mode 100644 index 40a2327..0000000 --- a/Ragon.Client/Sources/Replication/RagonScene.cs +++ /dev/null @@ -1,119 +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 Ragon.Protocol; - -namespace Ragon.Client.Replication; - -public class RagonScene -{ - public string Name { get; private set; } - - private readonly RagonClient _client; - private readonly RagonEntityCache _entityCache; - private readonly RagonPlayerCache _playerCache; - - public RagonScene(RagonClient client, RagonPlayerCache playerCache, RagonEntityCache entityCache, string sceneName) - { - Name = sceneName; - - _client = client; - _playerCache = playerCache; - _entityCache = entityCache; - } - - internal void Update(string scene) - { - Name = scene; - } - - internal void Load(string sceneName) - { - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.LOAD_SCENE); - buffer.WriteString(sceneName); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - internal void SceneLoaded() - { - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.SCENE_LOADED); - - // if (_playerCache.IsRoomOwner) - // _entityCache.WriteScene(buffer); - // else - // _entityCache.CacheScene(); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - public void ReplicateEvent(TEvent evnt, RagonTarget target, RagonReplicationMode replicationMode) - where TEvent : IRagonEvent, new() - { - var evntId = _client.Event.GetEventCode(evnt); - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REPLICATE_ROOM_EVENT); - buffer.WriteUShort(evntId); - buffer.WriteByte((byte)replicationMode); - buffer.WriteByte((byte)target); - - evnt.Serialize(buffer); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - public void ReplicateEvent(TEvent evnt, RagonPlayer target, RagonReplicationMode replicationMode) - where TEvent : IRagonEvent, new() - { - var evntId = _client.Event.GetEventCode(evnt); - var buffer = _client.Buffer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REPLICATE_ROOM_EVENT); - buffer.WriteUShort(evntId); - buffer.WriteByte((byte)replicationMode); - buffer.WriteByte((byte)RagonTarget.Player); - buffer.WriteUShort(target.PeerId); - - evnt.Serialize(buffer); - - var sendData = buffer.ToArray(); - _client.Reliable.Send(sendData); - } - - public void ReplicateData(byte[] data, bool reliable) - { - var sendData = new byte[data.Length + 1]; - sendData[0] = (byte)RagonOperation.REPLICATE_RAW_DATA; - Array.Copy(data, 0, sendData, 1, data.Length); - - if (reliable) - _client.Reliable.Send(sendData); - else - _client.Unreliable.Send(sendData); - } -} \ No newline at end of file diff --git a/Ragon.Relay/Ragon.Relay.csproj b/Ragon.Relay/Ragon.Relay.csproj index 23b5632..657fbb5 100644 --- a/Ragon.Relay/Ragon.Relay.csproj +++ b/Ragon.Relay/Ragon.Relay.csproj @@ -23,12 +23,11 @@ - - + diff --git a/Ragon.Relay/Sources/Command/KickPlayerCommand.cs b/Ragon.Relay/Sources/Command/KickPlayerCommand.cs deleted file mode 100644 index 8fdcd9a..0000000 --- a/Ragon.Relay/Sources/Command/KickPlayerCommand.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Ragon.Relay; - -public class KickPlayerCommand -{ - public string Id; -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs b/Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs index c0d95a2..e258712 100644 --- a/Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs +++ b/Ragon.Relay/Sources/Plugin/RelayRoomPlugin.cs @@ -1,8 +1,5 @@ using System; -using Ragon.Server; -using Ragon.Server.Entity; using Ragon.Server.Plugin; -using Ragon.Server.Room; namespace Ragon.Relay; @@ -22,16 +19,4 @@ public class RelayRoomPlugin: BaseRoomPlugin { 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/Plugin/RelayServerPlugin.cs b/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs index 03b8593..93a7ac8 100644 --- a/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs +++ b/Ragon.Relay/Sources/Plugin/RelayServerPlugin.cs @@ -1,26 +1,12 @@ -using System; -using Newtonsoft.Json; using Ragon.Server; using Ragon.Server.Plugin; namespace Ragon.Relay { - public class RelayServerPlugin : BaseServerPlugin { public override bool OnCommand(string command, string payload) { - Console.WriteLine(command); - if (command == "kick-player") - { - var commandPayload = JsonConvert.DeserializeObject(payload); - var player = Server.GetContextById(commandPayload.Id); - if (player != null) - player.Connection.Close(); - else - Console.WriteLine($"Player not found with Id {commandPayload.Id}"); - } - return true; } diff --git a/Ragon.Relay/Sources/Relay.cs b/Ragon.Relay/Sources/Relay.cs index d9b0e77..5629b35 100644 --- a/Ragon.Relay/Sources/Relay.cs +++ b/Ragon.Relay/Sources/Relay.cs @@ -14,16 +14,15 @@ * limitations under the License. */ -using System; using System.IO; using System.Threading; using Newtonsoft.Json; using Ragon.Server; -using Ragon.Server.ENetServer; using Ragon.Server.IO; using Ragon.Server.Logging; using Ragon.Server.Plugin; using Ragon.Server.WebSocketServer; +using Ragon.Transport; namespace Ragon.Relay { @@ -69,7 +68,7 @@ namespace Ragon.Relay }; var relay = new RagonServer(networkServer, plugin, serverConfiguration); - relay.Start(); + relay.Listen(); while (relay.IsRunning) { relay.Tick(); diff --git a/Ragon.Relay/Sources/Replication/Entity/IRagonEntity.cs b/Ragon.Relay/Sources/Replication/Entity/IRagonEntity.cs deleted file mode 100644 index bd61eba..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/IRagonEntity.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ragon.Protocol; -using Ragon.Server.Room; - -namespace Ragon.Server.Entity; - -public interface IRagonEntity -{ - public ushort Id { get; } - public ushort Type { get; } - public ushort StaticId { get; } - public ushort AttachId { get; } - public RagonRoomPlayer Owner { get; } - public RagonAuthority Authority { get; } - public RagonPayload Payload { get; } - public IRagonEntityState State { get; } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Entity/IRagonEntityState.cs b/Ragon.Relay/Sources/Replication/Entity/IRagonEntityState.cs deleted file mode 100644 index 95d303c..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/IRagonEntityState.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Ragon.Protocol; - -namespace Ragon.Server.Entity; - -public interface IRagonEntityState -{ - -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Entity/RagonEntity.cs b/Ragon.Relay/Sources/Replication/Entity/RagonEntity.cs deleted file mode 100644 index 75b7838..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/RagonEntity.cs +++ /dev/null @@ -1,246 +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.Collections.Generic; -using Ragon.Protocol; -using Ragon.Server.Event; -using Ragon.Server.Room; - -namespace Ragon.Server.Entity; - -public class RagonEntity : IRagonEntity -{ - private static ushort _idGenerator = 100; - public ushort Id { get; private set; } - public ushort Type { get; private set; } - public ushort StaticId { get; private set; } - public ushort AttachId { get; private set; } - public RagonRoomPlayer Owner { get; private set; } - public RagonAuthority Authority { get; private set; } - public RagonPayload Payload { get; private set; } - public IRagonEntityState State => _state; - - private readonly List _bufferedEvents; - private readonly int _limitBufferedEvents; - private readonly RagonEntityState _state; - - public RagonEntity(RagonEntityParameters parameters) - { - Id = _idGenerator++; - - StaticId = parameters.StaticId; - Type = parameters.Type; - AttachId = parameters.AttachId; - Authority = parameters.Authority; - Payload = new RagonPayload(); - - _state = new RagonEntityState(this); - _bufferedEvents = new List(); - _limitBufferedEvents = parameters.BufferedEvents; - } - - public void Attach(RagonRoomPlayer owner) - { - Owner = owner; - } - - public void Detach() - { - } - - public void RestoreBufferedEvents(RagonRoomPlayer roomPlayer, RagonStream writer) - { - foreach (var evnt in _bufferedEvents) - { - writer.Clear(); - writer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); - writer.WriteUShort(evnt.EventCode); - writer.WriteUShort(evnt.Invoker.Connection.Id); - writer.WriteByte((byte)RagonReplicationMode.Server); - writer.WriteUShort(Id); - - evnt.Write(writer); - - var sendData = writer.ToArray(); - roomPlayer.Connection.Reliable.Send(sendData); - } - } - - public void Create() - { - var room = Owner.Room; - var buffer = room.Writer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.CREATE_ENTITY); - buffer.WriteUShort(AttachId); - buffer.WriteUShort(Type); - buffer.WriteUShort(Id); - buffer.WriteUShort(Owner.Connection.Id); - - Payload.Write(buffer); - - var sendData = buffer.ToArray(); - foreach (var player in room.ReadyPlayersList) - player.Connection.Reliable.Send(sendData); - } - - public void Destroy() - { - var room = Owner.Room; - var buffer = room.Writer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REMOVE_ENTITY); - buffer.WriteUShort(Id); - - Payload.Write(buffer); - - var sendData = buffer.ToArray(); - foreach (var player in room.ReadyPlayersList) - player.Connection.Reliable.Send(sendData); - } - - public void Snapshot(RagonStream buffer) - { - buffer.WriteUShort(Type); - buffer.WriteUShort(Id); - - if (StaticId != 0) - buffer.WriteUShort(StaticId); - - buffer.WriteUShort(Owner.Connection.Id); - buffer.WriteUShort(Payload.Size); - - Payload.Write(buffer); - - _state.Snapshot(buffer); - } - - public void ReplicateEvent( - RagonRoomPlayer invoker, - RagonEvent evnt, - RagonReplicationMode eventMode, - RagonRoomPlayer targetPlayer - ) - { - if (Authority == RagonAuthority.OwnerOnly && invoker.Connection.Id != Owner.Connection.Id) - { - return; - } - - var room = Owner.Room; - var buffer = room.Writer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); - buffer.WriteUShort(evnt.EventCode); - buffer.WriteUShort(invoker.Connection.Id); - buffer.WriteByte((byte)eventMode); - buffer.WriteUShort(Id); - - evnt.Write(buffer); - - var sendData = buffer.ToArray(); - targetPlayer.Connection.Reliable.Send(sendData); - } - - public void ReplicateEvent( - RagonRoomPlayer invoker, - RagonEvent evnt, - RagonReplicationMode eventMode, - RagonTarget targetMode - ) - { - if (Authority == RagonAuthority.OwnerOnly && invoker.Connection.Id != Owner.Connection.Id) - { - return; - } - - if (eventMode == RagonReplicationMode.Buffered && targetMode != RagonTarget.Owner && _bufferedEvents.Count < _limitBufferedEvents) - { - _bufferedEvents.Add(evnt); - } - - var room = Owner.Room; - var buffer = room.Writer; - - buffer.Clear(); - buffer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT); - buffer.WriteUShort(evnt.EventCode); - buffer.WriteUShort(invoker.Connection.Id); - buffer.WriteByte((byte)eventMode); - buffer.WriteUShort(Id); - - evnt.Write(buffer); - - var sendData = buffer.ToArray(); - switch (targetMode) - { - case RagonTarget.Owner: - { - Owner.Connection.Reliable.Send(sendData); - break; - } - case RagonTarget.ExceptOwner: - { - foreach (var roomPlayer in room.ReadyPlayersList) - { - if (roomPlayer.Connection.Id != Owner.Connection.Id) - roomPlayer.Connection.Reliable.Send(sendData); - } - - break; - } - case RagonTarget.ExceptInvoker: - { - foreach (var roomPlayer in room.ReadyPlayersList) - { - if (roomPlayer.Connection.Id != invoker.Connection.Id) - roomPlayer.Connection.Reliable.Send(sendData); - } - - break; - } - case RagonTarget.All: - { - foreach (var roomPlayer in room.ReadyPlayersList) - roomPlayer.Connection.Reliable.Send(sendData); - break; - } - } - } - - public void AddProperty(RagonProperty property) - { - _state.AddProperty(property); - } - - public void WriteState(RagonStream writer) - { - _state.Write(writer); - } - - public bool TryReadState(RagonRoomPlayer player, RagonBuffer reader) - { - if (Owner.Connection.Id != player.Connection.Id) - return false; - - _state.Read(reader); - - return true; - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Entity/RagonEntityCache.cs b/Ragon.Relay/Sources/Replication/Entity/RagonEntityCache.cs deleted file mode 100644 index 18b1af0..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/RagonEntityCache.cs +++ /dev/null @@ -1,53 +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.Collections.Generic; -using Ragon.Server.Entity; - -namespace Ragon.Server; - -public class RagonEntityCache -{ - private readonly List _dynamicEntitiesList = new List(); - private readonly List _staticEntitiesList = new List(); - private readonly Dictionary _entitiesMap = new Dictionary(); - - public IReadOnlyList StaticList => _staticEntitiesList; - public IReadOnlyList DynamicList => _dynamicEntitiesList; - public IReadOnlyDictionary Map => _entitiesMap; - - public void Add(RagonEntity entity) - { - if (entity.StaticId != 0) - _staticEntitiesList.Add(entity); - else - _dynamicEntitiesList.Add(entity); - - _entitiesMap.Add(entity.Id, entity); - } - - public bool Remove(RagonEntity entity) - { - if (_entitiesMap.Remove(entity.Id, out var existEntity)) - { - _staticEntitiesList.Remove(entity); - _dynamicEntitiesList.Remove(entity); - - return true; - } - return false; - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Entity/RagonEntityParameters.cs b/Ragon.Relay/Sources/Replication/Entity/RagonEntityParameters.cs deleted file mode 100644 index a1ce1e3..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/RagonEntityParameters.cs +++ /dev/null @@ -1,28 +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 Ragon.Protocol; - -namespace Ragon.Server.Entity; - -public ref struct RagonEntityParameters -{ - public ushort Type; - public ushort StaticId; - public ushort AttachId; - public RagonAuthority Authority; - public int BufferedEvents; -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Entity/RagonEntityState.cs b/Ragon.Relay/Sources/Replication/Entity/RagonEntityState.cs deleted file mode 100644 index 959d9ea..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/RagonEntityState.cs +++ /dev/null @@ -1,78 +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.Collections.Generic; -using Ragon.Protocol; - -namespace Ragon.Server.Entity; - -public class RagonEntityState: IRagonEntityState -{ - private readonly List _properties; - private readonly RagonEntity _entity; - - public RagonEntityState(RagonEntity entity, int capacity = 10) - { - _entity = entity; - _properties = new List(capacity); - } - - public void AddProperty(RagonProperty property) - { - _properties.Add(property); - } - - public void Write(RagonStream buffer) - { - buffer.WriteUShort(_entity.Id); - foreach (var property in _properties) - { - if (property.IsDirty) - { - buffer.WriteBool(true); - property.Write(buffer); - property.Clear(); - continue; - } - - buffer.WriteBool(false); - } - } - - public void Read(RagonBuffer buffer) - { - foreach (var property in _properties) - { - if (buffer.ReadBool()) - property.Read(buffer); - } - } - - public void Snapshot(RagonStream buffer) - { - foreach (var property in _properties) - { - if (property.HasData) - { - buffer.WriteBool(true); - property.Write(buffer); - continue; - } - - buffer.WriteBool(false); - } - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Entity/RagonPayload.cs b/Ragon.Relay/Sources/Replication/Entity/RagonPayload.cs deleted file mode 100644 index bd7f862..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/RagonPayload.cs +++ /dev/null @@ -1,40 +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 Ragon.Protocol; - -namespace Ragon.Server.Entity; - -public class RagonPayload -{ - private uint[] _data = new uint[128]; - private int _size = 0; - - public ushort Size => (ushort) _size; - - public void Read(RagonStream buffer) - { - // _size = buffer.Capacity; - // buffer.ReadArray(_data, _size); - } - - public void Write(RagonStream buffer) - { - // if (_size == 0) return; - // buffer.WriteArray(_data, _size); - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Entity/RagonProperty.cs b/Ragon.Relay/Sources/Replication/Entity/RagonProperty.cs deleted file mode 100644 index b161b82..0000000 --- a/Ragon.Relay/Sources/Replication/Entity/RagonProperty.cs +++ /dev/null @@ -1,78 +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; -using System.Linq; -using Ragon.Protocol; - -namespace Ragon.Server.Entity; - -public class RagonProperty : RagonPayload -{ - public int Size { get; set; } - public bool IsDirty { get; private set; } - public bool IsFixed { get; private set; } - public bool HasData { get; private set; } - - private uint[] _data; - - public RagonProperty(int size, bool isFixed, int limit) - { - Size = size; - IsFixed = isFixed; - IsDirty = false; - - _data = new uint[limit / 4 + 1]; - } - - public void Read(RagonBuffer buffer) - { - if (IsFixed) - { - buffer.ReadArray(_data, Size); - } - else - { - Size = (int) buffer.Read(); - buffer.ReadArray(_data, Size); - } - - HasData = true; - IsDirty = true; - } - - public void Write(RagonBuffer buffer) - { - if (IsFixed) - { - buffer.WriteArray(_data, Size); - return; - } - - buffer.Write((ushort) Size); - buffer.WriteArray(_data, Size); - } - - public void Clear() - { - IsDirty = false; - } - - public void Dump() - { - Console.WriteLine( $"[{Size.ToString("00")}] {string.Join("", _data.Take(8).Reverse().Select(b => Convert.ToString(b, 2).PadLeft(32, '0')))}"); - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Handler/EntityCreateOperation.cs b/Ragon.Relay/Sources/Replication/Handler/EntityCreateOperation.cs deleted file mode 100644 index 5489d01..0000000 --- a/Ragon.Relay/Sources/Replication/Handler/EntityCreateOperation.cs +++ /dev/null @@ -1,80 +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 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 IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityCreateOperation)); - private RagonServerConfiguration _configuration; - - public EntityCreateOperation( - RagonStream reader, - RagonStream writer, - RagonServerConfiguration configuration) : base(reader, writer) - { - _configuration = configuration; - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - var player = context.RoomPlayer; - var room = context.Room; - var attachId = Reader.ReadUShort(); - var entityType = Reader.ReadUShort(); - var eventAuthority = (RagonAuthority)Reader.ReadByte(); - var propertiesCount = Reader.ReadUShort(); - - var entityParameters = new RagonEntityParameters() - { - Type = entityType, - Authority = eventAuthority, - AttachId = attachId, - StaticId = 0, - BufferedEvents = context.LimitBufferedEvents, - }; - - var entity = new RagonEntity(entityParameters); - for (var i = 0; i < propertiesCount; i++) - { - var propertyType = Reader.ReadBool(); - var propertySize = Reader.ReadUShort(); - - entity.AddProperty(new RagonProperty(propertySize, propertyType, _configuration.LimitPropertySize)); - } - - // if (Reader.Capacity > 0) - // entity.Payload.Read(Reader); - - // var plugin = room.Plugin; - // if (!plugin.OnEntityCreate(player, entity)) - // return; - - entity.Attach(player); - // room.AttachEntity(entity); - // player.AttachEntity(entity); - - entity.Create(); - - _logger.Trace( - $"Player {context.Connection.Id}|{context.LobbyPlayer.Name} created entity {entity.Id}:{entity.Type}"); - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Handler/EntityEventOperation.cs b/Ragon.Relay/Sources/Replication/Handler/EntityEventOperation.cs deleted file mode 100644 index 948ccce..0000000 --- a/Ragon.Relay/Sources/Replication/Handler/EntityEventOperation.cs +++ /dev/null @@ -1,63 +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 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 IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityEventOperation)); - - public EntityEventOperation(RagonStream reader, RagonStream writer) : base(reader, writer) - { - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - var player = context.RoomPlayer; - var room = context.Room; - var entityId = Reader.ReadUShort(); - - // if (!room.Entities.TryGetValue(entityId, out var ent)) - // { - // _logger.Warning($"Entity not found for event with Id {entityId}"); - // return; - // } - - var eventId = Reader.ReadUShort(); - var eventMode = (RagonReplicationMode)Reader.ReadByte(); - var targetMode = (RagonTarget)Reader.ReadByte(); - var targetPlayerPeerId = (ushort)0; - - if (targetMode == RagonTarget.Player) - targetPlayerPeerId = Reader.ReadUShort(); - - var @event = new RagonEvent(player, eventId); - @event.Read(Reader); - - // if (targetMode == RagonTarget.Player && room.Players.TryGetValue(targetPlayerPeerId, out var targetPlayer)) - // { - // ent.ReplicateEvent(player, @event, eventMode, targetPlayer); - // return; - // } - // - // ent.ReplicateEvent(player, @event, eventMode, targetMode); - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Handler/EntityOwnershipOperation.cs b/Ragon.Relay/Sources/Replication/Handler/EntityOwnershipOperation.cs deleted file mode 100644 index 50e6610..0000000 --- a/Ragon.Relay/Sources/Replication/Handler/EntityOwnershipOperation.cs +++ /dev/null @@ -1,75 +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 Ragon.Protocol; -using Ragon.Server.IO; -using Ragon.Server.Logging; - -namespace Ragon.Server.Handler; - -public sealed class EntityOwnershipOperation : BaseOperation -{ - private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityOwnershipOperation)); - - public EntityOwnershipOperation(RagonStream reader, RagonStream writer) : base(reader, writer) - { - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - var currentOwner = context.RoomPlayer; - var room = context.Room; - - var entityId = Reader.ReadUShort(); - var playerPeerId = Reader.ReadUShort(); - - // if (!room.Entities.TryGetValue(entityId, out var entity)) - // { - // _logger.Error($"Entity not found with id {entityId}"); - // return; - // } - - // if (entity.Owner.Connection.Id != currentOwner.Connection.Id) - // { - // _logger.Error($"Player not owner of entity with id {entityId}"); - // return; - // } - - if (!room.Players.TryGetValue(playerPeerId, out var nextOwner)) - { - _logger.Error($"Player not found with id {playerPeerId}"); - return; - } - - // currentOwner.Entities.Remove(entity); - // nextOwner.Entities.Add(entity); - // - // entity.Attach(nextOwner); - // - // _logger.Trace($"Entity {entity.Id} next owner {nextOwner.Connection.Id}"); - // - // Writer.Clear(); - // Writer.WriteOperation(RagonOperation.OWNERSHIP_ENTITY_CHANGED); - // Writer.WriteUShort(playerPeerId); - // Writer.WriteUShort(1); - // Writer.WriteUShort(entity.Id); - // - // var sendData = Writer.ToArray(); - // foreach (var player in room.PlayerList) - // player.Connection.Reliable.Send(sendData); - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Handler/EntityRemoveOperation.cs b/Ragon.Relay/Sources/Replication/Handler/EntityRemoveOperation.cs deleted file mode 100644 index 51a000b..0000000 --- a/Ragon.Relay/Sources/Replication/Handler/EntityRemoveOperation.cs +++ /dev/null @@ -1,55 +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 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 IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityDestroyOperation)); - - public EntityDestroyOperation(RagonStream reader, RagonStream writer) : base(reader, writer) - { - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - var player = context.RoomPlayer; - var room = context.Room; - var entityId = Reader.ReadUShort(); - - // if (room.Entities.TryGetValue(entityId, out var entity) && entity.Owner.Connection.Id == player.Connection.Id) - // { - // var payload = new RagonPayload(); - // payload.Read(Reader); - // - // room.DetachEntity(entity); - // player.DetachEntity(entity); - // - // entity.Destroy(); - // - // _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} destoyed entity {entity.Id}"); - // } - // else - // { - // _logger.Trace($"Entity {entity.Id} not found or Player {context.Connection.Id}|{context.LobbyPlayer.Name} have not authority"); - // } - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Handler/EntityStateOperation.cs b/Ragon.Relay/Sources/Replication/Handler/EntityStateOperation.cs deleted file mode 100644 index f509bcb..0000000 --- a/Ragon.Relay/Sources/Replication/Handler/EntityStateOperation.cs +++ /dev/null @@ -1,50 +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 Ragon.Protocol; -using Ragon.Server.IO; -using Ragon.Server.Logging; - -namespace Ragon.Server.Handler; - -public sealed class EntityStateOperation: BaseOperation -{ - private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityStateOperation)); - - public EntityStateOperation(RagonStream reader, RagonStream writer) : base(reader, writer) - { - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - var room = context.Room; - var player = context.RoomPlayer; - var entitiesCount = Reader.ReadUShort(); - - for (var entityIndex = 0; entityIndex < entitiesCount; entityIndex++) - { - // var entityId = Reader.ReadUShort(); - // if (room.Entities.TryGetValue(entityId, out var entity) && entity.TryReadState(player, Reader)) - // { - // room.Track(entity); - // } - // else - // { - // _logger.Error($"Entity with Id {entityId} not found, replication interrupted"); - // } - } - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Handler/SceneLoadOperation.cs b/Ragon.Relay/Sources/Replication/Handler/SceneLoadOperation.cs deleted file mode 100644 index 01c9906..0000000 --- a/Ragon.Relay/Sources/Replication/Handler/SceneLoadOperation.cs +++ /dev/null @@ -1,52 +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 Ragon.Protocol; -using Ragon.Server.IO; -using Ragon.Server.Logging; - -namespace Ragon.Server.Handler; - -public class SceneLoadOperation: BaseOperation -{ - private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(SceneLoadOperation)); - - public SceneLoadOperation(RagonStream reader, RagonStream writer) : base(reader, writer) {} - - public override void Handle(RagonContext context, NetworkChannel channel) - { - var roomOwner = context.Room.Owner; - var currentPlayer = context.RoomPlayer; - var room = context.Room; - var sceneName = Reader.ReadString(); - - if (roomOwner.Connection.Id != currentPlayer.Connection.Id) - { - _logger.Warning("Only owner can change scene!"); - return; - } - - room.UpdateMap(sceneName); - - Writer.Clear(); - Writer.WriteOperation(RagonOperation.LOAD_SCENE); - Writer.WriteString(sceneName); - - var sendData = Writer.ToArray(); - foreach (var player in room.PlayerList) - player.Connection.Reliable.Send(sendData); - } -} \ No newline at end of file diff --git a/Ragon.Relay/Sources/Replication/Handler/SceneLoadedOperation.cs b/Ragon.Relay/Sources/Replication/Handler/SceneLoadedOperation.cs deleted file mode 100644 index 184cd43..0000000 --- a/Ragon.Relay/Sources/Replication/Handler/SceneLoadedOperation.cs +++ /dev/null @@ -1,167 +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 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 - { - private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(SceneLoadedOperation)); - private RagonServerConfiguration _configuration; - - public SceneLoadedOperation(RagonStream reader, RagonStream writer, RagonServerConfiguration serverConfiguration) : base(reader, writer) - { - _configuration = serverConfiguration; - } - - public override void Handle(RagonContext context, NetworkChannel channel) - { - if (context.ConnectionStatus == ConnectionStatus.Unauthorized) - return; - - var owner = context.Room.Owner; - var player = context.RoomPlayer; - var room = context.Room; - - if (player.IsLoaded) - { - _logger.Warning($"Player {player.Name}:{player.Connection.Id} already ready"); - return; - } - - if (player == owner) - { - var statics = Reader.ReadUShort(); - for (var staticIndex = 0; staticIndex < statics; staticIndex++) - { - var entityType = Reader.ReadUShort(); - var eventAuthority = (RagonAuthority)Reader.ReadByte(); - var staticId = Reader.ReadUShort(); - var propertiesCount = Reader.ReadUShort(); - - 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, _configuration.LimitPropertySize)); - } - - 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); - } - - _logger.Trace($"Player {context.Connection.Id}|{context.LobbyPlayer.Name} loaded"); - - 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(); - } - else if (owner.IsLoaded) - { - // player.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); - } - } - - private void DispatchPlayerJoinExcludePlayer(RagonRoom room, RagonRoomPlayer roomPlayer, RagonStream 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.Relay/Sources/Replication/ReplicationRoom.cs b/Ragon.Relay/Sources/Replication/ReplicationRoom.cs deleted file mode 100644 index 5c8e30f..0000000 --- a/Ragon.Relay/Sources/Replication/ReplicationRoom.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Ragon.Protocol; -using Ragon.Server; -using Ragon.Server.Entity; -using Ragon.Server.Plugin; -using Ragon.Server.Room; - -namespace Ragon.Relay.Entity; - -public class RelayRoom: RagonRoom -{ - public Dictionary Entities { get; private set; } - public List DynamicEntitiesList { get; private set; } - public List StaticEntitiesList { get; private set; } - public List EntityList { get; private set; } - - private readonly HashSet _entitiesDirtySet; - - public RelayRoom(string roomId, RoomInformation info, IRoomPlugin roomPlugin) : base(roomId, info, roomPlugin) - { - Entities = new Dictionary(); - DynamicEntitiesList = new List(); - StaticEntitiesList = new List(); - EntityList = new List(); - - _entitiesDirtySet = new HashSet(); - } - - public void AttachEntity(RagonEntity entity) - { - Entities.Add(entity.Id, entity); - EntityList.Add(entity); - - if (entity.StaticId == 0) - DynamicEntitiesList.Add(entity); - else - StaticEntitiesList.Add(entity); - } - - public void DetachEntity(RagonEntity entity) - { - Entities.Remove(entity.Id); - EntityList.Remove(entity); - StaticEntitiesList.Remove(entity); - DynamicEntitiesList.Remove(entity); - - _entitiesDirtySet.Remove(entity); - } - - - public void Track(RagonEntity entity) - { - _entitiesDirtySet.Add(entity); - } - - - public void OnLeaved(RagonRoomPlayer player) - { - // var entitiesToDelete = player.Entities.DynamicList; - // Writer.WriteUShort((ushort)entitiesToDelete.Count); - // foreach (var entity in entitiesToDelete) - // { - // Writer.WriteUShort(entity.Id); - // DetachEntity(entity); - // } - // - // var sendData = Writer.ToArray(); - // Broadcast(sendData); - } - - public void Tick(float dt) - { - var entities = (ushort)_entitiesDirtySet.Count; - if (entities > 0) - { - Writer.Clear(); - Writer.WriteOperation(RagonOperation.REPLICATE_ENTITY_STATE); - Writer.WriteUShort(entities); - - foreach (var entity in _entitiesDirtySet) - entity.WriteState(Writer); - - _entitiesDirtySet.Clear(); - - var sendData = Writer.ToArray(); - foreach (var roomPlayer in ReadyPlayersList) - roomPlayer.Connection.Unreliable.Send(sendData); - } - } - - public IRagonEntity? GetEntityById(ushort id) - { - return Entities.TryGetValue(id, out var entity) ? entity : null; - } - - public IRagonEntity[] GetEntitiesOfPlayer(RagonRoomPlayer player) - { - return EntityList.Where(e => e.Owner.Connection.Id == player.Connection.Id).ToArray(); - } - - void Deatach() - { - Entities.Clear(); - DynamicEntitiesList.Clear(); - StaticEntitiesList.Clear(); - EntityList.Clear(); - - _entitiesDirtySet.Clear(); - - // if (roomPlayer.Connection.Id == Owner.Connection.Id && PlayerList.Count > 0) - // { - // var nextOwner = PlayerList[0]; - // - // Owner = nextOwner; - // - // var entitiesToUpdate = roomPlayer.Entities.StaticList; - // - // Writer.Clear(); - // Writer.WriteOperation(RagonOperation.OWNERSHIP_ENTITY_CHANGED); - // Writer.WriteUShort(Owner.Connection.Id); - // Writer.WriteUShort((ushort)entitiesToUpdate.Count); - // - // foreach (var entity in entitiesToUpdate) - // { - // Writer.WriteUShort(entity.Id); - // - // entity.Attach(nextOwner); - // nextOwner.Entities.Add(entity); - // } - // - // var sendData = Writer.ToArray(); - // Broadcast(sendData); - // } - } -} \ No newline at end of file diff --git a/Ragon.Server.ENetServer/Sources/ENetConnection.cs b/Ragon.Relay/Sources/Transport/ENet/ENetConnection.cs similarity index 97% rename from Ragon.Server.ENetServer/Sources/ENetConnection.cs rename to Ragon.Relay/Sources/Transport/ENet/ENetConnection.cs index 36a3459..28d45b5 100644 --- a/Ragon.Server.ENetServer/Sources/ENetConnection.cs +++ b/Ragon.Relay/Sources/Transport/ENet/ENetConnection.cs @@ -17,7 +17,7 @@ using ENet; using Ragon.Server.IO; -namespace Ragon.Server.ENetServer; +namespace Ragon.Transport; public sealed class ENetConnection: INetworkConnection { diff --git a/Ragon.Server.ENetServer/Sources/ENetReliableChannel.cs b/Ragon.Relay/Sources/Transport/ENet/ENetReliableChannel.cs similarity index 87% rename from Ragon.Server.ENetServer/Sources/ENetReliableChannel.cs rename to Ragon.Relay/Sources/Transport/ENet/ENetReliableChannel.cs index 7760868..db2bbe5 100644 --- a/Ragon.Server.ENetServer/Sources/ENetReliableChannel.cs +++ b/Ragon.Relay/Sources/Transport/ENet/ENetReliableChannel.cs @@ -14,12 +14,12 @@ * limitations under the License. */ -using System.Net; + using ENet; using Ragon.Protocol; using Ragon.Server.IO; -namespace Ragon.Server.ENetServer; +namespace Ragon.Transport; public sealed class ENetReliableChannel: INetworkChannel { @@ -38,16 +38,16 @@ public sealed class ENetReliableChannel: INetworkChannel { var newPacket = new Packet(); newPacket.Create(data, data.Length, PacketFlags.Reliable); - + _peer.Send(_channelId, ref newPacket); } - public void Send(RagonBuffer buffer) + public void Send(RagonStream buffer) { - buffer.ToArray(_data); + _data = buffer.ToArray(); var newPacket = new Packet(); - newPacket.Create(_data, buffer.Length, PacketFlags.Reliable); + newPacket.Create(_data, _data.Length, PacketFlags.Reliable); _peer.Send(_channelId, ref newPacket); } diff --git a/Ragon.Relay/Sources/Transport/ENet/ENetServer.cs b/Ragon.Relay/Sources/Transport/ENet/ENetServer.cs new file mode 100644 index 0000000..f78fe6e --- /dev/null +++ b/Ragon.Relay/Sources/Transport/ENet/ENetServer.cs @@ -0,0 +1,141 @@ +/* + * 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; +using ENet; +using Ragon.Protocol; +using Ragon.Server.IO; +using Ragon.Server.Logging; + +namespace Ragon.Transport; + +public sealed class ENetServer : INetworkServer +{ + private readonly Host _host = new(); + private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(ENetServer)); + + private ENetConnection[] _connections = Array.Empty(); + private INetworkListener _listener; + private uint _protocol; + private Event _event; + + public void Listen(INetworkListener listener, NetworkConfiguration configuration) + { + Library.Initialize(); + + _connections = new ENetConnection[configuration.LimitConnections]; + + _listener = listener; + _protocol = configuration.Protocol; + + var address = new Address + { + Port = (ushort)configuration.Port, + }; + + _host.Create(address, _connections.Length, 2, 0, 0, 1024 * 1024); + + var protocolDecoded = RagonVersion.Parse(_protocol); + _logger.Info($"Listen at {configuration.Address}:{configuration.Port}"); + _logger.Info($"Protocol: {protocolDecoded}"); + } + + public void Update() + { + bool polled = false; + while (!polled) + { + if (_host.CheckEvents(out _event) <= 0) + { + if (_host.Service(0, out _event) <= 0) + break; + + polled = true; + } + + switch (_event.Type) + { + case EventType.None: + { + _logger.Trace("None event"); + break; + } + case EventType.Connect: + { + if (!IsValidProtocol(_event.Data)) + { + _logger.Warning( + $"Mismatched protocol Server: {RagonVersion.Parse(_protocol)} Client: {RagonVersion.Parse(_event.Data)}, close connection"); + _event.Peer.DisconnectNow(0); + break; + } + + var connection = new ENetConnection(_event.Peer); + + _connections[_event.Peer.ID] = connection; + _listener.OnConnected(connection); + break; + } + case EventType.Disconnect: + { + var connection = _connections[_event.Peer.ID]; + _listener.OnDisconnected(connection); + break; + } + case EventType.Timeout: + { + var connection = _connections[_event.Peer.ID]; + _listener.OnTimeout(connection); + break; + } + case EventType.Receive: + { + var peerId = (ushort)_event.Peer.ID; + var connection = _connections[peerId]; + var dataRaw = new byte[_event.Packet.Length]; + + _event.Packet.CopyTo(dataRaw); + _event.Packet.Dispose(); + + _listener.OnData(connection, (NetworkChannel)_event.ChannelID, dataRaw); + break; + } + } + } + } + + public void Broadcast(byte[] data, NetworkChannel channel) + { + var packet = new Packet(); + var flag = channel == NetworkChannel.RELIABLE ? PacketFlags.Reliable : PacketFlags.None; + + packet.Create(data, flag); + + _host.Broadcast((byte)channel, ref packet); + } + + public void Stop() + { + _host?.Dispose(); + + Library.Deinitialize(); + } + + private bool IsValidProtocol(uint protocol) + { + return protocol == _protocol; + } +} \ No newline at end of file diff --git a/Ragon.Server.ENetServer/Sources/ENetUnreliableChannel.cs b/Ragon.Relay/Sources/Transport/ENet/ENetUnreliableChannel.cs similarity index 88% rename from Ragon.Server.ENetServer/Sources/ENetUnreliableChannel.cs rename to Ragon.Relay/Sources/Transport/ENet/ENetUnreliableChannel.cs index 1e205de..4bf06c6 100644 --- a/Ragon.Server.ENetServer/Sources/ENetUnreliableChannel.cs +++ b/Ragon.Relay/Sources/Transport/ENet/ENetUnreliableChannel.cs @@ -18,7 +18,7 @@ using ENet; using Ragon.Protocol; using Ragon.Server.IO; -namespace Ragon.Server.ENetServer; +namespace Ragon.Transport; public sealed class ENetUnreliableChannel: INetworkChannel { @@ -40,12 +40,12 @@ public sealed class ENetUnreliableChannel: INetworkChannel _peer.Send(_channelId, ref newPacket); } - public void Send(RagonBuffer buffer) + public void Send(RagonStream buffer) { - buffer.ToArray(_data); + _data = buffer.ToArray(); var newPacket = new Packet(); - newPacket.Create(_data, buffer.Length, PacketFlags.None); + newPacket.Create(_data, _data.Length, PacketFlags.None); _peer.Send(_channelId, ref newPacket); } diff --git a/Ragon.Server.WebSocketServer/Sources/Executor/Executor.cs b/Ragon.Relay/Sources/Transport/WebSocket/Executor/Executor.cs similarity index 91% rename from Ragon.Server.WebSocketServer/Sources/Executor/Executor.cs rename to Ragon.Relay/Sources/Transport/WebSocket/Executor/Executor.cs index 0d41f23..bf317ec 100644 --- a/Ragon.Server.WebSocketServer/Sources/Executor/Executor.cs +++ b/Ragon.Relay/Sources/Transport/WebSocket/Executor/Executor.cs @@ -14,18 +14,21 @@ * limitations under the License. */ +using System; +using System.Collections.Generic; using System.Threading.Channels; +using System.Threading.Tasks; namespace Ragon.Server.IO; -public class Executor : TaskScheduler, IExecutor +public class Executor : TaskScheduler { private readonly ChannelReader _reader; private readonly ChannelWriter _writer; private readonly Queue _pendingTasks; private readonly TaskFactory _taskFactory; - public Task Run(Action action, TaskCreationOptions task = TaskCreationOptions.None) + public Task Run(Action action, TaskCreationOptions task) { return _taskFactory.StartNew(action, task); } diff --git a/Ragon.Server.WebSocketServer/Sources/WebSocketConnection.cs b/Ragon.Relay/Sources/Transport/WebSocket/WebSocketConnection.cs similarity index 96% rename from Ragon.Server.WebSocketServer/Sources/WebSocketConnection.cs rename to Ragon.Relay/Sources/Transport/WebSocket/WebSocketConnection.cs index 49455c9..7e3b9b1 100644 --- a/Ragon.Server.WebSocketServer/Sources/WebSocketConnection.cs +++ b/Ragon.Relay/Sources/Transport/WebSocket/WebSocketConnection.cs @@ -14,7 +14,10 @@ * limitations under the License. */ +using System; using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; using Ragon.Server.IO; using Ragon.Server.Logging; diff --git a/Ragon.Server.WebSocketServer/Sources/WebSocketReliableChannel.cs b/Ragon.Relay/Sources/Transport/WebSocket/WebSocketReliableChannel.cs similarity index 91% rename from Ragon.Server.WebSocketServer/Sources/WebSocketReliableChannel.cs rename to Ragon.Relay/Sources/Transport/WebSocket/WebSocketReliableChannel.cs index 383403b..5628e9f 100644 --- a/Ragon.Server.WebSocketServer/Sources/WebSocketReliableChannel.cs +++ b/Ragon.Relay/Sources/Transport/WebSocket/WebSocketReliableChannel.cs @@ -14,7 +14,10 @@ * limitations under the License. */ +using System.Collections.Generic; using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; using Ragon.Protocol; using Ragon.Server.IO; @@ -36,7 +39,7 @@ public class WebSocketReliableChannel : INetworkChannel _queue.Enqueue(data); } - public void Send(RagonBuffer buffer) + public void Send(RagonStream buffer) { var sendData = buffer.ToArray(); _queue.Enqueue(sendData); diff --git a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs b/Ragon.Relay/Sources/Transport/WebSocket/WebSocketServer.cs similarity index 97% rename from Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs rename to Ragon.Relay/Sources/Transport/WebSocket/WebSocketServer.cs index 6d5f232..da71407 100644 --- a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs +++ b/Ragon.Relay/Sources/Transport/WebSocket/WebSocketServer.cs @@ -14,9 +14,12 @@ * limitations under the License. */ +using System; using System.Buffers; +using System.Collections.Generic; using System.Net; using System.Net.WebSockets; +using System.Threading; using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Logging; @@ -160,7 +163,7 @@ public class WebSocketServer : INetworkServer _httpListener.Prefixes.Add($"http://{configuration.Address}:{configuration.Port}/"); _httpListener.Start(); - _executor.Run(() => StartAccept(_cancellationTokenSource.Token)); + // _executor.Run(() => StartAccept(_cancellationTokenSource.Token)); var protocolDecoded = RagonVersion.Parse(configuration.Protocol); _logger.Info($"Listen at http://{configuration.Address}:{configuration.Port}/"); diff --git a/Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj b/Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj deleted file mode 100644 index ce07810..0000000 --- a/Ragon.Server.ENetServer/Ragon.Server.ENetServer.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - enable - enable - Ragon.ENet - net6.0;net7.0;net8.0 - true - Eduard Kargin - Eduard Kargin - 1.4.0 - Ragon Server ENet - Ragon Server ENet transport - https://ragon.io - Apache-2.0 - https://github.com/edmand46/Ragon - Source - - - - - - - - - - - diff --git a/Ragon.Server.ENetServer/Sources/ENetServer.cs b/Ragon.Server.ENetServer/Sources/ENetServer.cs deleted file mode 100644 index 456e2e8..0000000 --- a/Ragon.Server.ENetServer/Sources/ENetServer.cs +++ /dev/null @@ -1,141 +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 ENet; -using Ragon.Protocol; -using Ragon.Server.IO; -using Ragon.Server.Logging; - -namespace Ragon.Server.ENetServer -{ - public sealed class ENetServer : INetworkServer - { - - private readonly Host _host = new(); - private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(ENetServer)); - - private ENetConnection[] _connections = Array.Empty(); - private INetworkListener _listener; - private uint _protocol; - private ENet.Event _event; - - public void Listen(INetworkListener listener, NetworkConfiguration configuration) - { - Library.Initialize(); - - _connections = new ENetConnection[configuration.LimitConnections]; - - _listener = listener; - _protocol = configuration.Protocol; - - var address = new Address - { - Port = (ushort)configuration.Port, - }; - - _host.Create(address, _connections.Length, 2, 0, 0, 1024 * 1024); - - var protocolDecoded = RagonVersion.Parse(_protocol); - _logger.Info($"Listen at {configuration.Address}:{configuration.Port}"); - _logger.Info($"Protocol: {protocolDecoded}"); - } - - public void Update() - { - bool polled = false; - while (!polled) - { - if (_host.CheckEvents(out _event) <= 0) - { - if (_host.Service(0, out _event) <= 0) - break; - - polled = true; - } - - switch (_event.Type) - { - case EventType.None: - { - _logger.Trace("None event"); - break; - } - case EventType.Connect: - { - if (!IsValidProtocol(_event.Data)) - { - _logger.Warning($"Mismatched protocol Server: {RagonVersion.Parse(_protocol)} Client: {RagonVersion.Parse(_event.Data)}, close connection"); - _event.Peer.DisconnectNow(0); - break; - } - - var connection = new ENetConnection(_event.Peer); - - _connections[_event.Peer.ID] = connection; - _listener.OnConnected(connection); - break; - } - case EventType.Disconnect: - { - var connection = _connections[_event.Peer.ID]; - _listener.OnDisconnected(connection); - break; - } - case EventType.Timeout: - { - var connection = _connections[_event.Peer.ID]; - _listener.OnTimeout(connection); - break; - } - case EventType.Receive: - { - var peerId = (ushort)_event.Peer.ID; - var connection = _connections[peerId]; - var dataRaw = new byte[_event.Packet.Length]; - - _event.Packet.CopyTo(dataRaw); - _event.Packet.Dispose(); - - _listener.OnData(connection, (NetworkChannel)_event.ChannelID, dataRaw); - break; - } - } - } - } - - public void Broadcast(byte[] data, NetworkChannel channel) - { - var packet = new Packet(); - var flag = channel == NetworkChannel.RELIABLE? PacketFlags.Reliable: PacketFlags.None; - - packet.Create(data, flag); - - _host.Broadcast((byte)channel, ref packet); - } - - public void Stop() - { - _host?.Dispose(); - - Library.Deinitialize(); - } - - private bool IsValidProtocol(uint protocol) - { - return protocol == _protocol; - } - } -} \ No newline at end of file diff --git a/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj b/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj index 87d8c95..9a0d669 100644 --- a/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj +++ b/Ragon.Server.WebSocketServer/Ragon.Server.WebSocketServer.csproj @@ -21,4 +21,8 @@ + + + + diff --git a/Ragon.Server.WebSocketServer/Sources/Executor/IExecutor.cs b/Ragon.Server.WebSocketServer/Sources/Executor/IExecutor.cs deleted file mode 100644 index 849c1cc..0000000 --- a/Ragon.Server.WebSocketServer/Sources/Executor/IExecutor.cs +++ /dev/null @@ -1,22 +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. - */ - -namespace Ragon.Server.IO; - -public interface IExecutor -{ - public Task Run(Action action, TaskCreationOptions task = TaskCreationOptions.None); -} \ No newline at end of file diff --git a/Ragon.Server/Sources/Data/RagonData.cs b/Ragon.Server/Sources/Data/RagonData.cs index c451fd2..4bebbaa 100644 --- a/Ragon.Server/Sources/Data/RagonData.cs +++ b/Ragon.Server/Sources/Data/RagonData.cs @@ -44,7 +44,7 @@ public class RagonData var toDelete = _data .Where(p => p.Value.Length == 0) .Select(p => p.Key); - + foreach (var prop in toDelete) _data.Remove(prop); diff --git a/Ragon.Server/Sources/Event/RagonEvent.cs b/Ragon.Server/Sources/Event/RagonEvent.cs index 92d6fc6..f3bbca1 100644 --- a/Ragon.Server/Sources/Event/RagonEvent.cs +++ b/Ragon.Server/Sources/Event/RagonEvent.cs @@ -23,8 +23,8 @@ public class RagonEvent { public RagonRoomPlayer Invoker { get; private set; } public ushort EventCode { get; private set; } - public ushort Size => (ushort) _size; - + public ushort Size => (ushort)_size; + private uint[] _data = new uint[128]; private int _size = 0; @@ -36,7 +36,7 @@ public class RagonEvent Invoker = invoker; EventCode = eventCode; } - + public void Read(RagonStream buffer) { // _size = buffer.Capacity; diff --git a/Ragon.Server/Sources/Handler/RoomDataOperation.cs b/Ragon.Server/Sources/Handler/RoomDataOperation.cs index 8a477a9..970a5a0 100644 --- a/Ragon.Server/Sources/Handler/RoomDataOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomDataOperation.cs @@ -29,7 +29,8 @@ public sealed class RoomDataOperation : BaseOperation { var player = context.RoomPlayer; var room = context.Room; - + + var data = Reader.ReadBinary(Reader.Lenght); var dataSize = data.Length - 1; var headerSize = 3; diff --git a/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs b/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs index 842f0ab..0b2cbab 100644 --- a/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomLeaveOperation.cs @@ -26,6 +26,7 @@ public sealed class RoomLeaveOperation: BaseOperation public RoomLeaveOperation(RagonStream reader, RagonStream writer): base(reader, writer) { + } public override void Handle(RagonContext context, NetworkChannel channel) diff --git a/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs b/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs index 67070a1..e8c029a 100644 --- a/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs +++ b/Ragon.Server/Sources/Handler/RoomOwnershipOperation.cs @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + using Ragon.Protocol; using Ragon.Server.IO; using Ragon.Server.Logging; diff --git a/Ragon.Server/Sources/IO/INetworkChannel.cs b/Ragon.Server/Sources/IO/INetworkChannel.cs index 147a5e2..db3e3df 100644 --- a/Ragon.Server/Sources/IO/INetworkChannel.cs +++ b/Ragon.Server/Sources/IO/INetworkChannel.cs @@ -21,5 +21,5 @@ namespace Ragon.Server.IO; public interface INetworkChannel { void Send(byte[] data); - void Send(RagonBuffer buffer); + void Send(RagonStream buffer); } \ No newline at end of file diff --git a/Ragon.Server/Sources/Lobby/RagonLobbyDispatcher.cs b/Ragon.Server/Sources/Lobby/RagonLobbyDispatcher.cs index 8593bf6..115bf13 100644 --- a/Ragon.Server/Sources/Lobby/RagonLobbyDispatcher.cs +++ b/Ragon.Server/Sources/Lobby/RagonLobbyDispatcher.cs @@ -22,7 +22,7 @@ public class RagonLobbyDispatcher for (int i = 0; i < rooms.Count; i++) { var room = rooms[i]; - + writer.WriteString(room.Id); writer.WriteString(room.Scene); writer.WriteUShort((ushort)room.PlayerMax); diff --git a/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs b/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs index 5622cab..6446a95 100644 --- a/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs +++ b/Ragon.Server/Sources/Lobby/RagonLobbyInMemory.cs @@ -73,6 +73,11 @@ public class LobbyInMemory : IRagonLobby return false; } + public bool FindRoomByProperties(Dictionary props) + { + return true; + } + public void Persist(RagonRoom room) { room.Attach(); diff --git a/Ragon.Server/Sources/Lobby/RagonLobbyPlayer.cs b/Ragon.Server/Sources/Lobby/RagonLobbyPlayer.cs index 6bd41e1..e613ac4 100644 --- a/Ragon.Server/Sources/Lobby/RagonLobbyPlayer.cs +++ b/Ragon.Server/Sources/Lobby/RagonLobbyPlayer.cs @@ -14,7 +14,6 @@ * limitations under the License. */ -using Ragon.Server.Data; using Ragon.Server.IO; namespace Ragon.Server.Lobby; diff --git a/Ragon.Server/Sources/RagonContext.cs b/Ragon.Server/Sources/RagonContext.cs index 337d8e7..76830e2 100644 --- a/Ragon.Server/Sources/RagonContext.cs +++ b/Ragon.Server/Sources/RagonContext.cs @@ -56,7 +56,7 @@ public class RagonContext internal void SetRoom(RagonRoom room, RagonRoomPlayer player) { - Room?.DetachPlayer(RoomPlayer); + Room?.DetachPlayer(player); Room = room; RoomPlayer = player; diff --git a/Ragon.Server/Sources/RagonServer.cs b/Ragon.Server/Sources/RagonServer.cs index 661346b..1c66c64 100644 --- a/Ragon.Server/Sources/RagonServer.cs +++ b/Ragon.Server/Sources/RagonServer.cs @@ -69,7 +69,7 @@ public class RagonServer : IRagonServer, INetworkListener _scheduler.Run(new RagonActionTimer(SendRoomList, 2.0f)); _scheduler.Run(new RagonActionTimer(SendPlayerUserData, 0.1f)); _scheduler.Run(new RagonActionTimer(SendRoomUserData, 0.1f)); - + _serverPlugin.OnAttached(this); _handlers = new BaseOperation[byte.MaxValue]; @@ -93,18 +93,16 @@ public class RagonServer : IRagonServer, INetworkListener if (_timer.ElapsedMilliseconds > _tickRate) { - + SendTimestamp(); _scheduler.Update(_timer.ElapsedMilliseconds); _timer.Restart(); } - SendTimestamp(); - _server.Update(); } - public void Start(bool executeInDedicatedThread = false) + public void Listen() { CopyrightInfo(); diff --git a/Ragon.Tests/Connection.cs b/Ragon.Tests/Tests.cs similarity index 60% rename from Ragon.Tests/Connection.cs rename to Ragon.Tests/Tests.cs index d540690..b08adf8 100644 --- a/Ragon.Tests/Connection.cs +++ b/Ragon.Tests/Tests.cs @@ -1,7 +1,9 @@ using NUnit.Mocks; using Ragon.Client; +using Ragon.Protocol; using Ragon.Relay; using Ragon.Server; +using Ragon.Server.Handler; using Ragon.Server.Logging; using Ragon.Server.Plugin; @@ -11,12 +13,12 @@ public class Tests { private RagonClient _client; private RagonServer _server; - + [SetUp] public void Setup() { LoggerManager.SetLoggerFactory(new RelayLoggerFactory()); - + var fakeNetwork = new FakeNetwork(); var serverConfiguration = new RagonServerConfiguration() { @@ -32,14 +34,33 @@ public class Tests ServerTickRate = 30, ServerAddress = "0.0.0.0", }; - + _client = new RagonClient(fakeNetwork.ClientNetwork, 30); _server = new RagonServer(fakeNetwork.ServerNetwork, new BaseServerPlugin(), serverConfiguration); } [Test] - public void Test1() + public void Connection() { - + _client.Connect("12", 000, ""); + _server.Listen(); + // var configuration = new RagonServerConfiguration(); + + // var reader = new RagonStream(); + // var writer = new RagonStream(); + + // var server = new RagonServer(); + // var plugin = new RelayServerPlugin(); + // var observer = new RagonContextObserver(); + + // var authorizationOperation = new AuthorizationOperation(reader, writer, server, plugin, observer, configuration); + + // authorizationOperation.Handle() + } + + [Test] + public void Authorization() + { + } } \ No newline at end of file diff --git a/Ragon.Tests/Utilities/FakeNetwork.cs b/Ragon.Tests/Utilities/FakeNetwork.cs index a8a288f..7960184 100644 --- a/Ragon.Tests/Utilities/FakeNetwork.cs +++ b/Ragon.Tests/Utilities/FakeNetwork.cs @@ -6,7 +6,8 @@ public class FakeNetwork { public FakeClientNetwork ClientNetwork; public FakeServerNetwork ServerNetwork; - + public FakeSocket Socket; + public FakeNetwork() { ClientNetwork = new FakeClientNetwork(); diff --git a/Ragon.Tests/Utilities/FakeServerNetworkChannel.cs b/Ragon.Tests/Utilities/FakeServerNetworkChannel.cs index 5ec7d4b..f693369 100644 --- a/Ragon.Tests/Utilities/FakeServerNetworkChannel.cs +++ b/Ragon.Tests/Utilities/FakeServerNetworkChannel.cs @@ -10,7 +10,7 @@ public class FakeServerNetworkChannel: INetworkChannel } - public void Send(RagonBuffer buffer) + public void Send(RagonStream buffer) { } diff --git a/Ragon.Tests/Utilities/FakeSocket.cs b/Ragon.Tests/Utilities/FakeSocket.cs new file mode 100644 index 0000000..7f7f6a7 --- /dev/null +++ b/Ragon.Tests/Utilities/FakeSocket.cs @@ -0,0 +1,4 @@ +public class FakeSocket +{ + // public void +} diff --git a/Ragon.sln b/Ragon.sln index 75bc476..7590e07 100644 --- a/Ragon.sln +++ b/Ragon.sln @@ -6,10 +6,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Protocol", "Ragon.Pro EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Server", "Ragon.Server\Ragon.Server.csproj", "{F4AA86B9-2486-4B53-BA77-43D958A2FDC3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Server.WebSocketServer", "Ragon.Server.WebSocketServer\Ragon.Server.WebSocketServer.csproj", "{81050343-A9B8-487B-86C8-7A5B7DD9C39B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Server.ENetServer", "Ragon.Server.ENetServer\Ragon.Server.ENetServer.csproj", "{DD79AC4F-9E5C-4938-850E-805D537E68D0}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Client", "Ragon.Client\Ragon.Client.csproj", "{C82D65BF-6D80-4263-ADFE-CB9ED990B6C3}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Tests", "Ragon.Tests\Ragon.Tests.csproj", "{5833194D-CAD0-4517-BBC6-4DB0D7F1BEF1}" @@ -32,14 +28,6 @@ Global {F4AA86B9-2486-4B53-BA77-43D958A2FDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {F4AA86B9-2486-4B53-BA77-43D958A2FDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {F4AA86B9-2486-4B53-BA77-43D958A2FDC3}.Release|Any CPU.Build.0 = Release|Any CPU - {81050343-A9B8-487B-86C8-7A5B7DD9C39B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {81050343-A9B8-487B-86C8-7A5B7DD9C39B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {81050343-A9B8-487B-86C8-7A5B7DD9C39B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {81050343-A9B8-487B-86C8-7A5B7DD9C39B}.Release|Any CPU.Build.0 = Release|Any CPU - {DD79AC4F-9E5C-4938-850E-805D537E68D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DD79AC4F-9E5C-4938-850E-805D537E68D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DD79AC4F-9E5C-4938-850E-805D537E68D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DD79AC4F-9E5C-4938-850E-805D537E68D0}.Release|Any CPU.Build.0 = Release|Any CPU {C82D65BF-6D80-4263-ADFE-CB9ED990B6C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C82D65BF-6D80-4263-ADFE-CB9ED990B6C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {C82D65BF-6D80-4263-ADFE-CB9ED990B6C3}.Release|Any CPU.ActiveCfg = Release|Any CPU