Unofficial CardLife revival project, pronounced like "celery"
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.5KB

  1. using System.Reflection;
  2. using System.Text;
  3. using GameNetworkLayer.Shared;
  4. using HarmonyLib;
  5. using Svelto.DataStructures;
  6. using Svelto.DataStructures.Experimental;
  7. namespace CLre_server.API.Tools
  8. {
  9. public class NetServerListener
  10. {
  11. internal static bool isEnabled = false;
  12. private static FasterDictionary<short, FasterList<NetReceiveMessageCallback>> callbacks = new FasterDictionary<short,FasterList<NetReceiveMessageCallback>>();
  13. public delegate void NetReceiveMessageCallback(NetworkDispatcherCode code, byte[] data, int playerId);
  14. public static void Enable()
  15. {
  16. isEnabled = true;
  17. }
  18. public static void Disable()
  19. {
  20. isEnabled = false;
  21. }
  22. public static void DebugReceiveMessage(NetworkDispatcherCode code, NetReceiveMessageCallback callback)
  23. {
  24. short key = (short)code;
  25. if (callbacks.TryGetValue(key, out FasterList<NetReceiveMessageCallback> handlers))
  26. {
  27. handlers.Add(callback);
  28. }
  29. else
  30. {
  31. FasterList<NetReceiveMessageCallback> newHandlers = new FasterList<NetReceiveMessageCallback>(new [] {callback});
  32. callbacks.Add(key, newHandlers);
  33. }
  34. }
  35. internal static bool RunDebugCallbacks(NetworkDispatcherCode code, byte[] data, int playerId)
  36. {
  37. short key = (short)code;
  38. if (callbacks.TryGetValue(key, out FasterList<NetReceiveMessageCallback> handlers))
  39. {
  40. foreach (NetReceiveMessageCallback callback in handlers)
  41. {
  42. callback(code, data, playerId);
  43. }
  44. return true;
  45. }
  46. else
  47. {
  48. return false;
  49. }
  50. }
  51. public static void Log(NetworkDispatcherCode code, byte[] data, int playerId)
  52. {
  53. StringBuilder sb = new StringBuilder("Received ");
  54. sb.Append(code.ToString());
  55. sb.Append(" for player #");
  56. sb.Append(playerId);
  57. sb.Append(": 0x");
  58. foreach (byte b in data)
  59. {
  60. sb.Append(b.ToString("X"));
  61. }
  62. Utility.Logging.Log(sb.ToString());
  63. }
  64. }
  65. [HarmonyPatch]
  66. class NetMessageClientListener_HandleAllMessages_Patch
  67. {
  68. [HarmonyPrefix]
  69. public static void BeforeMethodCall(object ____deserializer, int playerId, object value)
  70. {
  71. if (!NetServerListener.isEnabled) return;
  72. // TODO optimize this to not use Traverse
  73. Traverse result = Traverse.Create(____deserializer).Method("Deserialize", value);
  74. NetworkDispatcherCode code = result.Field<NetworkDispatcherCode>("dispatcherCode").Value;
  75. byte[] data = result.Field<byte[]>("bytes").Value;
  76. if (data == null)
  77. {
  78. Utility.Logging.LogWarning("Network message data was deserialized as null");
  79. return;
  80. }
  81. bool isHandled = NetServerListener.RunDebugCallbacks(code, data, playerId);
  82. if (!isHandled) Utility.Logging.Log($"Received network message for player {playerId} (code: {code.ToString()}, len: {data.Length})");
  83. }
  84. [HarmonyTargetMethod]
  85. public static MethodBase Target()
  86. {
  87. return AccessTools.Method("GameNetworkLayer.Server.NetMessageServerListener:HandleAllMessages");
  88. }
  89. }
  90. }