From 2dd81cd85967bfdc1ff2ef0f326bdff73b85edcd Mon Sep 17 00:00:00 2001 From: Edmand46 Date: Sat, 30 Apr 2022 08:20:17 +0400 Subject: [PATCH] refactoring: heap -> span --- .../Game.csproj | 4 + {YohohoArenaPlugin => Game}/NLog.config | 2 +- {YohohoArenaPlugin => Game}/Program.cs | 2 +- Game/Source/GameAuthorizer.cs | 11 + Game/Source/GameFactory.cs | 11 + .../Source/Modes/ExamplePlugin.cs | 13 +- {YohohoArenaPlugin => Game}/config.json | 1 + Ragon.Common/BitBufferExtension.cs | 29 -- Ragon.Common/Protocol/Data/AuthorizeData.cs | 23 -- Ragon.Common/Protocol/Data/FindAndJoinData.cs | 19 -- Ragon.Common/Protocol/Data/SceneLoadData.cs | 19 -- Ragon.Common/Protocol/Data/SnapshotData.cs | 45 --- .../{Data/Abstract/IData.cs => IPacket.cs} | 2 +- Ragon.Common/Protocol/Opcode.cs | 7 +- Ragon.Common/Protocol/ProtocolHeader.cs | 36 +++ Ragon.Common/Protocol/Wrapper.cs | 55 ---- Ragon.Common/Ragon.Common.csproj | 2 + Ragon.sln | 2 +- Ragon/Ragon.csproj | 14 + Ragon/Ragon.csproj.DotSettings | 2 - Ragon/Sources/AuthorizationManager.cs | 9 + Ragon/Sources/Configuration/Configuration.cs | 4 +- Ragon/Sources/ENetServer.cs | 40 +-- Ragon/Sources/Event/DeliveryType.cs | 7 + Ragon/Sources/Event/Event.cs | 3 + Ragon/Sources/Event/EventStream.cs | 39 +++ Ragon/Sources/Plugin/PluginBase.cs | 114 ++++++- Ragon/Sources/Plugin/PluginFactory.cs | 4 + Ragon/Sources/Rooms/Room.cs | 291 +++++++++--------- Ragon/Sources/Rooms/RoomManager.cs | 84 +++-- Ragon/Sources/Rooms/RoomThread.cs | 9 +- Ragon/todo | 2 - YohohoArenaPlugin/Source/ArenaPlugin.cs | 46 --- YohohoArenaPlugin/Source/Events/SpawnEvent.cs | 6 - YohohoArenaPlugin/Source/GameFactory.cs | 17 - readme.md | 9 +- 36 files changed, 494 insertions(+), 489 deletions(-) rename YohohoArenaPlugin/YohohoArenaPlugin.csproj => Game/Game.csproj (88%) rename {YohohoArenaPlugin => Game}/NLog.config (93%) rename {YohohoArenaPlugin => Game}/Program.cs (94%) create mode 100644 Game/Source/GameAuthorizer.cs create mode 100644 Game/Source/GameFactory.cs rename YohohoArenaPlugin/Source/SpawnPlugin.cs => Game/Source/Modes/ExamplePlugin.cs (59%) rename {YohohoArenaPlugin => Game}/config.json (95%) delete mode 100644 Ragon.Common/BitBufferExtension.cs delete mode 100644 Ragon.Common/Protocol/Data/AuthorizeData.cs delete mode 100644 Ragon.Common/Protocol/Data/FindAndJoinData.cs delete mode 100644 Ragon.Common/Protocol/Data/SceneLoadData.cs delete mode 100644 Ragon.Common/Protocol/Data/SnapshotData.cs rename Ragon.Common/Protocol/{Data/Abstract/IData.cs => IPacket.cs} (85%) create mode 100644 Ragon.Common/Protocol/ProtocolHeader.cs delete mode 100644 Ragon.Common/Protocol/Wrapper.cs delete mode 100644 Ragon/Ragon.csproj.DotSettings create mode 100644 Ragon/Sources/AuthorizationManager.cs create mode 100644 Ragon/Sources/Event/DeliveryType.cs create mode 100644 Ragon/Sources/Event/EventStream.cs delete mode 100644 Ragon/todo delete mode 100755 YohohoArenaPlugin/Source/ArenaPlugin.cs delete mode 100644 YohohoArenaPlugin/Source/Events/SpawnEvent.cs delete mode 100644 YohohoArenaPlugin/Source/GameFactory.cs diff --git a/YohohoArenaPlugin/YohohoArenaPlugin.csproj b/Game/Game.csproj similarity index 88% rename from YohohoArenaPlugin/YohohoArenaPlugin.csproj rename to Game/Game.csproj index e15ecc8..3984c7e 100755 --- a/YohohoArenaPlugin/YohohoArenaPlugin.csproj +++ b/Game/Game.csproj @@ -19,4 +19,8 @@ + + + + diff --git a/YohohoArenaPlugin/NLog.config b/Game/NLog.config similarity index 93% rename from YohohoArenaPlugin/NLog.config rename to Game/NLog.config index 55111aa..6919795 100755 --- a/YohohoArenaPlugin/NLog.config +++ b/Game/NLog.config @@ -1,4 +1,4 @@ - + diff --git a/YohohoArenaPlugin/Program.cs b/Game/Program.cs similarity index 94% rename from YohohoArenaPlugin/Program.cs rename to Game/Program.cs index 4a24121..04fae28 100755 --- a/YohohoArenaPlugin/Program.cs +++ b/Game/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using Game.Source; using NetStack.Serialization; using Ragon.Core; diff --git a/Game/Source/GameAuthorizer.cs b/Game/Source/GameAuthorizer.cs new file mode 100644 index 0000000..2e390eb --- /dev/null +++ b/Game/Source/GameAuthorizer.cs @@ -0,0 +1,11 @@ +using Ragon.Core; + +namespace Game.Source; + +public class GameAuthorizer: AuthorizationManager +{ + public override bool OnAuthorize(uint peerId, byte[] payload) + { + return true; + } +} \ No newline at end of file diff --git a/Game/Source/GameFactory.cs b/Game/Source/GameFactory.cs new file mode 100644 index 0000000..085bd8f --- /dev/null +++ b/Game/Source/GameFactory.cs @@ -0,0 +1,11 @@ +using Ragon.Core; + +namespace Game.Source +{ + public class GameFactory : PluginFactory + { + public string PluginName { get; set; } = "ExamplePlugin"; + public PluginBase CreatePlugin(string map) => new ExamplePlugin(); + public AuthorizationManager CreateManager() => new GameAuthorizer(); + } +} \ No newline at end of file diff --git a/YohohoArenaPlugin/Source/SpawnPlugin.cs b/Game/Source/Modes/ExamplePlugin.cs similarity index 59% rename from YohohoArenaPlugin/Source/SpawnPlugin.cs rename to Game/Source/Modes/ExamplePlugin.cs index 4779a31..cb75baa 100755 --- a/YohohoArenaPlugin/Source/SpawnPlugin.cs +++ b/Game/Source/Modes/ExamplePlugin.cs @@ -1,21 +1,14 @@ -using Game.Source.Events; -using NLog; +using NLog; using Ragon.Core; namespace Game.Source { - public class SpawnPlugin: PluginBase + public class ExamplePlugin: PluginBase { private ILogger _logger = LogManager.GetCurrentClassLogger(); - - public void SpawnEvent(SpawnEvent evnt) - { - - } + public override void OnStart() { - Subscribe(SpawnEvent); - _logger.Info("Plugin started"); } diff --git a/YohohoArenaPlugin/config.json b/Game/config.json similarity index 95% rename from YohohoArenaPlugin/config.json rename to Game/config.json index 9a87d33..8af11dd 100755 --- a/YohohoArenaPlugin/config.json +++ b/Game/config.json @@ -1,4 +1,5 @@ { + "apiKey": "123", "server": { "port": 4444, "skipTimeout": 60 diff --git a/Ragon.Common/BitBufferExtension.cs b/Ragon.Common/BitBufferExtension.cs deleted file mode 100644 index 958cdcf..0000000 --- a/Ragon.Common/BitBufferExtension.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using NetStack.Serialization; - -namespace Ragon.Common -{ - public static class BitBufferExtension - { - public static BitBuffer AddBytes(this BitBuffer buffer, byte[] data) - { - buffer.AddInt(data.Length); - foreach (var b in data) - buffer.AddByte(b); - - return buffer; - } - - public static byte[] ReadBytes(this BitBuffer buffer) - { - var size = buffer.ReadInt(); - var data = new byte[size]; - var i = 0; - - while (i < size) - data[i] = buffer.ReadByte(); - - return data; - } - } -} \ No newline at end of file diff --git a/Ragon.Common/Protocol/Data/AuthorizeData.cs b/Ragon.Common/Protocol/Data/AuthorizeData.cs deleted file mode 100644 index 828889e..0000000 --- a/Ragon.Common/Protocol/Data/AuthorizeData.cs +++ /dev/null @@ -1,23 +0,0 @@ -using NetStack.Serialization; - -namespace Ragon.Core -{ - - public class AuthorationData : IData - { - public string Login { get; set; } - public string Password { get; set; } - - public void Serialize(BitBuffer buffer) - { - buffer.AddString(Login); - buffer.AddString(Password); - } - - public void Deserialize(BitBuffer buffer) - { - Login = buffer.ReadString(); - Password = buffer.ReadString(); - } - } -} \ No newline at end of file diff --git a/Ragon.Common/Protocol/Data/FindAndJoinData.cs b/Ragon.Common/Protocol/Data/FindAndJoinData.cs deleted file mode 100644 index bdb0a48..0000000 --- a/Ragon.Common/Protocol/Data/FindAndJoinData.cs +++ /dev/null @@ -1,19 +0,0 @@ -using NetStack.Serialization; - -namespace Ragon.Core -{ - public class FindAndJoinData: IData - { - public string Map; - - public void Serialize(BitBuffer buffer) - { - buffer.AddString(Map); - } - - public void Deserialize(BitBuffer buffer) - { - Map = buffer.ReadString(); - } - } -} \ No newline at end of file diff --git a/Ragon.Common/Protocol/Data/SceneLoadData.cs b/Ragon.Common/Protocol/Data/SceneLoadData.cs deleted file mode 100644 index 9c990f0..0000000 --- a/Ragon.Common/Protocol/Data/SceneLoadData.cs +++ /dev/null @@ -1,19 +0,0 @@ -using NetStack.Serialization; - -namespace Ragon.Core -{ - public class SceneLoadData: IData - { - public string Scene; - - public void Serialize(BitBuffer buffer) - { - buffer.AddString(Scene); - } - - public void Deserialize(BitBuffer buffer) - { - Scene = buffer.ReadString(); - } - } -} \ No newline at end of file diff --git a/Ragon.Common/Protocol/Data/SnapshotData.cs b/Ragon.Common/Protocol/Data/SnapshotData.cs deleted file mode 100644 index 6d702ba..0000000 --- a/Ragon.Common/Protocol/Data/SnapshotData.cs +++ /dev/null @@ -1,45 +0,0 @@ -using NetStack.Serialization; -using Ragon.Common; - -namespace Ragon.Core -{ - - public class EntityData: IData - { - public int EntityId; - public byte[] State; - public void Serialize(BitBuffer buffer) - { - buffer.AddInt(EntityId); - buffer.AddBytes(State); - } - - public void Deserialize(BitBuffer buffer) - { - EntityId = buffer.ReadInt(); - State = buffer.ReadBytes(); - } - } - public class SnapshotData: IData - { - public EntityData[] Entities; - public void Serialize(BitBuffer buffer) - { - buffer.AddInt(Entities.Length); - foreach (var entityData in Entities) - entityData.Serialize(buffer); - } - public void Deserialize(BitBuffer buffer) - { - var entitiesSize = buffer.ReadInt(); - var i = 0; - - Entities = new EntityData[entitiesSize]; - while (i < entitiesSize) - { - Entities[i] = new EntityData(); - Entities[i].Deserialize(buffer); - } - } - } -} \ No newline at end of file diff --git a/Ragon.Common/Protocol/Data/Abstract/IData.cs b/Ragon.Common/Protocol/IPacket.cs similarity index 85% rename from Ragon.Common/Protocol/Data/Abstract/IData.cs rename to Ragon.Common/Protocol/IPacket.cs index 81dc013..316cfe1 100644 --- a/Ragon.Common/Protocol/Data/Abstract/IData.cs +++ b/Ragon.Common/Protocol/IPacket.cs @@ -2,7 +2,7 @@ using NetStack.Serialization; namespace Ragon.Core { - public interface IData + public interface IPacket { public void Serialize(BitBuffer buffer); public void Deserialize(BitBuffer buffer); diff --git a/Ragon.Common/Protocol/Opcode.cs b/Ragon.Common/Protocol/Opcode.cs index 96d5e86..0e0fae6 100644 --- a/Ragon.Common/Protocol/Opcode.cs +++ b/Ragon.Common/Protocol/Opcode.cs @@ -11,9 +11,9 @@ namespace Ragon.Common.Protocol LOAD_SCENE, SCENE_IS_LOADED, - - PLAYER_CONNECTED, - PLAYER_DISCONNECTED, + + PLAYER_JOINED, + PLAYER_LEAVED, CREATE_ENTITY, DESTROY_ENTITY, @@ -24,6 +24,7 @@ namespace Ragon.Common.Protocol REPLICATE_ENTITY_STATE, REPLICATE_ENTITY_PROPERTY, + REPLICATE_ENTITY_EVENT, REPLICATE_EVENT, } } \ No newline at end of file diff --git a/Ragon.Common/Protocol/ProtocolHeader.cs b/Ragon.Common/Protocol/ProtocolHeader.cs new file mode 100644 index 0000000..ec6222f --- /dev/null +++ b/Ragon.Common/Protocol/ProtocolHeader.cs @@ -0,0 +1,36 @@ +using System; +using System.Runtime.CompilerServices; +using NetStack.Buffers; + +namespace Ragon.Core +{ + public static class ProtocolHeader + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteUShort(ushort id, ref Span data) { + data[0] = (byte)(id & 0x00FF); + data[1] = (byte)((id & 0xFF00) >> 8); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort ReadUShort(ref ReadOnlySpan data) + { + return (ushort)(data[0] + (data[1] << 8)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteInt(int id, ref Span data) { + data[0] = (byte)(id & 0x00FF); + data[1] = (byte)((id & 0xFF00) >> 8); + data[2] = (byte)((id & 0xFF00) >> 16); + data[3] = (byte)((id & 0xFF00) >> 24); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ReadInt(ref ReadOnlySpan data) + { + return (ushort)(data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)); + } + + } +} \ No newline at end of file diff --git a/Ragon.Common/Protocol/Wrapper.cs b/Ragon.Common/Protocol/Wrapper.cs deleted file mode 100644 index 2c35937..0000000 --- a/Ragon.Common/Protocol/Wrapper.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using NetStack.Buffers; - -namespace Ragon.Common.Protocol -{ - public static class ProtocolHeader - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteOperation(ushort id, byte[] data) { - data[0] = (byte)(id & 0x00FF); - data[1] = (byte)((id & 0xFF00) >> 8); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ushort ReadOperation(byte[] data, int offset = 0) - { - return (ushort)(data[offset] + (data[offset + 1] << 8)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteEntity(int id, byte[] data, int offset = 2) { - data[offset] = (byte)(id & 0x00FF); - data[offset + 1] = (byte)((id & 0xFF00) >> 8); - data[offset + 2] = (byte)((id & 0xFF00) >> 16); - data[offset + 3] = (byte)((id & 0xFF00) >> 24); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ReadEntity(byte[] data, int offset = 2) - { - return (ushort)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24)); - } - - public static int ReadProperty(byte[] data, int offset = 2) - { - return ReadEntity(data, offset); - } - - public static void WriteProperty(int id, byte[] data) - { - WriteEntity(id, data); - } - - public static int ReadEvent(byte[] data, int offset = 2) - { - return ReadEntity(data, offset); - } - - public static void WriteEvent(int id, byte[] data) - { - WriteEntity(id, data); - } - } -} \ No newline at end of file diff --git a/Ragon.Common/Ragon.Common.csproj b/Ragon.Common/Ragon.Common.csproj index 9d21669..70ae002 100644 --- a/Ragon.Common/Ragon.Common.csproj +++ b/Ragon.Common/Ragon.Common.csproj @@ -11,10 +11,12 @@ /Users/edmand46/UnityProjects/ragon-client/Assets/RagonSDK/ false true + TRACE;NETSTACK_SPAN /Users/edmand46/UnityProjects/ragon-client/Assets/RagonSDK/ + TRACE;NETSTACK_SPAN diff --git a/Ragon.sln b/Ragon.sln index 05a9c4c..6838f6b 100755 --- a/Ragon.sln +++ b/Ragon.sln @@ -2,7 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon", "Ragon\Ragon.csproj", "{BABA1AF0-CF91-43F2-9577-53800068ACCF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YohohoArenaPlugin", "YohohoArenaPlugin\YohohoArenaPlugin.csproj", "{C2B87ADE-A122-4366-8EB7-24DAE11EBAF0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Game", "Game\Game.csproj", "{C2B87ADE-A122-4366-8EB7-24DAE11EBAF0}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Common", "Ragon.Common\Ragon.Common.csproj", "{F478B2A2-36F4-43B9-9BB7-382A57C449B2}" EndProject diff --git a/Ragon/Ragon.csproj b/Ragon/Ragon.csproj index 4205978..2740052 100755 --- a/Ragon/Ragon.csproj +++ b/Ragon/Ragon.csproj @@ -6,6 +6,16 @@ net6.0;netstandard2.1 + + true + TRACE;NETSTACK_SPAN + + + + true + TRACE;NETSTACK_SPAN + + @@ -16,4 +26,8 @@ + + + + diff --git a/Ragon/Ragon.csproj.DotSettings b/Ragon/Ragon.csproj.DotSettings deleted file mode 100644 index fadcd66..0000000 --- a/Ragon/Ragon.csproj.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - True \ No newline at end of file diff --git a/Ragon/Sources/AuthorizationManager.cs b/Ragon/Sources/AuthorizationManager.cs new file mode 100644 index 0000000..ec9797b --- /dev/null +++ b/Ragon/Sources/AuthorizationManager.cs @@ -0,0 +1,9 @@ +namespace Ragon.Core; + +public class AuthorizationManager +{ + public virtual bool OnAuthorize(uint peerId, byte[] payload) + { + return true; + } +} \ No newline at end of file diff --git a/Ragon/Sources/Configuration/Configuration.cs b/Ragon/Sources/Configuration/Configuration.cs index 35002d2..5da93fd 100755 --- a/Ragon/Sources/Configuration/Configuration.cs +++ b/Ragon/Sources/Configuration/Configuration.cs @@ -2,6 +2,8 @@ { public class Configuration { - public string[] blacklist; + public int UdpPort; + public int WsPort; + public string Transport; } } \ No newline at end of file diff --git a/Ragon/Sources/ENetServer.cs b/Ragon/Sources/ENetServer.cs index b2745bb..9c0e078 100755 --- a/Ragon/Sources/ENetServer.cs +++ b/Ragon/Sources/ENetServer.cs @@ -5,7 +5,6 @@ using System.Threading; using DisruptorUnity3d; using ENet; using NLog; -using NLog.LayoutRenderers.Wrappers; namespace Ragon.Core { @@ -19,15 +18,6 @@ namespace Ragon.Core Connected } - public enum DeliveryType - { - UnreliableUnsequenced, - UnreliableSequenced, - UnreliableFragmented, - ReliableSequenced - } - - public class ENetServer : IDisposable { public Status Status { get; private set; } @@ -42,7 +32,7 @@ namespace Ragon.Core private RingBuffer _sendBuffer; public void WriteEvent(Event evnt) => _sendBuffer.Enqueue(evnt); public bool ReadEvent(out Event evnt) => _receiveBuffer.TryDequeue(out evnt); - + public void Start(ushort port) { Library.Initialize(); @@ -71,11 +61,25 @@ namespace Ragon.Core { while (_sendBuffer.TryDequeue(out var data)) { - var newPacket = new Packet(); - newPacket.Create(data.Data, data.Data.Length, PacketFlags.Reliable); - _peers[data.PeerId].Send(0, ref newPacket); + if (data.Type == EventType.DATA) + { + var newPacket = new Packet(); + + var packetFlags = PacketFlags.Instant; + if (data.Delivery == DeliveryType.Reliable) + packetFlags = PacketFlags.Reliable; + else if (data.Delivery == DeliveryType.Unreliable) + packetFlags = PacketFlags.Instant; + + newPacket.Create(data.Data, data.Data.Length, packetFlags); + _peers[data.PeerId].Send(0, ref newPacket); + } + else if (data.Type == EventType.DISCONNECTED) + { + _peers[data.PeerId].DisconnectNow(0); + } } - + bool polled = false; while (!polled) { @@ -96,7 +100,6 @@ namespace Ragon.Core case ENet.EventType.Connect: { var @event = new Event {PeerId = _netEvent.Peer.ID, Type = EventType.CONNECTED}; - // Console.WriteLine("Client connected - ID: " + _netEvent.Peer.ID + ", IP: " + _netEvent.Peer.IP); _peers[_netEvent.Peer.ID] = _netEvent.Peer; _receiveBuffer.Enqueue(@event); break; @@ -104,22 +107,19 @@ namespace Ragon.Core case ENet.EventType.Disconnect: { var @event = new Event {PeerId = _netEvent.Peer.ID, Type = EventType.DISCONNECTED}; - // Console.WriteLine("Client disconnected - ID: " + _netEvent.Peer.ID + ", IP: " + _netEvent.Peer.IP); _receiveBuffer.Enqueue(@event); break; } case ENet.EventType.Timeout: { - // Console.WriteLine("Client timeout - ID: " + _netEvent.Peer.ID + ", IP: " + _netEvent.Peer.IP); var @event = new Event {PeerId = _netEvent.Peer.ID, Type = EventType.TIMEOUT}; - // Console.WriteLine("Client disconnected - ID: " + _netEvent.Peer.ID + ", IP: " + _netEvent.Peer.IP); _receiveBuffer.Enqueue(@event); break; } case ENet.EventType.Receive: { - // Console.WriteLine("Packet received from - ID: " + _netEvent.Peer.ID + ", IP: " + _netEvent.Peer.IP + ", Channel ID: " + _netEvent.ChannelID + ", Data length: " + _netEvent.Packet.Length); var data = new byte[_netEvent.Packet.Length]; + _netEvent.Packet.CopyTo(data); _netEvent.Packet.Dispose(); diff --git a/Ragon/Sources/Event/DeliveryType.cs b/Ragon/Sources/Event/DeliveryType.cs new file mode 100644 index 0000000..0ecf70f --- /dev/null +++ b/Ragon/Sources/Event/DeliveryType.cs @@ -0,0 +1,7 @@ +namespace Ragon.Core; + +public enum DeliveryType +{ + Unreliable, + Reliable +} \ No newline at end of file diff --git a/Ragon/Sources/Event/Event.cs b/Ragon/Sources/Event/Event.cs index 4f8902d..ec7bdda 100644 --- a/Ragon/Sources/Event/Event.cs +++ b/Ragon/Sources/Event/Event.cs @@ -1,8 +1,11 @@ +using System; + namespace Ragon.Core { public struct Event { public EventType Type; + public DeliveryType Delivery; public uint PeerId; public byte[] Data; } diff --git a/Ragon/Sources/Event/EventStream.cs b/Ragon/Sources/Event/EventStream.cs new file mode 100644 index 0000000..9b376d5 --- /dev/null +++ b/Ragon/Sources/Event/EventStream.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.Runtime.ExceptionServices; +using DisruptorUnity3d; + +namespace Ragon.Core; + +public class EventStream +{ + private Stack _pool = new Stack(1024); + private RingBuffer _events = new RingBuffer(1024); + + // public ref Event Reserve() + // { + // if (_pool.Count == 0) + // { + // var evnt = new Event(); + // return ref evnt; + // } + // // var evnt = _pool.Pop(); + // // ref Event evntRef = ref evnt; + // // return evntRef; + // } + + // public void Retain(ref Event @event) + // { + // + // } + // + // public void WriteEvent(ref Event evnt) + // { + // // _pool.Push(evnt); + // _events.Enqueue(evnt); + // } + // + // public ref Event ReadEvent() + // { + // + // } +} \ No newline at end of file diff --git a/Ragon/Sources/Plugin/PluginBase.cs b/Ragon/Sources/Plugin/PluginBase.cs index 79f44d5..f3545e7 100755 --- a/Ragon/Sources/Plugin/PluginBase.cs +++ b/Ragon/Sources/Plugin/PluginBase.cs @@ -1,25 +1,121 @@  using System; using System.Collections.Generic; +using NetStack.Serialization; +using Ragon.Common.Protocol; namespace Ragon.Core { public class PluginBase { - static class Storage + private delegate void SubscribeDelegate(Player player, ref ReadOnlySpan data); + private Dictionary _subscribes = new(); + private BitBuffer _buffer = new BitBuffer(1024); + + protected Room Room { get; private set; } + + public void Attach(Room room) => Room = room; + public void Detach() => _subscribes.Clear(); + + public void Subscribe(ushort evntCode, Action action) where T: IPacket, new() { - public static Dictionary>> Subscribes = new(); + var data = new T(); + _subscribes.Add(evntCode, (Player player, ref ReadOnlySpan raw) => + { + _buffer.Clear(); + _buffer.FromSpan(ref raw, raw.Length); + data.Deserialize(_buffer); + action.Invoke(player, data); + }); } - - protected Room _room; - // protected Dictionary _subscribes = new Dictionary(); - public void Attach(Room room) => _room = room; + // public void Subscribe(RagonOperation operation, Action action) where T: IPacket, new() + // { + // var data = new T(); + // _subscribes.Add(evntCode, (Player player, ref ReadOnlySpan raw) => + // { + // _buffer.Clear(); + // _buffer.FromSpan(ref raw, raw.Length); + // data.Deserialize(_buffer); + // action.Invoke(player, data); + // }); + // } + public void UnsubscribeAll() + { + _subscribes.Clear(); + } - public void Subscribe(ushort evntCode, Action val) + + public bool InternalHandle(uint peerId, ushort evntCode, ref ReadOnlySpan payload) { - Storage.Subscribes.Add(_room, val); + if (_subscribes.ContainsKey(evntCode)) + { + var player = Room.GetPlayerByPeerId(peerId); + _subscribes[evntCode].Invoke(player, ref payload); + return true; + } + + return false; } + + public void Send(Player player, RagonOperation operation, IPacket payload) + { + Send(player.PeerId, operation, payload); + } + + public void Broadcast(Player[] players, RagonOperation operation, IPacket payload) + { + var ids = new uint[players.Length]; + for (int i = 0; i < players.Length; i++) + ids[i] = players[i].PeerId; + + Broadcast(ids, operation, payload); + } + + public void Send(uint peerId, RagonOperation operation, IPacket payload) + { + _buffer.Clear(); + + payload.Serialize(_buffer); + + Span data = stackalloc byte[_buffer.Length + 2]; + Span bufferSpan = data.Slice(2, data.Length - 2); + + _buffer.ToSpan(ref bufferSpan); + + ProtocolHeader.WriteUShort((ushort) operation, ref data); + + Room.Send(peerId, data); + } + + + public void Broadcast(uint[] peersIds, RagonOperation operation, IPacket payload) + { + _buffer.Clear(); + payload.Serialize(_buffer); + + Span data = stackalloc byte[_buffer.Length + 2]; + Span bufferSpan = data.Slice(2, data.Length - 2); + + _buffer.ToSpan(ref bufferSpan); + + ProtocolHeader.WriteUShort((ushort) operation, ref data); + + Room.Broadcast(peersIds, data); + } + + #region VIRTUAL + + public virtual void OnRoomJoined() + { + + } + + public virtual void OnRoomLeaved() + { + + } + public virtual void OnStart() { } @@ -32,5 +128,7 @@ namespace Ragon.Core { } + + #endregion } } \ No newline at end of file diff --git a/Ragon/Sources/Plugin/PluginFactory.cs b/Ragon/Sources/Plugin/PluginFactory.cs index c4c3854..c660bbd 100644 --- a/Ragon/Sources/Plugin/PluginFactory.cs +++ b/Ragon/Sources/Plugin/PluginFactory.cs @@ -2,6 +2,10 @@ namespace Ragon.Core { public interface PluginFactory { + public string PluginName { get; set; } public PluginBase CreatePlugin(string map); + public AuthorizationManager CreateManager(); } + + } \ No newline at end of file diff --git a/Ragon/Sources/Rooms/Room.cs b/Ragon/Sources/Rooms/Room.cs index 04057bc..f476288 100755 --- a/Ragon/Sources/Rooms/Room.cs +++ b/Ragon/Sources/Rooms/Room.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using NetStack.Serialization; using NLog; +using NLog.LayoutRenderers; using Ragon.Common.Protocol; namespace Ragon.Core @@ -13,10 +15,7 @@ namespace Ragon.Core private ILogger _logger = LogManager.GetCurrentClassLogger(); private Dictionary _players = new(); private Dictionary _entities = new(); - private uint Owner; - - private BitBuffer _buffer = new BitBuffer(8192); - private byte[] _bytes = new byte[8192]; + private uint _owner; private readonly PluginBase _plugin; private readonly RoomThread _roomThread; @@ -25,9 +24,8 @@ namespace Ragon.Core // Cache private uint[] _readyPlayers = Array.Empty(); - - public int Players => _players.Count; - public int MaxPlayers { get; } = 0; + private uint[] _allPlayers = Array.Empty(); + private Entity[] _entitiesAll = Array.Empty(); public Room(RoomThread roomThread, PluginBase pluginBase, string map) { @@ -35,6 +33,7 @@ namespace Ragon.Core _plugin = pluginBase; _map = map; + _logger.Info("Room created"); _plugin.Attach(this); } @@ -42,7 +41,7 @@ namespace Ragon.Core { if (_players.Count == 0) { - Owner = peerId; + _owner = peerId; } var player = new Player() @@ -55,88 +54,112 @@ namespace Ragon.Core }; _players.Add(peerId, player); - _plugin.OnPlayerConnected(player); + + _allPlayers = _players.Select(p => p.Key).ToArray(); + + Span data = stackalloc byte[10]; + Span operationData = data.Slice(0, 2); + Span peerData = data.Slice(2, 4); + Span ownerData = data.Slice(4, 4); - var data = new byte[8]; - ProtocolHeader.WriteEntity((int) peerId, data, 0); - ProtocolHeader.WriteEntity((int) Owner, data, 4); - Send(peerId, RagonOperation.JOIN_ROOM, data); + ProtocolHeader.WriteUShort((ushort) RagonOperation.JOIN_ROOM, ref operationData); + ProtocolHeader.WriteInt((int) peerId, ref peerData); + ProtocolHeader.WriteInt((int) _owner, ref ownerData); - var sceneRawData = Encoding.UTF8.GetBytes(_map); - Send(peerId, RagonOperation.LOAD_SCENE, sceneRawData); + Send(peerId, data); + + // var sceneRawData = Encoding.UTF8.GetBytes(_map); + // Send(peerId, RagonOperation.LOAD_SCENE, sceneRawData); } public void Leave(uint peerId) { if (_players.Remove(peerId, out var player)) { - _plugin.OnPlayerDisconnected(player); + _allPlayers = _players.Select(p => p.Key).ToArray(); + foreach (var entityId in player.EntitiesIds) { - var entityData = new byte[4]; - ProtocolHeader.WriteEntity(entityId, entityData, 0); - Broadcast(_readyPlayers, RagonOperation.DESTROY_ENTITY, entityData); + Span entityData = stackalloc byte[6]; + var operationData = entityData.Slice(0, 2); + ProtocolHeader.WriteUShort((ushort) RagonOperation.DESTROY_ENTITY, ref operationData); + ProtocolHeader.WriteInt(entityId, ref entityData); + + Broadcast(_allPlayers, entityData); + _entities.Remove(entityId); } } } - public void ProcessEvent(RagonOperation operation, uint peerId, byte[] rawData) + public void ProcessEvent(RagonOperation operation, uint peerId, ReadOnlySpan rawData) { + if (_plugin.InternalHandle(peerId, (ushort) operation, ref rawData)) return; + switch (operation) { case RagonOperation.REPLICATE_ENTITY_STATE: { - var entityId = ProtocolHeader.ReadEntity(rawData, 2); + var entityData = rawData.Slice(2, 4); + var entityId = ProtocolHeader.ReadInt(ref entityData); if (_entities.TryGetValue(entityId, out var ent)) { - var data = new byte[rawData.Length - 6]; // opcode(ushort)(2) + entity(int)(4) - Array.Copy(rawData, 6, data, 0, rawData.Length - 6); - _entities[entityId].State = data; - - Broadcast(_readyPlayers, rawData); + ent.State = rawData.Slice(6, rawData.Length - 6).ToArray(); + + Span data = stackalloc byte[rawData.Length]; + rawData.CopyTo(data); + Broadcast(_readyPlayers, data); } - break; } case RagonOperation.REPLICATE_ENTITY_PROPERTY: { - var entityId = ProtocolHeader.ReadEntity(rawData, 2); + var entityData = rawData.Slice(2, 4); + var entityId = ProtocolHeader.ReadInt(ref entityData); if (_entities.TryGetValue(entityId, out var ent)) { - var propertyId = ProtocolHeader.ReadProperty(rawData, 6); - var data = new byte[rawData.Length - 10]; // opcode(ushort)(2) + entity(int)(4) + propertyId(int)(4) - Array.Copy(rawData, 10, data, 0, rawData.Length - 10); - + var propertyData = rawData.Slice(6, 4); + var propertyId = ProtocolHeader.ReadInt(ref propertyData); + var payload = rawData.Slice(10, rawData.Length - 10).ToArray(); var props = _entities[entityId].Properties; + if (props.ContainsKey(propertyId)) { - props[propertyId] = data; + props[propertyId] = payload; } else { - props.Add(propertyId, data); + props.Add(propertyId, payload); } - Broadcast(_readyPlayers, RagonOperation.REPLICATE_ENTITY_PROPERTY, rawData); + // Span sendData = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(rawData), rawData.Length); + + Span sendData = stackalloc byte[rawData.Length]; + rawData.CopyTo(sendData); + Broadcast(_readyPlayers, sendData, DeliveryType.Reliable); } break; } case RagonOperation.REPLICATE_EVENT: + case RagonOperation.REPLICATE_ENTITY_EVENT: { - - Broadcast(_readyPlayers, rawData); + Span data = stackalloc byte[rawData.Length + 4]; + Span peerData = data.Slice(2, 4); + Span rawDataSlice = data.Slice(4, rawData.Length); + + rawData.CopyTo(rawDataSlice); + ProtocolHeader.WriteInt((int) peerId, ref peerData); + + Broadcast(_readyPlayers, data, DeliveryType.Reliable); break; } case RagonOperation.CREATE_ENTITY: { var entity = new Entity(peerId); - var data = new byte[rawData.Length - 2]; // opcode(ushort)(2) - Array.Copy(rawData, 2, data, 0, rawData.Length - 2); - - entity.State = data; + var entityPayload = rawData.Slice(2, rawData.Length - 2); + entity.State = entityPayload.ToArray(); entity.Properties = new Dictionary(); var player = _players[peerId]; @@ -144,21 +167,27 @@ namespace Ragon.Core player.EntitiesIds.Add(entity.EntityId); _entities.Add(entity.EntityId, entity); - - var entityData = new byte[entity.State.Length + 8]; - ProtocolHeader.WriteEntity(entity.EntityId, entityData, 0); - ProtocolHeader.WriteEntity((int) peerId, entityData, 4); + _entitiesAll = _entities.Values.ToArray(); - Array.Copy(entity.State, 0, entityData, 8, entity.State.Length); + Span data = stackalloc byte[entityPayload.Length + 10]; + var operationData = data.Slice(0, 2); + var entityData = data.Slice(2, 4); + var peerData = data.Slice(6, 4); + var payload = data.Slice(10, entityPayload.Length); - _logger.Trace("Create entity Owner:" + peerId + " Id: " + entity.EntityId); + entityPayload.CopyTo(payload); - Broadcast(_readyPlayers, RagonOperation.CREATE_ENTITY, entityData); + ProtocolHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData); + ProtocolHeader.WriteInt(entity.EntityId, ref entityData); + ProtocolHeader.WriteInt((int) peerId, ref peerData); + + Broadcast(_allPlayers, data, DeliveryType.Reliable); break; } case RagonOperation.DESTROY_ENTITY: { - var entityId = ProtocolHeader.ReadEntity(rawData); + var entityData = rawData.Slice(2, 4); + var entityId = ProtocolHeader.ReadInt(ref entityData); if (_entities.TryGetValue(entityId, out var entity)) { if (entity.OwnerId == peerId) @@ -169,8 +198,11 @@ namespace Ragon.Core player.EntitiesIds.Remove(entity.EntityId); _entities.Remove(entityId); + _entitiesAll = _entities.Values.ToArray(); - Broadcast(_readyPlayers, rawData); + Span sendData = stackalloc byte[rawData.Length]; + rawData.CopyTo(sendData); + Broadcast(_readyPlayers, sendData, DeliveryType.Reliable); } } @@ -178,17 +210,26 @@ namespace Ragon.Core } case RagonOperation.SCENE_IS_LOADED: { - Send(peerId, RagonOperation.RESTORE_BEGIN, Array.Empty()); + Send(peerId, RagonOperation.RESTORE_BEGIN); foreach (var entity in _entities.Values) { - var entityData = new byte[entity.State.Length + 8]; - ProtocolHeader.WriteEntity(entity.EntityId, entityData, 0); - ProtocolHeader.WriteEntity((int) entity.OwnerId, entityData, 4); - - Array.Copy(entity.State, 0, entityData, 8, entity.State.Length); - Send(peerId, RagonOperation.CREATE_ENTITY, entityData); + var entityState = entity.State.AsSpan(); + + Span sendData = stackalloc byte[entity.State.Length + 10]; + Span operationData = sendData.Slice(0, 2); + Span entityData = sendData.Slice(2, 4); + Span ownerData = sendData.Slice(6, 4); + Span entityStateData = sendData.Slice(10, entity.State.Length); + + ProtocolHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);; + ProtocolHeader.WriteInt(entity.EntityId, ref entityData); + ProtocolHeader.WriteInt((int) entity.OwnerId, ref ownerData); + + entityState.CopyTo(entityStateData); + + Send(peerId, sendData, DeliveryType.Reliable); } - Send(peerId, RagonOperation.RESTORE_END, Array.Empty()); + Send(peerId, RagonOperation.RESTORE_END); break; } case RagonOperation.RESTORED: @@ -203,140 +244,92 @@ namespace Ragon.Core public void Tick(float deltaTime) { _ticks++; - _plugin.OnTick(_ticks, deltaTime); + + // for (var i = 0; i < _entitiesAll.Length; i++) + // { + // var entity = _entities[i]; + // Span data = stackalloc byte[entity.State.Length]; + // rawData.CopyTo(data); + // Broadcast(_readyPlayers, data); + // } } public void Start() { + _logger.Info("Room started"); _plugin.OnStart(); } public void Stop() { + _logger.Info("Room stopped"); _plugin.OnStop(); } public void Dispose() { + _logger.Info("Room destroyed"); + _plugin.Detach(); } - public void Send(uint peerId, RagonOperation operation, byte[] payload) + public Player GetPlayerByPeerId(uint peerId) => _players[peerId]; + public Player GetOwner() => _players[_owner]; + public int PlayersCount => _players.Count; + + public void Send(uint peerId, RagonOperation operation, DeliveryType deliveryType = DeliveryType.Unreliable) { - if (payload.Length > 0) - { - var data = new byte[payload.Length + 2]; - - Array.Copy(payload, 0, data, 2, payload.Length); - ProtocolHeader.WriteOperation((ushort) operation, data); - - _roomThread.WriteOutEvent(new Event() - { - PeerId = peerId, - Data = data, - Type = EventType.DATA, - }); - } - else - { - var data = new byte[2]; - - ProtocolHeader.WriteOperation((ushort) operation, data); - - _roomThread.WriteOutEvent(new Event() - { - PeerId = peerId, - Data = data, - Type = EventType.DATA, - }); - } - } - - public void Send(uint peerId, RagonOperation operation, IData payload) - { - _buffer.Clear(); - payload.Serialize(_buffer); - _buffer.ToArray(_bytes); - - var data = new byte[_buffer.Length + 2]; - - Array.Copy(_bytes, 0, data, 2, _buffer.Length); - - ProtocolHeader.WriteOperation((ushort) operation, data); - + Span data = stackalloc byte[2]; + ProtocolHeader.WriteUShort((ushort) operation, ref data); + + var bytes = data.ToArray(); _roomThread.WriteOutEvent(new Event() { PeerId = peerId, - Data = data, + Data = bytes, Type = EventType.DATA, + Delivery = deliveryType, + }); + } + + public void Send(uint peerId, Span payload, DeliveryType deliveryType = DeliveryType.Unreliable) + { + var bytes = payload.ToArray(); + _roomThread.WriteOutEvent(new Event() + { + PeerId = peerId, + Data = bytes, + Type = EventType.DATA, + Delivery = deliveryType, }); } - - public void Broadcast(uint[] peersIds, RagonOperation operation, IData payload) + public void Broadcast(uint[] peersIds, Span rawData, DeliveryType deliveryType = DeliveryType.Unreliable) { - _buffer.Clear(); - payload.Serialize(_buffer); - _buffer.ToArray(_bytes); - - var data = new byte[_buffer.Length + 2]; - - Array.Copy(_bytes, 0, data, 2, _buffer.Length); - - ProtocolHeader.WriteOperation((ushort) operation, data); - + var bytes = rawData.ToArray(); foreach (var peer in peersIds) { _roomThread.WriteOutEvent(new Event() { PeerId = peer, - Data = data, + Data = bytes, Type = EventType.DATA, + Delivery = deliveryType, }); } } - public void Broadcast(uint[] peersIds, RagonOperation operation, byte[] payload) - { - var data = new byte[payload.Length + 2]; - - Array.Copy(payload, 0, data, 2, payload.Length); - - ProtocolHeader.WriteOperation((ushort) operation, data); - - foreach (var peer in peersIds) - { - _roomThread.WriteOutEvent(new Event() - { - PeerId = peer, - Data = data, - Type = EventType.DATA, - }); - } - } - - public void Broadcast(uint[] peersIds, byte[] rawData) - { - foreach (var peer in peersIds) - { - _roomThread.WriteOutEvent(new Event() - { - PeerId = peer, - Data = rawData, - Type = EventType.DATA, - }); - } - } - - public void Broadcast(byte[] rawData) + public void Broadcast(Span rawData, DeliveryType deliveryType = DeliveryType.Unreliable) { + var bytes = rawData.ToArray(); foreach (var player in _players.Values.ToArray()) { _roomThread.WriteOutEvent(new Event() { PeerId = player.PeerId, - Data = rawData, + Data = bytes, Type = EventType.DATA, + Delivery = deliveryType, }); } } diff --git a/Ragon/Sources/Rooms/RoomManager.cs b/Ragon/Sources/Rooms/RoomManager.cs index 4dedda6..9975c86 100644 --- a/Ragon/Sources/Rooms/RoomManager.cs +++ b/Ragon/Sources/Rooms/RoomManager.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Text; -using NetStack.Serialization; using NLog; using Ragon.Common.Protocol; @@ -13,8 +12,8 @@ namespace Ragon.Core private List _rooms; private Dictionary _peersByRoom; private PluginFactory _factory; + private AuthorizationManager _manager; private RoomThread _roomThread; - private BitBuffer _bitBuffer; public Action<(uint, Room)> OnJoined; public Action<(uint, Room)> OnLeaved; @@ -23,12 +22,13 @@ namespace Ragon.Core { _roomThread = roomThread; _factory = factory; + + _manager = _factory.CreateManager(); _rooms = new List(); _peersByRoom = new Dictionary(); - _bitBuffer = new BitBuffer(1024); } - public void ProccessEvent(RagonOperation operation, uint peerId, byte[] payload) + public void ProcessEvent(RagonOperation operation, uint peerId, byte[] payload) { switch (operation) { @@ -54,28 +54,47 @@ namespace Ragon.Core public void OnAuthorize(uint peerId, byte[] payload) { - _bitBuffer.Clear(); - // _bitBuffer.FromArray(payload, payload.Length); - - // var authorizePacket = new AuthorationData(); - // authorizePacket.Deserialize(_bitBuffer); - - var data = new byte[2]; - - ProtocolHeader.WriteOperation((ushort) RagonOperation.AUTHORIZED_SUCCESS, data); - - _roomThread.WriteOutEvent(new Event() + if (_manager.OnAuthorize(peerId, payload)) { - Type = EventType.DATA, - Data = data, - PeerId = peerId, - }); + Span data = stackalloc byte[2]; + ProtocolHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_SUCCESS, ref data); + + var bytes = data.ToArray(); + _roomThread.WriteOutEvent(new Event() + { + Delivery = DeliveryType.Reliable, + Type = EventType.DATA, + Data = bytes, + PeerId = peerId, + }); + } + else + { + Span data = stackalloc byte[2]; + ProtocolHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_FAILED, ref data); + + var bytes = data.ToArray(); + _roomThread.WriteOutEvent(new Event() + { + Delivery = DeliveryType.Reliable, + Type = EventType.DATA, + Data = bytes, + PeerId = peerId, + }); + + _roomThread.WriteOutEvent(new Event() + { + Delivery = DeliveryType.Reliable, + Type = EventType.DISCONNECTED, + Data = Array.Empty(), + PeerId = peerId, + }); + } } public Room Join(uint peerId, byte[] payload) { var map = Encoding.UTF8.GetString(payload); - if (_rooms.Count > 0) { var existsRoom = _rooms[0]; @@ -89,10 +108,10 @@ namespace Ragon.Core if (plugin == null) throw new NullReferenceException($"Plugin for map {map} is null"); - _logger.Info("Room created"); - var room = new Room(_roomThread, plugin, map); room.Joined(peerId, payload); + room.Start(); + _peersByRoom.Add(peerId, room); _rooms.Add(room); @@ -102,12 +121,27 @@ namespace Ragon.Core public Room Left(uint peerId, byte[] payload) { - _peersByRoom.Remove(peerId, out var room); - room?.Leave(peerId); - + _peersByRoom.Remove(peerId, out var room); + return room; } + public void Disconnected(uint peerId) + { + _peersByRoom.Remove(peerId, out var room); + if (room != null) + { + room.Leave(peerId); + if (room.PlayersCount <= 0) + { + _rooms.Remove(room); + + room.Stop(); + room.Dispose(); + } + } + } + public void Tick(float deltaTime) { foreach (Room room in _rooms) diff --git a/Ragon/Sources/Rooms/RoomThread.cs b/Ragon/Sources/Rooms/RoomThread.cs index 1da823c..27da35c 100755 --- a/Ragon/Sources/Rooms/RoomThread.cs +++ b/Ragon/Sources/Rooms/RoomThread.cs @@ -62,14 +62,15 @@ namespace Ragon.Core if (_socketByRooms.ContainsKey(evnt.PeerId)) { - _roomManager.Left(evnt.PeerId, Array.Empty()); + _roomManager.Disconnected(evnt.PeerId); _socketByRooms.Remove(evnt.PeerId); } } if (evnt.Type == EventType.DATA) { - var operation = (RagonOperation) ProtocolHeader.ReadOperation(evnt.Data, 0); + ReadOnlySpan data = evnt.Data.AsSpan(); + var operation = (RagonOperation) ProtocolHeader.ReadUShort(ref data); if (_socketByRooms.TryGetValue(evnt.PeerId, out var room)) { room.ProcessEvent(operation, evnt.PeerId, evnt.Data); @@ -77,10 +78,8 @@ namespace Ragon.Core else { var payload = new byte[evnt.Data.Length - 2]; - Array.Copy(evnt.Data, 2, payload, 0, evnt.Data.Length - 2); - - _roomManager.ProccessEvent(operation, evnt.PeerId, payload); + _roomManager.ProcessEvent(operation, evnt.PeerId, payload); } } } diff --git a/Ragon/todo b/Ragon/todo deleted file mode 100644 index 60a5551..0000000 --- a/Ragon/todo +++ /dev/null @@ -1,2 +0,0 @@ -- Send states only on scene loaded -- Add events global and by entity \ No newline at end of file diff --git a/YohohoArenaPlugin/Source/ArenaPlugin.cs b/YohohoArenaPlugin/Source/ArenaPlugin.cs deleted file mode 100755 index 71f0658..0000000 --- a/YohohoArenaPlugin/Source/ArenaPlugin.cs +++ /dev/null @@ -1,46 +0,0 @@ -using NLog; -using Ragon.Core; - -namespace Game.Source -{ - public class ArenaPlugin: PluginBase - { - private ILogger _logger = LogManager.GetCurrentClassLogger(); - - public override void OnStart() - { - // _logger.Info("Plugin started"); - } - - public override void OnStop() - { - // _logger.Info("Plugin stopped"); - } - - public long FindPrimeNumber(int n) - { - int count=0; - long a = 2; - while(count 0) - { - count++; - } - a++; - } - return (--a); - } - } -} \ No newline at end of file diff --git a/YohohoArenaPlugin/Source/Events/SpawnEvent.cs b/YohohoArenaPlugin/Source/Events/SpawnEvent.cs deleted file mode 100644 index d04a97d..0000000 --- a/YohohoArenaPlugin/Source/Events/SpawnEvent.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Game.Source.Events; - -public class SpawnEvent -{ - -} \ No newline at end of file diff --git a/YohohoArenaPlugin/Source/GameFactory.cs b/YohohoArenaPlugin/Source/GameFactory.cs deleted file mode 100644 index 2f5887d..0000000 --- a/YohohoArenaPlugin/Source/GameFactory.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Ragon.Core; - -namespace Game.Source -{ - public class GameFactory : PluginFactory - { - public PluginBase CreatePlugin(string map) - { - // if (map == "spawn") - // return new SpawnPlugin(); - // - // if (map == "arena") - // return new ArenaPlugin(); - return new SpawnPlugin(); - } - } -} \ No newline at end of file diff --git a/readme.md b/readme.md index badd871..8159f87 100755 --- a/readme.md +++ b/readme.md @@ -2,5 +2,12 @@

-Ragon - high perfomance game server with plugin based architecture. +Ragon - high perfomance room based game server with plugin based architecture. + +Features: +- Room base architecture +- Efficient memory management +- Flexible plugin system +- No CCU limitations +- Fully multithreaded