Decompiled source of Entanglement Redux v0.0.5

EntanglementRedux.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Linq;
using Entanglement;
using Entanglement.Compat;
using Entanglement.Compat.Playermodels;
using Entanglement.Data;
using Entanglement.Exceptions;
using Entanglement.Extensions;
using Entanglement.Managers;
using Entanglement.Modularity;
using Entanglement.Network;
using Entanglement.Objects;
using Entanglement.Patching;
using Entanglement.Representation;
using Entanglement.UI;
using HarmonyLib;
using Il2CppSystem;
using MelonLoader;
using ModThatIsNotMod;
using ModThatIsNotMod.BoneMenu;
using Steamworks;
using StressLevelZero;
using StressLevelZero.AI;
using StressLevelZero.Arena;
using StressLevelZero.Combat;
using StressLevelZero.Data;
using StressLevelZero.Interaction;
using StressLevelZero.Player;
using StressLevelZero.Pool;
using StressLevelZero.Props;
using StressLevelZero.Props.Weapons;
using StressLevelZero.Rig;
using StressLevelZero.SFX;
using StressLevelZero.Utilities;
using StressLevelZero.VRMK;
using StressLevelZero.Zones;
using TMPro;
using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: Guid("490e160d-251d-4ab4-a3bb-f473961ff8a1")]
[assembly: AssemblyTitle("Entanglement")]
[assembly: AssemblyFileVersion("0.3.0")]
[assembly: MelonInfo(typeof(EntanglementMod), "Entanglement", "0.3.0", "zCubed, Lakatrazz", null)]
[assembly: MelonGame("Stress Level Zero", "BONEWORKS")]
[assembly: MelonIncompatibleAssemblies(new string[] { "MultiplayerMod" })]
[assembly: MelonPriority(-10000)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.3.0.0")]
namespace Entanglement
{
	public static class EntangleLogger
	{
		public static void Log(string txt, ConsoleColor txt_color = ConsoleColor.White)
		{
			((MelonBase)EntanglementMod.Instance).LoggerInstance.Msg(txt_color, txt);
		}

		public static void Log(object obj, ConsoleColor txt_color = ConsoleColor.White)
		{
			((MelonBase)EntanglementMod.Instance).LoggerInstance.Msg(txt_color, obj);
		}

		public static void Warn(string txt)
		{
			((MelonBase)EntanglementMod.Instance).LoggerInstance.Warning(txt);
		}

		public static void Warn(object obj)
		{
			((MelonBase)EntanglementMod.Instance).LoggerInstance.Warning(obj);
		}

		public static void Error(string txt)
		{
			((MelonBase)EntanglementMod.Instance).LoggerInstance.Error(txt);
		}

		public static void Error(object obj)
		{
			((MelonBase)EntanglementMod.Instance).LoggerInstance.Error(obj);
		}
	}
	public static class EntangleNotif
	{
		public static void PlayerJoin(string username)
		{
			Notifications.SendNotification(username + " has joined the server!", 4f);
		}

		public static void PlayerLeave(string username)
		{
			Notifications.SendNotification(username + " has left the server!", 4f);
		}

		public static void PlayerDisconnect(DisconnectReason reason)
		{
			Notifications.SendNotification($"You were disconnected for reason {reason}.", 4f);
		}

		public static void JoinServer(string username)
		{
			Notifications.SendNotification("Joined " + username + "'s server!", 4f);
		}

		public static void LeftServer()
		{
			Notifications.SendNotification("You left the server.", 4f);
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct EntanglementVersion
	{
		public const byte versionMajor = 0;

		public const byte versionMinor = 3;

		public const short versionPatch = 0;

		public const byte minVersionMajorSupported = 0;

		public const byte minVersionMinorSupported = 3;
	}
	public class EntanglementMod : MelonMod
	{
		public static byte? sceneChange;

		public static Assembly entanglementAssembly;

		public static bool hasUnpatched;

		public static EntanglementMod Instance { get; protected set; }

		public static string VersionString { get; protected set; }

		public override void OnApplicationStart()
		{
			entanglementAssembly = Assembly.GetExecutingAssembly();
			Instance = this;
			VersionString = $"{(byte)0}.{(byte)3}.{(short)0}";
			EntangleLogger.Log("Current Entanglement: Redux version is " + VersionString);
			EntangleLogger.Log($"Minimum supported Entanglement: Redux version is {(byte)0}.{(byte)3}.*");
			VersionChecking.CheckModVersion((MelonMod)(object)this, "https://boneworks.thunderstore.io/package/Entanglement/Entanglement/");
			PersistentData.Initialize();
			try
			{
				EntangleLogger.Log("Entanglement: Redux - Initializing Steam...");
				SteamIntegration.Initialize();
				EntangleLogger.Log("Entanglement: Redux - SteamIntegration initialized!");
			}
			catch (Exception ex)
			{
				EntangleLogger.Error("Failed to initialize Steam: " + ex.Message + "\nTrace: " + ex.StackTrace);
				return;
			}
			try
			{
				EntangleLogger.Log("Entanglement: Redux - Starting Patcher...");
				Patcher.Initialize();
				EntangleLogger.Log("Entanglement: Redux - Patcher initialized!");
			}
			catch (Exception ex2)
			{
				EntangleLogger.Error("Failed to initialize patchers: " + ex2.Message + "\nTrace: " + ex2.StackTrace);
				return;
			}
			try
			{
				EntangleLogger.Log("Entanglement: Redux - Registering message handlers...");
				NetworkMessage.RegisterHandlersFromAssembly(entanglementAssembly);
				EntangleLogger.Log("Entanglement: Redux - Message handlers registered!");
			}
			catch (Exception ex3)
			{
				EntangleLogger.Error("Failed to register message handlers: " + ex3.Message + "\nTrace: " + ex3.StackTrace);
				return;
			}
			try
			{
				EntangleLogger.Log("Entanglement: Redux - Starting client...");
				Client.StartClient();
				EntangleLogger.Log("Entanglement: Redux - Client started!");
			}
			catch (Exception ex4)
			{
				EntangleLogger.Error("Failed to start client: " + ex4.Message + "\nTrace: " + ex4.StackTrace);
				return;
			}
			try
			{
				EntangleLogger.Log("Entanglement: Redux - Loading bundles...");
				PlayerRepresentation.LoadBundle();
				LoadingScreen.LoadBundle();
				EntangleLogger.Log("Entanglement: Redux - Bundles loaded!");
			}
			catch (Exception ex5)
			{
				EntangleLogger.Error("Failed to load bundles: " + ex5.Message + "\nTrace: " + ex5.StackTrace);
				return;
			}
			try
			{
				EntangleLogger.Log("Entanglement: Redux - Creating UI...");
				EntanglementUI.CreateUI();
				EntangleLogger.Log("Entanglement: Redux - UI created!");
			}
			catch (Exception ex6)
			{
				EntangleLogger.Error("Failed to create UI: " + ex6.Message + "\nTrace: " + ex6.StackTrace);
				return;
			}
			try
			{
				EntangleLogger.Log("Entanglement: Redux - Loading ban list...");
				BanList.PullFromFile();
				EntangleLogger.Log("Entanglement: Redux - Ban list loaded!");
			}
			catch (Exception ex7)
			{
				EntangleLogger.Error("Failed to load ban list: " + ex7.Message + "\nTrace: " + ex7.StackTrace);
				return;
			}
			EntangleLogger.Log("Welcome to Entanglement: Redux!", ConsoleColor.DarkYellow);
		}

		public override void OnApplicationLateStart()
		{
			if (SteamIntegration.isInvalid)
			{
				((MelonBase)this).HarmonyInstance.UnpatchSelf();
				hasUnpatched = true;
			}
			else
			{
				PlayerDeathManager.Initialize();
			}
		}

		public override void OnUpdate()
		{
			if (SteamIntegration.isInvalid)
			{
				if (!hasUnpatched)
				{
					((MelonBase)this).HarmonyInstance.UnpatchSelf();
					hasUnpatched = true;
				}
			}
			else
			{
				ModuleHandler.Update();
				StatsUI.UpdateUI();
				PlayerRepresentation.SyncPlayerReps();
				DataTransaction.Process();
			}
		}

		public override void OnFixedUpdate()
		{
			if (!SteamIntegration.isInvalid)
			{
				ModuleHandler.FixedUpdate();
				PlayerRepresentation.UpdatePlayerReps();
			}
		}

		public override void OnLateUpdate()
		{
			if (!SteamIntegration.isInvalid)
			{
				ModuleHandler.LateUpdate();
				Client.instance?.Tick();
				Server.instance?.Tick();
				SteamIntegration.Tick();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			if (SteamIntegration.isInvalid)
			{
				return;
			}
			ModuleHandler.OnSceneWasInitialized(buildIndex, sceneName);
			SpawnableData.GetData();
			PlayerScripts.GetPlayerScripts();
			PlayerRepresentation.GetPlayerTransforms();
			foreach (PlayerRepresentation value in PlayerRepresentation.representations.Values)
			{
				value.RecreateRepresentations();
			}
			Client.instance.currentScene = (byte)buildIndex;
			sceneChange = (byte)buildIndex;
			SteamIntegration.targetScene = sceneName.ToLower();
			SteamIntegration.UpdateActivity();
		}

		public override void BONEWORKS_OnLoadingScreen()
		{
			if (!SteamIntegration.isInvalid)
			{
				ModuleHandler.OnLoadingScreen();
				LoadingScreen.OverrideScreen();
				ObjectSync.OnCleanup();
				ObjectSync.poolPairs.Clear();
				PooleeSyncable._Cache.Clear();
				PooleeSyncable._PooleeLookup.Clear();
			}
		}

		public override void OnApplicationQuit()
		{
			if (!SteamIntegration.isInvalid)
			{
				ModuleHandler.OnApplicationQuit();
				Node.activeNode.Shutdown();
				SteamIntegration.Shutdown();
			}
		}
	}
}
namespace Entanglement.UI
{
	public static class BanlistUI
	{
		public static MenuCategory banCategory;

		private const string refreshText = "Refresh";

		public static void CreateUI(MenuCategory category)
		{
			//IL_0006: 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)
			banCategory = category.CreateSubCategory("Banned Users", Color.white);
			banCategory.CreateFunctionElement("Refresh", Color.white, (Action)Refresh);
		}

		public static void ClearPlayers()
		{
			List<string> list = new List<string>();
			foreach (MenuElement element in banCategory.elements)
			{
				if (element.displayText != "Refresh")
				{
					list.Add(element.displayText);
				}
			}
			foreach (string item in list)
			{
				banCategory.RemoveElement(item);
			}
		}

		public static void Refresh()
		{
			ClearPlayers();
			foreach (Tuple<ulong, string> bannedUser in BanList.bannedUsers)
			{
				AddUser(bannedUser.Item1, bannedUser.Item2);
			}
			UpdateMenu();
		}

		public static void UpdateMenu()
		{
			MenuManager.OpenCategory(banCategory);
		}

		public static void AddUser(ulong steamId, string username)
		{
			//IL_002a: 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)
			string text = username ?? "";
			banCategory.CreateSubCategory(text, Color.white).CreateFunctionElement("Unban", Color.red, (Action)delegate
			{
				BanList.UnbanUser(steamId, username);
				Refresh();
			});
		}
	}
	public static class ClientUI
	{
		public static void CreateUI(MenuCategory category)
		{
			//IL_0006: 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)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			category.CreateSubCategory("Client Menu", Color.white).CreateSubCategory("Client Settings", Color.white).CreateBoolElement("NameTags", Color.white, true, (Action<bool>)delegate(bool value)
			{
				Client.nameTagsVisible = value;
			});
		}
	}
	public static class LoadingScreen
	{
		public static AssetBundle assetBundle;

		public static void LoadBundle()
		{
			assetBundle = EmebeddedAssetBundle.LoadFromAssembly(EntanglementMod.entanglementAssembly, "Entanglement.resources.logo.eres");
		}

		public static void OverrideScreen()
		{
			Texture2D texture = assetBundle.LoadAsset<Texture2D>("entanglement.png");
			GameObject.Find("Canvas/RawImage (1)").GetComponent<RawImage>().texture = (Texture)(object)texture;
		}
	}
	public static class LobbiesUI
	{
		private static MenuCategory lobbiesCategory;

		private const string refreshText = "Refresh Lobbies";

		private static CallResult<LobbyMatchList_t> lobbyListResult;

		public static void CreateUI(MenuCategory category)
		{
			//IL_0006: 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)
			lobbiesCategory = category.CreateSubCategory("Public Lobbies", Color.white);
			lobbiesCategory.CreateFunctionElement("Refresh Lobbies", Color.white, (Action)Refresh);
			lobbyListResult = CallResult<LobbyMatchList_t>.Create((APIDispatchDelegate<LobbyMatchList_t>)OnLobbyMatchList);
		}

		public static void Refresh()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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)
			ClearMenuItems();
			EntangleLogger.Log("Searching for public Steam lobbies...");
			SteamMatchmaking.AddRequestLobbyListDistanceFilter((ELobbyDistanceFilter)3);
			SteamAPICall_t val = SteamMatchmaking.RequestLobbyList();
			lobbyListResult.Set(val, (APIDispatchDelegate<LobbyMatchList_t>)null);
			UpdateMenu();
		}

		public static void OnLobbyMatchList(LobbyMatchList_t result, bool bIOFailure)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (bIOFailure)
			{
				EntangleLogger.Error("Failed to search for Steam Lobbies (IO Failure).");
				return;
			}
			int nLobbiesMatching = (int)result.m_nLobbiesMatching;
			EntangleLogger.Log(string.Format("Found {0} Public Lobb{1}.", nLobbiesMatching, (nLobbiesMatching == 1) ? "y" : "ies"));
			for (int i = 0; i < nLobbiesMatching; i++)
			{
				AddLobby(SteamMatchmaking.GetLobbyByIndex(i));
			}
		}

		public static void ClearMenuItems()
		{
			List<string> list = new List<string>();
			foreach (MenuElement element in lobbiesCategory.elements)
			{
				if (element.displayText != "Refresh Lobbies")
				{
					list.Add(element.displayText);
				}
			}
			foreach (string item in list)
			{
				lobbiesCategory.RemoveElement(item);
			}
		}

		public static void AddLobby(CSteamID lobbyId)
		{
			//IL_0000: 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)
			//IL_0017: 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)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			string text = SteamMatchmaking.GetLobbyData(lobbyId, "name");
			string lobbyData = SteamMatchmaking.GetLobbyData(lobbyId, "version");
			int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(lobbyId);
			int lobbyMemberLimit = SteamMatchmaking.GetLobbyMemberLimit(lobbyId);
			if (string.IsNullOrEmpty(text))
			{
				text = "Unnamed Server";
			}
			if (!(lobbyData != EntanglementMod.VersionString))
			{
				CreateLobbyItem($"{text} ({numLobbyMembers}/{lobbyMemberLimit})", lobbyId);
			}
		}

		public static void CreateLobbyItem(string name, CSteamID lobbyId)
		{
			//IL_0007: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			lobbiesCategory.CreateFunctionElement(name, Color.white, (Action)delegate
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				if (SteamIntegration.hasLobby)
				{
					EntangleLogger.Error("Entanglement: Redux - Already in a server!");
				}
				else
				{
					Client.instance?.JoinLobby(lobbyId);
				}
			});
			UpdateMenu();
		}

		public static void UpdateMenu()
		{
			MenuManager.OpenCategory(lobbiesCategory);
		}
	}
	public static class ServerUI
	{
		private static MenuCategory playersCategory;

		private const string refreshText = "Refresh";

		public static void CreateUI(MenuCategory category)
		{
			//IL_0006: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			MenuCategory obj = category.CreateSubCategory("Server Menu", Color.white);
			obj.CreateFunctionElement("Start Server", Color.white, (Action)delegate
			{
				Server.StartServer();
			});
			obj.CreateFunctionElement("Stop Server", Color.white, (Action)delegate
			{
				if (Server.instance != null)
				{
					Server.instance.Shutdown();
				}
			});
			obj.CreateFunctionElement("Disconnect", Color.white, (Action)delegate
			{
				if (Node.activeNode is Client client)
				{
					client.DisconnectFromServer();
				}
			});
			MenuCategory obj2 = obj.CreateSubCategory("Server Settings", Color.white);
			obj2.CreateIntElement("Max Players", Color.white, 8, (Action<int>)delegate(int value)
			{
				Server.maxPlayers = (byte)value;
				Server.instance?.UpdateLobbyConfig();
			}, 1, 1, 250, true);
			obj2.CreateBoolElement("Locked", Color.white, false, (Action<bool>)delegate(bool value)
			{
				Server.isLocked = value;
				Server.instance?.UpdateLobbyConfig();
			});
			obj2.CreateEnumElement("Visibility", Color.white, (Enum)LobbyType.Private, (Action<Enum>)delegate(Enum value)
			{
				if (value is LobbyType)
				{
					Server.lobbyType = (LobbyType)(object)value;
					Server.instance?.UpdateLobbyConfig();
				}
			});
			playersCategory = obj.CreateSubCategory("Players", Color.white);
			playersCategory.CreateFunctionElement("Refresh", Color.white, (Action)Refresh);
		}

		public static void ClearPlayers()
		{
			List<string> list = new List<string>();
			foreach (MenuElement element in playersCategory.elements)
			{
				if (element.displayText != "Refresh")
				{
					list.Add(element.displayText);
				}
			}
			foreach (string item in list)
			{
				playersCategory.RemoveElement(item);
			}
		}

		public static void Refresh()
		{
			//IL_0012: 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)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			ClearPlayers();
			if (!SteamIntegration.hasLobby)
			{
				UpdateMenu();
				return;
			}
			int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(SteamIntegration.lobbyId);
			for (int i = 0; i < numLobbyMembers; i++)
			{
				CSteamID lobbyMemberByIndex = SteamMatchmaking.GetLobbyMemberByIndex(SteamIntegration.lobbyId, i);
				if (!(lobbyMemberByIndex == SteamIntegration.currentUser))
				{
					AddUser(lobbyMemberByIndex);
				}
			}
			UpdateMenu();
		}

		public static void UpdateMenu()
		{
			MenuManager.OpenCategory(playersCategory);
		}

		public static void AddUser(CSteamID player)
		{
			//IL_0007: 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_000f: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_004c: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			string playerName = SteamFriends.GetFriendPersonaName(player);
			Color val = Color.white;
			if (player == SteamIntegration.hostUser)
			{
				playerName += " (Host)";
				val = Color.yellow;
			}
			MenuCategory val2 = playersCategory.CreateSubCategory(playerName, val);
			if (!SteamIntegration.isHost)
			{
				return;
			}
			val2.CreateFunctionElement("Kick", Color.red, (Action)delegate
			{
				if (SteamIntegration.isHost)
				{
					Server.instance?.KickUser(player.m_SteamID, playerName);
					Refresh();
				}
			});
			val2.CreateFunctionElement("Ban", Color.red, (Action)delegate
			{
				if (SteamIntegration.isHost)
				{
					BanList.BanUser(player.m_SteamID, playerName);
					Server.instance.KickUser(player.m_SteamID, playerName, DisconnectReason.Banned);
					Refresh();
				}
			});
			val2.CreateFunctionElement("Teleport To", Color.yellow, (Action)delegate
			{
				Server.instance?.TeleportTo(player.m_SteamID);
			});
		}
	}
	public static class StatsUI
	{
		public static IntElement downElem;

		public static IntElement upElem;

		public static void CreateUI(MenuCategory category)
		{
			//IL_0006: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			MenuCategory obj = category.CreateSubCategory("Net Stats", Color.white);
			obj.CreateIntElement("Bytes Down", Color.white, 0, (Action<int>)null, 1, int.MinValue, int.MaxValue, false);
			obj.CreateIntElement("Bytes Up", Color.white, 0, (Action<int>)null, 1, int.MinValue, int.MaxValue, false);
			MenuElement obj2 = obj.elements[0];
			downElem = (IntElement)(object)((obj2 is IntElement) ? obj2 : null);
			MenuElement obj3 = obj.elements[1];
			upElem = (IntElement)(object)((obj3 is IntElement) ? obj3 : null);
		}

		public static void UpdateUI()
		{
			((GenericElement<int>)(object)downElem).SetValue((int)Node.activeNode.recievedByteCount);
			Node.activeNode.recievedByteCount = 0u;
			((GenericElement<int>)(object)upElem).SetValue((int)Node.activeNode.sentByteCount);
			Node.activeNode.sentByteCount = 0u;
		}
	}
	public static class EntanglementUI
	{
		public static void CreateUI()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			MenuCategory category = MenuManager.CreateCategory("Entanglement: Redux", Color.white);
			ServerUI.CreateUI(category);
			ClientUI.CreateUI(category);
			BanlistUI.CreateUI(category);
			LobbiesUI.CreateUI(category);
			VoiceUI.CreateUI(category);
			StatsUI.CreateUI(category);
		}
	}
	public static class VoiceUI
	{
		public static void CreateUI(MenuCategory category)
		{
			//IL_0006: 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)
			category.CreateSubCategory("Voice Menu", Color.white).CreateEnumElement("Voice Activity", Color.yellow, (Enum)SteamIntegration.voiceStatus, (Action<Enum>)delegate(Enum value)
			{
				SteamIntegration.UpdateVoice((VoiceStatus)(object)value);
			});
		}
	}
}
namespace Entanglement.Representation
{
	public class PlayerRepresentation
	{
		public static float legJitter = 10f;

		public static Dictionary<ulong, PlayerRepresentation> representations = new Dictionary<ulong, PlayerRepresentation>();

		public static Transform[] syncedPoints = (Transform[])(object)new Transform[3];

		public static Transform syncedRoot;

		public Transform[] repTransforms = (Transform[])(object)new Transform[3];

		public Transform repRoot;

		public GameObject repFord;

		public Material repHologram;

		public GameObject repCanvas;

		public Canvas repCanvasComponent;

		public Transform repCanvasTransform;

		public TextMeshProUGUI repNameText;

		public Transform repGeo;

		public Transform repSHJnt;

		public Collider[] colliders = (Collider[])(object)new Collider[0];

		public SLZ_Body repBody;

		public SLZ_Body ragdollBody;

		public CharacterAnimationManager repAnimationManager;

		public GunSFX repGunSFX;

		public GunSFX repBalloonSFX;

		public GunSFX repStabSFX;

		public GravGunSFX repPowerPunchSFX;

		public Animator repAnimator;

		public Animator skinAnimator;

		public Animator activeAnimator;

		public GameObject currentSkinObject;

		public AssetBundle currentSkinBundle;

		public string currentSkinPath;

		public bool isCustomSkinned;

		public Vector3 repInputVel = Vector3.zero;

		public Vector3 repSavedVel = Vector3.zero;

		public Vector3 prevRepRootPos = Vector3.zero;

		public string playerName;

		public ulong playerId;

		public bool isGrounded;

		public static AssetBundle playerRepBundle;

		public static void LoadBundle()
		{
			playerRepBundle = EmebeddedAssetBundle.LoadFromAssembly(EntanglementMod.entanglementAssembly, "Entanglement.resources.playerrep.eres");
			if ((Object)(object)playerRepBundle == (Object)null)
			{
				throw new NullReferenceException("playerRepBundle is null! Did you forget to compile the player bundle into the dll?");
			}
		}

		public PlayerRepresentation(string playerName, ulong playerId)
		{
			//IL_0019: 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)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			this.playerName = playerName;
			this.playerId = playerId;
			RecreateRepresentations();
		}

		public void DeleteRepresentations()
		{
			Object.Destroy((Object)(object)repFord);
			Object.Destroy((Object)(object)repCanvas);
			if (Object.op_Implicit((Object)(object)currentSkinObject))
			{
				Object.Destroy((Object)(object)currentSkinObject);
			}
		}

		public void RecreateRepresentations()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0044: 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)
			try
			{
				repCanvas = new GameObject("RepCanvas");
				repCanvasComponent = repCanvas.AddComponent<Canvas>();
				repCanvasComponent.renderMode = (RenderMode)2;
				repCanvasTransform = repCanvas.transform;
				repCanvasTransform.localScale = Vector3.one / 200f;
				repNameText = repCanvas.AddComponent<TextMeshProUGUI>();
				((TMP_Text)repNameText).alignment = (TextAlignmentOptions)4098;
				((TMP_Text)repNameText).enableAutoSizing = true;
				((TMP_Text)repNameText).text = playerName;
				repHologram = Object.Instantiate<Material>(playerRepBundle.LoadAsset<Material>("PlayerHolographic"));
				repFord = Object.Instantiate<GameObject>(playerRepBundle.LoadAsset<GameObject>("PlayerRep"));
				((Object)repFord).name = $"PlayerRep.{playerId}";
				repRoot = repFord.transform;
				repGunSFX = ((Component)repRoot.Find("GunSFX")).GetComponent<GunSFX>();
				repBalloonSFX = ((Component)repRoot.Find("BalloonSFX")).GetComponent<GunSFX>();
				repStabSFX = ((Component)repRoot.Find("StabSFX")).GetComponent<GunSFX>();
				repPowerPunchSFX = ((Component)repRoot.Find("PuncherSFX")).GetComponent<GravGunSFX>();
				Transform val = repRoot.Find("Body");
				repBody = ((Component)val).GetComponent<SLZ_Body>();
				repBody.OnStart();
				ragdollBody = ((Component)repRoot.Find("Ragdoll")).GetComponent<SLZ_Body>();
				Transform val2 = repRoot.Find("Brett@neutral");
				repAnimator = ((Component)val2).GetComponent<Animator>();
				repAnimator.runtimeAnimatorController = PlayerScripts.playerAnimatorController;
				activeAnimator = repAnimator;
				repAnimationManager = ((Component)val2).GetComponent<CharacterAnimationManager>();
				repGeo = val2.Find("geoGrp");
				repSHJnt = val2.Find("SHJntGrp");
				repTransforms[0] = repRoot.Find("Head");
				repTransforms[1] = repRoot.Find("Hand (left)");
				repTransforms[2] = repRoot.Find("Hand (right)");
				colliders = Il2CppArrayBase<Collider>.op_Implicit(((Component)repRoot).GetComponentsInChildren<Collider>());
				if (isCustomSkinned && currentSkinPath != null)
				{
					PlayerSkinLoader.ApplyPlayermodel(this, currentSkinPath);
				}
			}
			catch
			{
				EntangleLogger.Error($"Error caught creating rep from user {playerId}");
			}
		}

		public void CreateRagdoll()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)activeAnimator))
			{
				return;
			}
			GameObject val = new GameObject($"Ragdoll {Time.realtimeSinceStartup}");
			GameObject val2 = Object.Instantiate<GameObject>(((Component)ragdollBody).gameObject);
			val2.transform.parent = val.transform;
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit(val2.GetComponentsInChildren<Collider>(true));
			Collider[] array2 = array;
			foreach (Collider val3 in array2)
			{
				Collider[] array3 = array;
				foreach (Collider val4 in array3)
				{
					if (!((Object)(object)val3 == (Object)(object)val4))
					{
						Physics.IgnoreCollision(val3, val4, true);
					}
				}
			}
			val2.gameObject.SetActive(true);
			foreach (Rigidbody componentsInChild in val2.GetComponentsInChildren<Rigidbody>(true))
			{
				componentsInChild.velocity = repSavedVel;
				componentsInChild.angularVelocity = Vector3.zero;
			}
			CopyBone(((Component)repBody).transform, val2.transform);
			CopyBones(repBody.references, val2.GetComponent<SLZ_Body>().references);
			val2.gameObject.AddComponent<RagdollBehaviour>();
		}

		public void CopyBones(References from, References to)
		{
			CopyBone(from.skull, to.skull);
			CopyBone(from.c4Vertebra, to.c4Vertebra);
			CopyBone(from.t1Offset, to.t1Offset);
			CopyBone(from.t7Vertebra, to.t7Vertebra);
			CopyBone(from.l1Vertebra, to.l1Vertebra);
			CopyBone(from.l3Vertebra, to.l3Vertebra);
			CopyBone(from.sacrum, to.sacrum);
			CopyBone(from.leftHip, to.leftHip);
			CopyBone(from.leftKnee, to.leftKnee);
			CopyBone(from.leftAnkle, to.leftAnkle);
			CopyBone(from.rightHip, to.rightHip);
			CopyBone(from.rightKnee, to.rightKnee);
			CopyBone(from.rightAnkle, to.rightAnkle);
			CopyBone(from.leftShoulder, to.leftShoulder);
			CopyBone(from.leftElbow, to.leftElbow);
			CopyBone(from.leftWrist, to.leftWrist);
			CopyBone(from.rightShoulder, to.rightShoulder);
			CopyBone(from.rightElbow, to.rightElbow);
			CopyBone(from.rightWrist, to.rightWrist);
		}

		public void CopyBone(Transform from, Transform to)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			to.position = from.position;
			to.rotation = from.rotation;
		}

		public void SaveVelocity()
		{
			//IL_0006: 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_0014: 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)
			//IL_001b: 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)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = repRoot.position;
			float fixedDeltaTime = Time.fixedDeltaTime;
			repSavedVel = Vector3.Slerp(repInputVel, PhysicsData.GetVelocity(position, prevRepRootPos, fixedDeltaTime), fixedDeltaTime * legJitter);
			if (isGrounded)
			{
				repInputVel = repSavedVel;
			}
			else
			{
				repInputVel = Vector3.zero;
			}
			prevRepRootPos = position;
		}

		public void UpdateIK()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((!Object.op_Implicit((Object)(object)currentSkinBundle) || !Object.op_Implicit((Object)(object)currentSkinObject)) && isCustomSkinned)
				{
					PlayerSkinLoader.ApplyPlayermodel(this, currentSkinPath);
				}
				if (Object.op_Implicit((Object)(object)activeAnimator))
				{
					activeAnimator.Update(Time.fixedDeltaTime);
					repAnimationManager.OnLateUpdate();
					SaveVelocity();
					repBody.FullBodyUpdate(repInputVel, Vector3.zero);
					repBody.ArtToBlender.UpdateBlender();
				}
			}
			catch
			{
			}
		}

		public void UpdatePose(Handedness hand, int index)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			Il2CppStringArray playerHandPoses = PlayerScripts.playerHandPoses;
			if (((Il2CppArrayBase<string>)(object)playerHandPoses).Count >= index + 1)
			{
				UpdatePose(hand, ((Il2CppArrayBase<string>)(object)playerHandPoses)[index]);
			}
		}

		public void UpdatePose(Handedness hand, string pose)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			CharacterAnimationManager obj = repAnimationManager;
			if (obj != null)
			{
				obj.SetHandPose(hand, pose);
			}
		}

		public void UpdatePoseRadius(Handedness hand, float radius)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			CharacterAnimationManager obj = repAnimationManager;
			if (obj != null)
			{
				obj.SetCylinderRadius(hand, radius);
			}
		}

		public void UpdateFingers(Handedness hand, float indexCurl = 1f, float middleCurl = 1f, float ringCurl = 1f, float pinkyCurl = 1f, float thumbCurl = 1f)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			repAnimationManager.ApplyFingerCurl(hand, 1f - thumbCurl, 1f - indexCurl, 1f - middleCurl, 1f - ringCurl, 1f - pinkyCurl);
		}

		public void UpdateFingers(Handedness hand, SimplifiedHand handData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			UpdateFingers(hand, handData.indexCurl, handData.middleCurl, handData.ringCurl, handData.pinkyCurl, handData.thumbCurl);
		}

		public void IgnoreCollision(Rigidbody otherBody, bool ignore)
		{
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit(((Component)otherBody).GetComponentsInChildren<Collider>());
			Collider[] array2 = colliders;
			foreach (Collider val in array2)
			{
				Collider[] array3 = array;
				foreach (Collider val2 in array3)
				{
					Physics.IgnoreCollision(val, val2, ignore);
				}
			}
		}

		public static void GetPlayerTransforms()
		{
			GameObject val = GameObject.Find("[RigManager (Default Brett)]/[SkeletonRig (GameWorld Brett)]");
			if (Object.op_Implicit((Object)(object)val))
			{
				syncedRoot = val.transform;
				syncedPoints[0] = syncedRoot.Find("Head");
				syncedPoints[1] = syncedRoot.Find("Hand (left)");
				syncedPoints[2] = syncedRoot.Find("Hand (right)");
			}
		}

		public static PlayerRepSyncData GetPlayerSyncData()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			Transform[] array = syncedPoints;
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i] == (Object)null)
				{
					return null;
				}
			}
			PlayerRepSyncData playerRepSyncData = new PlayerRepSyncData();
			playerRepSyncData.userId = SteamIntegration.currentUser.m_SteamID;
			for (int j = 0; j < playerRepSyncData.simplifiedTransforms.Length; j++)
			{
				playerRepSyncData.simplifiedTransforms[j].position = syncedPoints[j].position;
				playerRepSyncData.simplifiedTransforms[j].rotation = SimplifiedQuaternion.SimplifyQuat(syncedPoints[j].rotation);
			}
			playerRepSyncData.rootPosition = syncedRoot.position;
			playerRepSyncData.isGrounded = PlayerScripts.playerGrounder.isGrounded;
			playerRepSyncData.simplifiedLeftHand = new SimplifiedHand(PlayerScripts.playerLeftHand.fingerCurl);
			playerRepSyncData.simplifiedRightHand = new SimplifiedHand(PlayerScripts.playerRightHand.fingerCurl);
			return playerRepSyncData;
		}

		public static void SyncPlayerReps()
		{
			if (SteamIntegration.hasLobby)
			{
				PlayerRepSyncData playerSyncData = GetPlayerSyncData();
				if (playerSyncData != null)
				{
					NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.PlayerRepSync, playerSyncData);
					Node.activeNode.BroadcastMessage(NetworkChannel.Unreliable, networkMessage.GetBytes());
				}
				else
				{
					GetPlayerTransforms();
				}
			}
		}

		public static void UpdatePlayerReps()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)syncedRoot == (Object)null)
			{
				return;
			}
			foreach (PlayerRepresentation value in representations.Values)
			{
				if (value == null || (Object)(object)value.repRoot == (Object)null)
				{
					continue;
				}
				Vector3 val = syncedRoot.position - value.repRoot.position;
				if (!(((Vector3)(ref val)).sqrMagnitude < 1000000f))
				{
					continue;
				}
				value.UpdateIK();
				Transform obj = value.repCanvasTransform;
				if (obj != null)
				{
					GameObject gameObject = ((Component)obj).gameObject;
					if (gameObject != null)
					{
						gameObject.SetActive(Client.nameTagsVisible);
					}
				}
			}
		}
	}
}
namespace Entanglement.Patching
{
	public static class Patcher
	{
		public static void Initialize()
		{
			OptionalAssemblyPatch.AttemptPatches();
		}

		public static void Patch(MethodBase method, HarmonyMethod prefix = null, HarmonyMethod postfix = null)
		{
			((MelonBase)EntanglementMod.Instance).HarmonyInstance.Patch(method, prefix, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}
	[HarmonyPatch(typeof(Prop_Health), "DESTROYED")]
	public static class PropHealthPatch
	{
		public static bool Prefix(Prop_Health __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance.impactSFX))
			{
				return false;
			}
			return true;
		}

		public static void Postfix(Prop_Health __instance)
		{
			if (SteamIntegration.hasLobby)
			{
				TransformSyncable transformSyncable = TransformSyncable.DestructCache.Get(((Component)__instance).gameObject);
				if (Object.op_Implicit((Object)(object)transformSyncable) && transformSyncable.IsOwner())
				{
					byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.ObjectDestroy, new ObjectDestroyMessageData
					{
						objectId = transformSyncable.objectId
					}).GetBytes();
					Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ObjectDestructable), "TakeDamage")]
	public static class DestructablePatch
	{
		public static void Postfix(ObjectDestructable __instance)
		{
			if (SteamIntegration.hasLobby && __instance._isDead)
			{
				TransformSyncable transformSyncable = TransformSyncable.DestructCache.Get(((Component)__instance).gameObject);
				if (Object.op_Implicit((Object)(object)transformSyncable) && transformSyncable.IsOwner())
				{
					byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.ObjectDestroy, new ObjectDestroyMessageData
					{
						objectId = transformSyncable.objectId
					}).GetBytes();
					Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
				}
			}
		}
	}
	public static class FantasyArena_Settings
	{
		public static bool m_invalidSettings;

		public static void SendEnemyCount(bool isLow)
		{
			byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.FantasyCount, new FantasyEnemyCountMessageData
			{
				isLow = isLow
			}).GetBytes();
			Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
		}

		public static void SendDifficulty(byte difficulty)
		{
			byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.FantasyDiff, new FantasyDifficultyMessageData
			{
				difficulty = difficulty
			}).GetBytes();
			Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
		}
	}
	[HarmonyPatch(typeof(UIHapticHoverArena), "OnPointerEnter")]
	public static class ChallengePatch
	{
		public static void Postfix(UIHapticHoverArena __instance, PointerEventData eventData)
		{
			if (Object.op_Implicit((Object)(object)__instance.arenaUIControl) && Object.op_Implicit((Object)(object)__instance.challenge) && (Object)(object)__instance.arenaUIControl.activeChallenge == (Object)(object)__instance.challenge)
			{
				Arena_Challenge challenge = __instance.challenge;
				byte index = (byte)((IEnumerable<Arena_Challenge>)Arena_GameManager.instance.masterChallengeList.ToArray()).ToList().FindIndex((Arena_Challenge o) => (Object)(object)o == (Object)(object)challenge);
				byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.FantasyChal, new FantasyChallengeMessageData
				{
					index = index
				}).GetBytes();
				Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
			}
		}
	}
	[HarmonyPatch(typeof(Control_UI_Arena), "SetEasyDifficulty")]
	public static class EasyDifficultyPatch
	{
		public static void Postfix()
		{
			if (!FantasyArena_Settings.m_invalidSettings)
			{
				FantasyArena_Settings.SendDifficulty(0);
			}
			FantasyArena_Settings.m_invalidSettings = false;
		}
	}
	[HarmonyPatch(typeof(Control_UI_Arena), "SetMediumDifficulty")]
	public static class MediumDifficultyPatch
	{
		public static void Postfix()
		{
			if (!FantasyArena_Settings.m_invalidSettings)
			{
				FantasyArena_Settings.SendDifficulty(1);
			}
			FantasyArena_Settings.m_invalidSettings = false;
		}
	}
	[HarmonyPatch(typeof(Control_UI_Arena), "SetHardDifficulty")]
	public static class HardDifficultyPatch
	{
		public static void Postfix()
		{
			if (!FantasyArena_Settings.m_invalidSettings)
			{
				FantasyArena_Settings.SendDifficulty(2);
			}
			FantasyArena_Settings.m_invalidSettings = false;
		}
	}
	[HarmonyPatch(typeof(Control_UI_Arena), "ToggleEnemyCount")]
	public static class ToggleEnemyCountPatch
	{
		public static void Postfix(Control_UI_Arena __instance)
		{
			FantasyArena_Settings.SendEnemyCount(__instance.arenaStats.arenaDataPlayer.playerStats.isLowEnemyCount);
		}
	}
	[HarmonyPatch(typeof(Control_UI_Arena), "OnLoadSaveFile")]
	public static class LoadSaveFilePatch
	{
		public static void Postfix(Control_UI_Arena __instance)
		{
			if (Server.instance != null)
			{
				FantasyArena_Settings.SendEnemyCount(__instance.arenaStats.arenaDataPlayer.playerStats.isLowEnemyCount);
			}
		}
	}
	[HarmonyPatch(typeof(PowerPuncher), "OnCollisionEnter")]
	public class GadgetPatches
	{
		public static void Prefix(PowerPuncher __instance, Collision collision)
		{
			//IL_0059: 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)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)collision.rigidbody))
			{
				return;
			}
			string name = ((Object)collision.gameObject.transform.root).name;
			if (!name.Contains("PlayerRep"))
			{
				return;
			}
			string[] array = name.Split(new char[1] { '.' });
			if (array.Length < 2)
			{
				throw new IndexOutOfRangeException();
			}
			ulong userId = ulong.Parse(array[1]);
			ContactPoint contact = collision.GetContact(0);
			if (!(((Object)((ContactPoint)(ref contact)).thisCollider).name != "col_mainBody (1)"))
			{
				Vector3 relativeVelocity = collision.relativeVelocity;
				float num = Vector3.Dot(((Vector3)(ref relativeVelocity)).normalized, ((Component)__instance).transform.TransformDirection(__instance.forward));
				num = Mathf.Min(0f, num);
				Vector3 val = collision.relativeVelocity * num * __instance._triggerStartTime;
				val = Vector3.ClampMagnitude(val, 30f) * 7f;
				if (!(val == Vector3.zero))
				{
					byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.PowerPunch, new PowerPunchMessageData
					{
						force = val,
						localPosition = PlayerRepresentation.syncedRoot.InverseTransformPosition(((Component)__instance).transform.position)
					}).GetBytes();
					Node.activeNode.SendMessage(userId, NetworkChannel.Attack, bytes);
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameControl), "RELOADLEVEL")]
	public static class ReloadLevelPatch
	{
		public static bool Prefix()
		{
			if (SteamIntegration.hasLobby)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ForcePullGrip), "OnFarHandHoverUpdate")]
	public class ForcePullPatch
	{
		public static void Prefix(ForcePullGrip __instance, ref bool __state, Hand hand)
		{
			__state = __instance.pullCoroutine != null;
		}

		public static void Postfix(ForcePullGrip __instance, ref bool __state, Hand hand)
		{
			if (__instance.pullCoroutine != null && !__state)
			{
				ObjectSync.OnGripAttached(((Component)__instance).gameObject);
			}
		}
	}
	[HarmonyPatch(typeof(ForcePullGrip), "CancelPull")]
	public class ForceCancelPatch
	{
		public static void Postfix(ForcePullGrip __instance, Hand hand)
		{
			ObjectSync.OnForcePullCancelled(((Component)__instance).gameObject);
		}
	}
	[HarmonyPatch(typeof(Gun), "OnFire")]
	public class GunShotPatch
	{
		public static void Prefix(Gun __instance)
		{
			BulletObject chamberedCartridge = __instance.chamberedCartridge;
			Transform firePointTransform = __instance.firePointTransform;
			if (Object.op_Implicit((Object)(object)firePointTransform) && Object.op_Implicit((Object)(object)chamberedCartridge))
			{
				GunShotMessageData data = new GunShotMessageData
				{
					userId = SteamIntegration.currentUser.m_SteamID,
					bulletObject = chamberedCartridge,
					bulletTransform = new SimplifiedTransform(firePointTransform)
				};
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.GunShot, data);
				Node.activeNode.BroadcastMessage(NetworkChannel.Attack, networkMessage.GetBytes());
			}
		}
	}
	[HarmonyPatch(typeof(BalloonGun), "OnFire")]
	public class BalloonShotPatch
	{
		public static void Prefix(BalloonGun __instance)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Transform firePointTransform = ((Gun)__instance).firePointTransform;
			if (Object.op_Implicit((Object)(object)firePointTransform))
			{
				BalloonShotMessageData data = new BalloonShotMessageData
				{
					userId = SteamIntegration.currentUser.m_SteamID,
					balloonColor = __instance.currentColor,
					balloonTransform = new SimplifiedTransform(firePointTransform)
				};
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.BalloonShot, data);
				Node.activeNode.BroadcastMessage(NetworkChannel.Attack, networkMessage.GetBytes());
			}
		}
	}
	public static class Magazine_Settings
	{
		public static bool InGun(this MagazinePlug plug)
		{
			if (!Object.op_Implicit((Object)(object)plug))
			{
				return false;
			}
			Socket lastSocket = ((AlignPlug)plug)._lastSocket;
			if (Object.op_Implicit((Object)(object)lastSocket) && (Object)(object)lastSocket.LockedPlug == (Object)(object)plug)
			{
				return true;
			}
			return false;
		}

		public static bool EnteringOrInside(this MagazinePlug plug)
		{
			if (!((AlignPlug)plug)._isEnterTransition)
			{
				return plug.InGun();
			}
			return true;
		}

		public static void ForceEject(this MagazinePlug plug)
		{
			try
			{
				((AlignPlug)plug).EjectPlug();
				((AlignPlug)plug).ClearFromSocket();
			}
			catch
			{
			}
			((Component)plug.magazine).gameObject.SetActive(true);
			((Component)plug.magazine).transform.parent = null;
			((AlignPlug)plug)._isEnterTransition = false;
			((AlignPlug)plug)._isExitTransition = false;
			((AlignPlug)plug)._isExitComplete = true;
		}
	}
	[HarmonyPatch(typeof(MagazinePlug), "OnPlugExitComplete")]
	public static class PlugExitPatch
	{
		public static void Postfix(MagazinePlug __instance)
		{
			TransformSyncable orAdd = TransformSyncable.cache.GetOrAdd(((Component)__instance.magazine).gameObject);
			if (!Object.op_Implicit((Object)(object)orAdd) || !orAdd.IsOwner())
			{
				return;
			}
			Gun componentInParent = ((Component)((Il2CppObjectBase)((AlignPlug)__instance)._lastSocket).Cast<MagazineSocket>()).GetComponentInParent<Gun>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				TransformSyncable orAdd2 = TransformSyncable.cache.GetOrAdd(((Component)componentInParent).gameObject);
				if (Object.op_Implicit((Object)(object)orAdd2) && orAdd2.IsOwner())
				{
					MagazinePlugMessageData data = new MagazinePlugMessageData
					{
						magId = orAdd.objectId,
						gunId = orAdd2.objectId,
						isInsert = false
					};
					NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.MagazinePlug, data);
					Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, networkMessage.GetBytes());
				}
			}
		}
	}
	[HarmonyPatch(typeof(MagazinePlug), "OnPlugInsertComplete")]
	public static class PlugEnterPatch
	{
		public static void Postfix(MagazinePlug __instance)
		{
			TransformSyncable orAdd = TransformSyncable.cache.GetOrAdd(((Component)__instance.magazine).gameObject);
			if (!Object.op_Implicit((Object)(object)orAdd) || !orAdd.IsOwner())
			{
				return;
			}
			Gun componentInParent = ((Component)((Il2CppObjectBase)((AlignPlug)__instance)._lastSocket).Cast<MagazineSocket>()).GetComponentInParent<Gun>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				TransformSyncable orAdd2 = TransformSyncable.cache.GetOrAdd(((Component)componentInParent).gameObject);
				if (Object.op_Implicit((Object)(object)orAdd2) && orAdd2.IsOwner())
				{
					MagazinePlugMessageData data = new MagazinePlugMessageData
					{
						magId = orAdd.objectId,
						gunId = orAdd2.objectId,
						isInsert = true
					};
					NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.MagazinePlug, data);
					Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, networkMessage.GetBytes());
				}
			}
		}
	}
	[HarmonyPatch(typeof(StabPoint), "SpawnStab")]
	public class StabPatch
	{
		public static void Postfix(StabPoint __instance, Transform tran, Collision c, float stabForce, ImpactProperties surfaceProperties)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Object.op_Implicit((Object)(object)__instance.rb))
				{
					TransformSyncable transformSyncable = TransformSyncable.cache.Get(((Component)__instance.rb).gameObject);
					if (Object.op_Implicit((Object)(object)transformSyncable) && !transformSyncable.IsOwner())
					{
						return;
					}
				}
				string name = ((Object)((Component)surfaceProperties).transform.root).name;
				if (name.Contains("PlayerRep"))
				{
					string[] array = name.Split(new char[1] { '.' });
					if (array.Length < 2)
					{
						throw new IndexOutOfRangeException();
					}
					ulong userId = ulong.Parse(array[1]);
					byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.PlayerAttack, new PlayerAttackMessageData
					{
						attackType = (AttackType)32,
						attackDamage = __instance.damage * ((ImpactPropertiesVariables)surfaceProperties).FireResistance
					}).GetBytes();
					Node.activeNode.SendMessage(userId, NetworkChannel.Attack, bytes);
				}
			}
			catch
			{
			}
		}
	}
	public static class Pool_Settings
	{
		public static List<Poolee> GetAllPoolees(this Pool pool)
		{
			if (!ObjectSync.poolPairs.TryGetValue(pool, out var value))
			{
				value = new List<Poolee>();
				ObjectSync.poolPairs.Add(pool, value);
			}
			return value;
		}

		public static float GetRelativeSpawnTime(this Poolee poolee)
		{
			if (!Object.op_Implicit((Object)(object)poolee.pool))
			{
				return -1f;
			}
			float num = (((Component)poolee).gameObject.activeInHierarchy ? poolee.timeSpawned : 0f);
			return (float)poolee.pool._timeOfLastSpawn - num;
		}

		public static Poolee GetAccuratePoolee(this Pool pool, int index, float relativeTime = -1f)
		{
			List<Poolee> allPoolees = pool.GetAllPoolees();
			if (allPoolees.Count <= 0)
			{
				return null;
			}
			Poolee result = null;
			if (relativeTime < 0f)
			{
				return allPoolees[Math.Min(index, allPoolees.Count() - 1)];
			}
			int num = -1;
			float num2 = -1f;
			for (int i = 0; i < allPoolees.Count(); i++)
			{
				Poolee val = allPoolees[i];
				float relativeSpawnTime = val.GetRelativeSpawnTime();
				if (!(Mathf.Abs(relativeSpawnTime - relativeTime) > Mathf.Abs(num2 - relativeTime)) && Math.Abs(i - index) <= Math.Abs(num - index))
				{
					num = i;
					num2 = relativeSpawnTime;
					result = val;
				}
			}
			return result;
		}
	}
	[HarmonyPatch(typeof(Poolee), "OnCleanup")]
	public static class CleanupPatch
	{
		public static void Prefix(Poolee __instance, ref SimplifiedTransform __state)
		{
			__state = new SimplifiedTransform(((Component)__instance).transform);
		}

		public static void Postfix(Poolee __instance, ref SimplifiedTransform __state)
		{
			__state.Apply(((Component)__instance).transform);
		}
	}
	[HarmonyPatch(typeof(Pool), "InstantiatePoolee")]
	public static class InstantiatePatch
	{
		[CompilerGenerated]
		private sealed class <OnSpawnClient>d__3 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject spawnedObject;

			private int <i>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnSpawnClient>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (SceneLoader.loading)
					{
						goto IL_0042;
					}
					goto IL_0049;
				case 1:
					<>1__state = -1;
					goto IL_0042;
				case 2:
					{
						<>1__state = -1;
						if (Object.op_Implicit((Object)(object)spawnedObject))
						{
							spawnedObject.SetActive(false);
						}
						<i>5__2++;
						break;
					}
					IL_0049:
					<i>5__2 = 0;
					break;
					IL_0042:
					if (SceneLoader.loading)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					goto IL_0049;
				}
				if (<i>5__2 < 2)
				{
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <OnSpawnHost>d__4 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject spawnedObject;

			public Pool pool;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnSpawnHost>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
				}
				else
				{
					<>1__state = -1;
					if (!SceneLoader.loading)
					{
						goto IL_004d;
					}
				}
				if (SceneLoader.loading)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (!spawnedObject.activeInHierarchy)
				{
					return false;
				}
				goto IL_004d;
				IL_004d:
				ushort num2 = ++ObjectSync.lastId;
				Rigidbody[] array = Il2CppArrayBase<Rigidbody>.op_Implicit(spawnedObject.GetComponentsInChildren<Rigidbody>());
				byte rbCount = (byte)array.Length;
				for (ushort num3 = 0; num3 < array.Length; num3++)
				{
					GameObject gameObject = ((Component)array[num3]).gameObject;
					ushort num4 = (ushort)(num3 + num2);
					TransformSyncable orAdd = TransformSyncable.cache.GetOrAdd(gameObject);
					if (Object.op_Implicit((Object)(object)orAdd))
					{
						ObjectSync.MoveSyncable(orAdd, num4);
						orAdd.ClearOwner();
						orAdd.TrySetStale(SteamIntegration.hostUser.m_SteamID);
					}
					else
					{
						TransformSyncable.CreateSync(SteamIntegration.hostUser.m_SteamID, ComponentCacheExtensions.m_RigidbodyCache.GetOrAdd(gameObject), num4);
					}
					ObjectSync.lastId = num4;
				}
				SpawnClientMessageData data = new SpawnClientMessageData
				{
					rbCount = rbCount,
					spawnId = num2,
					title = SpawnManager.GetPoolTitle(pool),
					transform = new SimplifiedTransform(spawnedObject.transform)
				};
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.SpawnClient, data);
				Node.activeNode.BroadcastMessage(NetworkChannel.Object, networkMessage.GetBytes());
				PooleeSyncable pooleeSyncable = spawnedObject.AddComponent<PooleeSyncable>();
				pooleeSyncable.id = num2;
				pooleeSyncable.transforms = Il2CppArrayBase<TransformSyncable>.op_Implicit(spawnedObject.GetComponentsInChildren<TransformSyncable>(true));
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static bool Prefix(Pool __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance.Prefab))
			{
				return false;
			}
			return true;
		}

		public static void Postfix(Pool __instance, Poolee __result, Vector3 position, Quaternion rotation)
		{
			if (__instance.IsBlacklisted())
			{
				return;
			}
			try
			{
				if (!__instance._pooledObjects.Contains(__result))
				{
					return;
				}
				if (!ObjectSync.poolPairs.TryGetValue(__instance, out var value))
				{
					value = new List<Poolee>();
					if (ObjectSync.poolPairs.ContainsKey(__instance))
					{
						ObjectSync.poolPairs[__instance] = value;
					}
					else
					{
						ObjectSync.poolPairs.Add(__instance, value);
					}
				}
				if (!value.Contains(__result))
				{
					value.Add(__result);
					__result.onSpawnDelegate = ((Il2CppObjectBase)Delegate.Combine((Delegate)(object)__result.onSpawnDelegate, (Delegate)(object)Action<GameObject>.op_Implicit((Action<GameObject>)delegate(GameObject go)
					{
						OnSpawn(go, __instance);
					}))).Cast<Action<GameObject>>();
				}
			}
			catch
			{
			}
		}

		public static void OnSpawn(GameObject spawnedObject, Pool pool)
		{
			if (!SteamIntegration.hasLobby || SpawnManager.SpawnOverride)
			{
				return;
			}
			PooleeSyncable pooleeSyncable = PooleeSyncable._Cache.Get(spawnedObject);
			if (Object.op_Implicit((Object)(object)pooleeSyncable))
			{
				if (Node.isServer)
				{
					pooleeSyncable.SetOwner(SteamIntegration.currentUser.m_SteamID);
					SpawnTransferMessageData data = new SpawnTransferMessageData
					{
						spawnId = pooleeSyncable.id,
						transform = new SimplifiedTransform(spawnedObject.transform)
					};
					NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.SpawnTransfer, data);
					Node.activeNode.BroadcastMessage(NetworkChannel.Object, networkMessage.GetBytes());
				}
			}
			else if (Node.isServer)
			{
				MelonCoroutines.Start(OnSpawnHost(spawnedObject, pool));
			}
			else
			{
				MelonCoroutines.Start(OnSpawnClient(spawnedObject));
			}
		}

		[IteratorStateMachine(typeof(<OnSpawnClient>d__3))]
		public static IEnumerator OnSpawnClient(GameObject spawnedObject)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnSpawnClient>d__3(0)
			{
				spawnedObject = spawnedObject
			};
		}

		[IteratorStateMachine(typeof(<OnSpawnHost>d__4))]
		public static IEnumerator OnSpawnHost(GameObject spawnedObject, Pool pool)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnSpawnHost>d__4(0)
			{
				spawnedObject = spawnedObject,
				pool = pool
			};
		}
	}
	[HarmonyPatch(typeof(SpawnGun), "OnFire")]
	public class SpawnFirePatch
	{
		[CompilerGenerated]
		private sealed class <SpawnGunFire>d__1 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public SpawnGun __instance;

			private SpawnableObject <spawnable>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnGunFire>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<spawnable>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<spawnable>5__2 = __instance._selectedSpawnable;
					if ((int)__instance._selectedMode != 0 || !Object.op_Implicit((Object)(object)<spawnable>5__2))
					{
						return false;
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
				{
					<>1__state = -1;
					Pool pool = PoolManager.GetPool(<spawnable>5__2.title);
					if (!Object.op_Implicit((Object)(object)pool))
					{
						return false;
					}
					Poolee lastSpawn = pool._lastSpawn;
					if (!Object.op_Implicit((Object)(object)lastSpawn))
					{
						return false;
					}
					if (!Node.isServer)
					{
						Transform transform = ((Component)lastSpawn).transform;
						Vector3 position = transform.position;
						Quaternion rotation = transform.rotation;
						SpawnRequestMessageData data = new SpawnRequestMessageData
						{
							title = <spawnable>5__2.title,
							transform = new SimplifiedTransform(position, rotation)
						};
						NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.SpawnRequest, data);
						Node.activeNode.BroadcastMessage(NetworkChannel.Object, networkMessage.GetBytes());
						((Component)lastSpawn).gameObject.SetActive(false);
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static void Postfix(SpawnGun __instance)
		{
			if (SteamIntegration.hasLobby)
			{
				MelonCoroutines.Start(SpawnGunFire(__instance));
			}
		}

		[IteratorStateMachine(typeof(<SpawnGunFire>d__1))]
		public static IEnumerator SpawnGunFire(SpawnGun __instance)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnGunFire>d__1(0)
			{
				__instance = __instance
			};
		}
	}
	[HarmonyPatch(typeof(Player_Health), "TAKEDAMAGE")]
	public static class PlayerDamagePatch
	{
		public static bool Prefix(Player_Health __instance, float damage, bool crit)
		{
			if (!__instance.alive)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Hand), "AttachObject")]
	public static class GripAttachPatch
	{
		public static void Prefix(Hand __instance, GameObject objectToAttach)
		{
			ObjectSync.OnGripAttached(objectToAttach);
		}
	}
	[HarmonyPatch(typeof(Hand), "DetachObject")]
	public static class GripDetachPatch
	{
		public static void Prefix(Hand __instance, GameObject objectToDetach, bool restoreOriginalParent = true)
		{
			try
			{
				ObjectSync.OnGripDetached(__instance);
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(HandSFX), "PunchAttack")]
	public static class PunchPatch
	{
		public static void Postfix(HandSFX __instance, Collision c, float impulse, float relVelSqr)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Object)c.gameObject.transform.root).name;
			if (name.Contains("PlayerRep"))
			{
				string[] array = name.Split(new char[1] { '.' });
				if (array.Length < 2)
				{
					throw new IndexOutOfRangeException();
				}
				ulong userId = ulong.Parse(array[1]);
				byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.PlayerAttack, new PlayerAttackMessageData
				{
					attackType = (AttackType)2,
					attackDamage = (int)(ushort)(impulse / 5f)
				}).GetBytes();
				Node.activeNode.SendMessage(userId, NetworkChannel.Attack, bytes);
			}
		}
	}
	[HarmonyPatch(typeof(SkeletonHand), "SetHandPose")]
	public static class PosePatch
	{
		public static int prevLeftPose;

		public static int prevRightPose;

		public static void Postfix(SkeletonHand __instance, string handPoseName)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			//IL_002a: Invalid comparison between Unknown and I4
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)__instance.GetCharacterAnimationManager()))
			{
				return;
			}
			int num = ((Il2CppArrayBase<string>)(object)PlayerScripts.playerHandPoses).IndexOf(handPoseName);
			if (num > -1)
			{
				Handedness handedness = __instance.handedness;
				bool flag = true;
				if ((int)handedness == 1)
				{
					flag = prevLeftPose != num;
					prevLeftPose = num;
				}
				else
				{
					flag = prevRightPose != num;
					prevRightPose = num;
				}
				if (flag)
				{
					HandPoseChangeMessageData handPoseChangeMessageData = new HandPoseChangeMessageData();
					handPoseChangeMessageData.userId = SteamIntegration.currentUser.m_SteamID;
					handPoseChangeMessageData.hand = handedness;
					handPoseChangeMessageData.poseIndex = (ushort)num;
					byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.HandPose, handPoseChangeMessageData).GetBytes();
					Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
				}
			}
		}
	}
	[HarmonyPatch(typeof(SkeletonHand), "SetCylinderRadius")]
	public static class GripRadiusPatch
	{
		public static float prevLeftRadius;

		public static float prevRightRadius;

		public static void Postfix(SkeletonHand __instance, float radius)
		{
			//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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0056: 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)
			if (!Object.op_Implicit((Object)(object)__instance.GetCharacterAnimationManager()))
			{
				return;
			}
			Handedness handedness = __instance.handedness;
			if ((int)handedness != 1)
			{
				if ((int)handedness == 2)
				{
					if (radius == prevRightRadius)
					{
						return;
					}
					prevRightRadius = radius;
				}
			}
			else
			{
				if (radius == prevLeftRadius)
				{
					return;
				}
				prevLeftRadius = radius;
			}
			GripRadiusMessageData gripRadiusMessageData = new GripRadiusMessageData();
			gripRadiusMessageData.userId = SteamIntegration.currentUser.m_SteamID;
			gripRadiusMessageData.hand = handedness;
			gripRadiusMessageData.radius = radius;
			byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.GripRadius, gripRadiusMessageData).GetBytes();
			Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
		}
	}
	[HarmonyPatch(typeof(HandWeaponSlotReciever), "MakeStatic")]
	public static class WeaponInsertPatch
	{
		public static void Prefix(this HandWeaponSlotReciever __instance)
		{
			TransformSyncable transformSyncable;
			if (SteamIntegration.hasLobby && Object.op_Implicit((Object)(object)(transformSyncable = TransformSyncable.cache.Get(((Component)__instance.m_WeaponHost.rb).gameObject))))
			{
				TransformCollisionMessageData data = new TransformCollisionMessageData
				{
					objectId = transformSyncable.objectId,
					enabled = false
				};
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.TransformCollision, data);
				Node.activeNode.BroadcastMessage(NetworkChannel.Object, networkMessage.GetBytes());
			}
		}
	}
	[HarmonyPatch(typeof(HandWeaponSlotReciever), "MakeDynamic")]
	public static class WeaponExitPatch
	{
		public static void Prefix(this HandWeaponSlotReciever __instance)
		{
			TransformSyncable transformSyncable;
			if (SteamIntegration.hasLobby && Object.op_Implicit((Object)(object)(transformSyncable = TransformSyncable.cache.Get(((Component)__instance.m_WeaponHost.rb).gameObject))))
			{
				TransformCollisionMessageData data = new TransformCollisionMessageData
				{
					objectId = transformSyncable.objectId,
					enabled = true
				};
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.TransformCollision, data);
				Node.activeNode.BroadcastMessage(NetworkChannel.Object, networkMessage.GetBytes());
			}
		}
	}
	public static class ZombieMode_Settings
	{
		public static bool m_invalidSettings;

		public static void SetDifficulty(this Zombie_GameControl __instance, Difficulty dif)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected I4, but got Unknown
			__instance.difficulty = dif;
			__instance.gamePageDiffText.text = ((object)(Difficulty)(ref dif)).ToString();
			__instance.diffText.text = $"DIFFICULTY: {dif}";
			string text = (int)dif switch
			{
				1 => __instance.medDesc, 
				2 => __instance.hardDesc, 
				3 => __instance.harderDesc, 
				4 => __instance.hardestDesc, 
				_ => __instance.easyDesc, 
			};
			__instance.diffDescriptionText.text = text;
		}
	}
	[HarmonyPatch(typeof(Zombie_GameControl), "SetGameMode")]
	public class GameModePatch
	{
		public static void Postfix(Zombie_GameControl __instance, int mode)
		{
			if (!ZombieMode_Settings.m_invalidSettings)
			{
				byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.ZombieMode, new ZombieModeMessageData
				{
					mode = (byte)mode
				}).GetBytes();
				Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
			}
			ZombieMode_Settings.m_invalidSettings = false;
		}
	}
	[HarmonyPatch(typeof(Zombie_GameControl), "ToggleLoadout")]
	public class ToggleLoadoutPatch
	{
		public static void Postfix(Zombie_GameControl __instance, int loadIndex)
		{
			if (!ZombieMode_Settings.m_invalidSettings)
			{
				byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.ZombieLoadout, new ZombieLoadoutMessageData
				{
					loadIndex = (byte)loadIndex
				}).GetBytes();
				Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
			}
			ZombieMode_Settings.m_invalidSettings = false;
		}
	}
	[HarmonyPatch(typeof(Zombie_GameControl), "ToggleDifficulty")]
	public class ToggleDifficultyPatch
	{
		public static void Postfix(Zombie_GameControl __instance)
		{
			//IL_000c: 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)
			byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.ZombieDiff, new ZombieDifficultyMessageData
			{
				difficulty = __instance.difficulty
			}).GetBytes();
			Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
		}
	}
	[HarmonyPatch(typeof(Zombie_GameControl), "StartSelectedMode")]
	public class ZombieStartPatch
	{
		public static void Postfix(Zombie_GameControl __instance)
		{
			if (!ZombieMode_Settings.m_invalidSettings)
			{
				byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.ZombieStart, new EmptyMessageData()).GetBytes();
				Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, bytes);
			}
		}
	}
	public static class ZoneTrackingUtilities
	{
		public static Dictionary<SceneZone, int> zoneCount = new Dictionary<SceneZone, int>((IEqualityComparer<SceneZone>?)new UnityComparer());

		public static Dictionary<PlayerTrigger, int> triggerCount = new Dictionary<PlayerTrigger, int>((IEqualityComparer<PlayerTrigger>?)new UnityComparer());

		public static void Increment(SceneZone zone)
		{
			if (!zoneCount.ContainsKey(zone))
			{
				zoneCount.Add(zone, 0);
			}
			zoneCount[zone]++;
		}

		public static void Decrement(SceneZone zone)
		{
			if (!zoneCount.ContainsKey(zone))
			{
				zoneCount.Add(zone, 0);
			}
			zoneCount[zone]--;
			zoneCount[zone] = Mathf.Clamp(zoneCount[zone], 0, int.MaxValue);
		}

		public static bool CanEnter(SceneZone zone)
		{
			if (!zoneCount.ContainsKey(zone))
			{
				return false;
			}
			return zoneCount[zone] <= 1;
		}

		public static bool CanExit(SceneZone zone)
		{
			if (!zoneCount.ContainsKey(zone))
			{
				return false;
			}
			return zoneCount[zone] <= 0;
		}

		public static void Increment(PlayerTrigger trigger)
		{
			if (!triggerCount.ContainsKey(trigger))
			{
				triggerCount.Add(trigger, 0);
			}
			triggerCount[trigger]++;
		}

		public static void Decrement(PlayerTrigger trigger)
		{
			if (!triggerCount.ContainsKey(trigger))
			{
				triggerCount.Add(trigger, 0);
			}
			triggerCount[trigger]--;
			triggerCount[trigger] = Mathf.Clamp(triggerCount[trigger], 0, int.MaxValue);
		}

		public static bool CanEnter(PlayerTrigger trigger)
		{
			if (!triggerCount.ContainsKey(trigger))
			{
				return false;
			}
			return triggerCount[trigger] <= 1;
		}

		public static bool CanExit(PlayerTrigger trigger)
		{
			if (!triggerCount.ContainsKey(trigger))
			{
				return false;
			}
			return triggerCount[trigger] <= 0;
		}
	}
	[HarmonyPatch(typeof(SceneZone), "OnTriggerEnter")]
	public static class ZoneEnterPatch
	{
		public static bool Prefix(SceneZone __instance, Collider other)
		{
			if (((Component)other).CompareTag("Player"))
			{
				ZoneTrackingUtilities.Increment(__instance);
				return ZoneTrackingUtilities.CanEnter(__instance);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SceneZone), "OnTriggerExit")]
	public static class ZoneExitPatch
	{
		public static bool Prefix(SceneZone __instance, Collider other)
		{
			if (((Component)other).CompareTag("Player"))
			{
				ZoneTrackingUtilities.Decrement(__instance);
				return ZoneTrackingUtilities.CanExit(__instance);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerTrigger), "OnTriggerEnter")]
	public static class PlayerTriggerEnterPatch
	{
		public static bool Prefix(PlayerTrigger __instance, Collider other)
		{
			if (((Component)other).CompareTag("Player"))
			{
				ZoneTrackingUtilities.Increment(__instance);
				return ZoneTrackingUtilities.CanEnter(__instance);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerTrigger), "OnTriggerExit")]
	public static class PlayerTriggerExitPatch
	{
		public static bool Prefix(PlayerTrigger __instance, Collider other)
		{
			if (((Component)other).CompareTag("Player"))
			{
				ZoneTrackingUtilities.Decrement(__instance);
				return ZoneTrackingUtilities.CanExit(__instance);
			}
			return true;
		}
	}
}
namespace Entanglement.Objects
{
	public static class ObjectBlacklist
	{
		private static string[] blacklistedObjects = new string[1] { "[RigManager (Default Brett)]" };

		public static bool IsBlacklisted(this GameObject obj)
		{
			for (int i = 0; i < blacklistedObjects.Length; i++)
			{
				if (obj.transform.InHierarchyOf(blacklistedObjects[i]))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class ObjectSync
	{
		[CompilerGenerated]
		private sealed class <OnGripValid>d__13 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject grip;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnGripValid>d__13(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
				{
					<>1__state = -1;
					if (!Object.op_Implicit((Object)(object)grip) || !grip.activeInHierarchy)
					{
						return false;
					}
					if (grip.IsBlacklisted())
					{
						return false;
					}
					Rigidbody[] rigidbodies = null;
					GetPooleeData(grip.transform, out rigidbodies, out var overrideRootName, out var spawnIndex, out var spawnTime);
					for (int i = 0; i < rigidbodies.Length; i++)
					{
						SyncUtilities.UpdateBodyAttached(rigidbodies[i], overrideRootName, spawnIndex, spawnTime);
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static Dictionary<Pool, List<Poolee>> poolPairs = new Dictionary<Pool, List<Poolee>>((IEqualityComparer<Pool>?)new UnityComparer());

		public static Dictionary<ushort, Syncable> syncedObjects = new Dictionary<ushort, Syncable>();

		public static List<Syncable> queuedSyncs = new List<Syncable>();

		public static ushort lastId = 0;

		public static void OnCleanup()
		{
			try
			{
				RemoveObjects();
			}
			catch
			{
			}
			lastId = 0;
		}

		public static void RemoveObjects()
		{
			foreach (Syncable value in syncedObjects.Values)
			{
				try
				{
					value.Cleanup();
				}
				catch
				{
				}
			}
			syncedObjects.Clear();
			queuedSyncs.Clear();
			TransformSyncable.cache = new CustomComponentCache<TransformSyncable>();
			TransformSyncable.DestructCache = new CustomComponentCache<TransformSyncable>();
		}

		public static void MoveSyncable(Syncable syncable, ushort newId)
		{
			syncedObjects.Remove(syncable.objectId);
			syncedObjects.Remove(newId);
			syncedObjects.Add(newId, syncable);
			syncable.objectId = newId;
		}

		public static void RegisterSyncable(Syncable syncable, ushort objectId)
		{
			if (syncedObjects.ContainsKey(objectId))
			{
				if ((Object)(object)syncedObjects[objectId] != (Object)(object)syncable)
				{
					syncedObjects[objectId].Cleanup();
				}
				syncedObjects.Remove(objectId);
			}
			syncedObjects.Add(objectId, syncable);
			lastId = objectId;
		}

		public static ushort QueueSyncable(Syncable syncable)
		{
			int num = queuedSyncs.IndexOf(syncable);
			if (num >= 0)
			{
				queuedSyncs.RemoveAt(num);
			}
			queuedSyncs.Add(syncable);
			return (ushort)(queuedSyncs.Count - 1);
		}

		public static bool TryGetSyncable(ushort id, out Syncable syncable)
		{
			return syncedObjects.TryGetValue(id, out syncable);
		}

		public static void GetPooleeData(Transform obj, out Rigidbody[] rigidbodies, out string overrideRootName, out short spawnIndex, out float spawnTime)
		{
			Transform root = ((Component)obj).transform.root;
			overrideRootName = null;
			spawnIndex = -1;
			spawnTime = -1f;
			rigidbodies = null;
			Magazine val = Magazine.Cache.Get(((Component)root).gameObject);
			if (Object.op_Implicit((Object)(object)val))
			{
				SpawnableObject spawnableObject = val.magazineData.spawnableObject;
				if (Object.op_Implicit((Object)(object)spawnableObject))
				{
					spawnTime = 0f;
					spawnIndex = 0;
					overrideRootName = spawnableObject.title;
					rigidbodies = root.GetChildBodies();
				}
				return;
			}
			Poolee objPoolee = Poolee.Cache.Get(((Component)root).gameObject);
			if (Object.op_Implicit((Object)(object)objPoolee))
			{
				Pool pool = objPoolee.pool;
				if (Object.op_Implicit((Object)(object)pool))
				{
					List<Poolee> allPoolees = pool.GetAllPoolees();
					spawnIndex = (short)allPoolees.FindIndex((Poolee o) => (Object)(object)o == (Object)(object)objPoolee);
					spawnTime = objPoolee.GetRelativeSpawnTime();
					overrideRootName = ((Object)pool).name.Remove(0, 7);
				}
				rigidbodies = ((Component)objPoolee).transform.GetChildBodies();
			}
			else
			{
				rigidbodies = ((Component)obj).transform.GetJointedBodies();
			}
		}

		public static bool CheckForInstantiation(GameObject prefab, string poolName)
		{
			if (string.Equals(poolName, "nimbus gun", StringComparison.OrdinalIgnoreCase) || string.Equals(poolName, "utility gun", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return (Object)(object)prefab.GetComponent<Magazine>() != (Object)null;
		}

		public static void OnGripAttached(GameObject grip)
		{
			if (SteamIntegration.hasLobby)
			{
				MelonCoroutines.Start(OnGripValid(grip));
			}
		}

		[IteratorStateMachine(typeof(<OnGripValid>d__13))]
		public static IEnumerator OnGripValid(GameObject grip)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnGripValid>d__13(0)
			{
				grip = grip
			};
		}

		public static void OnGripDetached(Hand __instance)
		{
			if (!SteamIntegration.hasLobby)
			{
				return;
			}
			GameObject currentAttachedObject = __instance.m_CurrentAttachedObject;
			if (!Object.op_Implicit((Object)(object)currentAttachedObject) || currentAttachedObject.IsBlacklisted())
			{
				return;
			}
			Rigidbody[] jointedBodies = currentAttachedObject.transform.GetJointedBodies();
			Rigidbody heldObject = __instance.otherHand.GetHeldObject();
			if (!Object.op_Implicit((Object)(object)heldObject) || !jointedBodies.Has<Rigidbody>(heldObject))
			{
				for (int i = 0; i < jointedBodies.Length; i++)
				{
					SyncUtilities.UpdateBodyDetached(jointedBodies[i]);
				}
			}
		}

		public static void OnForcePullCancelled(GameObject grip)
		{
			if (SteamIntegration.hasLobby && !grip.IsBlacklisted())
			{
				Rigidbody[] jointedBodies = grip.transform.GetJointedBodies();
				for (int i = 0; i < jointedBodies.Length; i++)
				{
					SyncUtilities.UpdateBodyDetached(jointedBodies[i]);
				}
			}
		}
	}
	[RegisterTypeInIl2Cpp]
	public class PooleeSyncable : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <CoOnSpawn>d__11 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public PooleeSyncable <>4__this;

			public SimplifiedTransform simplifiedTransform;

			public ulong ownerId;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CoOnSpawn>d__11(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				PooleeSyncable pooleeSyncable = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					((Component)pooleeSyncable).gameObject.SetActive(false);
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					simplifiedTransform.Apply(((Component)pooleeSyncable).transform);
					((Component)pooleeSyncable).gameObject.SetActive(true);
					pooleeSyncable.SetOwner(ownerId);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static CustomComponentCache<PooleeSyncable> _Cache = new CustomComponentCache<PooleeSyncable>();

		public static Dictionary<ushort, PooleeSyncable> _PooleeLookup = new Dictionary<ushort, PooleeSyncable>(new UnityComparer());

		public Poolee Poolee;

		public ushort id;

		public TransformSyncable[] transforms;

		public PooleeSyncable(IntPtr intPtr)
			: base(intPtr)
		{
		}

		public void Awake()
		{
			Poolee = ((Component)this).GetComponent<Poolee>();
			_Cache.Add(((Component)this).gameObject, this);
		}

		public void Start()
		{
			_PooleeLookup[id] = this;
		}

		public void OnDestroy()
		{
			_Cache.Remove(((Component)this).gameObject);
			_PooleeLookup.Remove(id);
		}

		public void OnSpawn(ulong ownerId, SimplifiedTransform simplifiedTransform)
		{
			MelonCoroutines.Start(CoOnSpawn(ownerId, simplifiedTransform));
		}

		public void SetOwner(ulong ownerId)
		{
			TransformSyncable[] array = transforms;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].ForceOwner(ownerId, checkForMag: false);
			}
		}

		[IteratorStateMachine(typeof(<CoOnSpawn>d__11))]
		public IEnumerator CoOnSpawn(ulong ownerId, SimplifiedTransform simplifiedTransform)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CoOnSpawn>d__11(0)
			{
				<>4__this = this,
				ownerId = ownerId,
				simplifiedTransform = simplifiedTransform
			};
		}
	}
	public static class SpawnManager
	{
		internal static bool SpawnOverride = false;

		private static readonly HashSet<string> BlacklistedPools = new HashSet<string> { "ProjectilePool", "AudioPlayer", "Utility Gun" };

		public static string GetPoolTitle(Pool pool)
		{
			return ((Object)pool).name.Remove(0, 7);
		}

		public static bool IsBlacklisted(this Pool pool)
		{
			string poolTitle = GetPoolTitle(pool);
			if (BlacklistedPools.Contains(poolTitle))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)pool.Prefab) && Object.op_Implicit((Object)(object)pool.Prefab.GetComponentInChildren<Rigidbody>()))
			{
				return pool.Prefab.HasBlacklistedComponent();
			}
			return true;
		}

		public static bool HasBlacklistedComponent(this GameObject prefab)
		{
			return Object.op_Implicit((Object)(object)prefab.GetComponentInChildren<Magazine>());
		}
	}
	[RegisterTypeInIl2Cpp]
	public abstract class Syncable : MonoBehaviour
	{
		public List<ulong> ownerQueue = new List<ulong>();

		public ulong staleOwner;

		public ulong lastOwner;

		public ushort objectId;

		public bool isValid;

		public Syncable(IntPtr intPtr)
			: base(intPtr)
		{
		}

		public virtual void RemoveFromQueue(ushort id)
		{
			if (!isValid)
			{
				objectId = id;
				isValid = true;
				ObjectSync.RegisterSyncable(this, id);
			}
		}

		public virtual bool ShouldSync()
		{
			return true;
		}

		public abstract void SyncUpdate();

		protected virtual void FixedUpdate()
		{
			if (isValid && IsOwner() && ShouldSync())
			{
				SyncUpdate();
			}
		}

		protected abstract void UpdateOwner(bool checkForMag = true);

		public virtual void EnqueueOwner(ulong owner)
		{
			if (!ownerQueue.Contains(owner))
			{
				ownerQueue.Add(owner);
			}
			UpdateStale();
			UpdateOwner();
		}

		public virtual void DequeueOwner(ulong owner)
		{
			if (ownerQueue.Contains(owner))
			{
				ownerQueue.Remove(owner);
			}
			UpdateStale();
			UpdateOwner();
		}

		public virtual void ClearOwner()
		{
			ownerQueue.Clear();
			lastOwner = staleOwner;
			staleOwner = 0uL;
		}

		public virtual void TrySetStale(ulong owner)
		{
			lastOwner = staleOwner;
			if (ownerQueue.Count == 0)
			{
				staleOwner = owner;
			}
			else
			{
				EnqueueOwner(owner);
			}
			UpdateOwner();
		}

		public virtual void ForceOwner(ulong owner, bool checkForMag = true)
		{
			lastOwner = staleOwner;
			ownerQueue.Clear();
			staleOwner = owner;
			UpdateOwner(checkForMag);
		}

		public virtual void SendEnqueue()
		{
		}

		public virtual void SendDequeue()
		{
		}

		public virtual void Cleanup()
		{
			Object.Destroy((Object)(object)this);
		}

		public void UpdateStale()
		{
			lastOwner = staleOwner;
			if (ownerQueue.Count > 0)
			{
				staleOwner = ownerQueue[0];
			}
		}

		public bool IsOwner()
		{
			return staleOwner == SteamIntegration.currentUser.m_SteamID;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class TransformSyncable : Syncable
	{
		public enum GripEventType : byte
		{
			AttachedEvent,
			DetachEvent,
			PrimaryButtonEventDown,
			PrimaryButtonEvent,
			PrimaryButtonEventUp
		}

		[CompilerGenerated]
		private sealed class <WaitUntilValid>d__53 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public TransformSyncable <>4__this;

			public Action onFinish;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitUntilValid>d__53(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				TransformSyncable transformSyncable = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!transformSyncable.isValid)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				onFinish?.Invoke();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static CustomComponentCache<TransformSyncable> DestructCache = new CustomComponentCache<TransformSyncable>();

		public Prop_Health _CachedHealth;

		public ObjectDestructable _CachedDestructable;

		public float objectHealth;

		public GripEvents[] events;

		private bool ignoreThisFrame;

		public static CustomComponentCache<TransformSyncable> cache = new CustomComponentCache<TransformSyncable>();

		public Rigidbody rb;

		public Rigidbody[] _CachedBodies;

		public Vector3 lastPosition;

		public Quaternion lastRotation;

		public Rigidbody targetBody;

		public GameObject targetGo;

		public ConfigurableJoint syncJoint;

		public Gun _CachedGun;

		public MagazinePlug _CachedPlug;

		public float startDrag = -1f;

		public float startAngularDrag = -1f;

		public const float positionSpring = 250000f;

		public const float positionDamper = 15000f;

		public const float maximumForce = 150000f;

		public const float linearLimit = 0.005f;

		protected float timeOfDisable;

		private TransformSyncMessageData _cachedSyncData;

		public void SetHealth(float health)
		{
			if (Object.op_Implicit((Object)(object)_CachedDestructable))
			{
				_CachedDestructable._health = health;
			}
			if (Object.op_Implicit((Object)(object)_CachedHealth))
			{
				_CachedHealth.cur_Health = health;
			}
		}

		public float GetHealth()
		{
			if (Object.op_Implicit((Object)(object)_CachedDestructable))
			{
				return _CachedDestructable._health;
			}
			if (Object.op_Implicit((Object)(object)_CachedHealth))
			{
				return _CachedHealth.cur_Health;
			}
			return 0f;
		}

		public void Destruct()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_CachedDestructable))
			{
				_CachedDestructable._health = 0f;
				_CachedDestructable.TakeDamage(Vector3.up, 10f, true, (AttackType)64);
			}
			if (Object.op_Implicit((Object)(object)_CachedHealth))
			{
				_CachedHealth.TIMEDKILL();
			}
			timeOfDisable = Time.realtimeSinceStartup;
		}

		public void SetupEvents()
		{
			for (byte b = 0; b < events.Length; b++)
			{
				GripEvents grip = events[b];
				Action action = delegate
				{
					AttachedEvent(grip);
				};
				Action action2 = delegate
				{
					DetachEvent(grip);
				};
				Action action3 = delegate
				{
					PrimaryButtonEventDown(grip);
				};
				Action action4 = delegate
				{
					PrimaryButtonEvent(grip);
				};
				Action action5 = delegate
				{
					PrimaryButtonEventUp(grip);
				};
				UnityEvent attachedEvent = grip.AttachedEvent;
				if (attachedEvent != null)
				{
					attachedEvent.AddListener(UnityAction.op_Implicit(action));
				}
				UnityEvent detachEvent = grip.DetachEvent;
				if (detachEvent != null)
				{
					detachEvent.AddListener(UnityAction.op_Implicit(action2));
				}
				UnityEvent primaryButtonEventDown = grip.PrimaryButtonEventDown;
				if (primaryButtonEventDown != null)
				{
					primaryButtonEventDown.AddListener(UnityAction.op_Implicit(action3));
				}
				UnityEvent primaryButtonEvent = grip.PrimaryButtonEvent;
				if (primaryButtonEvent != null)
				{
					primaryButtonEvent.AddListener(UnityAction.op_Implicit(action4));
				}
				UnityEvent primaryButtonEventUp = grip.PrimaryButtonEventUp;
				if (primaryButtonEventUp != null)
				{
					primaryButtonEventUp.AddListener(UnityAction.op_Implicit(action5));
				}
			}
		}

		public void CallEvent(GripEventType type, byte idx)
		{
			if (events.Length <= idx)
			{
				return;
			}
			GripEvents val = events[idx];
			ignoreThisFrame = true;
			try
			{
				switch (type)
				{
				default:
				{
					UnityEvent attachedEvent = val.AttachedEvent;
					if (attachedEvent != null)
					{
						attachedEvent.Invoke();
					}
					break;
				}
				case GripEventType.DetachEvent:
				{
					UnityEvent detachEvent = val.DetachEvent;
					if (detachEvent != null)
					{
						detachEvent.Invoke();
					}
					break;
				}
				case GripEventType.PrimaryButtonEvent:
				{
					UnityEvent primaryButtonEvent = val.PrimaryButtonEvent;
					if (primaryButtonEvent != null)
					{
						primaryButtonEvent.Invoke();
					}
					break;
				}
				case GripEventType.PrimaryButtonEventDown:
				{
					UnityEvent primaryButtonEventDown = val.PrimaryButtonEventDown;
					if (primaryButtonEventDown != null)
					{
						primaryButtonEventDown.Invoke();
					}
					break;
				}
				case GripEventType.PrimaryButtonEventUp:
				{
					UnityEvent primaryButtonEventUp = val.PrimaryButtonEventUp;
					if (primaryButtonEventUp != null)
					{
						primaryButtonEventUp.Invoke();
					}
					break;
				}
				}
			}
			catch
			{
			}
			ignoreThisFrame = false;
		}

		public void AttachedEvent(GripEvents grip)
		{
			SendEvent(GripEventType.AttachedEvent, grip);
		}

		public void DetachEvent(GripEvents grip)
		{
			SendEvent(GripEventType.DetachEvent, grip);
		}

		public void PrimaryButtonEventDown(GripEvents grip)
		{
			SendEvent(GripEventType.PrimaryButtonEventDown, grip);
		}

		public void PrimaryButtonEvent(GripEvents grip)
		{
			SendEvent(GripEventType.PrimaryButtonEvent, grip);
		}

		public void PrimaryButtonEventUp(GripEvents grip)
		{
			SendEvent(GripEventType.PrimaryButtonEventUp, grip);
		}

		public void SendEvent(GripEventType type, GripEvents grip)
		{
			if (ignoreThisFrame)
			{
				return;
			}
			byte index = 0;
			bool flag = false;
			for (byte b = 0; b < events.Length; b++)
			{
				if ((Object)(object)grip == (Object)(object)events[b])
				{
					index = b;
					flag = true;
					break;
				}
			}
			if (flag)
			{
				GripEventMessageData data = new GripEventMessageData
				{
					objectId = objectId,
					index = index,
					type = type
				};
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.GripEvent, data);
				Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, networkMessage.GetBytes());
			}
		}

		public TransformSyncable(IntPtr intPtr)
			: base(intPtr)
		{
		}

		public override void Cleanup()
		{
			DestroyJoint();
			if (Object.op_Implicit((Object)(object)targetGo))
			{
				Object.Destroy((Object)(object)targetGo);
			}
			base.Cleanup();
		}

		public override void SyncUpdate()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be