101 lines
3.5 KiB
C#
101 lines
3.5 KiB
C#
using System.Reflection;
|
|
using System.Text;
|
|
using GameNetworkLayer.Shared;
|
|
using HarmonyLib;
|
|
using Svelto.DataStructures;
|
|
using Svelto.DataStructures.Experimental;
|
|
|
|
namespace CLre_server.API.Tools
|
|
{
|
|
public class NetServerListener
|
|
{
|
|
internal static bool isEnabled = false;
|
|
|
|
private static FasterDictionary<short, FasterList<NetReceiveMessageCallback>> callbacks = new FasterDictionary<short,FasterList<NetReceiveMessageCallback>>();
|
|
|
|
public delegate void NetReceiveMessageCallback(NetworkDispatcherCode code, byte[] data, int playerId);
|
|
|
|
public static void Enable()
|
|
{
|
|
isEnabled = true;
|
|
}
|
|
|
|
public static void Disable()
|
|
{
|
|
isEnabled = false;
|
|
}
|
|
|
|
public static void DebugReceiveMessage(NetworkDispatcherCode code, NetReceiveMessageCallback callback)
|
|
{
|
|
short key = (short)code;
|
|
if (callbacks.TryGetValue(key, out FasterList<NetReceiveMessageCallback> handlers))
|
|
{
|
|
handlers.Add(callback);
|
|
}
|
|
else
|
|
{
|
|
FasterList<NetReceiveMessageCallback> newHandlers = new FasterList<NetReceiveMessageCallback>(new [] {callback});
|
|
callbacks.Add(key, newHandlers);
|
|
}
|
|
}
|
|
|
|
internal static bool RunDebugCallbacks(NetworkDispatcherCode code, byte[] data, int playerId)
|
|
{
|
|
short key = (short)code;
|
|
if (callbacks.TryGetValue(key, out FasterList<NetReceiveMessageCallback> handlers))
|
|
{
|
|
foreach (NetReceiveMessageCallback callback in handlers)
|
|
{
|
|
callback(code, data, playerId);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void Log(NetworkDispatcherCode code, byte[] data, int playerId)
|
|
{
|
|
StringBuilder sb = new StringBuilder("Received ");
|
|
sb.Append(code.ToString());
|
|
sb.Append(" for player #");
|
|
sb.Append(playerId);
|
|
sb.Append(": 0x");
|
|
foreach (byte b in data)
|
|
{
|
|
sb.Append(b.ToString("X"));
|
|
}
|
|
Utility.Logging.Log(sb.ToString());
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch]
|
|
class NetMessageClientListener_HandleAllMessages_Patch
|
|
{
|
|
[HarmonyPrefix]
|
|
public static void BeforeMethodCall(object ____deserializer, int playerId, object value)
|
|
{
|
|
if (!NetServerListener.isEnabled) return;
|
|
// TODO optimize this to not use Traverse
|
|
Traverse result = Traverse.Create(____deserializer).Method("Deserialize", value);
|
|
NetworkDispatcherCode code = result.Field<NetworkDispatcherCode>("dispatcherCode").Value;
|
|
byte[] data = result.Field<byte[]>("bytes").Value;
|
|
if (data == null)
|
|
{
|
|
Utility.Logging.LogWarning("Network message data was deserialized as null");
|
|
return;
|
|
}
|
|
bool isHandled = NetServerListener.RunDebugCallbacks(code, data, playerId);
|
|
if (!isHandled) Utility.Logging.Log($"Received network message for player {playerId} (code: {code.ToString()}, len: {data.Length})");
|
|
}
|
|
|
|
[HarmonyTargetMethod]
|
|
public static MethodBase Target()
|
|
{
|
|
return AccessTools.Method("GameNetworkLayer.Server.NetMessageServerListener:HandleAllMessages");
|
|
}
|
|
}
|
|
} |