using System; using System.Reflection; using System.Text; using GameNetworkLayer.Shared; using HarmonyLib; using NetworkFramework.Shared; namespace CLre_server.API.Tools { public class NetServerSender { private struct DummyNetDataStruct : ISerializedNetData { public byte[] Serialize() { return new byte[0]; } public void Deserialize(byte[] data) { } } private static readonly MethodInfo _genericSendMessage = AccessTools.Method("GameNetworkLayer.Server.NetMessageServerSender:SendMessage"); private static readonly MethodInfo _genericGetSendMessageMethod = AccessTools.Method(typeof(NetServerSender), "GetSendMessageMethod",parameters: new Type[0]);/* /*((Func) GetSendMessageMethod).Method .GetBaseDefinition() .GetGenericMethodDefinition();*/ private static readonly MethodInfo _genericLog = AccessTools.Method(typeof(NetServerSender), "Log");/* ((Action) Log).Method .GetBaseDefinition() .GetGenericMethodDefinition();*/ private static readonly MethodInfo _genericGetLogMethod = AccessTools.Method(typeof(NetServerSender), "GetLogMethod", new Type[0]);/* ((Func) GetLogMethod).Method .GetBaseDefinition() .GetGenericMethodDefinition();*/ public static MethodInfo GetSendMessageMethod(Type t) { return (MethodInfo) _genericGetSendMessageMethod.MakeGenericMethod(t) .Invoke(null, new object[0]); } public static MethodInfo GetSendMessageMethod() where T : struct, ISerializedNetData { return _genericSendMessage.MakeGenericMethod(typeof(T)); } public static MethodInfo DebugSendMessage(Harmony instance = null, MethodInfo before = null, MethodInfo after = null, MethodInfo transpiler = null, MethodInfo finalizer = null) where T : struct, ISerializedNetData { return DebugSendMessage(typeof(T), instance, before, after, transpiler, finalizer); } public static MethodInfo DebugSendMessage(Type generic, Harmony instance = null, MethodInfo before = null, MethodInfo after = null, MethodInfo transpiler = null, MethodInfo finalizer = null) { return DebugSendMessage( generic, instance, before == null ? null : new HarmonyMethod(before), after == null ? null : new HarmonyMethod(after), transpiler == null ? null : new HarmonyMethod(transpiler), finalizer == null ? null : new HarmonyMethod(finalizer)); } public static MethodInfo DebugSendMessage(Harmony instance = null, HarmonyMethod before = null, HarmonyMethod after = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null) where T : struct, ISerializedNetData { return DebugSendMessage(typeof(T), instance, before, after, transpiler, finalizer); } public static MethodInfo DebugSendMessage(Type generic, Harmony instance = null, HarmonyMethod before = null, HarmonyMethod after = null, HarmonyMethod transpiler = null, HarmonyMethod finalizer = null) { if (instance == null) instance = CLre.harmonyInstance; MethodInfo target = GetSendMessageMethod(generic); return instance.Patch(target, before, after, transpiler, finalizer); } public static MethodInfo GetLogMethod(Type t) { return (MethodInfo) _genericGetLogMethod.MakeGenericMethod(t) .Invoke(null, new object[0]); } public static MethodInfo GetLogMethod() where T : struct, ISerializedNetData { return _genericLog.MakeGenericMethod(typeof(T)); } private static void Log(NetworkDispatcherCode code, ref T data) where T : struct, ISerializedNetData { //Utility.Logging.Log($"Sending ISerializedNetData {data.GetType().FullName} (code: {code.ToString()})"); Traverse d = Traverse.Create(data); string codeName = (short) code > 217 ? "CUSTOM" : code.ToString(); StringBuilder sb = new StringBuilder($"Sending ISerializedNetData {data.GetType().FullName} (code: {codeName} {(short)code})"); foreach (string fieldName in d.Fields()) { Traverse field = d.Field(fieldName); sb.Append("\n"); sb.Append("\""); int start = fieldName.IndexOf('<'); int len = fieldName.LastIndexOf('>'); if (start != -1 && len > 0) { sb.Append(fieldName.Substring(start+1, len-1)); } else { sb.Append(fieldName); } sb.Append("\": "); sb.Append(field.GetValue()); } Utility.Logging.Log(sb.ToString()); } } }