Compare commits

..

4 Commits

Author SHA1 Message Date
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
edmand46 9e16c53cad fix: gameloop optimization 2022-08-20 22:05:43 +04:00
7 changed files with 67 additions and 70 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;
@@ -9,7 +9,7 @@ namespace Ragon.Core
public static class ConfigurationLoader public static class ConfigurationLoader
{ {
private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
private static readonly string _serverVersion = "1.0.9-rc"; private static readonly string _serverVersion = "1.0.13-rc";
private static void CopyrightInfo() private static void CopyrightInfo()
{ {
+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;
} }
} }
+34 -3
View File
@@ -117,7 +117,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;
@@ -178,6 +178,7 @@ namespace Ragon.Core
break; break;
} }
} }
break; break;
} }
case RagonOperation.REPLICATE_ENTITY_EVENT: case RagonOperation.REPLICATE_ENTITY_EVENT:
@@ -339,6 +340,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 +353,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}");
} }
{ {
@@ -384,6 +384,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 +414,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 +466,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;
} }
} }
@@ -513,6 +518,32 @@ 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];
_serializer.WriteBool(true);
var span = _serializer.GetWritableData(property.Size);
var data = property.Read();
data.CopyTo(span);
}
}
var sendData = _serializer.ToArray();
Send(peerId, sendData, DeliveryType.Reliable);
}
public void Start() public void Start()
{ {
_plugin.OnStart(); _plugin.OnStart();
+16 -52
View File
@@ -1,7 +1,4 @@
using System; using System;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.Threading; using System.Threading;
using Ragon.Common; using Ragon.Common;
using ENet; using ENet;
@@ -13,42 +10,33 @@ namespace Ragon.Core
{ {
private readonly RoomManager _roomManager; private readonly RoomManager _roomManager;
private readonly Thread _thread; private readonly Thread _thread;
private readonly Stopwatch _gameLoopTimer;
private readonly Stopwatch _statisticsTimer;
private readonly Stopwatch _serverTimer;
private readonly Stopwatch _logicTimer;
private readonly Lobby _lobby; private readonly Lobby _lobby;
private readonly ISocketServer _server;
private readonly IDispatcherInternal _dispatcherInternal;
private readonly IDispatcher _dispatcher;
private readonly ILogger _logger = LogManager.GetCurrentClassLogger(); private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
private readonly float _deltaTime = 0.0f; private readonly float _deltaTime = 0.0f;
private readonly Configuration _configuration; private readonly Configuration _configuration;
private readonly IDispatcherInternal _dispatcherInternal;
public IDispatcher ThreadDispatcher { get; private set; } public ISocketServer Server => _server;
public ISocketServer Server { get; private set; } public IDispatcher ThreadDispatcher => _dispatcher;
public GameThread(PluginFactory factory, Configuration configuration) public GameThread(PluginFactory factory, Configuration configuration)
{ {
var authorizationProvider = factory.CreateAuthorizationProvider(configuration);
_configuration = configuration; _configuration = configuration;
var authorizationProvider = factory.CreateAuthorizationProvider(configuration);
var dispatcher = new Dispatcher(); var dispatcher = new Dispatcher();
_dispatcherInternal = dispatcher; _dispatcherInternal = dispatcher;
_dispatcher = dispatcher;
ThreadDispatcher = dispatcher; _server = new ENetServer(this);
Server = new ENetServer(this);
_deltaTime = 1000.0f / configuration.SendRate; _deltaTime = 1000.0f / configuration.SendRate;
_roomManager = new RoomManager(factory, this); _roomManager = new RoomManager(factory, this);
_lobby = new Lobby(authorizationProvider, _roomManager, this); _lobby = new Lobby(authorizationProvider, _roomManager, this);
_gameLoopTimer = new Stopwatch();
_statisticsTimer = new Stopwatch();
_serverTimer = new Stopwatch();
_logicTimer = new Stopwatch();
_thread = new Thread(Execute); _thread = new Thread(Execute);
_thread.Name = "Game Thread"; _thread.Name = "Game Thread";
_thread.IsBackground = true; _thread.IsBackground = true;
@@ -62,6 +50,7 @@ namespace Ragon.Core
_logger.Error("Wrong protocol passed to connect method"); _logger.Error("Wrong protocol passed to connect method");
return; return;
} }
var parts = new uint[] {0, 0, 0}; var parts = new uint[] {0, 0, 0};
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
{ {
@@ -70,25 +59,18 @@ namespace Ragon.Core
_logger.Error("Wrong protocol"); _logger.Error("Wrong protocol");
return; return;
} }
parts[i] = v; parts[i] = v;
} }
uint encoded = (parts[0] << 16) | (parts[1] << 8) | parts[2]; uint encoded = (parts[0] << 16) | (parts[1] << 8) | parts[2];
Server.Start(_configuration.Port, _configuration.MaxConnections, encoded); _server.Start(_configuration.Port, _configuration.MaxConnections, encoded);
_gameLoopTimer.Start();
_statisticsTimer.Start();
_logicTimer.Start();
_serverTimer.Start();
_thread.Start(); _thread.Start();
} }
public void Stop() public void Stop()
{ {
Server.Stop(); _server.Stop();
_gameLoopTimer.Stop();
_statisticsTimer.Stop();
_thread.Interrupt(); _thread.Interrupt();
} }
@@ -96,29 +78,11 @@ namespace Ragon.Core
{ {
while (true) while (true)
{ {
_logicTimer.Restart(); _server.Process();
_serverTimer.Restart();
Server.Process();
_dispatcherInternal.Process(); _dispatcherInternal.Process();
_roomManager.Tick(_deltaTime);
var elapsedMilliseconds = _gameLoopTimer.ElapsedMilliseconds; Thread.Sleep((int) _deltaTime);
if (elapsedMilliseconds > _deltaTime)
{
_roomManager.Tick(elapsedMilliseconds / 1000.0f);
_gameLoopTimer.Restart();
continue;
}
if (_statisticsTimer.Elapsed.Seconds > _configuration.StatisticsInterval && _roomManager.RoomsBySocket.Count > 0)
{
var rooms = _roomManager.Rooms.Count;
var clients = _roomManager.RoomsBySocket.Count;
var entities = _roomManager.Rooms.Select(r => r.EntitiesCount).Sum();
_logger.Trace($"Rooms: {rooms} Clients: {clients} Entities: {entities}");
_statisticsTimer.Restart();
}
} }
} }
+1 -1
View File
@@ -94,7 +94,7 @@ namespace Ragon.Core
{ {
if (_host.CheckEvents(out _netEvent) <= 0) if (_host.CheckEvents(out _netEvent) <= 0)
{ {
if (_host.Service(15, out _netEvent) <= 0) if (_host.Service(0, out _netEvent) <= 0)
break; break;
polled = true; polled = true;
+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