Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of UnityNetworkMessages v2.0.0
UnityNetworkMessages.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using OdinSerializer; using OdinSerializer.Utilities; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityNetMessages.Events; using UnityNetMessages.Logging; using UnityNetMessages.OdinSerializer; using UnityNetMessages.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("UnityNetworkMessages")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("UnityNetworkMessages")] [assembly: AssemblyTitle("UnityNetworkMessages")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace UnityNetMessages { [BepInPlugin("Saradora.UnityNetworkMessages", "Unity Network Messagin", "2.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony _harmonyInstance = new Harmony("Saradora.UnityNetworkMessages"); private void Awake() { _harmonyInstance.PatchAll(); } } public static class UnityNetworkMessages { public const string ModGuid = "Saradora.UnityNetworkMessages"; public const string ModVersion = "2.0.0"; public const string ModName = "Unity Network Messagin"; } public static class Hashing { [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe static uint Hash32(byte* input, int length, uint seed = 0u) { uint num = seed + 374761393; if (length >= 16) { uint num2 = seed - 1640531535 - 2048144777; uint num3 = seed + 2246822519u; uint num4 = seed; uint num5 = seed - 2654435761u; int num6 = length >> 4; for (int i = 0; i < num6; i++) { uint num7 = *(uint*)input; uint num8 = *(uint*)(input + 4); uint num9 = *(uint*)(input + 8); uint num10 = *(uint*)(input + 12); uint num11 = num2 + (uint)((int)num7 * -2048144777); num2 = ((num11 << 13) | (num11 >> 19)) * 2654435761u; uint num12 = num3 + (uint)((int)num8 * -2048144777); num3 = ((num12 << 13) | (num12 >> 19)) * 2654435761u; uint num13 = num4 + (uint)((int)num9 * -2048144777); num4 = ((num13 << 13) | (num13 >> 19)) * 2654435761u; uint num14 = num5 + (uint)((int)num10 * -2048144777); num5 = ((num14 << 13) | (num14 >> 19)) * 2654435761u; input += 16; } num = ((num2 << 1) | (num2 >> 31)) + ((num3 << 7) | (num3 >> 25)) + ((num4 << 12) | (num4 >> 20)) + ((num5 << 18) | (num5 >> 14)); } uint num15 = num + (uint)length; for (length &= 0xF; length >= 4; length -= 4) { uint num16 = num15 + (uint)((int)(*(uint*)input) * -1028477379); num15 = ((num16 << 17) | (num16 >> 15)) * 668265263; input += 4; } while (length > 0) { uint num17 = num15 + (uint)(*input * 374761393); num15 = ((num17 << 11) | (num17 >> 21)) * 2654435761u; input++; length--; } int num18 = (int)(num15 ^ (num15 >> 15)) * -2048144777; int num19 = (num18 ^ (num18 >>> 13)) * -1028477379; return (uint)num19 ^ ((uint)num19 >> 16); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static uint Hash32(this byte[] buffer) { int length = buffer.Length; fixed (byte* input = buffer) { return Hash32(input, length); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Hash32(this string text) { return Encoding.UTF8.GetBytes(text).Hash32(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Hash32(this Type type) { return type.FullName.Hash32(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Hash32<T>() { return typeof(T).Hash32(); } } } namespace UnityNetMessages.Logging { public static class Log { private static readonly Dictionary<Assembly, ManualLogSource> LOGSources = new Dictionary<Assembly, ManualLogSource>(); public static void Print(object message) { GetLogger(Assembly.GetCallingAssembly()).LogInfo(message ?? "Null"); } public static void Warning(object message) { GetLogger(Assembly.GetCallingAssembly()).LogWarning(message ?? "Null"); } public static void Error(object message) { GetLogger(Assembly.GetCallingAssembly()).LogError(message ?? "Null"); } public static void Exception(Exception exception) { GetLogger(Assembly.GetCallingAssembly()).LogError((object)(exception?.Message ?? "Null")); } private static ManualLogSource GetLogger(Assembly assembly) { if (LOGSources.TryGetValue(assembly, out var value)) { return value; } LOGSources[assembly] = Logger.CreateLogSource(assembly.GetName().Name); return LOGSources[assembly]; } } } namespace UnityNetMessages.OdinSerializer { internal sealed class CachedMemoryStream : ICacheNotificationReceiver { public static int InitialCapacity = 1024; public static int MaxCapacity = 32768; private MemoryStream memoryStream; public MemoryStream MemoryStream { get { if (!memoryStream.CanRead) { memoryStream = new MemoryStream(InitialCapacity); } return memoryStream; } } public CachedMemoryStream() { memoryStream = new MemoryStream(InitialCapacity); } public void OnFreed() { memoryStream.SetLength(0L); memoryStream.Position = 0L; if (memoryStream.Capacity > MaxCapacity) { memoryStream.Capacity = MaxCapacity; } } public void OnClaimed() { memoryStream.SetLength(0L); memoryStream.Position = 0L; } public static Cache<CachedMemoryStream> Claim(int minCapacity) { Cache<CachedMemoryStream> val = Cache<CachedMemoryStream>.Claim(); if (val.Value.MemoryStream.Capacity < minCapacity) { val.Value.MemoryStream.Capacity = minCapacity; } return val; } public static Cache<CachedMemoryStream> Claim(byte[] bytes = null) { Cache<CachedMemoryStream> val = Cache<CachedMemoryStream>.Claim(); if (bytes != null) { val.Value.MemoryStream.Write(bytes, 0, bytes.Length); val.Value.MemoryStream.Position = 0L; } return val; } } public static class Serialization { public static T Deserialize<T>(byte[] bytes) { return (T)Deserialize(bytes, typeof(T)); } public static object Deserialize(byte[] bytes, Type type) { Cache<CachedMemoryStream> val = CachedMemoryStream.Claim(bytes); try { Cache<BinaryDataReader> obj = Cache<BinaryDataReader>.Claim(); BinaryDataReader value = obj.Value; ((BaseDataReader)value).Stream = val.Value.MemoryStream; ((BaseDataReader)value).Context = null; ((BaseDataReader)value).PrepareNewSerializationSession(); IDataReader val2 = (IDataReader)(object)value; IDisposable disposable = (IDisposable)obj; try { Cache<DeserializationContext> val3 = Cache<DeserializationContext>.Claim(); try { val2.Context = Cache<DeserializationContext>.op_Implicit(val3); return Serializer.Get(type).ReadValueWeak(val2); } finally { ((IDisposable)val3)?.Dispose(); } } finally { disposable.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } } } namespace UnityNetMessages.Patches { [HarmonyPatch(typeof(NetworkManager))] public static class NetworkManager_Patching { private static NetworkManager _currentSingleton; private static CustomMessagingManager _currentMessagingManager; [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void Singleton_SetterPostfix(NetworkManager value) { if (!((Object)(object)_currentSingleton == (Object)(object)value)) { if ((Object)(object)value == (Object)null) { CustomMessagingManager_SetterPostfix(null); } NetworkMessaging.TriggerSingletonChange(value); _currentSingleton = value; } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void CustomMessagingManager_SetterPostfix(CustomMessagingManager value) { if (_currentMessagingManager != value) { NetworkMessaging.TriggerMessengerChange(value); _currentMessagingManager = value; } } } [HarmonyPatch(typeof(NetworkObject))] public static class NetworkObject_Patching { private static Dictionary<NetworkObject, Action<ulong>> _networkIdsEvents = new Dictionary<NetworkObject, Action<ulong>>(); [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void NetworkObjectId_SetterPostfix(ulong value, NetworkObject __instance) { if (_networkIdsEvents.ContainsKey(__instance)) { _networkIdsEvents[__instance]?.Invoke(value); } } public static void RegisterToObjectIdChanges(this NetworkObject obj, Action<ulong> action) { if (!_networkIdsEvents.ContainsKey(obj)) { _networkIdsEvents.Add(obj, action); return; } Dictionary<NetworkObject, Action<ulong>> networkIdsEvents = _networkIdsEvents; networkIdsEvents[obj] = (Action<ulong>)Delegate.Combine(networkIdsEvents[obj], action); } public static void UnregisterFromObjectIdChanges(this NetworkObject obj, Action<ulong> action) { if (_networkIdsEvents.ContainsKey(obj)) { Dictionary<NetworkObject, Action<ulong>> networkIdsEvents = _networkIdsEvents; networkIdsEvents[obj] = (Action<ulong>)Delegate.Remove(networkIdsEvents[obj], action); if (_networkIdsEvents[obj] == null) { _networkIdsEvents.Remove(obj); } } } [HarmonyPatch("OnDestroy")] [HarmonyPrefix] private static void OnDestroy_Prefix(NetworkObject __instance) { if (_networkIdsEvents.ContainsKey(__instance)) { _networkIdsEvents[__instance]?.Invoke(0uL); _networkIdsEvents.Remove(__instance); } } } } namespace UnityNetMessages.Events { public class GlobalNetEvent : NetEventBase { private readonly uint _hash; public GlobalNetEvent(string name, bool assemblySpecific = false) { string text = name; if (assemblySpecific) { text = Assembly.GetCallingAssembly().GetName().Name + "+" + text; } _hash = text.Hash32(); RegisterEvent<NetworkEvent>(); } protected override uint? GetHash() { return _hash; } } public class GlobalNetMessage<T> : NetMessageBase<T> { private readonly uint _hash; public GlobalNetMessage(string name, bool assemblySpecific = false) { string text = name; if (assemblySpecific) { text = Assembly.GetCallingAssembly().GetName().Name + "+" + text; } _hash = text.Hash32(); RegisterEvent<T>(); } protected override uint? GetHash() { return _hash; } } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct NetworkEvent { } public class MessageHandler { private readonly List<WeakReference> _actions = new List<WeakReference>(); public Type ReturnType { get; } public bool IsEmpty { get { if (_actions.Count <= 0) { return true; } foreach (WeakReference action in _actions) { if (action.IsAlive) { return false; } } return true; } } private MessageHandler(MessageReceiver action, Type returnType) { ReturnType = returnType; _actions.Add(new WeakReference(action)); } public static MessageHandler Create<TReturnType>(MessageReceiver action) { return new MessageHandler(action, typeof(TReturnType)); } public void Subscribe<TReturnType>(MessageReceiver action) { if (ReturnType != typeof(TReturnType)) { throw new ArgumentException("Cannot create network event with type " + typeof(TReturnType).Name + " because an event with the same name already exists with a different type of " + ReturnType.Name + "."); } foreach (WeakReference action2 in _actions) { if (action2.Target == action) { return; } } _actions.Add(new WeakReference(action)); } public void Unsubscribe(MessageReceiver action) { foreach (WeakReference action2 in _actions) { if (action2.IsAlive && action2.Target == action) { _actions.Remove(action2); break; } } } public void RaiseEvent(ulong clientId) { for (int num = _actions.Count - 1; num >= 0; num--) { WeakReference weakReference = _actions[num]; if (!weakReference.IsAlive) { _actions.RemoveAt(num); } else { ((MessageReceiver)weakReference.Target).Invoke(clientId, null); } } } public void RaiseMessage(ulong clientId, FastBufferReader buffer) { int num = ((FastBufferReader)(ref buffer)).Length - 1 - 4; if (num < 0) { return; } if (num == 0) { RaiseEvent(clientId); } object obj = null; if (!((FastBufferReader)(ref buffer)).TryBeginRead(num)) { Log.Error("Couldn't read buffer"); return; } byte[] bytes = new byte[num]; ((FastBufferReader)(ref buffer)).ReadBytes(ref bytes, num, 0); obj = Serialization.Deserialize(bytes, ReturnType); for (int num2 = _actions.Count - 1; num2 >= 0; num2--) { WeakReference weakReference = _actions[num2]; if (!weakReference.IsAlive) { _actions.RemoveAt(num2); } else { ((MessageReceiver)weakReference.Target).Invoke(clientId, obj); } } } } public abstract class MessageReceiver : IDisposable { private bool _disposed; internal void RegisterEvent<TReturnType>() { uint? hashInternal = GetHashInternal(); if (!hashInternal.HasValue) { throw new NullReferenceException("Cannot register event as it is uninitialized."); } NetworkMessaging.RegisterEvent<TReturnType>(hashInternal.Value, this); } internal void UnregisterEvent() { uint? hashInternal = GetHashInternal(); if (hashInternal.HasValue) { NetworkMessaging.UnregisterEvent(hashInternal.Value, this); } } internal void Invoke(ulong senderId, object data) { OnReceiveMessage(senderId, data); } protected abstract uint? GetHash(); protected abstract void OnReceiveMessage(ulong senderId, object data); protected uint? GetHashInternal() { if (!_disposed) { return GetHash(); } return null; } ~MessageReceiver() { Dispose(); } public void Dispose() { if (!_disposed) { _disposed = true; DoDispose(); } } protected virtual void DoDispose() { UnregisterEvent(); } } public abstract class NetEventBase : MessageReceiver { public event Action<ulong> EventReceived; public event Action<ulong> EventReceivedFromClient; public event Action EventReceivedFromServer; protected override void OnReceiveMessage(ulong senderId, object data) { this.EventReceived?.Invoke(senderId); if (senderId == NetworkMessaging.ServerClientId) { this.EventReceivedFromServer?.Invoke(); } else { this.EventReceivedFromClient?.Invoke(senderId); } } private FastBufferWriter GetWriterAndHash(out uint outHash) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) uint? hash = GetHash(); if (!hash.HasValue) { throw new NullReferenceException("Cannot send as it is uninitialized."); } FastBufferWriter writer = NetworkMessaging.GetWriter(EMessageType.Event, hash.Value, 0); outHash = hash.Value; return writer; } public void InvokeOnServer(NetworkDelivery delivery = 3) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) uint outHash; FastBufferWriter writerAndHash = GetWriterAndHash(out outHash); try { NetworkMessaging.TrySendMessageToServer<NetworkEvent>(outHash, writerAndHash, delivery); } finally { ((IDisposable)(FastBufferWriter)(ref writerAndHash)).Dispose(); } } public void InvokeOnClient(ulong clientId, NetworkDelivery delivery = 3) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) uint outHash; FastBufferWriter writerAndHash = GetWriterAndHash(out outHash); try { NetworkMessaging.TrySendMessageToClient<NetworkEvent>(outHash, clientId, writerAndHash, delivery); } finally { ((IDisposable)(FastBufferWriter)(ref writerAndHash)).Dispose(); } } public void InvokeOnAllClients(bool includeHost = false, NetworkDelivery delivery = 3) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) uint outHash; FastBufferWriter writerAndHash = GetWriterAndHash(out outHash); try { NetworkMessaging.TrySendMessageToAllClients<NetworkEvent>(outHash, writerAndHash, includeHost, delivery); } finally { ((IDisposable)(FastBufferWriter)(ref writerAndHash)).Dispose(); } } } public abstract class NetMessageBase<T> : MessageReceiver { public event Action<T, ulong> MessageReceived; public event Action<T, ulong> MessageReceivedFromClient; public event Action<T> MessageReceivedFromServer; protected override void OnReceiveMessage(ulong senderId, object data) { if (data is T) { T val = (T)data; this.MessageReceived?.Invoke(val, senderId); if (senderId == NetworkMessaging.ServerClientId) { this.MessageReceivedFromServer?.Invoke(val); } else { this.MessageReceivedFromClient?.Invoke(val, senderId); } } } private bool TryGetWriterAndHash(T data, out uint outHash, out FastBufferWriter outWriter) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) uint? hash = GetHash(); if (!hash.HasValue) { throw new NullReferenceException("Cannot send as it is uninitialized."); } byte[] array; try { array = SerializationUtility.SerializeValue<T>(data, (DataFormat)0, (SerializationContext)null); } catch { Log.Exception(new Exception("Cannot serialize type " + data.GetType().Name)); throw; } outWriter = NetworkMessaging.GetWriter(EMessageType.Data, hash.Value, array.Length); ((FastBufferWriter)(ref outWriter)).WriteBytes(array, -1, 0); outHash = hash.Value; return true; } public void SendToServer(T data, NetworkDelivery delivery = 3) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!TryGetWriterAndHash(data, out var outHash, out var outWriter)) { return; } FastBufferWriter val = outWriter; try { NetworkMessaging.TrySendMessageToServer<T>(outHash, outWriter, delivery); } catch (Exception exception) { Log.Exception(exception); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public void SendToClient(T data, ulong clientId, NetworkDelivery delivery = 3) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!TryGetWriterAndHash(data, out var outHash, out var outWriter)) { return; } FastBufferWriter val = outWriter; try { NetworkMessaging.TrySendMessageToClient<T>(outHash, clientId, outWriter, delivery); } catch (Exception exception) { Log.Exception(exception); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public void SendToAllClients(T data, bool includeHost = false, NetworkDelivery delivery = 3) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!TryGetWriterAndHash(data, out var outHash, out var outWriter)) { return; } FastBufferWriter val = outWriter; try { NetworkMessaging.TrySendMessageToAllClients<T>(outHash, outWriter, includeHost, delivery); } catch (Exception exception) { Log.Exception(exception); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } } public enum EMessageType : byte { Event, Data } public static class NetworkMessaging { private static readonly Dictionary<uint, MessageHandler> _registeredMessages; private static CustomMessagingManager _messenger; private static readonly List<ulong> _clientIds; public static bool IsServer => NetworkManager.Singleton.IsServer; public static ulong ServerClientId => 0uL; public static IReadOnlyList<ulong> NonHostClientIds { get { IReadOnlyList<ulong> connectedClientsIds = NetworkManager.Singleton.ConnectedClientsIds; _clientIds.Clear(); ulong num = 0uL; foreach (ulong item in connectedClientsIds) { if (item != num) { _clientIds.Add(item); } } return _clientIds; } } public static event Action<NetworkManager> SingletonChanged; public static event Action<CustomMessagingManager> MessagingManagerChanged; internal static void TriggerSingletonChange(NetworkManager singleton) { NetworkMessaging.SingletonChanged?.Invoke(singleton); } internal static void TriggerMessengerChange(CustomMessagingManager messenger) { NetworkMessaging.MessagingManagerChanged?.Invoke(messenger); } public static FastBufferWriter GetWriter(EMessageType messageType, uint hash, int size) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) FastBufferWriter result = default(FastBufferWriter); switch (messageType) { case EMessageType.Event: ((FastBufferWriter)(ref result))..ctor(5, (Allocator)2, -1); ((FastBufferWriter)(ref result)).WriteValue<EMessageType>(ref messageType, default(ForEnums)); ((FastBufferWriter)(ref result)).WriteValue<uint>(ref hash, default(ForPrimitives)); break; case EMessageType.Data: ((FastBufferWriter)(ref result))..ctor(5 + size, (Allocator)2, -1); ((FastBufferWriter)(ref result)).WriteValue<EMessageType>(ref messageType, default(ForEnums)); ((FastBufferWriter)(ref result)).WriteValue<uint>(ref hash, default(ForPrimitives)); break; default: ((FastBufferWriter)(ref result))..ctor(1, (Allocator)2, -1); break; } return result; } static NetworkMessaging() { _registeredMessages = new Dictionary<uint, MessageHandler>(); _clientIds = new List<ulong>(); MessagingManagerChanged -= OnMessagingManagerChanged; MessagingManagerChanged += OnMessagingManagerChanged; } private static void OnMessagingManagerChanged(CustomMessagingManager instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown if (_messenger != null) { _messenger.OnUnnamedMessage -= new UnnamedMessageDelegate(OnUnnamedMessageReceived); } _messenger = instance; if (_messenger != null) { _messenger.OnUnnamedMessage += new UnnamedMessageDelegate(OnUnnamedMessageReceived); } } private static void OnUnnamedMessageReceived(ulong clientId, FastBufferReader bufferReader) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) EMessageType eMessageType = EMessageType.Event; if (!((FastBufferReader)(ref bufferReader)).TryBeginReadValue<EMessageType>(ref eMessageType)) { return; } ((FastBufferReader)(ref bufferReader)).ReadValue<EMessageType>(ref eMessageType, default(ForEnums)); uint key = 0u; MessageHandler value; switch (eMessageType) { case EMessageType.Event: if (((FastBufferReader)(ref bufferReader)).TryBeginReadValue<uint>(ref key)) { ((FastBufferReader)(ref bufferReader)).ReadValue<uint>(ref key, default(ForPrimitives)); if (_registeredMessages.TryGetValue(key, out value)) { value.RaiseEvent(clientId); } } break; case EMessageType.Data: if (((FastBufferReader)(ref bufferReader)).TryBeginReadValue<uint>(ref key)) { ((FastBufferReader)(ref bufferReader)).ReadValue<uint>(ref key, default(ForPrimitives)); if (_registeredMessages.TryGetValue(key, out value)) { value.RaiseMessage(clientId, bufferReader); } } break; } } public static void RegisterEvent<TReturnType>(uint hash, MessageReceiver action) { if (!_registeredMessages.ContainsKey(hash)) { _registeredMessages[hash] = MessageHandler.Create<TReturnType>(action); } else { _registeredMessages[hash].Subscribe<TReturnType>(action); } } public static void UnregisterEvent(uint hash, MessageReceiver action) { if (_registeredMessages.ContainsKey(hash)) { MessageHandler messageHandler = _registeredMessages[hash]; messageHandler.Unsubscribe(action); if (messageHandler.IsEmpty) { _registeredMessages.Remove(hash); } } } public static void TrySendMessageToServer<TReturnType>(uint hash, FastBufferWriter writer, NetworkDelivery delivery = 3) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (IsServer) { Log.Warning("Message couldn't be sent because you are the server."); } else { TrySendMessageToClientInternal<TReturnType>(hash, ServerClientId, writer, delivery); } } public static void TrySendMessageToClient<TReturnType>(uint hash, ulong clientId, FastBufferWriter writer, NetworkDelivery delivery = 3) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!IsServer) { Log.Warning("Message couldn't be sent because you are not the server."); } else { TrySendMessageToClientInternal<TReturnType>(hash, clientId, writer, delivery); } } public static void TrySendMessageToAllClients<TReturnType>(uint hash, FastBufferWriter writer, bool includeHost, NetworkDelivery delivery = 3) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!IsServer) { Log.Warning("Message couldn't be sent because you are not the server."); } else if (ValidateHandler<TReturnType>(hash)) { if (includeHost) { _messenger.SendUnnamedMessageToAll(writer, delivery); } else { _messenger.SendUnnamedMessage(NonHostClientIds, writer, delivery); } } } private static void TrySendMessageToClientInternal<TReturnType>(uint hash, ulong clientId, FastBufferWriter writer, NetworkDelivery delivery) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (ValidateHandler<TReturnType>(hash)) { _messenger.SendUnnamedMessage(clientId, writer, delivery); } } private static bool ValidateHandler<TReturnType>(uint hash) { if (_messenger == null) { Log.Warning("Message couldn't be sent because messenger isn't active"); return false; } if (!_registeredMessages.TryGetValue(hash, out var value)) { Log.Warning("Message couldn't be sent because it wasn't registered to the messenger"); return false; } if (value.ReturnType != typeof(TReturnType)) { Log.Error("Message couldn't be sent because the registered event with the same name has a different return type."); return false; } return true; } } public class ObjectMessageLink<TReturnType> { private readonly string _baseName; private readonly NetworkObject _targetObject; private readonly MessageReceiver _messageReceiver; public uint? Hash { get; private set; } public ObjectMessageLink(string baseName, NetworkObject obj, MessageReceiver receiver) { Hash = null; _baseName = baseName; _targetObject = obj; _messageReceiver = receiver; RegisterNetworkObject(); _targetObject.RegisterToObjectIdChanges(OnNetworkObjectIdChanged); } private void OnNetworkObjectIdChanged(ulong value) { if (value != 0L) { RegisterNetworkObject(); } else { Dispose(); } } private void RegisterNetworkObject() { if (_targetObject.NetworkObjectId != 0L) { if (Hash.HasValue) { UnregisterNetworkObject(); } Hash = $"obj{_targetObject.NetworkObjectId}+{_baseName}".Hash32(); _messageReceiver.RegisterEvent<TReturnType>(); } } private void UnregisterNetworkObject() { if (Hash.HasValue) { _messageReceiver.UnregisterEvent(); Hash = null; } } public void Dispose() { UnregisterNetworkObject(); if ((Object)(object)_targetObject != (Object)null) { _targetObject.UnregisterFromObjectIdChanges(OnNetworkObjectIdChanged); } } } public class ObjectNetEvent : NetEventBase { private readonly ObjectMessageLink<NetworkEvent> _objectMessageLink; public ObjectNetEvent(string name, NetworkObject targetObject, bool assemblySpecific = false) { if ((Object)(object)targetObject == (Object)null) { throw new NullReferenceException("Cannot create an object event without a target object."); } if (assemblySpecific) { name = Assembly.GetCallingAssembly().GetName().Name + "+" + name; } _objectMessageLink = new ObjectMessageLink<NetworkEvent>(name, targetObject, this); } protected override uint? GetHash() { return _objectMessageLink.Hash; } protected override void DoDispose() { _objectMessageLink.Dispose(); } } public class ObjectNetMessage<T> : NetMessageBase<T> { private readonly ObjectMessageLink<T> _objectMessageLink; public ObjectNetMessage(string name, NetworkObject targetObject, bool assemblySpecific = false) { if ((Object)(object)targetObject == (Object)null) { throw new NullReferenceException("Cannot create an object event without a target object."); } if (assemblySpecific) { name = Assembly.GetCallingAssembly().GetName().Name + "+" + name; } _objectMessageLink = new ObjectMessageLink<T>(name, targetObject, this); } protected override uint? GetHash() { return _objectMessageLink.Hash; } protected override void DoDispose() { _objectMessageLink.Dispose(); } } }