feat: ticks, state authority, event authority
This commit is contained in:
@@ -3,3 +3,4 @@
|
|||||||
.vs
|
.vs
|
||||||
obj
|
obj
|
||||||
bin
|
bin
|
||||||
|
*.user
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
using System.Runtime.InteropServices;
|
|
||||||
using Game.Source.Events;
|
|
||||||
using NLog;
|
|
||||||
using Ragon.Core;
|
|
||||||
|
|
||||||
namespace Game.Source
|
|
||||||
{
|
|
||||||
public class ExamplePlugin: PluginBase
|
|
||||||
{
|
|
||||||
public override void OnStart()
|
|
||||||
{
|
|
||||||
_logger.Info("Plugin started");
|
|
||||||
|
|
||||||
/*Subscribe<TestEvent>(123, OnTestEvent);
|
|
||||||
*/
|
|
||||||
// Subscribe(500, OnTestEvent2);;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTestEvent2(Player obj)
|
|
||||||
{
|
|
||||||
_logger.Info("Event without data");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnStop()
|
|
||||||
{
|
|
||||||
_logger.Info("Plugin stopped");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTestEvent(Player player, TestEvent myEvent)
|
|
||||||
{
|
|
||||||
_logger.Info("Data " + myEvent.TestData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnPlayerJoined(Player player)
|
|
||||||
{
|
|
||||||
_logger.Info("Player joined " + player.PlayerName);
|
|
||||||
|
|
||||||
SendEvent(player, 123, new TestEvent()
|
|
||||||
{
|
|
||||||
TestData = "asdf"
|
|
||||||
});
|
|
||||||
|
|
||||||
SendEvent(123, new TestEvent()
|
|
||||||
{
|
|
||||||
TestData = "Hello!",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnPlayerLeaved(Player player)
|
|
||||||
{
|
|
||||||
_logger.Info("Player leaved " + player.PlayerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnEntityCreated(Player creator, Entity entity)
|
|
||||||
{
|
|
||||||
// entity.
|
|
||||||
// Subscribe(entity, 500, OnEntityTestEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnEntityDestroyed(Player destoyer, Entity entity)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEntityTestEvent(Player player, Entity entity)
|
|
||||||
{
|
|
||||||
_logger.Info("Entity event with empty payload");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"apiKey": "123",
|
|
||||||
"server": {
|
|
||||||
"port": 5000,
|
|
||||||
"skipTimeout": 60
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Ragon.Common
|
||||||
|
{
|
||||||
|
public enum RagonAuthority: byte
|
||||||
|
{
|
||||||
|
OWNER_ONLY,
|
||||||
|
ALL,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,6 @@ namespace Ragon.Common
|
|||||||
RESTORED,
|
RESTORED,
|
||||||
|
|
||||||
REPLICATE_ENTITY_STATE,
|
REPLICATE_ENTITY_STATE,
|
||||||
REPLICATE_ENTITY_PROPERTY,
|
|
||||||
REPLICATE_ENTITY_EVENT,
|
REPLICATE_ENTITY_EVENT,
|
||||||
REPLICATE_EVENT,
|
REPLICATE_EVENT,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
<OutputPath>/Users/edmand46/UnityProjects/Ragon-Unity-SDK/Assets/RagonSDK/Plugins/</OutputPath>
|
<OutputPath></OutputPath>
|
||||||
<DebugSymbols>false</DebugSymbols>
|
<DebugSymbols>false</DebugSymbols>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DefineConstants>TRACE;NETSTACK_SPAN</DefineConstants>
|
<DefineConstants>TRACE;NETSTACK_SPAN</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
<OutputPath>/Users/edmand46/UnityProjects/Ragon-Unity-SDK/Assets/RagonSDK/Plugins/</OutputPath>
|
<OutputPath></OutputPath>
|
||||||
<DefineConstants>TRACE;NETSTACK_SPAN</DefineConstants>
|
<DefineConstants>TRACE;NETSTACK_SPAN</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon", "Ragon\Ragon.csproj", "{BABA1AF0-CF91-43F2-9577-53800068ACCF}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon", "Ragon\Ragon.csproj", "{BABA1AF0-CF91-43F2-9577-53800068ACCF}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Game", "Game\Game.csproj", "{C2B87ADE-A122-4366-8EB7-24DAE11EBAF0}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleServer", "SimpleServer\SimpleServer.csproj", "{C2B87ADE-A122-4366-8EB7-24DAE11EBAF0}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Common", "Ragon.Common\Ragon.Common.csproj", "{F478B2A2-36F4-43B9-9BB7-382A57C449B2}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ragon.Common", "Ragon.Common\Ragon.Common.csproj", "{F478B2A2-36F4-43B9-9BB7-382A57C449B2}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
<PackageReference Include="ENet-CSharp" Version="2.4.8" />
|
<PackageReference Include="ENet-CSharp" Version="2.4.8" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="NLog" Version="5.0.0-rc2" />
|
<PackageReference Include="NLog" Version="5.0.0-rc2" />
|
||||||
<PackageReference Include="StackExchange.Redis" Version="2.5.61" />
|
|
||||||
<PackageReference Include="StackExchange.Redis.Extensions.Core" Version="8.0.4" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ namespace Ragon.Core
|
|||||||
public struct Server
|
public struct Server
|
||||||
{
|
{
|
||||||
public ushort Port;
|
public ushort Port;
|
||||||
|
public ushort TickRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public struct Configuration
|
public struct Configuration
|
||||||
{
|
{
|
||||||
public string ApiKey;
|
public string Key;
|
||||||
public Server Server;
|
public Server Server;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using Ragon.Common;
|
||||||
|
|
||||||
namespace Ragon.Core;
|
namespace Ragon.Core;
|
||||||
|
|
||||||
@@ -8,13 +8,15 @@ public class Entity
|
|||||||
public int EntityId { get; private set; }
|
public int EntityId { get; private set; }
|
||||||
public uint OwnerId { get; private set; }
|
public uint OwnerId { get; private set; }
|
||||||
public ushort EntityType { get; private set; }
|
public ushort EntityType { get; private set; }
|
||||||
public byte[] State { get; set; }
|
public RagonAuthority Authority { get; private set; }
|
||||||
public Dictionary<int, byte[]> Properties { get; set; }
|
public EntityState State { get; private set; }
|
||||||
|
|
||||||
public Entity(uint ownerId, ushort entityType)
|
public Entity(uint ownerId, ushort entityType, RagonAuthority stateAuthority, RagonAuthority eventAuthority)
|
||||||
{
|
{
|
||||||
OwnerId = ownerId;
|
OwnerId = ownerId;
|
||||||
EntityType = entityType;
|
EntityType = entityType;
|
||||||
EntityId = _idGenerator++;
|
EntityId = _idGenerator++;
|
||||||
|
State = new EntityState(stateAuthority);
|
||||||
|
Authority = eventAuthority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using Ragon.Common;
|
||||||
|
|
||||||
|
namespace Ragon.Core;
|
||||||
|
|
||||||
|
public class EntityState
|
||||||
|
{
|
||||||
|
public bool isDirty { get; private set; }
|
||||||
|
public RagonAuthority Authority { get; private set; }
|
||||||
|
|
||||||
|
public byte[] Data
|
||||||
|
{
|
||||||
|
get => Data;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Data = value;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityState(RagonAuthority ragonAuthority)
|
||||||
|
{
|
||||||
|
Authority = ragonAuthority;
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -280,7 +280,7 @@ namespace Ragon.Core
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnTick(float deltaTime)
|
public virtual void OnTick(ulong ticks, float deltaTime)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-46
@@ -22,6 +22,7 @@ namespace Ragon.Core
|
|||||||
private Dictionary<uint, Player> _players = new();
|
private Dictionary<uint, Player> _players = new();
|
||||||
private Dictionary<int, Entity> _entities = new();
|
private Dictionary<int, Entity> _entities = new();
|
||||||
private uint _owner;
|
private uint _owner;
|
||||||
|
private uint _ticks;
|
||||||
|
|
||||||
private readonly PluginBase _plugin;
|
private readonly PluginBase _plugin;
|
||||||
private readonly RoomThread _roomThread;
|
private readonly RoomThread _roomThread;
|
||||||
@@ -135,9 +136,12 @@ namespace Ragon.Core
|
|||||||
{
|
{
|
||||||
var entityData = rawData.Slice(2, 4);
|
var entityData = rawData.Slice(2, 4);
|
||||||
var entityId = RagonHeader.ReadInt(ref entityData);
|
var entityId = RagonHeader.ReadInt(ref entityData);
|
||||||
if (_entities.TryGetValue(entityId, out var ent) && ent.OwnerId == peerId)
|
if (_entities.TryGetValue(entityId, out var ent))
|
||||||
{
|
{
|
||||||
ent.State = rawData.Slice(6, rawData.Length - 6).ToArray();
|
if (ent.State.Authority == RagonAuthority.OWNER_ONLY && ent.OwnerId != peerId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ent.State.Data = rawData.Slice(6, rawData.Length - 6).ToArray();
|
||||||
|
|
||||||
var data = new byte[rawData.Length];
|
var data = new byte[rawData.Length];
|
||||||
|
|
||||||
@@ -148,43 +152,17 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RagonOperation.REPLICATE_ENTITY_PROPERTY:
|
|
||||||
{
|
|
||||||
var entityData = rawData.Slice(2, 4);
|
|
||||||
var entityId = RagonHeader.ReadInt(ref entityData);
|
|
||||||
if (_entities.TryGetValue(entityId, out var ent) && ent.OwnerId == peerId)
|
|
||||||
{
|
|
||||||
var propertyData = rawData.Slice(6, 4);
|
|
||||||
var propertyId = RagonHeader.ReadInt(ref propertyData);
|
|
||||||
var payload = rawData.Slice(10, rawData.Length - 10).ToArray();
|
|
||||||
var props = _entities[entityId].Properties;
|
|
||||||
|
|
||||||
if (props.ContainsKey(propertyId))
|
|
||||||
props[propertyId] = payload;
|
|
||||||
else
|
|
||||||
props.Add(propertyId, payload);
|
|
||||||
|
|
||||||
var sendData = new byte[rawData.Length];
|
|
||||||
|
|
||||||
rawData.CopyTo(sendData);
|
|
||||||
|
|
||||||
Broadcast(_readyPlayers, sendData, DeliveryType.Reliable);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RagonOperation.REPLICATE_ENTITY_EVENT:
|
case RagonOperation.REPLICATE_ENTITY_EVENT:
|
||||||
{
|
{
|
||||||
|
|
||||||
var evntCodeData = rawData.Slice(2, 2);
|
var evntCodeData = rawData.Slice(2, 2);
|
||||||
var entityIdData = rawData.Slice(4, 4);
|
var entityIdData = rawData.Slice(4, 4);
|
||||||
var evntId = RagonHeader.ReadUShort(ref evntCodeData);
|
var evntId = RagonHeader.ReadUShort(ref evntCodeData);
|
||||||
var entityId = RagonHeader.ReadInt(ref entityIdData);
|
var entityId = RagonHeader.ReadInt(ref entityIdData);
|
||||||
|
|
||||||
if (!_entities.ContainsKey(entityId))
|
if (!_entities.TryGetValue(entityId, out var ent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_entities[entityId].OwnerId != peerId)
|
if (ent.Authority == RagonAuthority.OWNER_ONLY && ent.OwnerId != peerId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var payload = rawData.Slice(8, rawData.Length - 8);
|
var payload = rawData.Slice(8, rawData.Length - 8);
|
||||||
@@ -217,12 +195,14 @@ namespace Ragon.Core
|
|||||||
case RagonOperation.CREATE_ENTITY:
|
case RagonOperation.CREATE_ENTITY:
|
||||||
{
|
{
|
||||||
var typeData = rawData.Slice(2, 2);
|
var typeData = rawData.Slice(2, 2);
|
||||||
|
var authorityData = rawData.Slice(2, 2);
|
||||||
var entityPayloadData = rawData.Slice(4, rawData.Length - 4);
|
var entityPayloadData = rawData.Slice(4, rawData.Length - 4);
|
||||||
|
|
||||||
var entityType = RagonHeader.ReadUShort(ref typeData);
|
var entityType = RagonHeader.ReadUShort(ref typeData);
|
||||||
var entity = new Entity(peerId, entityType);
|
var stateAuthority = (RagonAuthority) authorityData[0];
|
||||||
entity.State = entityPayloadData.ToArray();
|
var eventAuthority = (RagonAuthority) authorityData[1];
|
||||||
entity.Properties = new Dictionary<int, byte[]>();
|
var entity = new Entity(peerId, entityType, stateAuthority, eventAuthority);
|
||||||
|
entity.State.Data = entityPayloadData.ToArray();
|
||||||
|
|
||||||
var player = _players[peerId];
|
var player = _players[peerId];
|
||||||
player.Entities.Add(entity);
|
player.Entities.Add(entity);
|
||||||
@@ -233,16 +213,20 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
_plugin.OnEntityCreated(player, entity);
|
_plugin.OnEntityCreated(player, entity);
|
||||||
|
|
||||||
var data = new byte[entityPayloadData.Length + 12];
|
var data = new byte[entityPayloadData.Length + 14];
|
||||||
var sendData = data.AsSpan();
|
var sendData = data.AsSpan();
|
||||||
var operationData = sendData.Slice(0, 2);
|
var operationData = sendData.Slice(0, 2);
|
||||||
var entityTypeData = sendData.Slice(2, 2);
|
var entityTypeData = sendData.Slice(2, 2);
|
||||||
var entityIdData = sendData.Slice(4, 4);
|
var authority = sendData.Slice(4, 2);
|
||||||
var peerData = sendData.Slice(8, 4);
|
var entityIdData = sendData.Slice(6, 4);
|
||||||
var payload = sendData.Slice(12, entityPayloadData.Length);
|
var peerData = sendData.Slice(10, 4);
|
||||||
|
var payload = sendData.Slice(14, entityPayloadData.Length);
|
||||||
|
|
||||||
entityPayloadData.CopyTo(payload);
|
entityPayloadData.CopyTo(payload);
|
||||||
|
|
||||||
|
authority[0] = authorityData[0];
|
||||||
|
authority[1] = authorityData[1];
|
||||||
|
|
||||||
RagonHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);
|
RagonHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);
|
||||||
RagonHeader.WriteUShort(entityType, ref entityTypeData);
|
RagonHeader.WriteUShort(entityType, ref entityTypeData);
|
||||||
RagonHeader.WriteInt(entity.EntityId, ref entityIdData);
|
RagonHeader.WriteInt(entity.EntityId, ref entityIdData);
|
||||||
@@ -257,8 +241,9 @@ namespace Ragon.Core
|
|||||||
var entityId = RagonHeader.ReadInt(ref entityData);
|
var entityId = RagonHeader.ReadInt(ref entityData);
|
||||||
if (_entities.TryGetValue(entityId, out var entity))
|
if (_entities.TryGetValue(entityId, out var entity))
|
||||||
{
|
{
|
||||||
if (entity.OwnerId == peerId)
|
if (entity.Authority == RagonAuthority.OWNER_ONLY && entity.OwnerId != peerId)
|
||||||
{
|
return;
|
||||||
|
|
||||||
var player = _players[peerId];
|
var player = _players[peerId];
|
||||||
|
|
||||||
player.Entities.Remove(entity);
|
player.Entities.Remove(entity);
|
||||||
@@ -275,7 +260,6 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
Broadcast(_readyPlayers, data, DeliveryType.Reliable);
|
Broadcast(_readyPlayers, data, DeliveryType.Reliable);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -284,21 +268,25 @@ namespace Ragon.Core
|
|||||||
Send(peerId, RagonOperation.RESTORE_BEGIN, DeliveryType.Reliable);
|
Send(peerId, RagonOperation.RESTORE_BEGIN, DeliveryType.Reliable);
|
||||||
foreach (var entity in _entities.Values)
|
foreach (var entity in _entities.Values)
|
||||||
{
|
{
|
||||||
var entityState = entity.State.AsSpan();
|
var entityState = entity.State.Data.AsSpan();
|
||||||
var data = new byte[entity.State.Length + 12];
|
var data = new byte[entity.State.Data.Length + 12];
|
||||||
|
|
||||||
Span<byte> sendData = data.AsSpan();
|
Span<byte> sendData = data.AsSpan();
|
||||||
Span<byte> operationData = sendData.Slice(0, 2);
|
Span<byte> operationData = sendData.Slice(0, 2);
|
||||||
Span<byte> entityTypeData = sendData.Slice(2, 2);
|
Span<byte> entityTypeData = sendData.Slice(2, 2);
|
||||||
Span<byte> entityData = sendData.Slice(4, 4);
|
Span<byte> authorityData = sendData.Slice(4, 2);
|
||||||
Span<byte> ownerData = sendData.Slice(8, 4);
|
Span<byte> entityData = sendData.Slice(6, 4);
|
||||||
Span<byte> entityStateData = sendData.Slice(12, entity.State.Length);
|
Span<byte> ownerData = sendData.Slice(10, 4);
|
||||||
|
Span<byte> entityStateData = sendData.Slice(14, entity.State.Data.Length);
|
||||||
|
|
||||||
RagonHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);
|
RagonHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);
|
||||||
RagonHeader.WriteUShort(entity.EntityType, ref entityTypeData);
|
RagonHeader.WriteUShort(entity.EntityType, ref entityTypeData);
|
||||||
RagonHeader.WriteInt(entity.EntityId, ref entityData);
|
RagonHeader.WriteInt(entity.EntityId, ref entityData);
|
||||||
RagonHeader.WriteInt((int) entity.OwnerId, ref ownerData);
|
RagonHeader.WriteInt((int) entity.OwnerId, ref ownerData);
|
||||||
|
|
||||||
|
authorityData[0] = (byte) entity.State.Authority;
|
||||||
|
authorityData[1] = (byte) entity.Authority;
|
||||||
|
|
||||||
entityState.CopyTo(entityStateData);
|
entityState.CopyTo(entityStateData);
|
||||||
|
|
||||||
Send(peerId, data, DeliveryType.Reliable);
|
Send(peerId, data, DeliveryType.Reliable);
|
||||||
@@ -320,7 +308,8 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
public void Tick(float deltaTime)
|
public void Tick(float deltaTime)
|
||||||
{
|
{
|
||||||
_plugin.OnTick(deltaTime);
|
_ticks++;
|
||||||
|
_plugin.OnTick(_ticks, deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Ragon.Core
|
|||||||
private readonly Thread _thread;
|
private readonly Thread _thread;
|
||||||
private readonly Stopwatch _timer;
|
private readonly Stopwatch _timer;
|
||||||
private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
|
private readonly ILogger _logger = LogManager.GetCurrentClassLogger();
|
||||||
|
private readonly float _deltaTime = 0.0f;
|
||||||
private RingBuffer<Event> _receiveBuffer = new RingBuffer<Event>(8192 + 8192);
|
private RingBuffer<Event> _receiveBuffer = new RingBuffer<Event>(8192 + 8192);
|
||||||
private RingBuffer<Event> _sendBuffer = new RingBuffer<Event>(8192 + 8192);
|
private RingBuffer<Event> _sendBuffer = new RingBuffer<Event>(8192 + 8192);
|
||||||
|
|
||||||
@@ -34,6 +34,7 @@ namespace Ragon.Core
|
|||||||
_socketByRooms = new Dictionary<uint, Room>();
|
_socketByRooms = new Dictionary<uint, Room>();
|
||||||
|
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
|
_deltaTime = 1000.0f / Configuration.Server.TickRate;
|
||||||
|
|
||||||
_roomManager = new RoomManager(this, factory);
|
_roomManager = new RoomManager(this, factory);
|
||||||
_roomManager.OnJoined += (tuple) => _socketByRooms.Add(tuple.Item1, tuple.Item2);
|
_roomManager.OnJoined += (tuple) => _socketByRooms.Add(tuple.Item1, tuple.Item2);
|
||||||
@@ -54,9 +55,6 @@ namespace Ragon.Core
|
|||||||
private void Execute()
|
private void Execute()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
|
||||||
var deltaTime = _timer.ElapsedMilliseconds;
|
|
||||||
if (deltaTime > 1000 / 60)
|
|
||||||
{
|
{
|
||||||
while (_receiveBuffer.TryDequeue(out var evnt))
|
while (_receiveBuffer.TryDequeue(out var evnt))
|
||||||
{
|
{
|
||||||
@@ -93,14 +91,15 @@ namespace Ragon.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_roomManager.Tick(deltaTime / 1000.0f);
|
var elapsedMilliseconds = _timer.ElapsedMilliseconds;
|
||||||
|
if (elapsedMilliseconds > _deltaTime)
|
||||||
_timer.Restart();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Thread.Sleep(1);
|
_roomManager.Tick(elapsedMilliseconds / 1000.0f);
|
||||||
|
_timer.Restart();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"key": "defaultkey",
|
||||||
|
"server": {
|
||||||
|
"port": 4444,
|
||||||
|
"skipTimeout": 60,
|
||||||
|
"tickRate": 30
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,9 @@ Ragon is fully free high perfomance room based game server with plugin based arc
|
|||||||
- Docker support
|
- Docker support
|
||||||
- Add additional API to plugin system
|
- Add additional API to plugin system
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
- OSX, Windows, Linux(Ubuntu, Debian)
|
||||||
|
- .NET 6.0
|
||||||
### Dependencies
|
### Dependencies
|
||||||
* ENet-Sharp
|
* ENet-Sharp
|
||||||
* NetStack
|
* NetStack
|
||||||
|
|||||||
Reference in New Issue
Block a user