Compare commits

..

14 Commits

Author SHA1 Message Date
edmand46 043523d712 fixed: checking owner 2023-03-25 20:52:36 +04:00
edmand46 0dc5307b92 fixed: tickrate 2023-03-23 19:17:54 +04:00
edmand46 7b581b9afe chore: added tickrate logging 2023-03-23 18:07:48 +04:00
edmand46 8c5e063ef0 fixed: initial dirty property not tracked 2023-03-23 14:05:03 +04:00
edmand46 1a5f72a815 fixed: property update 2023-03-23 05:28:47 +04:00
edmand46 828da0d3da fix: wrong initial capacity 2023-03-22 11:04:14 +04:00
edmand46 951174e491 feat: split interface IRagonListener 2023-03-07 13:12:48 +04:00
edmand46 10b85867af feat: split interface IRagonListener 2023-03-07 00:57:13 +04:00
edmand46 252a46a713 chore: naming 2023-03-06 10:46:02 +04:00
edmand46 273c167c87 chore: naming 2023-03-06 10:31:42 +04:00
edmand46 192fb9e8eb chore: grammarly mistake 2023-03-06 10:29:22 +04:00
edmand46 a8ddc40268 Merge pull request #11 from edmand46/next
Update readme
2023-03-06 10:23:13 +04:00
edmand46 1ae545b353 chore: update readme.md 2023-03-06 10:22:27 +04:00
edmand46 b2058d21ce Merge pull request #10 from edmand46/next
Major update
2023-03-06 10:11:32 +04:00
8 changed files with 200 additions and 76 deletions
-3
View File
@@ -26,9 +26,6 @@ Ragon is fully free, small and high perfomance room based game server with plugi
### Dependencies ### Dependencies
* ENet-Sharp [v2.4.8] * ENet-Sharp [v2.4.8]
### License
MIT
### Tips ### Tips
\* Limited to 4095 CCU by library ENet-Sharp (1) \* Limited to 4095 CCU by library ENet-Sharp (1)
\* Non finally (2) \* Non finally (2)
+16 -15
View File
@@ -23,7 +23,7 @@ namespace Ragon.Client
{ {
public string Name => _name; public string Name => _name;
public RagonEntity Entity => _entity; public RagonEntity Entity => _entity;
public event Action Changed; public event Action Changed;
public bool IsDirty => _dirty && _ticks >= _priority; public bool IsDirty => _dirty && _ticks >= _priority;
public bool IsFixed => _fixed; public bool IsFixed => _fixed;
@@ -32,13 +32,13 @@ namespace Ragon.Client
private bool _fixed; private bool _fixed;
private string _name; private string _name;
protected bool _invokeLocal; protected bool _invokeLocal;
private RagonEntity _entity; private RagonEntity _entity;
private bool _dirty; private bool _dirty;
private int _size; private int _size;
private int _ticks; private int _ticks;
private int _priority; private int _priority;
protected RagonProperty(int priority, bool invokeLocal) protected RagonProperty(int priority, bool invokeLocal)
{ {
_size = 0; _size = 0;
@@ -46,12 +46,12 @@ namespace Ragon.Client
_fixed = false; _fixed = false;
_invokeLocal = invokeLocal; _invokeLocal = invokeLocal;
} }
public void SetName(string name) public void SetName(string name)
{ {
_name = name; _name = name;
} }
protected void SetFixedSize(int size) protected void SetFixedSize(int size)
{ {
_size = size; _size = size;
@@ -62,18 +62,19 @@ namespace Ragon.Client
{ {
if (!_invokeLocal) if (!_invokeLocal)
return; return;
Changed?.Invoke(); Changed?.Invoke();
} }
protected void MarkAsChanged() protected void MarkAsChanged()
{ {
InvokeChanged(); InvokeChanged();
if (_dirty) return;
_dirty = true;
_entity?.TrackChangedProperty(this); if (_dirty || _entity == null)
return;
_dirty = true;
_entity.TrackChangedProperty(this);
} }
internal void Flush() internal void Flush()
@@ -86,10 +87,10 @@ namespace Ragon.Client
{ {
_ticks++; _ticks++;
} }
internal void AssignEntity(RagonEntity obj) internal void AssignEntity(RagonEntity ent)
{ {
_entity = obj; _entity = ent;
Changed?.Invoke(); Changed?.Invoke();
} }
@@ -107,8 +108,8 @@ namespace Ragon.Client
var propOffset = buffer.WriteOffset; var propOffset = buffer.WriteOffset;
Serialize(buffer); Serialize(buffer);
var propSize = (uint) (buffer.WriteOffset - propOffset); var propSize = (uint)(buffer.WriteOffset - propOffset);
buffer.Write(propSize, 16, sizeOffset); buffer.Write(propSize, 16, sizeOffset);
} }
+47 -35
View File
@@ -23,7 +23,7 @@ namespace Ragon.Client
private readonly INetworkConnection _connection; private readonly INetworkConnection _connection;
private readonly IRagonEntityListener _entityListener; private readonly IRagonEntityListener _entityListener;
private readonly IRagonSceneCollector _sceneCollector; private readonly IRagonSceneCollector _sceneCollector;
private Handler[] _processors; private Handler[] _handlers;
private RagonBuffer _readBuffer; private RagonBuffer _readBuffer;
private RagonBuffer _writeBuffer; private RagonBuffer _writeBuffer;
private RagonRoom _room; private RagonRoom _room;
@@ -35,8 +35,8 @@ namespace Ragon.Client
private RagonStatus _status; private RagonStatus _status;
private NetworkStatistics _stats; private NetworkStatistics _stats;
private float _replicatationRate = 0; private float _replicationRate = 0;
private float _replicatationTime = 0; private float _replicationTime = 0;
public IRagonConnection Connection => _connection; public IRagonConnection Connection => _connection;
public RagonStatus Status => _status; public RagonStatus Status => _status;
@@ -67,24 +67,14 @@ namespace Ragon.Client
_connection.OnConnected += OnConnected; _connection.OnConnected += OnConnected;
_connection.OnDisconnected += OnDisconnected; _connection.OnDisconnected += OnDisconnected;
_replicatationRate = (1000.0f / rate) / 1000.0f; _replicationRate = (1000.0f / rate) / 1000.0f;
_replicatationTime = 0; _replicationTime = 0;
_eventCache = new RagonEventCache(); _eventCache = new RagonEventCache();
_stats = new NetworkStatistics(); _stats = new NetworkStatistics();
_status = RagonStatus.DISCONNECTED; _status = RagonStatus.DISCONNECTED;
} }
public void AddListener(IRagonListener listener)
{
_listenerList.Add(listener);
}
public void RemoveListener(IRagonListener listener)
{
_listenerList.Remove(listener);
}
public void Connect(string address, ushort port, string protocol) public void Connect(string address, ushort port, string protocol)
{ {
_writeBuffer = new RagonBuffer(); _writeBuffer = new RagonBuffer();
@@ -94,25 +84,25 @@ namespace Ragon.Client
_playerCache = new RagonPlayerCache(); _playerCache = new RagonPlayerCache();
_entityCache = new RagonEntityCache(this, _playerCache, _entityListener, _sceneCollector); _entityCache = new RagonEntityCache(this, _playerCache, _entityListener, _sceneCollector);
_processors = new Handler[byte.MaxValue]; _handlers = new Handler[byte.MaxValue];
_processors[(byte)RagonOperation.AUTHORIZED_SUCCESS] = new AuthorizeSuccessHandler(_listenerList); _handlers[(byte)RagonOperation.AUTHORIZED_SUCCESS] = new AuthorizeSuccessHandler(_listenerList);
_processors[(byte)RagonOperation.AUTHORIZED_FAILED] = new AuthorizeFailedHandler(_listenerList); _handlers[(byte)RagonOperation.AUTHORIZED_FAILED] = new AuthorizeFailedHandler(_listenerList);
_processors[(byte)RagonOperation.JOIN_SUCCESS] = _handlers[(byte)RagonOperation.JOIN_SUCCESS] =
new JoinSuccessHandler(this, _readBuffer, _listenerList, _playerCache, _entityCache); new JoinSuccessHandler(this, _readBuffer, _listenerList, _playerCache, _entityCache);
_processors[(byte)RagonOperation.JOIN_FAILED] = new JoinFailedHandler(_listenerList); _handlers[(byte)RagonOperation.JOIN_FAILED] = new JoinFailedHandler(_listenerList);
_processors[(byte)RagonOperation.LEAVE_ROOM] = new LeaveRoomHandler(this, _listenerList, _entityCache); _handlers[(byte)RagonOperation.LEAVE_ROOM] = new LeaveRoomHandler(this, _listenerList, _entityCache);
_processors[(byte)RagonOperation.OWNERSHIP_CHANGED] = _handlers[(byte)RagonOperation.OWNERSHIP_CHANGED] =
new OwnershipHandler(_listenerList, _playerCache, _entityCache); new OwnershipHandler(_listenerList, _playerCache, _entityCache);
_processors[(byte)RagonOperation.PLAYER_JOINED] = new PlayerJoinHandler(_playerCache, _listenerList); _handlers[(byte)RagonOperation.PLAYER_JOINED] = new PlayerJoinHandler(_playerCache, _listenerList);
_processors[(byte)RagonOperation.PLAYER_LEAVED] = _handlers[(byte)RagonOperation.PLAYER_LEAVED] =
new PlayerLeftHandler(_entityCache, _playerCache, _listenerList); new PlayerLeftHandler(_entityCache, _playerCache, _listenerList);
_processors[(byte)RagonOperation.LOAD_SCENE] = new SceneLoadHandler(this, _listenerList); _handlers[(byte)RagonOperation.LOAD_SCENE] = new SceneLoadHandler(this, _listenerList);
_processors[(byte)RagonOperation.CREATE_ENTITY] = new EntityCreateHandler(this, _playerCache, _entityCache); _handlers[(byte)RagonOperation.CREATE_ENTITY] = new EntityCreateHandler(this, _playerCache, _entityCache);
_processors[(byte)RagonOperation.DESTROY_ENTITY] = new EntityDestroyHandler(_entityCache); _handlers[(byte)RagonOperation.DESTROY_ENTITY] = new EntityDestroyHandler(_entityCache);
_processors[(byte)RagonOperation.REPLICATE_ENTITY_STATE] = new StateEntityHandler(_entityCache); _handlers[(byte)RagonOperation.REPLICATE_ENTITY_STATE] = new StateEntityHandler(_entityCache);
_processors[(byte)RagonOperation.REPLICATE_ENTITY_EVENT] = _handlers[(byte)RagonOperation.REPLICATE_ENTITY_EVENT] =
new EntityEventHandler(this, _playerCache, _entityCache); new EntityEventHandler(this, _playerCache, _entityCache);
_processors[(byte)RagonOperation.SNAPSHOT] = _handlers[(byte)RagonOperation.SNAPSHOT] =
new SnapshotHandler(this, _listenerList, _entityCache, _playerCache); new SnapshotHandler(this, _listenerList, _entityCache, _playerCache);
var protocolRaw = RagonVersion.Parse(protocol); var protocolRaw = RagonVersion.Parse(protocol);
@@ -129,11 +119,11 @@ namespace Ragon.Client
public void Update(float dt) public void Update(float dt)
{ {
_replicatationTime += dt; _replicationTime += dt;
if (_replicatationTime >= _replicatationRate) if (_replicationTime >= _replicationRate)
{ {
_entityCache.WriteState(_readBuffer); _entityCache.WriteState(_readBuffer);
_replicatationTime = 0; _replicationTime = 0;
} }
_stats.Update(_connection.BytesSent, _connection.BytesReceived, _connection.Ping, dt); _stats.Update(_connection.BytesSent, _connection.BytesReceived, _connection.Ping, dt);
@@ -147,6 +137,28 @@ namespace Ragon.Client
_connection.Dispose(); _connection.Dispose();
} }
public void AddListener(IRagonListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonAuthorizationListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonConnectedListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonFailedListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonJoinListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonLeftListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonLevelListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonOwnershipChangedListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonPlayerJoinListener listener) => _listenerList.Add(listener);
public void AddListener(IRagonPlayerLeftListener listener) => _listenerList.Add(listener);
public void RemoveListener(IRagonListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonAuthorizationListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonConnectedListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonFailedListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonJoinListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonLeftListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonLevelListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonOwnershipChangedListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonPlayerJoinListener listener) => _listenerList.Remove(listener);
public void RemoveListener(IRagonPlayerLeftListener listener) => _listenerList.Remove(listener);
#endregion #endregion
#region INTERNAL #region INTERNAL
@@ -183,7 +195,7 @@ namespace Ragon.Client
_readBuffer.FromArray(data); _readBuffer.FromArray(data);
var operation = _readBuffer.ReadByte(); var operation = _readBuffer.ReadByte();
_processors[operation].Handle(_readBuffer); _handlers[operation].Handle(_readBuffer);
} }
#endregion #endregion
+130 -17
View File
@@ -18,10 +18,17 @@ namespace Ragon.Client
{ {
internal class RagonListenerList internal class RagonListenerList
{ {
public int Count => _listeners.Count; private readonly RagonClient _client;
private List<IRagonListener> _listeners = new(); private readonly List<IRagonAuthorizationListener> _authorizationListeners = new();
private RagonClient _client; private readonly List<IRagonConnectedListener> _connectionListeners = new();
private readonly List<IRagonFailedListener> _failedListeners = new();
private readonly List<IRagonJoinListener> _joinListeners = new();
private readonly List<IRagonLeftListener> _leftListeners = new();
private readonly List<IRagonLevelListener> _levelListeners = new();
private readonly List<IRagonOwnershipChangedListener> _ownershipChangedListeners = new();
private readonly List<IRagonPlayerJoinListener> _playerJoinListeners = new();
private readonly List<IRagonPlayerLeftListener> _playerLeftListeners = new();
public RagonListenerList(RagonClient client) public RagonListenerList(RagonClient client)
{ {
_client = client; _client = client;
@@ -29,77 +36,183 @@ namespace Ragon.Client
public void Add(IRagonListener listener) public void Add(IRagonListener listener)
{ {
_listeners.Add(listener); _authorizationListeners.Add(listener);
_connectionListeners.Add(listener);
_failedListeners.Add(listener);
_joinListeners.Add(listener);
_leftListeners.Add(listener);
_levelListeners.Add(listener);
_ownershipChangedListeners.Add(listener);
_playerJoinListeners.Add(listener);
_playerLeftListeners.Add(listener);
} }
public void Remove(IRagonListener listener) public void Remove(IRagonListener listener)
{ {
_listeners.Remove(listener); _authorizationListeners.Remove(listener);
_connectionListeners.Remove(listener);
_failedListeners.Remove(listener);
_joinListeners.Remove(listener);
_leftListeners.Remove(listener);
_levelListeners.Remove(listener);
_ownershipChangedListeners.Remove(listener);
_playerJoinListeners.Remove(listener);
_playerLeftListeners.Remove(listener);
} }
public void Add(IRagonAuthorizationListener listener)
{
_authorizationListeners.Add(listener);
}
public void Add(IRagonConnectedListener listener)
{
_connectionListeners.Add(listener);
}
public void Add(IRagonFailedListener listener)
{
_failedListeners.Add(listener);
}
public void Add(IRagonJoinListener listener)
{
_joinListeners.Add(listener);
}
public void Add(IRagonLeftListener listener)
{
_leftListeners.Add(listener);
}
public void Add(IRagonLevelListener listener)
{
_levelListeners.Add(listener);
}
public void Add(IRagonOwnershipChangedListener listener)
{
_ownershipChangedListeners.Add(listener);
}
public void Add(IRagonPlayerJoinListener listener)
{
_playerJoinListeners.Add(listener);
}
public void Add(IRagonPlayerLeftListener listener)
{
_playerLeftListeners.Add(listener);
}
public void Remove(IRagonAuthorizationListener listener)
{
_authorizationListeners.Remove(listener);
}
public void Remove(IRagonConnectedListener listener)
{
_connectionListeners.Remove(listener);
}
public void Remove(IRagonFailedListener listener)
{
_failedListeners.Remove(listener);
}
public void Remove(IRagonJoinListener listener)
{
_joinListeners.Remove(listener);
}
public void Remove(IRagonLeftListener listener)
{
_leftListeners.Remove(listener);
}
public void Remove(IRagonLevelListener listener)
{
_levelListeners.Remove(listener);
}
public void Remove(IRagonOwnershipChangedListener listener)
{
_ownershipChangedListeners.Remove(listener);
}
public void Remove(IRagonPlayerJoinListener listener)
{
_playerJoinListeners.Remove(listener);
}
public void Remove(IRagonPlayerLeftListener listener)
{
_playerLeftListeners.Remove(listener);
}
public void OnAuthorizationSuccess(string playerId, string playerName) public void OnAuthorizationSuccess(string playerId, string playerName)
{ {
foreach (var listener in _listeners) foreach (var listener in _authorizationListeners)
listener.OnAuthorizationSuccess(_client, playerId, playerName); listener.OnAuthorizationSuccess(_client, playerId, playerName);
} }
public void OnAuthorizationFailed(string message) public void OnAuthorizationFailed(string message)
{ {
foreach (var listener in _listeners) foreach (var listener in _authorizationListeners)
listener.OnAuthorizationFailed(_client, message); listener.OnAuthorizationFailed(_client, message);
} }
public void OnLeft() public void OnLeft()
{ {
foreach (var listener in _listeners) foreach (var listener in _leftListeners)
listener.OnLeft(_client); listener.OnLeft(_client);
} }
public void OnFailed(string message) public void OnFailed(string message)
{ {
foreach (var listener in _listeners) foreach (var listener in _failedListeners)
listener.OnFailed(_client, message); listener.OnFailed(_client, message);
} }
public void OnOwnershipChanged(RagonPlayer player) public void OnOwnershipChanged(RagonPlayer player)
{ {
foreach (var listener in _listeners) foreach (var listener in _ownershipChangedListeners)
listener.OnOwnershipChanged(_client, player); listener.OnOwnershipChanged(_client, player);
} }
public void OnPlayerLeft(RagonPlayer player) public void OnPlayerLeft(RagonPlayer player)
{ {
foreach (var listener in _listeners) foreach (var listener in _playerLeftListeners)
listener.OnPlayerLeft(_client, player); listener.OnPlayerLeft(_client, player);
} }
public void OnPlayerJoined(RagonPlayer player) public void OnPlayerJoined(RagonPlayer player)
{ {
foreach (var listener in _listeners) foreach (var listener in _playerJoinListeners)
listener.OnPlayerJoined(_client, player); listener.OnPlayerJoined(_client, player);
} }
public void OnLevel(string sceneName) public void OnLevel(string sceneName)
{ {
foreach (var listener in _listeners) foreach (var listener in _levelListeners)
listener.OnLevel(_client, sceneName); listener.OnLevel(_client, sceneName);
} }
public void OnJoined() public void OnJoined()
{ {
foreach (var listener in _listeners) foreach (var listener in _joinListeners)
listener.OnJoined(_client); listener.OnJoined(_client);
} }
public void OnConnected() public void OnConnected()
{ {
foreach (var listener in _listeners) foreach (var listener in _connectionListeners)
listener.OnConnected(_client); listener.OnConnected(_client);
} }
public void OnDisconnected() public void OnDisconnected()
{ {
foreach (var listener in _listeners) foreach (var listener in _connectionListeners)
listener.OnDisconnected(_client); listener.OnDisconnected(_client);
} }
} }
@@ -27,7 +27,7 @@ public class RagonEntityState
public RagonEntityState(RagonEntity entity, int capacity = 10) public RagonEntityState(RagonEntity entity, int capacity = 10)
{ {
_entity = entity; _entity = entity;
_properties = new List<RagonProperty>(10); _properties = new List<RagonProperty>(capacity);
} }
public void AddProperty(RagonProperty property) public void AddProperty(RagonProperty property)
@@ -31,7 +31,7 @@ public sealed class EntityStateOperation: IRagonOperation
for (var entityIndex = 0; entityIndex < entitiesCount; entityIndex++) for (var entityIndex = 0; entityIndex < entitiesCount; entityIndex++)
{ {
var entityId = reader.ReadUShort(); var entityId = reader.ReadUShort();
if (room.Entities.TryGetValue(entityId, out var entity)) if (room.Entities.TryGetValue(entityId, out var entity) && entity.Owner.Connection.Id == context.Connection.Id)
{ {
entity.State.Read(reader); entity.State.Read(reader);
room.Track(entity); room.Track(entity);
+4 -3
View File
@@ -51,7 +51,7 @@ public class RagonServer : INetworkListener
_reader = new RagonBuffer(); _reader = new RagonBuffer();
_writer = new RagonBuffer(); _writer = new RagonBuffer();
_tickrate = _configuration.ServerTickRate; _tickrate = 1000 / _configuration.ServerTickRate;
_timer = new Stopwatch(); _timer = new Stopwatch();
_handlers = new IRagonOperation[byte.MaxValue]; _handlers = new IRagonOperation[byte.MaxValue];
@@ -66,6 +66,8 @@ public class RagonServer : INetworkListener
_handlers[(byte) RagonOperation.DESTROY_ENTITY] = new EntityDestroyOperation(); _handlers[(byte) RagonOperation.DESTROY_ENTITY] = new EntityDestroyOperation();
_handlers[(byte) RagonOperation.REPLICATE_ENTITY_EVENT] = new EntityEventOperation(); _handlers[(byte) RagonOperation.REPLICATE_ENTITY_EVENT] = new EntityEventOperation();
_handlers[(byte) RagonOperation.REPLICATE_ENTITY_STATE] = new EntityStateOperation(); _handlers[(byte) RagonOperation.REPLICATE_ENTITY_STATE] = new EntityStateOperation();
_logger.Trace($"Server Tick Rate: {_configuration.ServerTickRate}");
} }
public void Execute() public void Execute()
@@ -76,12 +78,11 @@ public class RagonServer : INetworkListener
if (_timer.ElapsedMilliseconds > _tickrate) if (_timer.ElapsedMilliseconds > _tickrate)
{ {
_executor.Update(); _executor.Update();
_scheduler.Update();
_timer.Restart(); _timer.Restart();
} }
_scheduler.Update();
_server.Update(); _server.Update();
Thread.Sleep(1); Thread.Sleep(1);
} }
} }
@@ -38,7 +38,7 @@ public struct Configuration
public int LimitRooms; public int LimitRooms;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static readonly string ServerVersion = "1.1.0-rc"; private static readonly string ServerVersion = "1.1.3-rc";
private static Dictionary<string, ServerType> _serverTypes = new Dictionary<string, ServerType>() private static Dictionary<string, ServerType> _serverTypes = new Dictionary<string, ServerType>()
{ {
{"enet", Server.ServerType.ENET}, {"enet", Server.ServerType.ENET},