wip
This commit is contained in:
@@ -4,7 +4,7 @@ using NetStack.Buffers;
|
|||||||
|
|
||||||
namespace Ragon.Core
|
namespace Ragon.Core
|
||||||
{
|
{
|
||||||
public static class ProtocolHeader
|
public static class RagonHeader
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void WriteUShort(ushort id, ref Span<byte> data) {
|
public static void WriteUShort(ushort id, ref Span<byte> data) {
|
||||||
@@ -31,6 +31,5 @@ namespace Ragon.Core
|
|||||||
{
|
{
|
||||||
return (ushort)(data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24));
|
return (ushort)(data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,8 @@
|
|||||||
<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>
|
||||||
@@ -28,6 +30,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Sources\Protocol" />
|
<Folder Include="Sources\Protocol" />
|
||||||
|
<Folder Include="Sources\Storage" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
_buffer.ToSpan(ref bufferSpan);
|
_buffer.ToSpan(ref bufferSpan);
|
||||||
|
|
||||||
ProtocolHeader.WriteUShort((ushort) operation, ref data);
|
RagonHeader.WriteUShort((ushort) operation, ref data);
|
||||||
|
|
||||||
Room.Send(peerId, data);
|
Room.Send(peerId, data);
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
_buffer.ToSpan(ref bufferSpan);
|
_buffer.ToSpan(ref bufferSpan);
|
||||||
|
|
||||||
ProtocolHeader.WriteUShort((ushort) operation, ref data);
|
RagonHeader.WriteUShort((ushort) operation, ref data);
|
||||||
|
|
||||||
Room.Broadcast(peersIds, data);
|
Room.Broadcast(peersIds, data);
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-46
@@ -25,7 +25,7 @@ namespace Ragon.Core
|
|||||||
// Cache
|
// Cache
|
||||||
private uint[] _readyPlayers = Array.Empty<uint>();
|
private uint[] _readyPlayers = Array.Empty<uint>();
|
||||||
private uint[] _allPlayers = Array.Empty<uint>();
|
private uint[] _allPlayers = Array.Empty<uint>();
|
||||||
private Entity[] _entitiesAll = Array.Empty<Entity>();
|
private Entity[] _entitiesAll = Array.Empty<Entity>();
|
||||||
|
|
||||||
public Room(RoomThread roomThread, PluginBase pluginBase, string map)
|
public Room(RoomThread roomThread, PluginBase pluginBase, string map)
|
||||||
{
|
{
|
||||||
@@ -54,22 +54,33 @@ namespace Ragon.Core
|
|||||||
};
|
};
|
||||||
|
|
||||||
_players.Add(peerId, player);
|
_players.Add(peerId, player);
|
||||||
|
|
||||||
_allPlayers = _players.Select(p => p.Key).ToArray();
|
_allPlayers = _players.Select(p => p.Key).ToArray();
|
||||||
|
|
||||||
Span<byte> data = stackalloc byte[10];
|
{
|
||||||
Span<byte> operationData = data.Slice(0, 2);
|
Span<byte> data = stackalloc byte[10];
|
||||||
Span<byte> peerData = data.Slice(2, 4);
|
Span<byte> operationData = data.Slice(0, 2);
|
||||||
Span<byte> ownerData = data.Slice(4, 4);
|
Span<byte> peerData = data.Slice(2, 4);
|
||||||
|
Span<byte> ownerData = data.Slice(4, 4);
|
||||||
|
|
||||||
ProtocolHeader.WriteUShort((ushort) RagonOperation.JOIN_ROOM, ref operationData);
|
RagonHeader.WriteUShort((ushort) RagonOperation.JOIN_ROOM, ref operationData);
|
||||||
ProtocolHeader.WriteInt((int) peerId, ref peerData);
|
RagonHeader.WriteInt((int) peerId, ref peerData);
|
||||||
ProtocolHeader.WriteInt((int) _owner, ref ownerData);
|
RagonHeader.WriteInt((int) _owner, ref ownerData);
|
||||||
|
|
||||||
Send(peerId, data);
|
Send(peerId, data);
|
||||||
|
}
|
||||||
|
|
||||||
// var sceneRawData = Encoding.UTF8.GetBytes(_map);
|
{
|
||||||
// Send(peerId, RagonOperation.LOAD_SCENE, sceneRawData);
|
var sceneRawData = Encoding.UTF8.GetBytes(_map).AsSpan();
|
||||||
|
Span<byte> data = stackalloc byte[sceneRawData.Length + 2];
|
||||||
|
Span<byte> operationData = data.Slice(0, 2);
|
||||||
|
Span<byte> sceneData = data.Slice(2, sceneRawData.Length);
|
||||||
|
|
||||||
|
RagonHeader.WriteUShort((ushort) RagonOperation.LOAD_SCENE, ref operationData);
|
||||||
|
sceneRawData.CopyTo(sceneData);
|
||||||
|
|
||||||
|
Send(peerId, data, DeliveryType.Reliable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Leave(uint peerId)
|
public void Leave(uint peerId)
|
||||||
@@ -77,14 +88,14 @@ namespace Ragon.Core
|
|||||||
if (_players.Remove(peerId, out var player))
|
if (_players.Remove(peerId, out var player))
|
||||||
{
|
{
|
||||||
_allPlayers = _players.Select(p => p.Key).ToArray();
|
_allPlayers = _players.Select(p => p.Key).ToArray();
|
||||||
|
|
||||||
foreach (var entityId in player.EntitiesIds)
|
foreach (var entityId in player.EntitiesIds)
|
||||||
{
|
{
|
||||||
Span<byte> entityData = stackalloc byte[6];
|
Span<byte> entityData = stackalloc byte[6];
|
||||||
var operationData = entityData.Slice(0, 2);
|
var operationData = entityData.Slice(0, 2);
|
||||||
|
|
||||||
ProtocolHeader.WriteUShort((ushort) RagonOperation.DESTROY_ENTITY, ref operationData);
|
RagonHeader.WriteUShort((ushort) RagonOperation.DESTROY_ENTITY, ref operationData);
|
||||||
ProtocolHeader.WriteInt(entityId, ref entityData);
|
RagonHeader.WriteInt(entityId, ref entityData);
|
||||||
|
|
||||||
Broadcast(_allPlayers, entityData);
|
Broadcast(_allPlayers, entityData);
|
||||||
|
|
||||||
@@ -102,25 +113,26 @@ namespace Ragon.Core
|
|||||||
case RagonOperation.REPLICATE_ENTITY_STATE:
|
case RagonOperation.REPLICATE_ENTITY_STATE:
|
||||||
{
|
{
|
||||||
var entityData = rawData.Slice(2, 4);
|
var entityData = rawData.Slice(2, 4);
|
||||||
var entityId = ProtocolHeader.ReadInt(ref entityData);
|
var entityId = RagonHeader.ReadInt(ref entityData);
|
||||||
if (_entities.TryGetValue(entityId, out var ent))
|
if (_entities.TryGetValue(entityId, out var ent))
|
||||||
{
|
{
|
||||||
ent.State = rawData.Slice(6, rawData.Length - 6).ToArray();
|
ent.State = rawData.Slice(6, rawData.Length - 6).ToArray();
|
||||||
|
|
||||||
Span<byte> data = stackalloc byte[rawData.Length];
|
Span<byte> data = stackalloc byte[rawData.Length];
|
||||||
rawData.CopyTo(data);
|
rawData.CopyTo(data);
|
||||||
Broadcast(_readyPlayers, data);
|
Broadcast(_readyPlayers, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RagonOperation.REPLICATE_ENTITY_PROPERTY:
|
case RagonOperation.REPLICATE_ENTITY_PROPERTY:
|
||||||
{
|
{
|
||||||
var entityData = rawData.Slice(2, 4);
|
var entityData = rawData.Slice(2, 4);
|
||||||
var entityId = ProtocolHeader.ReadInt(ref entityData);
|
var entityId = RagonHeader.ReadInt(ref entityData);
|
||||||
if (_entities.TryGetValue(entityId, out var ent))
|
if (_entities.TryGetValue(entityId, out var ent))
|
||||||
{
|
{
|
||||||
var propertyData = rawData.Slice(6, 4);
|
var propertyData = rawData.Slice(6, 4);
|
||||||
var propertyId = ProtocolHeader.ReadInt(ref propertyData);
|
var propertyId = RagonHeader.ReadInt(ref propertyData);
|
||||||
var payload = rawData.Slice(10, rawData.Length - 10).ToArray();
|
var payload = rawData.Slice(10, rawData.Length - 10).ToArray();
|
||||||
var props = _entities[entityId].Properties;
|
var props = _entities[entityId].Properties;
|
||||||
|
|
||||||
@@ -145,20 +157,15 @@ namespace Ragon.Core
|
|||||||
case RagonOperation.REPLICATE_EVENT:
|
case RagonOperation.REPLICATE_EVENT:
|
||||||
case RagonOperation.REPLICATE_ENTITY_EVENT:
|
case RagonOperation.REPLICATE_ENTITY_EVENT:
|
||||||
{
|
{
|
||||||
Span<byte> data = stackalloc byte[rawData.Length + 4];
|
Span<byte> data = stackalloc byte[rawData.Length];
|
||||||
Span<byte> peerData = data.Slice(2, 4);
|
rawData.CopyTo(data);
|
||||||
Span<byte> rawDataSlice = data.Slice(4, rawData.Length);
|
|
||||||
|
|
||||||
rawData.CopyTo(rawDataSlice);
|
|
||||||
ProtocolHeader.WriteInt((int) peerId, ref peerData);
|
|
||||||
|
|
||||||
Broadcast(_readyPlayers, data, DeliveryType.Reliable);
|
Broadcast(_readyPlayers, data, DeliveryType.Reliable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RagonOperation.CREATE_ENTITY:
|
case RagonOperation.CREATE_ENTITY:
|
||||||
{
|
{
|
||||||
var entity = new Entity(peerId);
|
var entity = new Entity(peerId);
|
||||||
var entityPayload = rawData.Slice(2, rawData.Length - 2);
|
var entityPayload = rawData.Slice(2, rawData.Length - 2);
|
||||||
entity.State = entityPayload.ToArray();
|
entity.State = entityPayload.ToArray();
|
||||||
entity.Properties = new Dictionary<int, byte[]>();
|
entity.Properties = new Dictionary<int, byte[]>();
|
||||||
|
|
||||||
@@ -168,26 +175,26 @@ namespace Ragon.Core
|
|||||||
|
|
||||||
_entities.Add(entity.EntityId, entity);
|
_entities.Add(entity.EntityId, entity);
|
||||||
_entitiesAll = _entities.Values.ToArray();
|
_entitiesAll = _entities.Values.ToArray();
|
||||||
|
|
||||||
Span<byte> data = stackalloc byte[entityPayload.Length + 10];
|
Span<byte> data = stackalloc byte[entityPayload.Length + 10];
|
||||||
var operationData = data.Slice(0, 2);
|
var operationData = data.Slice(0, 2);
|
||||||
var entityData = data.Slice(2, 4);
|
var entityData = data.Slice(2, 4);
|
||||||
var peerData = data.Slice(6, 4);
|
var peerData = data.Slice(6, 4);
|
||||||
var payload = data.Slice(10, entityPayload.Length);
|
var payload = data.Slice(10, entityPayload.Length);
|
||||||
|
|
||||||
entityPayload.CopyTo(payload);
|
entityPayload.CopyTo(payload);
|
||||||
|
|
||||||
ProtocolHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);
|
RagonHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);
|
||||||
ProtocolHeader.WriteInt(entity.EntityId, ref entityData);
|
RagonHeader.WriteInt(entity.EntityId, ref entityData);
|
||||||
ProtocolHeader.WriteInt((int) peerId, ref peerData);
|
RagonHeader.WriteInt((int) peerId, ref peerData);
|
||||||
|
|
||||||
Broadcast(_allPlayers, data, DeliveryType.Reliable);
|
Broadcast(_allPlayers, data, DeliveryType.Reliable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RagonOperation.DESTROY_ENTITY:
|
case RagonOperation.DESTROY_ENTITY:
|
||||||
{
|
{
|
||||||
var entityData = rawData.Slice(2, 4);
|
var entityData = rawData.Slice(2, 4);
|
||||||
var entityId = ProtocolHeader.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.OwnerId == peerId)
|
||||||
@@ -214,21 +221,23 @@ namespace Ragon.Core
|
|||||||
foreach (var entity in _entities.Values)
|
foreach (var entity in _entities.Values)
|
||||||
{
|
{
|
||||||
var entityState = entity.State.AsSpan();
|
var entityState = entity.State.AsSpan();
|
||||||
|
|
||||||
Span<byte> sendData = stackalloc byte[entity.State.Length + 10];
|
Span<byte> sendData = stackalloc byte[entity.State.Length + 10];
|
||||||
Span<byte> operationData = sendData.Slice(0, 2);
|
Span<byte> operationData = sendData.Slice(0, 2);
|
||||||
Span<byte> entityData = sendData.Slice(2, 4);
|
Span<byte> entityData = sendData.Slice(2, 4);
|
||||||
Span<byte> ownerData = sendData.Slice(6, 4);
|
Span<byte> ownerData = sendData.Slice(6, 4);
|
||||||
Span<byte> entityStateData = sendData.Slice(10, entity.State.Length);
|
Span<byte> entityStateData = sendData.Slice(10, entity.State.Length);
|
||||||
|
|
||||||
ProtocolHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);;
|
RagonHeader.WriteUShort((ushort) RagonOperation.CREATE_ENTITY, ref operationData);
|
||||||
ProtocolHeader.WriteInt(entity.EntityId, ref entityData);
|
;
|
||||||
ProtocolHeader.WriteInt((int) entity.OwnerId, ref ownerData);
|
RagonHeader.WriteInt(entity.EntityId, ref entityData);
|
||||||
|
RagonHeader.WriteInt((int) entity.OwnerId, ref ownerData);
|
||||||
|
|
||||||
entityState.CopyTo(entityStateData);
|
entityState.CopyTo(entityStateData);
|
||||||
|
|
||||||
Send(peerId, sendData, DeliveryType.Reliable);
|
Send(peerId, sendData, DeliveryType.Reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
Send(peerId, RagonOperation.RESTORE_END);
|
Send(peerId, RagonOperation.RESTORE_END);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -245,7 +254,7 @@ namespace Ragon.Core
|
|||||||
{
|
{
|
||||||
_ticks++;
|
_ticks++;
|
||||||
_plugin.OnTick(_ticks, deltaTime);
|
_plugin.OnTick(_ticks, deltaTime);
|
||||||
|
|
||||||
// for (var i = 0; i < _entitiesAll.Length; i++)
|
// for (var i = 0; i < _entitiesAll.Length; i++)
|
||||||
// {
|
// {
|
||||||
// var entity = _entities[i];
|
// var entity = _entities[i];
|
||||||
@@ -280,8 +289,8 @@ namespace Ragon.Core
|
|||||||
public void Send(uint peerId, RagonOperation operation, DeliveryType deliveryType = DeliveryType.Unreliable)
|
public void Send(uint peerId, RagonOperation operation, DeliveryType deliveryType = DeliveryType.Unreliable)
|
||||||
{
|
{
|
||||||
Span<byte> data = stackalloc byte[2];
|
Span<byte> data = stackalloc byte[2];
|
||||||
ProtocolHeader.WriteUShort((ushort) operation, ref data);
|
RagonHeader.WriteUShort((ushort) operation, ref data);
|
||||||
|
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
_roomThread.WriteOutEvent(new Event()
|
_roomThread.WriteOutEvent(new Event()
|
||||||
{
|
{
|
||||||
@@ -291,7 +300,7 @@ namespace Ragon.Core
|
|||||||
Delivery = deliveryType,
|
Delivery = deliveryType,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(uint peerId, Span<byte> payload, DeliveryType deliveryType = DeliveryType.Unreliable)
|
public void Send(uint peerId, Span<byte> payload, DeliveryType deliveryType = DeliveryType.Unreliable)
|
||||||
{
|
{
|
||||||
var bytes = payload.ToArray();
|
var bytes = payload.ToArray();
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace Ragon.Core
|
|||||||
if (_manager.OnAuthorize(peerId, payload))
|
if (_manager.OnAuthorize(peerId, payload))
|
||||||
{
|
{
|
||||||
Span<byte> data = stackalloc byte[2];
|
Span<byte> data = stackalloc byte[2];
|
||||||
ProtocolHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_SUCCESS, ref data);
|
RagonHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_SUCCESS, ref data);
|
||||||
|
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
_roomThread.WriteOutEvent(new Event()
|
_roomThread.WriteOutEvent(new Event()
|
||||||
@@ -71,7 +71,7 @@ namespace Ragon.Core
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Span<byte> data = stackalloc byte[2];
|
Span<byte> data = stackalloc byte[2];
|
||||||
ProtocolHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_FAILED, ref data);
|
RagonHeader.WriteUShort((ushort) RagonOperation.AUTHORIZED_FAILED, ref data);
|
||||||
|
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
_roomThread.WriteOutEvent(new Event()
|
_roomThread.WriteOutEvent(new Event()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Ragon.Core
|
|||||||
private readonly Dictionary<uint, Room> _socketByRooms;
|
private readonly Dictionary<uint, Room> _socketByRooms;
|
||||||
private readonly Thread _thread;
|
private readonly Thread _thread;
|
||||||
private readonly Stopwatch _timer;
|
private readonly Stopwatch _timer;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ namespace Ragon.Core
|
|||||||
if (evnt.Type == EventType.DATA)
|
if (evnt.Type == EventType.DATA)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<byte> data = evnt.Data.AsSpan();
|
ReadOnlySpan<byte> data = evnt.Data.AsSpan();
|
||||||
var operation = (RagonOperation) ProtocolHeader.ReadUShort(ref data);
|
var operation = (RagonOperation) RagonHeader.ReadUShort(ref data);
|
||||||
if (_socketByRooms.TryGetValue(evnt.PeerId, out var room))
|
if (_socketByRooms.TryGetValue(evnt.PeerId, out var room))
|
||||||
{
|
{
|
||||||
room.ProcessEvent(operation, evnt.PeerId, evnt.Data);
|
room.ProcessEvent(operation, evnt.PeerId, evnt.Data);
|
||||||
|
|||||||
Reference in New Issue
Block a user