using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI.Internal;
using LethalNetworkAPI.Old;
using LethalNetworkAPI.Old.Networking;
using LethalNetworkAPI.Serializable;
using LethalNetworkAPI.Utils;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using OdinSerializer;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RegisterFormatter(typeof(NetworkBehaviourReferenceFormatter), 0)]
[assembly: RegisterFormatter(typeof(NetworkObjectReferenceFormatter), 0)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("Xilophor")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Easily create networked mods.")]
[assembly: AssemblyFileVersion("3.3.1.0")]
[assembly: AssemblyInformationalVersion("3.3.1+eadeda895384f16cec4845c9d44533f19f84b2ee")]
[assembly: AssemblyProduct("LethalNetworkAPI")]
[assembly: AssemblyTitle("LethalNetworkAPI")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Xilophor/LethalNetworkAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace LethalNetworkAPI
{
[BepInPlugin("LethalNetworkAPI", "LethalNetworkAPI", "3.3.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class LethalNetworkAPIPlugin : BaseUnityPlugin
{
private static Harmony _harmony;
public static LethalNetworkAPIPlugin Instance { get; private set; }
internal static ManualLogSource Logger { get; private set; }
private void Awake()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
Instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
_harmony = new Harmony("LethalNetworkAPI");
_harmony.PatchAll();
if (LobbyCompatibilityDep.Enabled)
{
LobbyCompatibilityDep.Initialize();
}
Logger.LogInfo((object)"LethalNetworkAPI v3.3.1 has Loaded.");
}
}
internal static class LobbyCompatibilityDep
{
private static bool? _enabled;
public static bool Enabled
{
get
{
bool valueOrDefault = _enabled.GetValueOrDefault();
if (!_enabled.HasValue)
{
valueOrDefault = Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility");
_enabled = valueOrDefault;
return valueOrDefault;
}
return valueOrDefault;
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void Initialize()
{
PluginHelper.RegisterPlugin("LethalNetworkAPI", new Version("3.3.1"), (CompatibilityLevel)1, (VersionStrictness)2);
}
}
[Obsolete("Use LNetworkEvent instead.")]
public sealed class LethalClientEvent : LNetworkEventDepricated
{
public event Action? OnReceived;
public event Action<ulong>? OnReceivedFromClient;
public LethalClientEvent(string identifier, Action? onReceived = null, Action<ulong>? onReceivedFromClient = null)
: base(identifier)
{
NetworkHandler.OnClientEvent += ReceiveClientEvent;
NetworkHandler.OnSyncedClientEvent += ReceiveSyncedClientEvent;
OnReceived += onReceived;
OnReceivedFromClient += onReceivedFromClient;
}
public void InvokeServer()
{
if (!IsNetworkHandlerNull())
{
NetworkHandler.Instance.EventServerRpc(Identifier);
}
}
public void InvokeAllClients(bool includeLocalClient = true, bool waitForServerResponse = false)
{
if (!IsNetworkHandlerNull())
{
NetworkHandler.Instance.EventServerRpc(Identifier, toOtherClients: true);
if (includeLocalClient)
{
this.OnReceivedFromClient?.Invoke(NetworkManager.Singleton.LocalClientId);
}
}
}
public void InvokeAllClientsSynced()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
if (!IsNetworkHandlerNull())
{
NetworkTime localTime = NetworkManager.Singleton.LocalTime;
double time = ((NetworkTime)(ref localTime)).Time;
NetworkHandler.Instance.SyncedEventServerRpc(Identifier, time);
ReceiveClientEvent(Identifier, NetworkManager.Singleton.LocalClientId);
}
}
public void ClearSubscriptions()
{
this.OnReceived = delegate
{
};
this.OnReceivedFromClient = delegate
{
};
}
private void ReceiveClientEvent(string identifier, ulong originatorClientId)
{
if (!(identifier != Identifier))
{
if (originatorClientId == 99999)
{
this.OnReceived?.Invoke();
}
else
{
this.OnReceivedFromClient?.Invoke(originatorClientId);
}
}
}
private void ReceiveSyncedClientEvent(string identifier, double time, ulong originatorClientId)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
if (!(identifier != Identifier) && NetworkHandler.Instance != null)
{
NetworkTime serverTime = NetworkManager.Singleton.ServerTime;
double num = time - ((NetworkTime)(ref serverTime)).Time;
((MonoBehaviour)NetworkManager.Singleton).StartCoroutine(WaitAndInvokeEvent((float)num, originatorClientId));
}
}
private IEnumerator WaitAndInvokeEvent(float timeToWait, ulong originatorClientId)
{
if (timeToWait > 0f)
{
yield return (object)new WaitForSeconds(timeToWait);
}
ReceiveClientEvent(Identifier, originatorClientId);
}
}
[Obsolete("Use LNetworkEvent instead.")]
public sealed class LethalServerEvent : LNetworkEventDepricated
{
public event Action<ulong>? OnReceived;
public LethalServerEvent(string identifier, Action<ulong>? onReceived = null)
: base(identifier)
{
NetworkHandler.OnServerEvent += ReceiveServerEvent;
NetworkHandler.OnSyncedServerEvent += ReceiveSyncedServerEvent;
OnReceived += onReceived;
}
public void InvokeClient(ulong clientId)
{
if (!IsNetworkHandlerNull() && IsHostOrServer())
{
NetworkHandler.Instance.EventClientRpc(Identifier, new ulong[1] { clientId });
}
}
public void InvokeClients(IEnumerable<ulong> clientIds)
{
if (!IsNetworkHandlerNull() && IsHostOrServer())
{
NetworkHandler.Instance.EventClientRpc(Identifier, clientIds.ToArray());
}
}
public void InvokeAllClients(bool receiveOnHost = true)
{
if (!IsNetworkHandlerNull() && IsHostOrServer())
{
if (receiveOnHost)
{
NetworkHandler.Instance.EventClientRpc(Identifier, LNetworkUtils.AllConnectedClients);
}
else
{
NetworkHandler.Instance.EventClientRpc(Identifier, LNetworkUtils.OtherConnectedClients);
}
}
}
public void ClearSubscriptions()
{
this.OnReceived = delegate
{
};
}
private void ReceiveServerEvent(string identifier, ulong originClientId)
{
if (!(identifier != Identifier))
{
this.OnReceived?.Invoke(originClientId);
}
}
private void ReceiveSyncedServerEvent(string identifier, double time, ulong originatorClientId)
{
//IL_0015: 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)
if (!(identifier != Identifier))
{
NetworkTime serverTime = NetworkManager.Singleton.ServerTime;
double num = time - ((NetworkTime)(ref serverTime)).Time;
((MonoBehaviour)NetworkManager.Singleton).StartCoroutine(WaitAndInvokeEvent((float)num, originatorClientId));
}
}
private IEnumerator WaitAndInvokeEvent(float timeToWait, ulong clientId)
{
if (timeToWait > 0f)
{
yield return (object)new WaitForSeconds(timeToWait);
}
this.OnReceived?.Invoke(clientId);
}
}
[Obsolete("Deprecated Internal Class")]
public abstract class LNetworkEventDepricated : LethalNetworkDeprecated
{
protected LNetworkEventDepricated(string identifier)
: base("evt." + identifier, "Event")
{
}
}
[Obsolete]
public static class LethalNetworkExtensions
{
public static PlayerControllerB? GetPlayerController(this ulong clientId)
{
return StartOfRound.Instance.allPlayerScripts[StartOfRound.Instance.ClientPlayerList[clientId]];
}
[Obsolete("GetPlayerFromId is deprecated, please use GetPlayerController instead.")]
public static PlayerControllerB? GetPlayerFromId(this ulong clientId)
{
return clientId.GetPlayerController();
}
public static ulong GetClientId(this PlayerControllerB player)
{
return player.actualClientId;
}
[Obsolete]
public static LethalNetworkVariable<TData>? GetNetworkVariable<TData>(this NetworkBehaviour networkBehaviour, string identifier, bool serverOwned = false)
{
return ((Component)networkBehaviour).gameObject.NetworkVariable<TData>(identifier, serverOwned);
}
[Obsolete]
public static LethalNetworkVariable<TData>? GetNetworkVariable<TData>(this NetworkObject networkObject, string identifier, bool serverOwned = false)
{
return ((Component)networkObject).gameObject.NetworkVariable<TData>(identifier, serverOwned);
}
[Obsolete]
public static LethalNetworkVariable<TData>? GetNetworkVariable<TData>(this GameObject gameObject, string identifier, bool serverOwned = false)
{
return gameObject.NetworkVariable<TData>(identifier, serverOwned);
}
[Obsolete]
private static LethalNetworkVariable<TData>? NetworkVariable<TData>(this GameObject gameObject, string identifier, bool serverOwned)
{
string identifier2 = identifier;
NetworkObject networkObjectComp = default(NetworkObject);
if (!gameObject.TryGetComponent<NetworkObject>(ref networkObjectComp))
{
LethalNetworkAPIPlugin.Logger.LogError((object)$"Unable to find the network object component. Are you adding variable \"{identifier2}\" to a network object?");
return null;
}
LethalNetworkVariable<TData> lethalNetworkVariable = (LethalNetworkVariable<TData>)NetworkHandler.Instance.ObjectNetworkVariableList.FirstOrDefault((ILethalNetVar i) => ((LethalNetworkVariable<TData>)i).Identifier == $"{identifier2}.{networkObjectComp.GlobalObjectIdHash}");
if (lethalNetworkVariable != null)
{
return lethalNetworkVariable;
}
lethalNetworkVariable = new LethalNetworkVariable<TData>($"{identifier2}.{networkObjectComp.GlobalObjectIdHash}", networkObjectComp, serverOwned, 3);
NetworkHandler.Instance.ObjectNetworkVariableList.Add(lethalNetworkVariable);
return lethalNetworkVariable;
}
}
[Obsolete("Use LNetworkMessage instead.")]
public sealed class LethalClientMessage<TData> : LNetworkMessageDeprecated
{
public event Action<TData>? OnReceived;
public event Action<TData, ulong>? OnReceivedFromClient;
[Obsolete("Use LNetworkMessage instead.")]
public LethalClientMessage(string identifier, Action<TData>? onReceived = null, Action<TData, ulong>? onReceivedFromClient = null)
: base(identifier)
{
NetworkHandler.OnClientMessage += ReceiveMessage;
OnReceived += onReceived;
OnReceivedFromClient += onReceivedFromClient;
}
public void SendServer(TData data)
{
if (!IsNetworkHandlerNull())
{
NetworkHandler.Instance.MessageServerRpc(Identifier, LethalNetworkSerializer.Serialize(data));
}
}
public void SendAllClients(TData data, bool includeLocalClient = true, bool waitForServerResponse = false)
{
if (!IsNetworkHandlerNull())
{
NetworkHandler.Instance.MessageServerRpc(Identifier, LethalNetworkSerializer.Serialize(data), toOtherClients: true);
if (includeLocalClient)
{
this.OnReceivedFromClient?.Invoke(data, NetworkManager.Singleton.LocalClientId);
}
}
}
public void ClearSubscriptions()
{
this.OnReceived = delegate
{
};
this.OnReceivedFromClient = delegate
{
};
}
private void ReceiveMessage(string identifier, byte[] data, ulong originatorClient)
{
if (!(identifier != Identifier))
{
if (originatorClient == 99999)
{
this.OnReceived?.Invoke(LethalNetworkSerializer.Deserialize<TData>(data));
}
else
{
this.OnReceivedFromClient?.Invoke(LethalNetworkSerializer.Deserialize<TData>(data), originatorClient);
}
}
}
}
[Obsolete("Use LNetworkMessage instead.")]
public class LethalServerMessage<TData> : LNetworkMessageDeprecated
{
public event Action<TData, ulong>? OnReceived;
[Obsolete("Use LNetworkMessage instead.")]
public LethalServerMessage(string identifier, Action<TData, ulong>? onReceived = null)
: base(identifier)
{
NetworkHandler.OnServerMessage += ReceiveServerMessage;
OnReceived += onReceived;
}
public void SendClient(TData data, ulong clientId)
{
if (!IsNetworkHandlerNull() && IsHostOrServer())
{
NetworkHandler.Instance.MessageClientRpc(Identifier, LethalNetworkSerializer.Serialize(data), new ulong[1] { clientId });
}
}
public void SendClients(TData data, IEnumerable<ulong> clientIds)
{
if (!IsNetworkHandlerNull() && IsHostOrServer())
{
NetworkHandler.Instance.MessageClientRpc(Identifier, LethalNetworkSerializer.Serialize(data), clientIds.ToArray());
}
}
public void SendAllClients(TData data, bool receiveOnHost = true)
{
if (!IsNetworkHandlerNull() && IsHostOrServer())
{
if (receiveOnHost)
{
NetworkHandler.Instance.MessageClientRpc(Identifier, LethalNetworkSerializer.Serialize(data), LNetworkUtils.AllConnectedClients);
}
else
{
NetworkHandler.Instance.MessageClientRpc(Identifier, LethalNetworkSerializer.Serialize(data), LNetworkUtils.OtherConnectedClients);
}
}
}
public void ClearSubscriptions()
{
this.OnReceived = delegate
{
};
}
private void ReceiveServerMessage(string identifier, byte[] data, ulong originClientId)
{
if (!(identifier != Identifier))
{
this.OnReceived?.Invoke(LethalNetworkSerializer.Deserialize<TData>(data), originClientId);
}
}
}
[Obsolete("Deprecated Internal Class.")]
public abstract class LNetworkMessageDeprecated : LethalNetworkDeprecated
{
protected LNetworkMessageDeprecated(string identifier)
: base("msg." + identifier, "Message")
{
}
}
internal interface ILethalNetVar
{
}
[Obsolete("Use LNetworkVariable instead.")]
public sealed class LethalNetworkVariable<TData> : LethalNetworkDeprecated, ILethalNetVar
{
private readonly bool _public;
private readonly NetworkObject? _ownerObject;
private bool _isDirty;
private TData _value;
public TData Value
{
get
{
return _value;
}
set
{
if (IsOwner && (value != null || _value != null) && (value == null || !value.Equals(_value)))
{
_value = value;
_isDirty = true;
this.OnValueChanged?.Invoke(_value);
}
}
}
private bool IsOwner
{
get
{
if (_public)
{
return true;
}
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
return true;
}
if (_ownerObject == null && NetworkManager.Singleton.IsServer)
{
return true;
}
if (_ownerObject != null)
{
return _ownerObject.OwnerClientId == NetworkManager.Singleton.LocalClientId;
}
return false;
}
}
public event Action<TData>? OnValueChanged;
public LethalNetworkVariable(string identifier)
: this(identifier, (NetworkObject?)null, serverOwned: true, 2)
{
}
internal LethalNetworkVariable(string identifier, NetworkObject? owner, bool serverOwned, int frameIndex)
: base(identifier, "Variable", frameIndex + 1)
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
_ownerObject = ((!serverOwned) ? owner : null);
NetworkHandler.OnVariableUpdate += ReceiveUpdate;
NetworkHandler.NetworkTick += OnNetworkTick;
NetworkHandler.NetworkSpawn += delegate
{
if (!IsNetworkHandlerNull() && IsHostOrServer(log: false))
{
NetworkHandler.OnPlayerJoin += OnPlayerJoin;
NetworkHandler.NetworkDespawn += ClearSubscriptions;
}
};
NetworkHandler.GetVariableValue += delegate(string id, ulong clientId)
{
if (!(id != Identifier) && !IsNetworkHandlerNull() && IsHostOrServer())
{
NetworkHandler.Instance.UpdateVariableClientRpc(Identifier, LethalNetworkSerializer.Serialize(_value), new ulong[1] { clientId });
}
};
if (typeof(LethalNetworkVariable<TData>).GetCustomAttributes(typeof(PublicNetworkVariableAttribute), inherit: true).Any())
{
_public = true;
}
if (!IsNetworkHandlerNull(log: false))
{
if (IsHostOrServer())
{
NetworkHandler.OnPlayerJoin += OnPlayerJoin;
}
else
{
NetworkHandler.Instance.GetVariableValueServerRpc(Identifier);
}
}
}
private void OnPlayerJoin(ulong clientId)
{
if (!IsNetworkHandlerNull() && IsHostOrServer())
{
NetworkHandler.Instance.UpdateVariableClientRpc(Identifier, LethalNetworkSerializer.Serialize(_value), new ulong[1] { clientId });
}
}
private void ClearSubscriptions()
{
NetworkHandler.OnPlayerJoin -= OnPlayerJoin;
NetworkHandler.NetworkDespawn -= ClearSubscriptions;
}
private void SendUpdate()
{
if (!IsNetworkHandlerNull() && IsOwner)
{
NetworkHandler.Instance.UpdateVariableServerRpc(Identifier, LethalNetworkSerializer.Serialize(_value));
}
}
private void ReceiveUpdate(string identifier, byte[] data)
{
if (!(identifier != Identifier))
{
TData val = LethalNetworkSerializer.Deserialize<TData>(data);
if (val != null)
{
_value = val;
this.OnValueChanged?.Invoke(val);
}
}
}
private void OnNetworkTick()
{
if (_isDirty && _value != null)
{
SendUpdate();
_isDirty = false;
}
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class PublicNetworkVariableAttribute : Attribute
{
}
public sealed class LNetworkEvent
{
internal string Identifier { get; }
public event Action<ulong>? OnServerReceived = delegate
{
};
public event Action? OnClientReceived = delegate
{
};
public event Action<ulong>? OnClientReceivedFromClient = delegate
{
};
public static LNetworkEvent Connect(string identifier, Action<ulong>? onServerReceived = null, Action? onClientReceived = null, Action<ulong>? onClientReceivedFromClient = null)
{
string text;
try
{
text = LNetworkUtils.GetModGuid(2) + "." + identifier;
}
catch (Exception arg)
{
LethalNetworkAPIPlugin.Logger.LogError((object)("Unable to find Mod Guid! To still work, this Event will only use the given identifier. " + $"Warning: This may cause collision with another mod's NetworkEvent! Stack Trace: {arg}"));
text = identifier;
}
if (!UnnamedMessageHandler.LNetworkEvents.TryGetValue(text, out LNetworkEvent value))
{
return new LNetworkEvent(text, onServerReceived, onClientReceived, onClientReceivedFromClient);
}
value.OnServerReceived += onServerReceived;
value.OnClientReceived += onClientReceived;
value.OnClientReceivedFromClient += onClientReceivedFromClient;
return value;
}
public static LNetworkEvent Create(string identifier, Action<ulong>? onServerReceived = null, Action? onClientReceived = null, Action<ulong>? onClientReceivedFromClient = null)
{
string identifier2;
try
{
identifier2 = LNetworkUtils.GetModGuid(2) + "." + identifier;
}
catch (Exception arg)
{
LethalNetworkAPIPlugin.Logger.LogError((object)("Unable to find Mod Guid! To still work, this Event will only use the given identifier. " + $"Warning: This may cause collision with another mod's NetworkEvent! Stack Trace: {arg}"));
identifier2 = identifier;
}
return new LNetworkEvent(identifier2, onServerReceived, onClientReceived, onClientReceivedFromClient);
}
private LNetworkEvent(string identifier, Action<ulong>? onServerReceived = null, Action? onClientReceived = null, Action<ulong>? onClientReceivedFromClient = null)
{
if (UnnamedMessageHandler.LNetworkEvents.TryGetValue(identifier, out LNetworkEvent _))
{
throw new InvalidOperationException("An event with the identifier " + identifier + " already exists! Please use a different identifier.");
}
Identifier = identifier;
OnServerReceived += onServerReceived;
OnClientReceived += onClientReceived;
OnClientReceivedFromClient += onClientReceivedFromClient;
UnnamedMessageHandler.LNetworkEvents.Add(identifier, this);
}
internal void InvokeOnServerReceived(ulong clientId)
{
this.OnServerReceived?.Invoke(clientId);
}
internal void InvokeOnClientReceived()
{
this.OnClientReceived?.Invoke();
}
internal void InvokeOnClientReceivedFromClient(ulong clientId)
{
this.OnClientReceivedFromClient?.Invoke(clientId);
}
public void ClearSubscriptions()
{
this.OnServerReceived = delegate
{
};
this.OnClientReceived = delegate
{
};
this.OnClientReceivedFromClient = delegate
{
};
}
public void InvokeClient(ulong clientGuid)
{
InvokeClients(new ulong[1] { clientGuid });
}
public void InvokeClient(int playerId)
{
InvokeClients(new ulong[1] { LNetworkUtils.GetClientGuid(playerId) });
}
public void InvokeClients(ulong[] clientGuidArray)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (!LNetworkUtils.IsConnected)
{
throw new NetworkConfigurationException("Attempting to use LNetworkMessage method while not connected to a server.");
}
if (!LNetworkUtils.IsHostOrServer)
{
throw new InvalidOperationException("Attempting to use LNetworkMessage Server-Only method while not the host.");
}
if (clientGuidArray.Any())
{
if (UnnamedMessageHandler.Instance == null)
{
throw new NetworkConfigurationException("The UnnamedMessageHandler is null. Shit's fucked! Please send this log to the LethalNetworkAPI developer.");
}
UnnamedMessageHandler.Instance.SendMessageToClients(new MessageData(Identifier, EMessageType.Event | EMessageType.ServerMessage), clientGuidArray);
}
}
public void InvokeClients(int[] playerIdArray)
{
InvokeClients(playerIdArray.Select(LNetworkUtils.GetClientGuid).ToArray());
}
public void InvokeClients()
{
InvokeClients(LNetworkUtils.AllConnectedClients);
}
public void InvokeServer()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if (!LNetworkUtils.IsConnected)
{
throw new NetworkConfigurationException("Attempting to use LNetworkMessage method while not connected to a server.");
}
if (UnnamedMessageHandler.Instance == null)
{
throw new NetworkConfigurationException("The UnnamedMessageHandler is null. Shit's fucked! Please send this log to the LethalNetworkAPI developer.");
}
UnnamedMessageHandler.Instance.SendMessageToServer(new MessageData(Identifier, EMessageType.Event | EMessageType.ClientMessage));
}
public void InvokeOtherClients(ulong[] clientGuidArray)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
if (!LNetworkUtils.IsConnected)
{
throw new NetworkConfigurationException("Attempting to use LNetworkMessage method while not connected to a server.");
}
if (clientGuidArray.Any())
{
if (UnnamedMessageHandler.Instance == null)
{
throw new NetworkConfigurationException("The UnnamedMessageHandler is null. Shit's fucked! Please send this log to the LethalNetworkAPI developer.");
}
if (UnnamedMessageHandler.Instance.IsServer)
{
UnnamedMessageHandler.Instance.SendMessageToClients(new MessageData(Identifier, EMessageType.Event | EMessageType.ClientMessageToClient), clientGuidArray);
}
else
{
UnnamedMessageHandler.Instance.SendMessageToServer(new MessageData(Identifier, EMessageType.Event | EMessageType.ClientMessageToClient, null, clientGuidArray));
}
}
}
public void InvokeOtherClients(int[] playerIdArray)
{
InvokeOtherClients(playerIdArray.Select(LNetworkUtils.GetClientGuid).ToArray());
}
public void InvokeOtherClients()
{
InvokeOtherClients(LNetworkUtils.OtherConnectedClients);
}
}
internal interface INetMessage
{
internal void InvokeOnServerReceived(object? data, ulong clientId);
internal void InvokeOnClientReceived(object? data);
internal void InvokeOnClientReceivedFromClient(object? data, ulong clientId);
}
public sealed class LNetworkMessage<TData> : INetMessage
{
internal string Identifier { get; }
public event Action<TData, ulong>? OnServerReceived = delegate
{
};
public event Action<TData>? OnClientReceived = delegate
{
};
public event Action<TData, ulong>? OnClientReceivedFromClient = delegate
{
};
public static LNetworkMessage<TData> Connect(string identifier, Action<TData, ulong>? onServerReceived = null, Action<TData>? onClientReceived = null, Action<TData, ulong>? onClientReceivedFromClient = null)
{
string text;
try
{
text = LNetworkUtils.GetModGuid(2) + "." + identifier;
}
catch (Exception arg)
{
LethalNetworkAPIPlugin.Logger.LogError((object)("Unable to find Mod Guid! To still work, this Message will only use the given identifier. " + $"Warning: This may cause collision with another mod's NetworkMessage! Stack Trace: {arg}"));
text = identifier;
}
if (!UnnamedMessageHandler.LNetworkMessages.TryGetValue(text, out INetMessage value))
{
return new LNetworkMessage<TData>(text, onServerReceived, onClientReceived, onClientReceivedFromClient);
}
LNetworkMessage<TData> lNetworkMessage = (LNetworkMessage<TData>)value;
lNetworkMessage.OnServerReceived += onServerReceived;
lNetworkMessage.OnClientReceived += onClientReceived;
lNetworkMessage.OnClientReceivedFromClient += onClientReceivedFromClient;
return lNetworkMessage;
}
public static LNetworkMessage<TData> Create(string identifier, Action<TData, ulong>? onServerReceived = null, Action<TData>? onClientReceived = null, Action<TData, ulong>? onClientReceivedFromClient = null)
{
string identifier2;
try
{
identifier2 = LNetworkUtils.GetModGuid(2) + "." + identifier;
}
catch (Exception arg)
{
LethalNetworkAPIPlugin.Logger.LogError((object)("Unable to find Mod Guid! To still work, this Message will only use the given identifier. " + $"Warning: This may cause collision with another mod's NetworkMessage! Stack Trace: {arg}"));
identifier2 = identifier;
}
return new LNetworkMessage<TData>(identifier2, onServerReceived, onClientReceived, onClientReceivedFromClient);
}
private LNetworkMessage(string identifier, Action<TData, ulong>? onServerReceived = null, Action<TData>? onClientReceived = null, Action<TData, ulong>? onClientReceivedFromClient = null)
{
if (UnnamedMessageHandler.LNetworkMessages.TryGetValue(identifier, out INetMessage _))
{
throw new InvalidOperationException("A message with the identifier " + identifier + " already exists! Please use a different identifier.");
}
Identifier = identifier;
OnServerReceived += onServerReceived;
OnClientReceived += onClientReceived;
OnClientReceivedFromClient += onClientReceivedFromClient;
UnnamedMessageHandler.LNetworkMessages.Add(identifier, this);
}
void INetMessage.InvokeOnServerReceived(object? data, ulong clientId)
{
this.OnServerReceived?.Invoke((TData)data, clientId);
}
void INetMessage.InvokeOnClientReceived(object? data)
{
this.OnClientReceived?.Invoke((TData)data);
}
void INetMessage.InvokeOnClientReceivedFromClient(object? data, ulong clientId)
{
this.OnClientReceivedFromClient?.Invoke((TData)data, clientId);
}
public void ClearSubscriptions()
{
this.OnServerReceived = delegate
{
};
this.OnClientReceived = delegate
{
};
this.OnClientReceivedFromClient = delegate
{
};
}
public void SendClient(TData data, ulong clientGuid)
{
SendClients(data, new ulong[1] { clientGuid });
}
public void SendClient(TData data, int playerId)
{
SendClients(data, new ulong[1] { LNetworkUtils.GetClientGuid(playerId) });
}
public void SendClients(TData data, ulong[] clientGuidArray)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (!LNetworkUtils.IsConnected)
{
throw new NetworkConfigurationException("Attempting to use LNetworkMessage method while not connected to a server.");
}
if (!LNetworkUtils.IsHostOrServer)
{
throw new InvalidOperationException("Attempting to use LNetworkMessage Server-Only method while not the host.");
}
if (clientGuidArray.Any())
{
if (UnnamedMessageHandler.Instance == null)
{
throw new NetworkConfigurationException("The UnnamedMessageHandler is null. Shit's fucked! Please send this log to the LethalNetworkAPI developer.");
}
UnnamedMessageHandler.Instance.SendMessageToClients(new MessageData(Identifier, EMessageType.Message | EMessageType.ServerMessage, data), clientGuidArray);
}
}
public void SendClients(TData data, int[] playerIdArray)
{
SendClients(data, playerIdArray.Select(LNetworkUtils.GetClientGuid).ToArray());
}
public void SendClients(TData data)
{
SendClients(data, LNetworkUtils.AllConnectedClients);
}
public void SendServer(TData data)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if (!LNetworkUtils.IsConnected)
{
throw new NetworkConfigurationException("Attempting to use LNetworkMessage method while not connected to a server.");
}
if (UnnamedMessageHandler.Instance == null)
{
throw new NetworkConfigurationException("The UnnamedMessageHandler is null. Shit's fucked! Please send this log to the LethalNetworkAPI developer.");
}
UnnamedMessageHandler.Instance.SendMessageToServer(new MessageData(Identifier, EMessageType.Message | EMessageType.ClientMessage, data));
}
public void SendOtherClients(TData data, ulong[] clientGuidArray)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
if (!LNetworkUtils.IsConnected)
{
throw new NetworkConfigurationException("Attempting to use LNetworkMessage method while not connected to a server.");
}
if (clientGuidArray.Any())
{
if (UnnamedMessageHandler.Instance == null)
{
throw new NetworkConfigurationException("The UnnamedMessageHandler is null. Shit's fucked! Please send this log to the LethalNetworkAPI developer.");
}
if (UnnamedMessageHandler.Instance.IsServer)
{
UnnamedMessageHandler.Instance.SendMessageToClients(new MessageData(Identifier, EMessageType.Message | EMessageType.ClientMessageToClient, data), clientGuidArray);
}
else
{
UnnamedMessageHandler.Instance.SendMessageToServer(new MessageData(Identifier, EMessageType.Message | EMessageType.ClientMessageToClient, data, clientGuidArray));
}
}
}
public void SendOtherClients(TData data, int[] playerIdArray)
{
SendOtherClients(data, playerIdArray.Select(LNetworkUtils.GetClientGuid).ToArray());
}
public void SendOtherClients(TData data)
{
SendOtherClients(data, LNetworkUtils.OtherConnectedClients);
}
}
public class LNetworkVariable<TData> : LNetworkVariableBase
{
private TData _offlineValue;
private TData _value;
private TData _previousValue;
internal bool Dirty { get; set; }
public TData OfflineValue
{
get
{
return _offlineValue;
}
set
{
_offlineValue = value;
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
ResetValue();
}
}
}
public TData Value
{
get
{
return _value;
}
set
{
if (!object.Equals(_value, value))
{
SetDirty(value: true);
_previousValue = _value;
_value = value;
this.OnValueChanged?.Invoke(_previousValue, _value);
}
}
}
public event Action<TData, TData>? OnValueChanged = delegate
{
};
private LNetworkVariable(string identifier, TData offlineValue, LNetworkVariableWritePerms writePerms, Action<TData, TData>? onValueChanged)
{
if (UnnamedMessageHandler.LNetworkVariables.TryGetValue(identifier, out LNetworkVariableBase _))
{
throw new InvalidOperationException("A variable with the identifier " + identifier + " already exists! Please use a different identifier.");
}
base.Identifier = identifier;
base.WritePerms = writePerms;
_offlineValue = offlineValue;
_value = offlineValue;
_previousValue = offlineValue;
OnValueChanged += onValueChanged;
UnnamedMessageHandler.VariableCheck += CheckForDirt;
UnnamedMessageHandler.LNetworkVariables.Add(base.Identifier, this);
UnnamedMessageHandler? instance = UnnamedMessageHandler.Instance;
if (instance != null && instance.UnInitializedValues.TryGetValue(base.Identifier, out object value2))
{
_value = (TData)value2;
UnnamedMessageHandler.Instance.UnInitializedValues.Remove(base.Identifier);
this.OnValueChanged?.Invoke(_previousValue, _value);
_previousValue = _value;
}
}
public static LNetworkVariable<TData> Connect(string identifier, TData offlineValue = default(TData), LNetworkVariableWritePerms writePerms = LNetworkVariableWritePerms.Server, Action<TData, TData>? onValueChanged = null)
{
string text;
try
{
text = LNetworkUtils.GetModGuid(2) + "." + identifier;
}
catch (Exception arg)
{
LethalNetworkAPIPlugin.Logger.LogError((object)("Unable to find Mod Guid! To still work, this Message will only use the given identifier. " + $"Warning: This may cause collision with another mod's NetworkMessage! Stack Trace: {arg}"));
text = identifier;
}
if (!UnnamedMessageHandler.LNetworkVariables.TryGetValue(text, out LNetworkVariableBase value))
{
return new LNetworkVariable<TData>(text, offlineValue, writePerms, onValueChanged);
}
LNetworkVariable<TData> lNetworkVariable = (LNetworkVariable<TData>)value;
lNetworkVariable.OfflineValue = offlineValue;
lNetworkVariable.OnValueChanged += onValueChanged;
return lNetworkVariable;
}
public static LNetworkVariable<TData> Create(string identifier, TData defaultValue = default(TData), LNetworkVariableWritePerms writePerms = LNetworkVariableWritePerms.Server, Action<TData, TData>? onValueChanged = null)
{
string identifier2;
try
{
identifier2 = LNetworkUtils.GetModGuid(2) + "." + identifier;
}
catch (Exception arg)
{
LethalNetworkAPIPlugin.Logger.LogError((object)("Unable to find Mod Guid! To still work, this Message will only use the given identifier. " + $"Warning: This may cause collision with another mod's NetworkMessage! Stack Trace: {arg}"));
identifier2 = identifier;
}
return new LNetworkVariable<TData>(identifier2, defaultValue, writePerms, onValueChanged);
}
private void CheckForDirt()
{
IsDirty();
}
private void SetDirty(bool value)
{
if (value)
{
UnnamedMessageHandler.Instance?.DirtyBois.Add(this);
}
Dirty = value;
}
internal override bool IsDirty()
{
if (Dirty)
{
return true;
}
if (object.Equals(_previousValue, Value))
{
return false;
}
if (!CanWrite())
{
return false;
}
if (typeof(TData).IsByRef)
{
_previousValue = (TData)AccessTools.MakeDeepCopy((object)_value, typeof(TData), (Func<string, Traverse, Traverse, object>)null, "");
}
else
{
_previousValue = _value;
}
SetDirty(value: true);
return true;
}
internal override void ResetValue()
{
_value = (_previousValue = _offlineValue);
Dirty = false;
}
internal override void ResetDirty()
{
if (Dirty)
{
_previousValue = _value;
Dirty = false;
}
}
internal override object? GetValue()
{
return _value;
}
internal override void ReceiveUpdate(object? data)
{
TData val = (TData)data;
if (!object.Equals(_value, val))
{
this.OnValueChanged?.Invoke(_value, val);
}
_value = val;
if (typeof(TData).IsByRef)
{
_previousValue = (TData)AccessTools.MakeDeepCopy((object)val, typeof(TData), (Func<string, Traverse, Traverse, object>)null, "");
}
else
{
_previousValue = val;
}
Dirty = false;
}
public void MakeDirty()
{
SetDirty(value: true);
}
public void UpdateOwner(params ulong[] clientGuidArray)
{
if (base.WritePerms != LNetworkVariableWritePerms.Owner)
{
throw new InvalidOperationException($"The variable `{base.Identifier}` does not allow changing ownership (writePerms: {base.WritePerms}).");
}
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
throw new InvalidOperationException("Cannot modify ownership of the variable `" + base.Identifier + "` while not connected to a server!");
}
if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
{
LethalNetworkAPIPlugin.Logger.LogWarning((object)("Cannot modify ownership of the variable `" + base.Identifier + "` if not the host!"));
}
else
{
base.OwnerClients = clientGuidArray;
}
}
public void UpdateOwner(params int[] playerIdArray)
{
if (base.WritePerms != LNetworkVariableWritePerms.Owner)
{
throw new InvalidOperationException($"The variable `{base.Identifier}` does not allow changing ownership (writePerms: {base.WritePerms}).");
}
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
throw new InvalidOperationException("Cannot modify ownership of the variable `" + base.Identifier + "` while not connected to a server!");
}
if (!NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsHost)
{
LethalNetworkAPIPlugin.Logger.LogWarning((object)("Cannot modify ownership of the variable `" + base.Identifier + "` if not the host!"));
}
else
{
base.OwnerClients = playerIdArray.Select(LNetworkUtils.GetClientGuid).ToArray();
}
}
public void Dispose()
{
UnnamedMessageHandler.LNetworkVariables.Remove(base.Identifier);
UnnamedMessageHandler.Instance?.DirtyBois.Remove(this);
this.OnValueChanged = null;
}
}
public enum LNetworkVariableWritePerms
{
Server,
Owner,
Everyone
}
internal static class TextDefinitions
{
internal const string NotInLobbyMessage = "Unable to send the {0} with identifier \"{1}\" and data {{{2}}}. Is the player in a lobby?";
internal const string UnableToFindGuid = "Unable to find plugin info for calling mod for {0} with identifier \"{1}\". Are you using BepInEx? \n Stacktrace: {2}";
internal const string NotServerInfo = "The client {0} cannot use server methods. {1} Identifier: \"{2}\"";
internal const string NotInLobbyEvent = "Unable to invoke the {0} with identifier \"{1}\". Is the player in a lobby?";
internal const string NetworkHandlerDoesNotExist = "The NetworkHandler does not exist. This shouldn't occur!";
internal const string TargetClientNotConnected = "The specified client {0} is not connected. {1} Identifier: \"{2}\"";
internal const string TargetClientsNotConnected = "None of the specified clients {0} are connected. {1} Identifier: \"{2}\"";
internal const string UnableToLocateNetworkObjectComponent = "Unable to find the network object component. Are you adding variable \"{0}\" to a network object?";
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "LethalNetworkAPI";
public const string PLUGIN_NAME = "LethalNetworkAPI";
public const string PLUGIN_VERSION = "3.3.1";
}
}
namespace LethalNetworkAPI.Utils
{
public static class LNetworkUtils
{
private static ulong[] _allClients;
public static bool IsConnected
{
get
{
NetworkManager singleton = NetworkManager.Singleton;
if (singleton == null)
{
return false;
}
return singleton.IsConnectedClient;
}
}
public static bool IsHostOrServer
{
get
{
if (!NetworkManager.Singleton.IsHost)
{
return NetworkManager.Singleton.IsServer;
}
return true;
}
}
public static ulong[] AllConnectedClients
{
get
{
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
return Array.Empty<ulong>();
}
if (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost)
{
return NetworkManager.Singleton.ConnectedClientsIds.ToArray();
}
return _allClients;
}
internal set
{
_allClients = value;
}
}
public static ulong[] OtherConnectedClients => AllConnectedClientsExcept(NetworkManager.Singleton.LocalClientId);
public static event Action<bool> OnNetworkStart;
public static ulong[] AllConnectedClientsExcept(ulong clientId)
{
return AllConnectedClients.Where((ulong i) => i != clientId).ToArray();
}
public static ulong[] AllConnectedClientsExcept(params ulong[] clientIds)
{
ulong[] clientIds2 = clientIds;
return AllConnectedClients.Where((ulong i) => !clientIds2.Contains(i)).ToArray();
}
public static ulong GetClientGuid(int playerId)
{
return StartOfRound.Instance.allPlayerScripts[playerId].actualClientId;
}
public static int GetPlayerId(ulong clientGuid)
{
return (int)StartOfRound.Instance.allPlayerScripts.First((PlayerControllerB player) => player.actualClientId == clientGuid).playerClientId;
}
internal static string GetModGuid(int frameIndex)
{
MethodBase method = new StackTrace().GetFrame(frameIndex).GetMethod();
Assembly assembly = method.ReflectedType.Assembly;
Type type2 = AccessTools.GetTypesFromAssembly(assembly).First((Type type) => type.GetCustomAttributes(typeof(BepInPlugin), inherit: false).Any());
return MetadataHelper.GetMetadata(type2).GUID;
}
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void InvokeOnNetworkStart(ulong clientID)
{
NetworkManager singleton = NetworkManager.Singleton;
if (clientID != ((singleton != null) ? new ulong?(singleton.LocalClientId) : null))
{
return;
}
Delegate[] invocationList = LNetworkUtils.OnNetworkStart.GetInvocationList();
foreach (Delegate @delegate in invocationList)
{
try
{
@delegate.DynamicInvoke(IsHostOrServer);
}
catch (Exception ex)
{
LethalNetworkAPIPlugin.Logger.LogError((object)ex);
}
}
}
static LNetworkUtils()
{
LNetworkUtils.OnNetworkStart = delegate
{
};
_allClients = Array.Empty<ulong>();
}
}
}
namespace LethalNetworkAPI.Patches
{
[HarmonyPatch(typeof(NetworkManager))]
[HarmonyPriority(500)]
[HarmonyWrapSafe]
internal static class NetworkManagerPatch
{
[HarmonyPatch("Initialize")]
[HarmonyPostfix]
public static void InitializePatch(NetworkManager __instance)
{
new UnnamedMessageHandler();
new NetworkHandler();
__instance.OnClientConnectedCallback += LNetworkUtils.InvokeOnNetworkStart;
}
[HarmonyPatch("ShutdownInternal")]
[HarmonyPrefix]
public static void ShutdownPatch(NetworkManager __instance)
{
__instance.OnClientConnectedCallback -= LNetworkUtils.InvokeOnNetworkStart;
UnnamedMessageHandler.Instance?.Dispose();
NetworkHandler.Instance?.Dispose();
}
}
}
namespace LethalNetworkAPI.Serializable
{
internal static class LethalNetworkSerializer
{
internal static byte[] Serialize<T>(T value)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
if (value == null)
{
return Array.Empty<byte>();
}
object obj = value;
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if (val != null)
{
return SerializationUtility.SerializeValue<NetworkObjectReference>(NetworkObjectReference.op_Implicit(val), (DataFormat)0, (SerializationContext)null);
}
object obj2 = value;
NetworkObject val2 = (NetworkObject)((obj2 is NetworkObject) ? obj2 : null);
if (val2 != null)
{
return SerializationUtility.SerializeValue<NetworkObjectReference>(NetworkObjectReference.op_Implicit(val2), (DataFormat)0, (SerializationContext)null);
}
object obj3 = value;
NetworkBehaviour val3 = (NetworkBehaviour)((obj3 is NetworkBehaviour) ? obj3 : null);
if (val3 != null)
{
return SerializationUtility.SerializeValue<NetworkBehaviourReference>(NetworkBehaviourReference.op_Implicit(val3), (DataFormat)0, (SerializationContext)null);
}
return SerializationUtility.SerializeValue<T>(value, (DataFormat)0, (SerializationContext)null);
}
internal static T Deserialize<T>(byte[] data)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
if (data.Length == 0)
{
return default(T);
}
T val = default(T);
if (!(val is GameObject))
{
if (!(val is NetworkObject))
{
if (val is NetworkBehaviour)
{
return (T)(object)NetworkBehaviourReference.op_Implicit(SerializationUtility.DeserializeValue<NetworkBehaviourReference>(data, (DataFormat)0, (DeserializationContext)null));
}
return SerializationUtility.DeserializeValue<T>(data, (DataFormat)0, (DeserializationContext)null);
}
return (T)(object)NetworkObjectReference.op_Implicit(SerializationUtility.DeserializeValue<NetworkObjectReference>(data, (DataFormat)0, (DeserializationContext)null));
}
return (T)(object)NetworkObjectReference.op_Implicit(SerializationUtility.DeserializeValue<NetworkObjectReference>(data, (DataFormat)0, (DeserializationContext)null));
}
}
public class NetworkBehaviourReferenceFormatter : MinimalBaseFormatter<NetworkBehaviourReference>
{
private static readonly Serializer<ushort> UInt16Serializer = Serializer.Get<ushort>();
private static readonly Serializer<NetworkObjectReference> NetworkObjectReferenceSerializer = Serializer.Get<NetworkObjectReference>();
protected override void Read(ref NetworkBehaviourReference value, IDataReader reader)
{
//IL_0007: 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)
value.m_NetworkObjectReference = NetworkObjectReferenceSerializer.ReadValue(reader);
value.m_NetworkBehaviourId = UInt16Serializer.ReadValue(reader);
}
protected override void Write(ref NetworkBehaviourReference value, IDataWriter writer)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
NetworkObjectReferenceSerializer.WriteValue(value.m_NetworkObjectReference, writer);
UInt16Serializer.WriteValue(value.m_NetworkBehaviourId, writer);
}
}
internal class NetworkObjectReferenceFormatter : MinimalBaseFormatter<NetworkObjectReference>
{
private static readonly Serializer<ulong> UInt64Serializer = Serializer.Get<ulong>();
protected override void Read(ref NetworkObjectReference value, IDataReader reader)
{
((NetworkObjectReference)(ref value)).NetworkObjectId = UInt64Serializer.ReadValue(reader);
}
protected override void Write(ref NetworkObjectReference value, IDataWriter writer)
{
UInt64Serializer.WriteValue(((NetworkObjectReference)(ref value)).NetworkObjectId, writer);
}
}
}
namespace LethalNetworkAPI.Old
{
[Obsolete]
public abstract class LethalNetworkDeprecated
{
internal readonly string Identifier;
private readonly string _networkType;
protected LethalNetworkDeprecated(string identifier, string networkType, int frameIndex = 3)
{
try
{
MethodBase method = new StackTrace().GetFrame(frameIndex).GetMethod();
Assembly assembly = method.ReflectedType.Assembly;
Type type2 = AccessTools.GetTypesFromAssembly(assembly).First((Type type) => type.GetCustomAttributes(typeof(BepInPlugin), inherit: false).Any());
Identifier = MetadataHelper.GetMetadata(type2).GUID + "." + identifier;
_networkType = networkType;
}
catch (Exception ex)
{
LethalNetworkAPIPlugin.Logger.LogError((object)ex);
}
}
protected bool IsNetworkHandlerNull(bool log = true)
{
if (NetworkHandler.Instance != null)
{
return false;
}
if (log)
{
LethalNetworkAPIPlugin.Logger.LogError((object)$"Unable to invoke the {_networkType.ToLower()} with identifier \"{Identifier}\". Is the player in a lobby?");
}
return true;
}
protected bool IsHostOrServer(bool log = true)
{
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
return false;
}
if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
{
return true;
}
if (log)
{
LethalNetworkAPIPlugin.Logger.LogError((object)$"The client {NetworkManager.Singleton.LocalClientId} cannot use server methods. {_networkType} Identifier: \"{Identifier}\"");
}
return false;
}
private bool DoClientsExist(IEnumerable<ulong> clientIds, bool log = true)
{
if (clientIds.Any())
{
return true;
}
if (log)
{
LethalNetworkAPIPlugin.Logger.LogError((object)$"None of the specified clients {clientIds} are connected. {_networkType} Identifier: \"{Identifier}\"");
}
return false;
}
private ClientRpcParams GenerateClientParams(IEnumerable<ulong> clientIds, bool allExcept)
{
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
ulong[] enumerable = (clientIds as ulong[]) ?? clientIds.ToArray();
NativeArray<ulong> val = default(NativeArray<ulong>);
if (!enumerable.Any() && allExcept)
{
val..ctor(NetworkManager.Singleton.ConnectedClientsIds.Where((ulong i) => i != 0).ToArray(), (Allocator)4);
}
else if (allExcept)
{
val..ctor(NetworkManager.Singleton.ConnectedClientsIds.Where((ulong i) => enumerable.All((ulong j) => i != j)).ToArray(), (Allocator)4);
}
else
{
val..ctor(enumerable.Where((ulong i) => NetworkManager.Singleton.ConnectedClientsIds.Contains(i)).ToArray(), (Allocator)4);
}
if (!DoClientsExist((IEnumerable<ulong>)(object)val))
{
return default(ClientRpcParams);
}
ClientRpcParams result = default(ClientRpcParams);
result.Send = new ClientRpcSendParams
{
TargetClientIdsNativeArray = val
};
return result;
}
protected ClientRpcParams GenerateClientParams(IEnumerable<ulong> clientIds)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
return GenerateClientParams(clientIds, allExcept: false);
}
protected ClientRpcParams GenerateClientParams(ulong clientId)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return GenerateClientParams(new <>z__ReadOnlySingleElementList<ulong>(clientId), allExcept: false);
}
protected ClientRpcParams GenerateClientParamsExcept(IEnumerable<ulong> clientIds)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
return GenerateClientParams(clientIds, allExcept: true);
}
protected ClientRpcParams GenerateClientParamsExcept(ulong clientId)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return GenerateClientParams(new <>z__ReadOnlySingleElementList<ulong>(clientId), allExcept: true);
}
protected ClientRpcParams GenerateClientParamsExceptHost()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
return GenerateClientParams(Array.Empty<ulong>(), allExcept: true);
}
}
}
namespace LethalNetworkAPI.Old.Networking
{
internal class NetworkHandler : IDisposable
{
internal readonly List<ILethalNetVar> ObjectNetworkVariableList = new List<ILethalNetVar>();
internal bool IsServer => UnnamedMessageHandler.Instance?.IsServer ?? false;
internal static NetworkHandler? Instance { get; private set; }
internal static event Action? NetworkSpawn;
internal static event Action? NetworkDespawn;
internal static event Action? NetworkTick;
internal static event Action<ulong>? OnPlayerJoin;
internal static event Action<string, byte[], ulong>? OnServerMessage;
internal static event Action<string, byte[], ulong>? OnClientMessage;
internal static event Action<string, byte[]>? OnVariableUpdate;
internal static event Action<string, ulong>? GetVariableValue;
internal static event Action<string, ulong>? OnServerEvent;
internal static event Action<string, ulong>? OnClientEvent;
internal static event Action<string, double, ulong>? OnSyncedServerEvent;
internal static event Action<string, double, ulong>? OnSyncedClientEvent;
private void SendMessageToServer(MessageData messageData)
{
UnnamedMessageHandler.Instance.SendMessageToServer(messageData, deprecatedMessage: true);
}
private void SendMessageToClients(MessageData messageData, ulong[] clientGuidArray)
{
UnnamedMessageHandler.Instance.SendMessageToClients(messageData, clientGuidArray, deprecatedMessage: true);
}
public NetworkHandler()
{
Instance = this;
NetworkHandler.NetworkSpawn?.Invoke();
NetworkManager.Singleton.NetworkTickSystem.Tick += InvokeNetworkTick;
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnectedCallback;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void InvokeNetworkTick()
{
NetworkHandler.NetworkTick?.Invoke();
}
public void Dispose()
{
NetworkHandler.NetworkDespawn?.Invoke();
NetworkHandler.OnPlayerJoin = delegate
{
};
NetworkHandler.NetworkDespawn = delegate
{
};
Instance = null;
NetworkManager.Singleton.NetworkTickSystem.Tick -= InvokeNetworkTick;
NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnectedCallback;
}
private void OnClientConnectedCallback(ulong client)
{
NetworkHandler.OnPlayerJoin?.Invoke(client);
}
public void ReadMessage(ulong clientId, FastBufferReader reader)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
string messageID = default(string);
((FastBufferReader)(ref reader)).ReadValueSafe(ref messageID, false);
EMessageType messageType = default(EMessageType);
((FastBufferReader)(ref reader)).ReadValueSafe<EMessageType>(ref messageType, default(ForEnums));
byte[] messageData = default(byte[]);
((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref messageData, default(ForPrimitives));
HandleMessage(clientId, messageID, messageType, messageData);
}
public void HandleMessage(ulong clientId, string messageID, EMessageType messageType, byte[] messageData)
{
switch (messageType)
{
case EMessageType.Event | EMessageType.ServerMessage:
NetworkHandler.OnClientEvent?.Invoke(messageID, 99999uL);
break;
case EMessageType.Event | EMessageType.ClientMessage:
NetworkHandler.OnServerEvent?.Invoke(messageID, clientId);
break;
case EMessageType.Event | EMessageType.ClientMessageToClient:
if (IsServer)
{
UnnamedMessageHandler.Instance.SendMessageToClientsExcept(new MessageData(messageID, messageType, messageData), clientId, deprecatedMessage: true);
}
NetworkHandler.OnClientEvent?.Invoke(messageID, clientId);
break;
case EMessageType.SyncedEvent:
if (IsServer)
{
UnnamedMessageHandler.Instance.SendMessageToClientsExcept(new MessageData(messageID, messageType, messageData), clientId, deprecatedMessage: true);
}
NetworkHandler.OnSyncedServerEvent?.Invoke(messageID, UnnamedMessageHandler.Deserialize<double>(messageData), clientId);
break;
case EMessageType.Message | EMessageType.ServerMessage:
NetworkHandler.OnClientMessage?.Invoke(messageID, messageData, 99999uL);
break;
case EMessageType.Message | EMessageType.ClientMessage:
NetworkHandler.OnServerMessage?.Invoke(messageID, messageData, clientId);
break;
case EMessageType.Message | EMessageType.ClientMessageToClient:
if (IsServer)
{
UnnamedMessageHandler.Instance.SendMessageToClientsExcept(new MessageData(messageID, messageType, messageData), clientId, deprecatedMessage: true);
}
NetworkHandler.OnClientMessage?.Invoke(messageID, messageData, clientId);
break;
case EMessageType.Variable | EMessageType.Request:
NetworkHandler.GetVariableValue?.Invoke(messageID, clientId);
break;
case EMessageType.Variable:
if (IsServer)
{
UnnamedMessageHandler.Instance.SendMessageToClientsExcept(new MessageData(messageID, messageType, messageData), clientId, deprecatedMessage: true);
}
NetworkHandler.OnVariableUpdate?.Invoke(messageID, messageData);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
internal void MessageServerRpc(string identifier, byte[] data, bool toOtherClients = false)
{
if (!toOtherClients)
{
SendMessageToServer(new MessageData(identifier, EMessageType.Message | EMessageType.ClientMessage, data));
}
else if (IsServer)
{
SendMessageToClients(new MessageData(identifier, EMessageType.Message | EMessageType.ClientMessageToClient, data), LNetworkUtils.OtherConnectedClients);
}
else
{
SendMessageToServer(new MessageData(identifier, EMessageType.Message | EMessageType.ClientMessageToClient, data));
}
}
internal void MessageClientRpc(string identifier, byte[] data, ulong[] clientGuidArray)
{
SendMessageToClients(new MessageData(identifier, EMessageType.Message | EMessageType.ServerMessage, data), clientGuidArray);
}
internal void EventServerRpc(string identifier, bool toOtherClients = false)
{
if (!toOtherClients)
{
SendMessageToServer(new MessageData(identifier, EMessageType.Event | EMessageType.ClientMessage));
}
else if (IsServer)
{
SendMessageToClients(new MessageData(identifier, EMessageType.Event | EMessageType.ClientMessageToClient), LNetworkUtils.OtherConnectedClients);
}
else
{
SendMessageToServer(new MessageData(identifier, EMessageType.Event | EMessageType.ClientMessageToClient));
}
}
internal void EventClientRpc(string identifier, ulong[] clientGuidArray)
{
SendMessageToClients(new MessageData(identifier, EMessageType.Event | EMessageType.ServerMessage), clientGuidArray);
}
internal void SyncedEventServerRpc(string identifier, double time)
{
if (IsServer)
{
SendMessageToClients(new MessageData(identifier, EMessageType.SyncedEvent, UnnamedMessageHandler.Serialize(time)), LNetworkUtils.OtherConnectedClients);
}
else
{
SendMessageToServer(new MessageData(identifier, EMessageType.SyncedEvent, UnnamedMessageHandler.Serialize(time)));
}
}
[ServerRpc(RequireOwnership = false)]
internal void UpdateVariableServerRpc(string identifier, byte[] data)
{
if (IsServer)
{
SendMessageToClients(new MessageData(identifier, EMessageType.Variable, data), LNetworkUtils.OtherConnectedClients);
}
else
{
SendMessageToServer(new MessageData(identifier, EMessageType.Variable, data));
}
}
[ClientRpc]
internal void UpdateVariableClientRpc(string identifier, byte[] data, ulong[] clientGuidArray)
{
SendMessageToClients(new MessageData(identifier, EMessageType.Variable, data), clientGuidArray);
}
[ServerRpc(RequireOwnership = false)]
internal void GetVariableValueServerRpc(string identifier, ServerRpcParams serverRpcParams = default(ServerRpcParams))
{
SendMessageToServer(new MessageData(identifier, EMessageType.Variable | EMessageType.Request));
}
}
}
namespace LethalNetworkAPI.Internal
{
[Flags]
internal enum EMessageType
{
None = 0,
Event = 1,
Message = 2,
Variable = 4,
SyncedEvent = 8,
ServerMessage = 0x10,
ClientMessage = 0x20,
ClientMessageToClient = 0x40,
Request = 0x80,
DataUpdate = 0x10,
OwnershipUpdate = 0x20,
UpdateClientList = 0x80
}
public abstract class LNetworkVariableBase
{
internal string Identifier { get; init; }
internal LNetworkVariableWritePerms WritePerms { get; init; }
internal ulong[]? OwnerClients { get; set; }
internal abstract void ReceiveUpdate(object? data);
internal abstract void ResetValue();
internal abstract bool IsDirty();
internal abstract void ResetDirty();
internal abstract object? GetValue();
internal bool CanWrite()
{
return WritePerms switch
{
LNetworkVariableWritePerms.Owner => OwnerClients != null && OwnerClients.Contains(NetworkManager.Singleton.LocalClientId),
LNetworkVariableWritePerms.Server => NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost,
LNetworkVariableWritePerms.Everyone => true,
_ => false,
};
}
}
internal record MessageData([property: OdinSerialize] string Identifier, [property: OdinSerialize] EMessageType MessageType, [property: OdinSerialize] object? Data = null, [property: OdinSerialize] ulong[]? TargetClients = null);
internal class UnnamedMessageHandler : IDisposable
{
private const string LibIdentifier = "LethalNetworkAPI";
private int _ticksSinceLastCheck;
internal static UnnamedMessageHandler? Instance { get; private set; }
internal static Dictionary<string, INetMessage> LNetworkMessages { get; } = new Dictionary<string, INetMessage>();
internal static Dictionary<string, LNetworkEvent> LNetworkEvents { get; } = new Dictionary<string, LNetworkEvent>();
internal static Dictionary<string, LNetworkVariableBase> LNetworkVariables { get; } = new Dictionary<string, LNetworkVariableBase>();
internal bool IsServer
{
get
{
if (!NetworkManager.IsServer)
{
return NetworkManager.IsHost;
}
return true;
}
}
private NetworkManager NetworkManager { get; }
private CustomMessagingManager CustomMessagingManager { get; }
internal HashSet<LNetworkVariableBase> DirtyBois { get; } = new HashSet<LNetworkVariableBase>();
internal Dictionary<string, object?> UnInitializedValues { get; } = new Dictionary<string, object>();
internal static event Action? VariableCheck;
internal UnnamedMessageHandler()
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
Instance = this;
NetworkManager = NetworkManager.Singleton;
CustomMessagingManager = NetworkManager.CustomMessagingManager;
NetworkManager.NetworkTickSystem.Tick += CheckVariablesForChanges;
CustomMessagingManager.OnUnnamedMessage += new UnnamedMessageDelegate(ReceiveMessage);
if (IsServer)
{
NetworkManager.OnClientConnectedCallback += UpdateNewClientVariables;
NetworkManager.OnClientDisconnectCallback += UpdateClientList;
}
}
private void CheckVariablesForChanges()
{
if (_ticksSinceLastCheck++ > 9)
{
UnnamedMessageHandler.VariableCheck?.Invoke();
_ticksSinceLastCheck = 0;
}
UpdateVariables();
}
private void UpdateVariables()
{
if (DirtyBois.Count == 0)
{
return;
}
foreach (LNetworkVariableBase dirtyBoi in DirtyBois)
{
if (IsServer)
{
SendMessageToClients(new MessageData(dirtyBoi.Identifier, EMessageType.Variable | EMessageType.ServerMessage, dirtyBoi.GetValue()), LNetworkUtils.OtherConnectedClients);
}
else
{
SendMessageToServer(new MessageData(dirtyBoi.Identifier, EMessageType.Variable | EMessageType.ServerMessage, dirtyBoi.GetValue()));
}
dirtyBoi.ResetDirty();
}
DirtyBois.Clear();
}
private void UpdateNewClientVariables(ulong newClient)
{
if (!IsServer)
{
return;
}
UpdateClientList(newClient);
foreach (LNetworkVariableBase value in LNetworkVariables.Values)
{
SendMessageToClients(new MessageData(value.Identifier, EMessageType.Variable | EMessageType.ServerMessage, value.OwnerClients), new ulong[1] { newClient });
}
}
private void UpdateClientList(ulong changedClient)
{
if (IsServer)
{
SendMessageToClients(new MessageData("Internal.UpdateClientList", EMessageType.Request, LNetworkUtils.OtherConnectedClients), LNetworkUtils.AllConnectedClients);
}
}
internal void SendMessageToClients(MessageData messageData, ulong[] clientGuidArray, bool deprecatedMessage = false)
{
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
if (clientGuidArray.Any((ulong client) => client == NetworkManager.LocalClientId))
{
clientGuidArray = clientGuidArray.Where((ulong client) => client != NetworkManager.LocalClientId).ToArray();
if (deprecatedMessage)
{
NetworkHandler.Instance.HandleMessage(NetworkManager.LocalClientId, messageData.Identifier, messageData.MessageType, ((byte[])messageData.Data) ?? Array.Empty<byte>());
}
else
{
HandleMessage(NetworkManager.LocalClientId, messageData.Identifier, messageData.MessageType, messageData.Data, new ulong[1] { NetworkManager.LocalClientId });
}
}
if (clientGuidArray.Any())
{
WriteMessageData(out var writer, messageData, deprecatedMessage);
CustomMessagingManager.SendUnnamedMessage((IReadOnlyList<ulong>)clientGuidArray, writer, (NetworkDelivery)4);
((FastBufferWriter)(ref writer)).Dispose();
}
}
internal void SendMessageToClientsExcept(MessageData messageData, ulong clientId, bool deprecatedMessage = false)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
WriteMessageData(out var writer, messageData, deprecatedMessage);
ulong[] array = LNetworkUtils.AllConnectedClientsExcept(clientId, 0uL);
if (array.Length != 0)
{
CustomMessagingManager.SendUnnamedMessage((IReadOnlyList<ulong>)LNetworkUtils.AllConnectedClientsExcept(clientId, 0uL), writer, (NetworkDelivery)4);
((FastBufferWriter)(ref writer)).Dispose();
}
}
internal void SendMessageToServer(MessageData messageData, bool deprecatedMessage = false)
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
if (IsServer)
{
if (deprecatedMessage)
{
NetworkHandler.Instance.HandleMessage(0uL, messageData.Identifier, messageData.MessageType, ((byte[])messageData.Data) ?? Array.Empty<byte>());
}
else
{
HandleMessage(0uL, messageData.Identifier, messageData.MessageType, messageData.Data, new ulong[1]);
}
}
else
{
WriteMessageData(out var writer, messageData, deprecatedMessage);
CustomMessagingManager.SendUnnamedMessage(0uL, writer, (NetworkDelivery)4);
((FastBufferWriter)(ref writer)).Dispose();
}
}
private void ReceiveMessage(ulong clientId, FastBufferReader reader)
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: 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_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: 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)
string text = default(string);
try
{
((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false);
}
catch
{
return;
}
if (text == "LethalNetworkAPI.Old")
{
NetworkHandler.Instance?.ReadMessage(clientId, reader);
}
if (!(text != "LethalNetworkAPI"))
{
string messageID = default(string);
((FastBufferReader)(ref reader)).ReadValueSafe(ref messageID, false);
EMessageType messageType = default(EMessageType);
((FastBufferReader)(ref reader)).ReadValueSafe<EMessageType>(ref messageType, default(ForEnums));
ulong[] targetClients = default(ulong[]);
((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref targetClients, default(ForPrimitives));
byte[] serializedData = default(byte[]);
((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref serializedData, default(ForPrimitives));
byte[] serializedData2 = default(byte[]);
((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref serializedData2, default(ForPrimitives));
Type type = Deserialize<Type>(serializedData2);
object messageData = ((type != null) ? Deserialize<object>(serializedData) : null);
HandleMessage(clientId, messageID, messageType, messageData, targetClients);
}
}
private void HandleMessage(ulong clientId, string messageID, EMessageType messageType, object? messageData, ulong[] targetClients)
{
ulong[] clientGuidArray = targetClients.Where((ulong i) => i != 0L && i != clientId).ToArray();
switch (messageType)
{
case EMessageType.Event | EMessageType.ServerMessage:
LNetworkEvents[messageID].InvokeOnClientReceived();
break;
case EMessageType.Event | EMessageType.ClientMessage:
LNetworkEvents[messageID].InvokeOnServerReceived(clientId);
break;
case EMessageType.Event | EMessageType.ClientMessageToClient:
if (!IsServer)
{
LNetworkMessages[messageID].InvokeOnClientReceivedFromClient(messageData, clientId);
break;
}
SendMessageToClients(new MessageData(messageID, messageType, messageData), clientGuidArray);
if (targetClients.Any((ulong i) => i == 0))
{
LNetworkEvents[messageID].InvokeOnClientReceivedFromClient(clientId);
}
break;
case EMessageType.Message | EMessageType.ServerMessage:
LNetworkMessages[messageID].InvokeOnClientReceived(messageData);
break;
case EMessageType.Message | EMessageType.ClientMessage:
LNetworkMessages[messageID].InvokeOnServerReceived(messageData, clientId);
break;
case EMessageType.Message | EMessageType.ClientMessageToClient:
if (!IsServer)
{
LNetworkMessages[messageID].InvokeOnClientReceivedFromClient(messageData, clientId);
break;
}
SendMessageToClients(new MessageData(messageID, messageType, messageData), clientGuidArray);
if (targetClients.Any((ulong i) => i == 0))
{
LNetworkMessages[messageID].InvokeOnClientReceivedFromClient(messageData, clientId);
}
break;
case EMessageType.Variable | EMessageType.ServerMessage:
{
if (!LNetworkVariables.TryGetValue(messageID, out LNetworkVariableBase lNetworkVariableBase))
{
UnInitializedValues[messageID] = messageData;
break;
}
if (IsServer)
{
if (!lNetworkVariableBase.CanWrite())
{
break;
}
SendMessageToClients(new MessageData(messageID, messageType, messageData), clientGuidArray);
}
lNetworkVariableBase.ReceiveUpdate(messageData);
break;
}
case EMessageType.Variable | EMessageType.ClientMessage:
{
LNetworkVariableBase lNetworkVariableBase = LNetworkVariables[messageID];
if (clientId == 0L && lNetworkVariableBase.WritePerms == LNetworkVariableWritePerms.Owner)
{
lNetworkVariableBase.OwnerClients = (ulong[])messageData;
}
break;
}
case EMessageType.Request:
if (clientId == 0L && NetworkManager.LocalClientId != 0L)
{
LNetworkUtils.AllConnectedClients = CollectionExtensions.AddToArray<ulong>(((ulong[])messageData) ?? new ulong[1] { NetworkManager.LocalClientId }, 0uL);
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
internal static byte[] Serialize(object? data)
{
return SerializationUtility.SerializeValue<object>(data, (DataFormat)0, (SerializationContext)null);
}
internal static T Deserialize<T>(byte[] serializedData)
{
return SerializationUtility.DeserializeValue<T>(serializedData, (DataFormat)0, (DeserializationContext)null);
}
private static void WriteMessageData(out FastBufferWriter writer, MessageData messageData, bool deprecatedMessage)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
(byte[], byte[], int) tuple = SerializeDataAndGetSize(messageData, deprecatedMessage);
byte[] item = tuple.Item1;
byte[] item2 = tuple.Item2;
int item3 = tuple.Item3;
writer = new FastBufferWriter(item3, (Allocator)2, item3 + 8);
if (!((FastBufferWriter)(ref writer)).TryBeginWrite(item3))
{
throw new OutOfMemoryException($"The buffer is too small ({((FastBufferWriter)(ref writer)).MaxCapacity}) " + $"to write the message data ({item3}) @ {((FastBufferWriter)(ref writer)).Position}. Shit's hella fucked!");
}
((FastBufferWriter)(ref writer)).WriteValue(deprecatedMessage ? "LethalNetworkAPI.Old" : "LethalNetworkAPI", false);
((FastBufferWriter)(ref writer)).WriteValue(messageData.Identifier, false);
EMessageType messageType = messageData.MessageType;
((FastBufferWriter)(ref writer)).WriteValue<EMessageType>(ref messageType, default(ForEnums));
if (!deprecatedMessage)
{
((FastBufferWriter)(ref writer)).WriteValue<ulong>(messageData.TargetClients ?? Array.Empty<ulong>(), default(ForPrimitives));
}
((FastBufferWriter)(ref writer)).WriteValue<byte>(item, default(ForPrimitives));
((FastBufferWriter)(ref writer)).WriteValue<byte>(item2, default(ForPrimitives));
}
private static (byte[], byte[], int) SerializeDataAndGetSize(MessageData messageData, bool deprecatedMessage)
{
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
byte[] array = ((messageData.Data?.GetType() == typeof(byte[])) ? ((byte[])messageData.Data) : Serialize(messageData.Data));
byte[] array2 = Serialize(messageData.Data?.GetType());
int writeSize = FastBufferWriter.GetWriteSize(deprecatedMessage ? "LethalNetworkAPI.Old" : "LethalNetworkAPI", false);
writeSize += FastBufferWriter.GetWriteSize(messageData.Identifier, false);
int num = writeSize;
EMessageType messageType = messageData.MessageType;
writeSize = num + FastBufferWriter.GetWriteSize<EMessageType>(ref messageType, default(ForStructs));
if (!deprecatedMessage)
{
writeSize += FastBufferWriter.GetWriteSize<ulong>(messageData.TargetClients ?? Array.Empty<ulong>(), -1, 0);
}
writeSize += FastBufferWriter.GetWriteSize<byte>(array, -1, 0);
writeSize += FastBufferWriter.GetWriteSize<byte>(array2, -1, 0);
if (writeSize > 65536)
{
LethalNetworkAPIPlugin.Logger.LogWarning((object)($"The serialized message size of '{messageData.Identifier}' is {writeSize} bytes. " + "This is larger than the recommended max size of 65536 bytes. The message may be dropped during transit."));
}
return (array, array2, writeSize);
}
public void Dispose()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
CustomMessagingManager.OnUnnamedMessage -= new UnnamedMessageDelegate(ReceiveMessage);
if (NetworkManager.NetworkTickSystem != null)
{
NetworkManager.NetworkTickSystem.Tick -= CheckVariablesForChanges;
}
if (IsServer)
{
NetworkManager.OnClientConnectedCallback -= UpdateNewClientVariables;
NetworkManager.OnClientDisconnectCallback -= UpdateClientList;
}
foreach (LNetworkVariableBase value in LNetworkVariables.Values)
{
value.ResetValue();
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
internal static class IsExternalInit
{
}
}
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
{
object IEnumerator.Current => _item;
T IEnumerator<T>.Current => _item;
public Enumerator(T item)
{
_item = item;
}
bool IEnumerator.MoveNext()
{
if (!_moveNextCalled)
{
return _moveNextCalled = true;
}
return false;
}
void IEnumerator.Reset()
{
_moveNextCalled = false;
}
void IDisposable.Dispose()
{
}
}
int ICollection.Count => 1;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
object IList.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
int IReadOnlyCollection<T>.Count => 1;
T IReadOnlyList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
}
int ICollection<T>.Count => 1;
bool ICollection<T>.IsReadOnly => true;
T IList<T>.this[int index]
{
get
{
if (index != 0)
{
throw new IndexOutOfRangeException();
}
return _item;
}
set
{
throw new NotSupportedException();
}
}
public <>z__ReadOnlySingleElementList(T item)
{
_item = item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection.CopyTo(Array array, int index)
{
array.SetValue(_item, index);
}
int IList.Add(object value)
{
throw new NotSupportedException();
}
void IList.Clear()
{
throw new NotSupportedException();
}
bool IList.Contains(object value)
{
return EqualityComparer<T>.Default.Equals(_item, (T)value);
}
int IList.IndexOf(object value)
{
if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
{
return -1;
}
return 0;
}
void IList.Insert(int index, object value)
{
throw new NotSupportedException();
}
void IList.Remove(object value)
{
throw new NotSupportedException();
}
void IList.RemoveAt(int index)
{
throw new NotSupportedException();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new Enumerator(_item);
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<T>.Contains(T item)
{
return EqualityComparer<T>.Default.Equals(_item, item);
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
array[arrayIndex] = _item;
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
int IList<T>.IndexOf(T item)
{
if (!EqualityComparer<T>.Default.Equals(_item, item))
{
return -1;
}
return 0;
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
}