diff --git a/Ragon.Protocol/Sources/RagonBuffer.cs b/Ragon.Protocol/Sources/RagonBuffer.cs index 40932f1..2b5b468 100644 --- a/Ragon.Protocol/Sources/RagonBuffer.cs +++ b/Ragon.Protocol/Sources/RagonBuffer.cs @@ -331,6 +331,9 @@ namespace Ragon.Protocol var limit = (size + 32 - 1) / 32; var capacity = size; + if (index + limit >= _buckets.Length) + Resize(size); + for (int i = 0; i < limit; i++) { var dataSize = capacity > 32 ? 32 : capacity; diff --git a/Ragon.Relay/Sources/Relay.cs b/Ragon.Relay/Sources/Relay.cs index e63c630..d9b0e77 100644 --- a/Ragon.Relay/Sources/Relay.cs +++ b/Ragon.Relay/Sources/Relay.cs @@ -56,9 +56,11 @@ namespace Ragon.Relay var serverConfiguration = new RagonServerConfiguration() { LimitConnections = configuration.LimitConnections, - LimitRooms = configuration.LimitConnections, - LimitBufferedEvents = configuration.LimitConnections, - LimitPlayersPerRoom = configuration.LimitConnections, + LimitRooms = configuration.LimitRooms, + LimitBufferedEvents = configuration.LimitBufferedEvents, + LimitPlayersPerRoom = configuration.LimitPlayersPerRoom, + LimitUserDataSize = configuration.LimitUserDataSize, + LimitPropertySize = configuration.LimitPropertySize, Port = configuration.Port, Protocol = configuration.Protocol, ServerKey = configuration.ServerKey, diff --git a/Ragon.Relay/Sources/RelayConfiguration.cs b/Ragon.Relay/Sources/RelayConfiguration.cs index da583a3..0b0d211 100644 --- a/Ragon.Relay/Sources/RelayConfiguration.cs +++ b/Ragon.Relay/Sources/RelayConfiguration.cs @@ -15,6 +15,7 @@ namespace Ragon.Relay public int LimitPlayersPerRoom; public int LimitRooms; public int LimitBufferedEvents; - public int LimitUserData; + public int LimitUserDataSize; + public int LimitPropertySize; } } \ No newline at end of file diff --git a/Ragon.Relay/relay.config.json b/Ragon.Relay/relay.config.json index 811e709..f80ef6e 100644 --- a/Ragon.Relay/relay.config.json +++ b/Ragon.Relay/relay.config.json @@ -4,10 +4,11 @@ "serverAddress": "*", "serverTickRate": 30, "protocol": "1.0.0", - "port": 5000, + "port": 8000, "limitConnections": 4095, "limitPlayersPerRoom": 20, "limitRooms": 200, "limitBufferedEvents": 50, - "limitUserData": 1024 + "limitUserDataSize": 1024, + "limitPropertySize": 512 } \ No newline at end of file diff --git a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs b/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs index e8a0f19..6d5f232 100644 --- a/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs +++ b/Ragon.Server.WebSocketServer/Sources/WebSocketServer.cs @@ -14,6 +14,7 @@ * limitations under the License. */ +using System.Buffers; using System.Net; using System.Net.WebSockets; using Ragon.Protocol; @@ -82,20 +83,30 @@ public class WebSocketServer : INetworkServer _networkListener.OnConnected(connection); var webSocket = connection.Socket; - var bytes = new byte[2048]; - var buffer = new Memory(bytes); + var rawData = new byte[2048]; + var rawDataBuffer = new Memory(rawData); + var data = new ArrayBufferWriter(); - while ( - webSocket.State == WebSocketState.Open || - !cancellationToken.IsCancellationRequested) + while (webSocket.State == WebSocketState.Open || !cancellationToken.IsCancellationRequested) { try { - var result = await webSocket.ReceiveAsync(buffer, cancellationToken); - if (result.Count > 0) + while (true) { - var payload = buffer.Slice(0, result.Count); - _networkListener.OnData(connection, NetworkChannel.RELIABLE, payload.ToArray()); + var result = await webSocket.ReceiveAsync(rawDataBuffer, cancellationToken); + var payload = rawDataBuffer.Slice(0, result.Count); + + data.Write(payload.Span); + + if (result.EndOfMessage) + break; + } + + if (data.WrittenCount > 0) + { + _networkListener.OnData(connection, NetworkChannel.RELIABLE, data.WrittenMemory.ToArray()); + + data.Clear(); } } catch (Exception ex) diff --git a/Ragon.Server/Sources/Entity/RagonProperty.cs b/Ragon.Server/Sources/Entity/RagonProperty.cs index 17184e6..a92474a 100644 --- a/Ragon.Server/Sources/Entity/RagonProperty.cs +++ b/Ragon.Server/Sources/Entity/RagonProperty.cs @@ -27,13 +27,13 @@ public class RagonProperty : RagonPayload private uint[] _data; - public RagonProperty(int size, bool isFixed) + public RagonProperty(int size, bool isFixed, int limit) { Size = size; IsFixed = isFixed; IsDirty = false; - - _data = new uint[128]; + + _data = new uint[limit / 4 + 1]; } public void Read(RagonBuffer buffer) diff --git a/Ragon.Server/Sources/Handler/EntityCreateOperation.cs b/Ragon.Server/Sources/Handler/EntityCreateOperation.cs index 11c6e71..ed6c6a9 100644 --- a/Ragon.Server/Sources/Handler/EntityCreateOperation.cs +++ b/Ragon.Server/Sources/Handler/EntityCreateOperation.cs @@ -24,11 +24,14 @@ namespace Ragon.Server.Handler; public sealed class EntityCreateOperation : BaseOperation { private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(EntityCreateOperation)); - - public EntityCreateOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) + private RagonServerConfiguration _configuration; + + public EntityCreateOperation(RagonBuffer reader, RagonBuffer writer, RagonServerConfiguration configuration) : + base(reader, writer) { + _configuration = configuration; } - + public override void Handle(RagonContext context, NetworkChannel channel) { var player = context.RoomPlayer; @@ -53,7 +56,7 @@ public sealed class EntityCreateOperation : BaseOperation var propertyType = Reader.ReadBool(); var propertySize = Reader.ReadUShort(); - entity.AddProperty(new RagonProperty(propertySize, propertyType)); + entity.AddProperty(new RagonProperty(propertySize, propertyType, _configuration.LimitPropertySize)); } if (Reader.Capacity > 0) diff --git a/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs b/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs index 84dd1ac..82ca96c 100644 --- a/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs +++ b/Ragon.Server/Sources/Handler/SceneLoadedOperation.cs @@ -27,9 +27,11 @@ namespace Ragon.Server.Handler public sealed class SceneLoadedOperation : BaseOperation { private readonly IRagonLogger _logger = LoggerManager.GetLogger(nameof(SceneLoadedOperation)); - - public SceneLoadedOperation(RagonBuffer reader, RagonBuffer writer) : base(reader, writer) + private RagonServerConfiguration _configuration; + + public SceneLoadedOperation(RagonBuffer reader, RagonBuffer writer, RagonServerConfiguration serverConfiguration) : base(reader, writer) { + _configuration = serverConfiguration; } public override void Handle(RagonContext context, NetworkChannel channel) @@ -40,6 +42,7 @@ namespace Ragon.Server.Handler 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"); @@ -70,10 +73,11 @@ namespace Ragon.Server.Handler { var propertyType = Reader.ReadBool(); var propertySize = Reader.ReadUShort(); - entity.AddProperty(new RagonProperty(propertySize, propertyType)); + 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}"; diff --git a/Ragon.Server/Sources/RagonServer.cs b/Ragon.Server/Sources/RagonServer.cs index f6060d2..358eadc 100644 --- a/Ragon.Server/Sources/RagonServer.cs +++ b/Ragon.Server/Sources/RagonServer.cs @@ -79,8 +79,8 @@ public class RagonServer : IRagonServer, INetworkListener _handlers[(byte)RagonOperation.JOIN_ROOM] = new RoomJoinOperation(_reader, _writer); _handlers[(byte)RagonOperation.LEAVE_ROOM] = new RoomLeaveOperation(_reader, _writer); _handlers[(byte)RagonOperation.LOAD_SCENE] = new SceneLoadOperation(_reader, _writer); - _handlers[(byte)RagonOperation.SCENE_LOADED] = new SceneLoadedOperation(_reader, _writer); - _handlers[(byte)RagonOperation.CREATE_ENTITY] = new EntityCreateOperation(_reader, _writer); + _handlers[(byte)RagonOperation.SCENE_LOADED] = new SceneLoadedOperation(_reader, _writer, _configuration); + _handlers[(byte)RagonOperation.CREATE_ENTITY] = new EntityCreateOperation(_reader, _writer, _configuration); _handlers[(byte)RagonOperation.REMOVE_ENTITY] = new EntityDestroyOperation(_reader, _writer); _handlers[(byte)RagonOperation.REPLICATE_ENTITY_EVENT] = new EntityEventOperation(_reader, _writer); _handlers[(byte)RagonOperation.REPLICATE_ENTITY_STATE] = new EntityStateOperation(_reader, _writer); @@ -89,8 +89,8 @@ public class RagonServer : IRagonServer, INetworkListener _handlers[(byte)RagonOperation.TIMESTAMP_SYNCHRONIZATION] = new TimestampSyncOperation(_reader, _writer); _handlers[(byte)RagonOperation.REPLICATE_ROOM_EVENT] = new RoomEventOperation(_reader, _writer); _handlers[(byte)RagonOperation.REPLICATE_RAW_DATA] = new RoomDataOperation(_reader, _writer); - _handlers[(byte)RagonOperation.ROOM_DATA_UPDATED] = new RoomUserDataOperation(_reader, _writer, _configuration.LimitUserData); - _handlers[(byte)RagonOperation.PLAYER_DATA_UPDATED] = new PlayerUserDataOperation(_reader, _writer, _configuration.LimitUserData); + _handlers[(byte)RagonOperation.ROOM_DATA_UPDATED] = new RoomUserDataOperation(_reader, _writer, _configuration.LimitUserDataSize); + _handlers[(byte)RagonOperation.PLAYER_DATA_UPDATED] = new PlayerUserDataOperation(_reader, _writer, _configuration.LimitUserDataSize); } public void Tick() { diff --git a/Ragon.Server/Sources/RagonServerConfiguration.cs b/Ragon.Server/Sources/RagonServerConfiguration.cs index 00ba57a..5c4cc7d 100644 --- a/Ragon.Server/Sources/RagonServerConfiguration.cs +++ b/Ragon.Server/Sources/RagonServerConfiguration.cs @@ -34,7 +34,8 @@ public struct RagonServerConfiguration public int LimitPlayersPerRoom; public int LimitRooms; public int LimitBufferedEvents; - public int LimitUserData; + public int LimitUserDataSize; + public int LimitPropertySize; private static Dictionary _serverTypes = new Dictionary() {