diff --git a/Ragon.Common/Protocol/RagonSerializer.cs b/Ragon.Common/Protocol/RagonSerializer.cs index f2d8d7a..fd4e48a 100644 --- a/Ragon.Common/Protocol/RagonSerializer.cs +++ b/Ragon.Common/Protocol/RagonSerializer.cs @@ -24,6 +24,8 @@ namespace Ragon.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteByte(byte value) { + ResizeIfNeed(1); + _data[_offset] = value; _offset += 1; } @@ -39,6 +41,8 @@ namespace Ragon.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteInt(int value) { + ResizeIfNeed(4); + _data[_offset] = (byte) (value & 0x00FF); _data[_offset + 1] = (byte) ((value & 0xFF00) >> 8); _data[_offset + 2] = (byte) ((value & 0xFF00) >> 16); @@ -58,8 +62,9 @@ namespace Ragon.Common public void WriteString(string value) { var stringRaw = Encoding.UTF8.GetBytes(value).AsSpan(); + ResizeIfNeed(2 + stringRaw.Length); + WriteUShort((ushort) stringRaw.Length); - var data = _data.AsSpan().Slice(_offset, stringRaw.Length); stringRaw.CopyTo(data); _offset += stringRaw.Length; @@ -88,6 +93,8 @@ namespace Ragon.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteData(ref ReadOnlySpan payload) { + ResizeIfNeed(payload.Length); + var data = _data.AsSpan(); var payloadData = data.Slice(_offset, payload.Length); @@ -98,6 +105,8 @@ namespace Ragon.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span GetWritableData(int lenght) { + ResizeIfNeed(lenght); + var data = _data.AsSpan(); var payloadData = data.Slice(_offset, lenght); @@ -108,6 +117,8 @@ namespace Ragon.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteOperation(RagonOperation ragonOperation) { + ResizeIfNeed(1); + _data[_offset] = (byte) ragonOperation; _offset += 1; } @@ -123,6 +134,8 @@ namespace Ragon.Common [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteUShort(ushort value) { + ResizeIfNeed(2); + _data[_offset] = (byte) (value & 0x00FF); _data[_offset + 1] = (byte) ((value & 0xFF00) >> 8); _offset += 2; @@ -149,13 +162,6 @@ namespace Ragon.Common dataSpan.CopyTo(data); } - public byte[] ToArray() - { - var bytes = new byte[_offset]; - Buffer.BlockCopy(_data, 0, bytes, 0, _offset); - return bytes; - } - public void FromSpan(ref ReadOnlySpan data) { Clear(); @@ -163,5 +169,24 @@ namespace Ragon.Common data.CopyTo(dataSpan); _size = data.Length; } + + public byte[] ToArray() + { + var bytes = new byte[_offset]; + Buffer.BlockCopy(_data, 0, bytes, 0, _offset); + return bytes; + } + + private void ResizeIfNeed(int lenght) + { + if (_offset + lenght < _data.Length) + return; + + Console.WriteLine("Resize: " + (_data.Length + 512)); + + var newData = new byte[_data.Length * 2]; + Buffer.BlockCopy(_data, 0, newData, 0, _data.Length); + _data = newData; + } } } \ No newline at end of file diff --git a/Ragon/Sources/Rooms/Room.cs b/Ragon/Sources/Rooms/Room.cs index 32c951c..4373c0f 100755 --- a/Ragon/Sources/Rooms/Room.cs +++ b/Ragon/Sources/Rooms/Room.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using NLog; using Ragon.Common; @@ -22,7 +23,7 @@ namespace Ragon.Core private readonly PluginBase _plugin; private readonly RoomThread _roomThread; - private readonly RagonSerializer _serializer = new(2048); + private readonly RagonSerializer _serializer = new(512); // Cache private uint[] _readyPlayers = Array.Empty(); @@ -106,6 +107,8 @@ namespace Ragon.Core if (_players.Remove(peerId, out var player)) { _allPlayers = _players.Select(p => p.Key).ToArray(); + _readyPlayers = _players.Where(p => p.Value.IsLoaded).Select(p => p.Key).ToArray(); + var isOwnershipChange = player.PeerId == _owner; { @@ -176,7 +179,11 @@ namespace Ragon.Core if (ent.Authority == RagonAuthority.OWNER_ONLY && ent.OwnerId != peerId) return; - var payload = _serializer.ReadData(_serializer.Size); + Span payloadRaw = stackalloc byte[_serializer.Size]; + ReadOnlySpan payload = payloadRaw; + var payloadData = _serializer.ReadData(_serializer.Size); + payloadData.CopyTo(payloadRaw); + if (_plugin.InternalHandle(peerId, entityId, evntId, ref payload)) return;