Compare commits

...

7 Commits

Author SHA1 Message Date
edmand46 a51d7c73cd fixed: mistype 2022-08-28 11:46:30 +04:00
edmand46 957622a170 fix: on player leave logic 2022-08-28 00:18:26 +04:00
edmand46 4a07424293 feat: added checks for size of payload 2022-08-27 11:21:51 +04:00
edmand46 568a3282c3 fix: restoring properties 2022-08-27 10:51:57 +04:00
edmand46 6a71fe5fe0 feat: restore properties 2022-08-25 23:12:33 +04:00
edmand46 082e183989 chore: move copyright on top of license 2022-08-24 00:06:37 +04:00
edmand46 51c0482a40 fix: leave player logic 2022-08-21 00:15:07 +04:00
7 changed files with 78 additions and 30 deletions
+1
View File
@@ -27,6 +27,7 @@ namespace Ragon.Common
private byte[] _data; private byte[] _data;
private int _offset; private int _offset;
private int _size; private int _size;
public int Lenght => _offset; public int Lenght => _offset;
public int Size => _size - _offset; public int Size => _size - _offset;
@@ -48,7 +48,7 @@ public class AuthorizationManager : IAuthorizationManager
PeerId = peerId, PeerId = peerId,
IsLoaded = false, IsLoaded = false,
Entities = new List<Entity>(), Entities = new List<Entity>(),
EntitiesIds = new List<int>(), EntitiesIds = new List<ushort>(),
}; };
_playersByIds.Add(playerId, player); _playersByIds.Add(playerId, player);
+2 -1
View File
@@ -1,3 +1,4 @@
using System;
using Ragon.Common; using Ragon.Common;
namespace Ragon.Core; namespace Ragon.Core;
@@ -20,7 +21,7 @@ public class Entity
EntityType = entityType; EntityType = entityType;
EntityId = _idGenerator++; EntityId = _idGenerator++;
Properties = new EntityProperty[props]; Properties = new EntityProperty[props];
Payload = new byte[1024]; Payload = Array.Empty<byte>();
Authority = eventAuthority; Authority = eventAuthority;
} }
} }
+4 -2
View File
@@ -6,17 +6,19 @@ namespace Ragon.Core;
public class EntityProperty public class EntityProperty
{ {
public int Size { get; set; } public int Size { get; set; }
public int Capacity { get; set; }
public bool IsDirty { get; private set; } public bool IsDirty { get; private set; }
public bool IsFixed { get; private set; } public bool IsFixed { get; private set; }
private byte[] _data; private byte[] _data;
public EntityProperty(int size, bool isFixed) public EntityProperty(int size, bool isFixed)
{ {
_data = new byte[512]; Capacity = 512;
Size = size; Size = size;
IsFixed = isFixed; IsFixed = isFixed;
IsDirty = true; IsDirty = true;
_data = new byte[Capacity];
} }
public ReadOnlySpan<byte> Read() public ReadOnlySpan<byte> Read()
+61 -17
View File
@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using NLog; using NLog;
using Ragon.Common; using Ragon.Common;
@@ -109,7 +108,7 @@ namespace Ragon.Core
_serializer.WriteUShort((ushort) player.EntitiesIds.Count); _serializer.WriteUShort((ushort) player.EntitiesIds.Count);
foreach (var entityId in player.EntitiesIds) foreach (var entityId in player.EntitiesIds)
{ {
_serializer.WriteInt(entityId); _serializer.WriteUShort(entityId);
_entities.Remove(entityId); _entities.Remove(entityId);
} }
@@ -117,7 +116,7 @@ namespace Ragon.Core
Broadcast(_readyPlayers, sendData); Broadcast(_readyPlayers, sendData);
} }
if (_allPlayers.Length > 0) if (_allPlayers.Length > 0 && player.PeerId == _owner)
{ {
var nextOwnerId = _allPlayers[0]; var nextOwnerId = _allPlayers[0];
_owner = nextOwnerId; _owner = nextOwnerId;
@@ -161,11 +160,19 @@ namespace Ragon.Core
if (_serializer.ReadBool()) if (_serializer.ReadBool())
{ {
var property = ent.Properties[i]; var property = ent.Properties[i];
var size = property.Size;
if (!property.IsFixed) if (!property.IsFixed)
property.Size = _serializer.ReadUShort(); size = _serializer.ReadUShort();
var propertyPayload = _serializer.ReadData(property.Size); if (size > property.Capacity)
{
_logger.Warn($"Property {i} payload too large, size: {size}");
continue;
}
var propertyPayload = _serializer.ReadData(size);
property.Write(ref propertyPayload); property.Write(ref propertyPayload);
property.Size = size;
} }
} }
@@ -178,6 +185,7 @@ namespace Ragon.Core
break; break;
} }
} }
break; break;
} }
case RagonOperation.REPLICATE_ENTITY_EVENT: case RagonOperation.REPLICATE_ENTITY_EVENT:
@@ -339,6 +347,7 @@ namespace Ragon.Core
{ {
ReadOnlySpan<byte> entityPayload = entity.Payload.AsSpan(); ReadOnlySpan<byte> entityPayload = entity.Payload.AsSpan();
_serializer.WriteUShort((ushort) entityPayload.Length);
_serializer.WriteData(ref entityPayload); _serializer.WriteData(ref entityPayload);
} }
@@ -351,13 +360,11 @@ namespace Ragon.Core
var entityType = _serializer.ReadUShort(); var entityType = _serializer.ReadUShort();
var propertiesCount = _serializer.ReadUShort(); var propertiesCount = _serializer.ReadUShort();
var entity = new Entity(peerId, entityType, 0, RagonAuthority.ALL, RagonAuthority.ALL, propertiesCount); var entity = new Entity(peerId, entityType, 0, RagonAuthority.ALL, RagonAuthority.ALL, propertiesCount);
// _logger.Trace("Created entity with properties: " + propertiesCount);
for (var i = 0; i < propertiesCount; i++) for (var i = 0; i < propertiesCount; i++)
{ {
var propertyType = _serializer.ReadBool(); var propertyType = _serializer.ReadBool();
var propertySize = _serializer.ReadUShort(); var propertySize = _serializer.ReadUShort();
entity.Properties[i] = new EntityProperty(propertySize, propertyType); entity.Properties[i] = new EntityProperty(propertySize, propertyType);
// _logger.Trace($"Property: {i} Size: {propertySize} IsFixed: {propertyType}");
} }
{ {
@@ -369,7 +376,7 @@ namespace Ragon.Core
player.Entities.Add(entity); player.Entities.Add(entity);
player.EntitiesIds.Add(entity.EntityId); player.EntitiesIds.Add(entity.EntityId);
var ownerId = (ushort) peerId; var ownerId = peerId;
_entities.Add(entity.EntityId, entity); _entities.Add(entity.EntityId, entity);
_entitiesAll = _entities.Values.ToArray(); _entitiesAll = _entities.Values.ToArray();
@@ -384,6 +391,7 @@ namespace Ragon.Core
{ {
ReadOnlySpan<byte> entityPayload = entity.Payload.AsSpan(); ReadOnlySpan<byte> entityPayload = entity.Payload.AsSpan();
_serializer.WriteUShort((ushort) entityPayload.Length);
_serializer.WriteData(ref entityPayload); _serializer.WriteData(ref entityPayload);
} }
@@ -413,6 +421,7 @@ namespace Ragon.Core
_serializer.Clear(); _serializer.Clear();
_serializer.WriteOperation(RagonOperation.DESTROY_ENTITY); _serializer.WriteOperation(RagonOperation.DESTROY_ENTITY);
_serializer.WriteInt(entityId); _serializer.WriteInt(entityId);
_serializer.WriteUShort((ushort) destroyPayload.Length);
_serializer.WriteData(ref destroyPayload); _serializer.WriteData(ref destroyPayload);
var sendData = _serializer.ToArray(); var sendData = _serializer.ToArray();
@@ -464,9 +473,12 @@ namespace Ragon.Core
var sendData = _serializer.ToArray(); var sendData = _serializer.ToArray();
Send(peerId, sendData, DeliveryType.Reliable); Send(peerId, sendData, DeliveryType.Reliable);
RestoreProperties(peerId);
_players[peerId].IsLoaded = true; _players[peerId].IsLoaded = true;
_readyPlayers = _players.Where(p => p.Value.IsLoaded).Select(p => p.Key).ToArray(); _readyPlayers = _players.Where(p => p.Value.IsLoaded).Select(p => p.Key).ToArray();
_plugin.OnPlayerJoined(_players[peerId]); _plugin.OnPlayerJoined(_players[peerId]);
break; break;
} }
} }
@@ -476,6 +488,11 @@ namespace Ragon.Core
{ {
_scheduler.Tick(deltaTime); _scheduler.Tick(deltaTime);
ReplicateProperties();
}
private void ReplicateProperties()
{
if (_entitiesDirty.Count > 0) if (_entitiesDirty.Count > 0)
{ {
_serializer.Clear(); _serializer.Clear();
@@ -513,6 +530,39 @@ namespace Ragon.Core
} }
} }
public void RestoreProperties(uint peerId)
{
_serializer.Clear();
_serializer.WriteOperation(RagonOperation.REPLICATE_ENTITY_STATE);
_serializer.WriteUShort((ushort) _entitiesAll.Length);
for (var entityIndex = 0; entityIndex < _entitiesAll.Length; entityIndex++)
{
var entity = _entitiesAll[entityIndex];
_serializer.WriteUShort(entity.EntityId);
for (int propertyIndex = 0; propertyIndex < entity.Properties.Length; propertyIndex++)
{
var property = entity.Properties[propertyIndex];
var hasPayload = property.IsFixed || property.Size > 0 && !property.IsFixed;
if (hasPayload)
{
_serializer.WriteBool(true);
var span = _serializer.GetWritableData(property.Size);
var data = property.Read();
data.CopyTo(span);
}
else
{
_serializer.WriteBool(false);
}
}
}
var sendData = _serializer.ToArray();
Send(peerId, sendData, DeliveryType.Reliable);
}
public void Start() public void Start()
{ {
_plugin.OnStart(); _plugin.OnStart();
@@ -537,19 +587,13 @@ namespace Ragon.Core
public IScheduler GetScheduler() => _scheduler; public IScheduler GetScheduler() => _scheduler;
public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) public void Send(uint peerId, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) =>
{
_gameThread.Server.Send(peerId, rawData, deliveryType); _gameThread.Server.Send(peerId, rawData, deliveryType);
}
public void Broadcast(uint[] peersIds, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) public void Broadcast(uint[] peersIds, byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) =>
{
_gameThread.Server.Broadcast(peersIds, rawData, deliveryType); _gameThread.Server.Broadcast(peersIds, rawData, deliveryType);
}
public void Broadcast(byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) public void Broadcast(byte[] rawData, DeliveryType deliveryType = DeliveryType.Unreliable) =>
{
_gameThread.Server.Broadcast(_allPlayers, rawData, deliveryType); _gameThread.Server.Broadcast(_allPlayers, rawData, deliveryType);
}
} }
} }
+1 -1
View File
@@ -11,6 +11,6 @@ namespace Ragon.Core
public bool IsLoaded { get; set; } public bool IsLoaded { get; set; }
public List<Entity> Entities; public List<Entity> Entities;
public List<int> EntitiesIds; public List<ushort> EntitiesIds;
} }
} }
+2 -2
View File
@@ -1,7 +1,7 @@
MIT License
Copyright (c) 2022 Eduard Kargin (theedison4@gmail.com) Copyright (c) 2022 Eduard Kargin (theedison4@gmail.com)
MIT License:
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights