2022-05-08 00:40:11 +04:00
|
|
|
using System;
|
2022-04-24 09:05:15 +04:00
|
|
|
using System.Collections.Generic;
|
2022-05-08 00:40:11 +04:00
|
|
|
using NLog;
|
2022-05-01 21:39:46 +04:00
|
|
|
using Ragon.Common;
|
2022-04-24 09:05:15 +04:00
|
|
|
|
|
|
|
|
namespace Ragon.Core
|
|
|
|
|
{
|
2022-06-23 20:45:41 +04:00
|
|
|
public class PluginBase
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
|
|
|
|
private delegate void SubscribeDelegate(Player player, ref ReadOnlySpan<byte> data);
|
|
|
|
|
private delegate void SubscribeEntityDelegate(Player player, Entity entity, ref ReadOnlySpan<byte> data);
|
|
|
|
|
|
|
|
|
|
private Dictionary<ushort, SubscribeDelegate> _globalEvents = new();
|
|
|
|
|
private Dictionary<int, Dictionary<ushort, SubscribeEntityDelegate>> _entityEvents = new();
|
2022-05-26 21:09:53 +04:00
|
|
|
private readonly RagonSerializer _serializer = new();
|
2022-05-08 00:40:11 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
protected IGameRoom Room { get; private set; } = null!;
|
2022-06-25 11:08:50 +04:00
|
|
|
protected ILogger Logger = null!;
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-06-23 20:45:41 +04:00
|
|
|
public void Attach(GameRoom gameRoom)
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger = LogManager.GetLogger($"Plugin<{GetType().Name}>");
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
Room = gameRoom;
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-05-08 00:40:11 +04:00
|
|
|
_globalEvents.Clear();
|
|
|
|
|
_entityEvents.Clear();
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-06-23 20:45:41 +04:00
|
|
|
public void Detach()
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
|
|
|
|
_globalEvents.Clear();
|
|
|
|
|
_entityEvents.Clear();
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void OnEvent<T>(ushort evntCode, Action<Player, T> action) where T : IRagonSerializable, new()
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
|
|
|
|
if (_globalEvents.ContainsKey(evntCode))
|
|
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger.Warn($"Event subscriber already added {evntCode}");
|
2022-05-08 00:40:11 +04:00
|
|
|
return;
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-05-08 00:40:11 +04:00
|
|
|
var data = new T();
|
|
|
|
|
_globalEvents.Add(evntCode, (Player player, ref ReadOnlySpan<byte> raw) =>
|
|
|
|
|
{
|
2022-05-08 09:59:20 +04:00
|
|
|
if (raw.Length == 0)
|
|
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger.Warn($"Payload is empty for event {evntCode}");
|
2022-05-08 09:59:20 +04:00
|
|
|
return;
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-07-31 18:02:17 +04:00
|
|
|
_serializer.Clear();
|
|
|
|
|
_serializer.FromSpan(ref raw);
|
|
|
|
|
data.Deserialize(_serializer);
|
2022-05-08 00:40:11 +04:00
|
|
|
action.Invoke(player, data);
|
|
|
|
|
});
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void OnEvent(ushort evntCode, Action<Player> action)
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
2022-05-08 09:59:20 +04:00
|
|
|
if (_globalEvents.ContainsKey(evntCode))
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger.Warn($"Event subscriber already added {evntCode}");
|
2022-05-08 00:40:11 +04:00
|
|
|
return;
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
|
|
|
|
_globalEvents.Add(evntCode, (Player player, ref ReadOnlySpan<byte> raw) => { action.Invoke(player); });
|
2022-05-08 00:40:11 +04:00
|
|
|
}
|
|
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void OnEvent<T>(Entity entity, ushort evntCode, Action<Player, Entity, T> action) where T : IRagonSerializable, new()
|
2022-05-08 09:59:20 +04:00
|
|
|
{
|
|
|
|
|
if (_entityEvents.ContainsKey(entity.EntityId))
|
|
|
|
|
{
|
|
|
|
|
if (_entityEvents[entity.EntityId].ContainsKey(evntCode))
|
|
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger.Warn($"Event subscriber already added {evntCode} for {entity.EntityId}");
|
2022-05-08 09:59:20 +04:00
|
|
|
return;
|
2022-05-26 21:09:53 +04:00
|
|
|
}
|
|
|
|
|
|
2022-05-08 09:59:20 +04:00
|
|
|
var data = new T();
|
|
|
|
|
_entityEvents[entity.EntityId].Add(evntCode, (Player player, Entity ent, ref ReadOnlySpan<byte> raw) =>
|
|
|
|
|
{
|
|
|
|
|
if (raw.Length == 0)
|
|
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger.Warn($"Payload is empty for entity {ent.EntityId} event {evntCode}");
|
2022-05-08 09:59:20 +04:00
|
|
|
return;
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-07-31 18:02:17 +04:00
|
|
|
_serializer.Clear();
|
|
|
|
|
_serializer.FromSpan(ref raw);
|
|
|
|
|
data.Deserialize(_serializer);
|
2022-05-08 09:59:20 +04:00
|
|
|
action.Invoke(player, ent, data);
|
|
|
|
|
});
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-05-08 09:59:20 +04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
var data = new T();
|
|
|
|
|
_entityEvents.Add(entity.EntityId, new Dictionary<ushort, SubscribeEntityDelegate>());
|
|
|
|
|
_entityEvents[entity.EntityId].Add(evntCode, (Player player, Entity ent, ref ReadOnlySpan<byte> raw) =>
|
|
|
|
|
{
|
|
|
|
|
if (raw.Length == 0)
|
|
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger.Warn($"Payload is empty for entity {ent.EntityId} event {evntCode}");
|
2022-05-08 09:59:20 +04:00
|
|
|
return;
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-07-31 18:02:17 +04:00
|
|
|
_serializer.Clear();
|
|
|
|
|
_serializer.FromSpan(ref raw);
|
|
|
|
|
data.Deserialize(_serializer);
|
2022-05-08 10:00:00 +04:00
|
|
|
action.Invoke(player, ent, data);
|
2022-05-08 09:59:20 +04:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void OnEvent(Entity entity, ushort evntCode, Action<Player, Entity> action)
|
2022-05-08 09:59:20 +04:00
|
|
|
{
|
|
|
|
|
if (_entityEvents.ContainsKey(entity.EntityId))
|
|
|
|
|
{
|
|
|
|
|
if (_entityEvents[entity.EntityId].ContainsKey(evntCode))
|
|
|
|
|
{
|
2022-06-25 11:08:50 +04:00
|
|
|
Logger.Warn($"Event subscriber already added {evntCode} for {entity.EntityId}");
|
2022-05-08 09:59:20 +04:00
|
|
|
return;
|
2022-05-26 21:09:53 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_entityEvents[entity.EntityId].Add(evntCode, (Player player, Entity ent, ref ReadOnlySpan<byte> raw) => { action.Invoke(player, ent); });
|
2022-05-08 09:59:20 +04:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
_entityEvents.Add(entity.EntityId, new Dictionary<ushort, SubscribeEntityDelegate>());
|
2022-05-26 21:09:53 +04:00
|
|
|
_entityEvents[entity.EntityId].Add(evntCode, (Player player, Entity ent, ref ReadOnlySpan<byte> raw) => { action.Invoke(player, ent); });
|
2022-05-08 09:59:20 +04:00
|
|
|
}
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-05-08 00:40:11 +04:00
|
|
|
public void UnsubscribeAll()
|
|
|
|
|
{
|
|
|
|
|
_globalEvents.Clear();
|
|
|
|
|
_entityEvents.Clear();
|
2022-04-24 09:05:15 +04:00
|
|
|
}
|
2022-05-08 00:40:11 +04:00
|
|
|
|
|
|
|
|
public bool InternalHandle(uint peerId, int entityId, ushort evntCode, ref ReadOnlySpan<byte> payload)
|
|
|
|
|
{
|
|
|
|
|
if (!_entityEvents.ContainsKey(entityId))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!_entityEvents[entityId].ContainsKey(evntCode))
|
|
|
|
|
return false;
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
var player = Room.GetPlayerById(peerId);
|
|
|
|
|
var entity = Room.GetEntityById(entityId);
|
|
|
|
|
|
2022-05-08 00:40:11 +04:00
|
|
|
_entityEvents[entityId][evntCode].Invoke(player, entity, ref payload);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool InternalHandle(uint peerId, ushort evntCode, ref ReadOnlySpan<byte> payload)
|
|
|
|
|
{
|
|
|
|
|
if (_globalEvents.ContainsKey(evntCode))
|
|
|
|
|
{
|
2022-08-28 19:31:07 +04:00
|
|
|
var player = Room.GetPlayerById(peerId);
|
2022-05-08 00:40:11 +04:00
|
|
|
_globalEvents[evntCode].Invoke(player, ref payload);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void ReplicateEvent(Player player, uint eventCode, IRagonSerializable payload)
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
2022-05-26 21:09:53 +04:00
|
|
|
_serializer.Clear();
|
|
|
|
|
_serializer.WriteOperation(RagonOperation.REPLICATE_EVENT);
|
|
|
|
|
|
2022-07-31 18:02:17 +04:00
|
|
|
payload.Serialize(_serializer);
|
2022-05-08 00:40:11 +04:00
|
|
|
|
2022-05-26 21:09:53 +04:00
|
|
|
var sendData = _serializer.ToArray();
|
2022-08-28 19:31:07 +04:00
|
|
|
Room.Send(player.PeerId, sendData);
|
2022-05-08 00:40:11 +04:00
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void ReplicateEvent(ushort eventCode, IRagonSerializable payload)
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
2022-05-26 21:09:53 +04:00
|
|
|
_serializer.Clear();
|
|
|
|
|
_serializer.WriteOperation(RagonOperation.REPLICATE_EVENT);
|
|
|
|
|
|
2022-07-31 18:02:17 +04:00
|
|
|
payload.Serialize(_serializer);
|
2022-05-26 21:09:53 +04:00
|
|
|
|
|
|
|
|
var sendData = _serializer.ToArray();
|
2022-08-28 19:31:07 +04:00
|
|
|
Room.Broadcast(sendData, DeliveryType.Reliable);
|
2022-05-08 00:40:11 +04:00
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void ReplicateEntityEvent(Player player, Entity entity, IRagonSerializable payload)
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
2022-05-26 21:09:53 +04:00
|
|
|
_serializer.Clear();
|
|
|
|
|
_serializer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT);
|
|
|
|
|
_serializer.WriteInt(entity.EntityId);
|
|
|
|
|
|
2022-07-31 18:02:17 +04:00
|
|
|
payload.Serialize(_serializer);
|
2022-05-26 21:09:53 +04:00
|
|
|
|
|
|
|
|
var sendData = _serializer.ToArray();
|
2022-08-28 19:31:07 +04:00
|
|
|
Room.Send(player.PeerId, sendData, DeliveryType.Reliable);
|
2022-05-08 00:40:11 +04:00
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-08-28 19:31:07 +04:00
|
|
|
public void ReplicateEntityEvent(Entity entity, IRagonSerializable payload)
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
2022-05-26 21:09:53 +04:00
|
|
|
_serializer.Clear();
|
|
|
|
|
_serializer.WriteOperation(RagonOperation.REPLICATE_ENTITY_EVENT);
|
|
|
|
|
_serializer.WriteInt(entity.EntityId);
|
|
|
|
|
|
2022-07-31 18:02:17 +04:00
|
|
|
payload.Serialize(_serializer);
|
2022-05-26 21:09:53 +04:00
|
|
|
|
|
|
|
|
var sendData = _serializer.ToArray();
|
2022-08-28 19:31:07 +04:00
|
|
|
Room.Broadcast(sendData);
|
2022-05-08 00:40:11 +04:00
|
|
|
}
|
|
|
|
|
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-05-08 00:40:11 +04:00
|
|
|
#region VIRTUAL
|
|
|
|
|
|
|
|
|
|
public virtual void OnPlayerJoined(Player player)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void OnPlayerLeaved(Player player)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-26 21:09:53 +04:00
|
|
|
public virtual void OnOwnershipChanged(Player player)
|
2022-05-08 00:40:11 +04:00
|
|
|
{
|
|
|
|
|
}
|
2022-05-26 21:09:53 +04:00
|
|
|
|
2022-05-08 00:40:11 +04:00
|
|
|
public virtual void OnEntityCreated(Player creator, Entity entity)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void OnEntityDestroyed(Player destoyer, Entity entity)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void OnStart()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void OnStop()
|
|
|
|
|
{
|
|
|
|
|
}
|
2022-07-02 11:02:09 +04:00
|
|
|
|
2022-05-08 00:40:11 +04:00
|
|
|
#endregion
|
|
|
|
|
}
|
2022-04-24 09:05:15 +04:00
|
|
|
}
|