feat: player/room user data now available on joined event

This commit is contained in:
2024-05-12 10:57:46 +03:00
parent a9e6a3e853
commit 646744c9a1
26 changed files with 328 additions and 143 deletions
+20 -13
View File
@@ -54,12 +54,12 @@ namespace Ragon.Client
public ushort Id { get; private set; }
public ushort Type { get; private set; }
public RagonAuthority Authority { get; private set; }
public RagonPlayer Owner { get; private set; }
public RagonEntityState State { get; private set; }
public bool IsStatic => SceneId > 0;
public bool IsStatic => SceneId > 0;
public bool IsReplicated { get; private set; }
public bool IsAttached { get; private set; }
public bool HasAuthority { get; private set; }
@@ -71,22 +71,22 @@ namespace Ragon.Client
internal bool PropertiesChanged => _propertiesChanged;
internal ushort SceneId => _sceneId;
private ushort _sceneId;
private readonly ushort _sceneId;
private bool _propertiesChanged;
private RagonPayload _spawnPayload;
private RagonPayload _destroyPayload;
private readonly Dictionary<int, OnEventDelegate> _events = new Dictionary<int, OnEventDelegate>();
private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _localListeners = new Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>>();
private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _listeners = new Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>>();
private readonly Dictionary<int, OnEventDelegate> _events = new();
private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _localListeners = new();
private readonly Dictionary<int, List<Action<RagonPlayer, IRagonEvent>>> _listeners = new();
public RagonEntity(ushort type = 0, ushort sceneId = 0, bool replicated = true)
{
State = new RagonEntityState(this);
Type = type;
IsReplicated = replicated;
_spawnPayload = new RagonPayload(0);
_destroyPayload = new RagonPayload(0);
_sceneId = sceneId;
@@ -95,7 +95,7 @@ namespace Ragon.Client
internal void Attach()
{
IsAttached = true;
Attached?.Invoke(this);
}
@@ -107,7 +107,7 @@ namespace Ragon.Client
internal void Detach(RagonPayload payload)
{
_destroyPayload = payload;
Detached?.Invoke();
}
@@ -125,7 +125,14 @@ namespace Ragon.Client
return payload;
}
public void Prepare(RagonClient client, ushort entityId, ushort entityType, bool hasAuthority, RagonPlayer player, RagonPayload payload)
public void Prepare(
RagonClient client,
ushort entityId,
ushort entityType,
bool hasAuthority,
RagonPlayer player,
RagonPayload payload
)
{
Type = entityType;
Id = entityId;
@@ -133,7 +140,7 @@ namespace Ragon.Client
_client = client;
_spawnPayload = payload;
Owner = player;
}
@@ -262,7 +269,7 @@ namespace Ragon.Client
_propertiesChanged = false;
}
internal void Read(RagonBuffer buffer)
{
State.ReadState(buffer);
@@ -271,7 +278,7 @@ namespace Ragon.Client
internal void Event(ushort eventCode, RagonPlayer caller, RagonBuffer buffer)
{
if (!IsReplicated) return;
if (_events.TryGetValue(eventCode, out var evnt))
evnt?.Invoke(caller, buffer);
else
@@ -39,8 +39,6 @@ public struct RoomParameters
internal class JoinSuccessHandler : IHandler
{
private readonly RagonListenerList _listenerList;
private readonly RagonPlayerCache _playerCache;
private readonly RagonEntityCache _entityCache;
@@ -62,19 +60,39 @@ internal class JoinSuccessHandler : IHandler
public void Handle(RagonBuffer reader)
{
var roomId = reader.ReadString();
var localId = reader.ReadString();
var ownerId = reader.ReadString();
var min = reader.ReadUShort();
var max = reader.ReadUShort();
var sceneName = reader.ReadString();
var localId = reader.ReadString();
var ownerId = reader.ReadString();
_playerCache.SetOwnerAndLocal(ownerId, localId);
var scene = new RagonScene(_client, _playerCache, _entityCache, sceneName);
var roomInfo = new RoomParameters(roomId, localId, ownerId, min, max);
var room = new RagonRoom(_client, _entityCache, _playerCache, roomInfo, scene);
_playerCache.SetOwnerAndLocal(ownerId, localId);
_client.AssignRoom(room);
room.UserData.Read(reader);
var playersCount = reader.ReadUShort();
RagonLog.Trace("Players: " + playersCount);
for (var i = 0; i < playersCount; i++)
{
var playerPeerId = reader.ReadUShort();
var playerId = reader.ReadString();
var playerName = reader.ReadString();
var player = _playerCache.AddPlayer(playerPeerId, playerId, playerName);
player.UserData.Read(reader);
RagonLog.Trace($"Player {playerPeerId} - {playerId} - {playerName}");
}
_client.AssignRoom(room);
_client.SetStatus(RagonStatus.ROOM);
_listenerList.OnJoined();
_listenerList.OnSceneRequest(sceneName);
}
}
+10 -29
View File
@@ -27,7 +27,7 @@ internal class SnapshotHandler : IHandler
private readonly RagonListenerList _listenerList;
private readonly RagonEntityCache _entityCache;
private readonly RagonPlayerCache _playerCache;
public SnapshotHandler(
RagonClient ragonClient,
RagonListenerList listenerList,
@@ -46,19 +46,6 @@ internal class SnapshotHandler : IHandler
public void Handle(RagonBuffer buffer)
{
var entities = new List<RagonEntity>();
var playersCount = buffer.ReadUShort();
RagonLog.Trace("Players: " + playersCount);
for (var i = 0; i < playersCount; i++)
{
var playerPeerId = buffer.ReadUShort();
var playerId = buffer.ReadString();
var playerName = buffer.ReadString();
_playerCache.AddPlayer(playerPeerId, playerId, playerName);
RagonLog.Trace($"Player {playerPeerId} - {playerId} - {playerName}");
}
var dynamicEntities = buffer.ReadUShort();
RagonLog.Trace("Dynamic Entities: " + dynamicEntities);
for (var i = 0; i < dynamicEntities; i++)
@@ -67,7 +54,7 @@ internal class SnapshotHandler : IHandler
var entityId = buffer.ReadUShort();
var ownerPeerId = buffer.ReadUShort();
var payloadSize = buffer.ReadUShort();
var player = _playerCache.GetPlayerByPeer(ownerPeerId);
if (player == null)
{
@@ -85,13 +72,13 @@ internal class SnapshotHandler : IHandler
payload = new RagonPayload(payloadSize);
payload.Read(buffer);
}
entity.Prepare(_client, entityId, entityType, hasAuthority, player, payload);
_entityListener.OnEntityCreated(entity);
entity.Read(buffer);
entities.Add(entity);
}
@@ -109,26 +96,20 @@ internal class SnapshotHandler : IHandler
if (player == null)
{
RagonLog.Error($"Player not found with peerId: {ownerPeerId}");
_playerCache.Dump();
return;
}
var hasAuthority = _playerCache.Local.Id == player.Id;
var entity = _entityCache.TryGetEntity(0, entityType, staticId, entityId, hasAuthority, out _);
entity.Prepare(_client, entityId, entityType, hasAuthority, player, RagonPayload.Empty);
entity.Read(buffer);
entities.Add(entity);
}
if (_client.Status == RagonStatus.LOBBY)
{
_client.SetStatus(RagonStatus.ROOM);
_listenerList.OnJoined();
}
foreach (var entity in entities)
entity.Attach();
@@ -18,5 +18,5 @@ namespace Ragon.Client;
public interface IRagonDataListener
{
public void OnData(RagonPlayer player, byte[] data);
public void OnData(RagonClient client, RagonPlayer player, byte[] data);
}
@@ -2,5 +2,5 @@ namespace Ragon.Client;
public interface IRagonRoomListListener
{
public void OnRoomListUpdate(IReadOnlyList<RagonRoomInformation> roomsInfos);
public void OnRoomListUpdate(RagonClient client, IReadOnlyList<RagonRoomInformation> roomsInfos);
}
+2 -2
View File
@@ -298,13 +298,13 @@ namespace Ragon.Client
public void OnData(RagonPlayer player, byte[] data)
{
foreach (var listener in _dataListeners)
listener.OnData(player, data);
listener.OnData(_client, player, data);
}
public void OnRoomList(RagonRoomInformation[] roomInfos)
{
foreach (var listListener in _roomListListeners)
listListener.OnRoomListUpdate(roomInfos);
listListener.OnRoomListUpdate(_client, roomInfos);
}
public void OnRoomUserData(IReadOnlyList<string> changes)
+4 -2
View File
@@ -52,10 +52,10 @@ public sealed class RagonPlayerCache
_localId = localId;
}
public void AddPlayer(ushort peerId, string playerId, string playerName)
public RagonPlayer AddPlayer(ushort peerId, string playerId, string playerName)
{
if (_playersById.ContainsKey(playerId))
return;
return null;
var isOwner = playerId == _ownerId;
var isLocal = playerId == _localId;
@@ -73,6 +73,8 @@ public sealed class RagonPlayerCache
_players.Add(player);
_playersById.Add(player.Id, player);
_playersByConnection.Add(player.PeerId, player);
return player;
}
public void RemovePlayer(string playerId)
+1 -1
View File
@@ -104,7 +104,7 @@ namespace Ragon.Client
if (_events.TryGetValue(eventCode, out var evnt))
evnt?.Invoke(caller, buffer);
else
RagonLog.Warn($"Handler event on entity {Id} with eventCode {eventCode} not defined");
RagonLog.Warn($"Handler event {Id} with eventCode {eventCode} not defined");
}
internal void HandleUserData(RagonBuffer buffer)
+2
View File
@@ -80,6 +80,8 @@ public class RagonScene
buffer.WriteByte((byte)replicationMode);
buffer.WriteByte((byte)target);
evnt.Serialize(buffer);
var sendData = buffer.ToArray();
_client.Reliable.Send(sendData);
}
+10 -12
View File
@@ -18,7 +18,7 @@ using Ragon.Protocol;
namespace Ragon.Client
{
public class RagonUserData: IUserData
public class RagonUserData : IUserData
{
public byte[] this[string key]
{
@@ -34,7 +34,7 @@ namespace Ragon.Client
}
}
}
public void Remove(string key)
{
if (_properties.Remove(key))
@@ -46,16 +46,15 @@ namespace Ragon.Client
}
}
}
public bool Dirty => _localChanges.Count > 0;
private readonly List<string> _localChanges = new ();
private readonly List<string> _localChanges = new();
private readonly Dictionary<string, bool> _changesCache = new();
private readonly Dictionary<string, byte[]> _properties = new();
public RagonUserData()
{
}
public IReadOnlyList<string> Read(RagonBuffer buffer)
@@ -65,18 +64,17 @@ namespace Ragon.Client
for (int i = 0; i < len; i++)
{
var key = buffer.ReadString();
var valueSize = buffer.ReadUShort();
var valueSize = buffer.ReadUShort();
if (valueSize > 0)
{
var value = buffer.ReadBytes(valueSize);
_properties[key] = value;
}
else
{
_properties.Remove(key);
}
changes.Add(key);
}
@@ -91,15 +89,15 @@ namespace Ragon.Client
buffer.WriteString(propertyChanged);
if (_properties.TryGetValue(propertyChanged, out var property))
{
buffer.WriteUShort((ushort) property.Length);
buffer.WriteBytes(property);
buffer.WriteUShort((ushort)property.Length);
buffer.WriteBytes(property);
}
else
{
buffer.WriteUShort(0);
}
}
_localChanges.Clear();
}
}