Decompiled source of Entanglement Redux v1.2.1

EntanglementRedux.dll

Decompiled 2 months 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("EntanglementRedux")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: MelonInfo(typeof(EntanglementMod), "EntanglementRedux", "0.1.0", "willpsdk, 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.1.0.0")]
namespace Entanglement
{
	public static class EntangleLogger
	{
		public static bool isVerbose;

		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 Verbose(string txt, ConsoleColor txt_color = ConsoleColor.Gray)
		{
			if (isVerbose)
			{
				((MelonBase)EntanglementMod.Instance).LoggerInstance.Msg(txt_color, "[VERBOSE] " + txt);
			}
		}

		public static void Verbose(object obj, ConsoleColor txt_color = ConsoleColor.Gray)
		{
			if (isVerbose)
			{
				((MelonBase)EntanglementMod.Instance).LoggerInstance.Msg(txt_color, "[VERBOSE] " + obj.ToString());
			}
		}

		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
	{
		private static float lastDisconnectNotifTime = -10f;

		private const float DISCONNECT_NOTIF_COOLDOWN = 2f;

		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)
		{
			if (!(Time.time - lastDisconnectNotifTime < 2f))
			{
				lastDisconnectNotifTime = Time.time;
				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()
		{
			if (!(Time.time - lastDisconnectNotifTime < 2f))
			{
				lastDisconnectNotifTime = Time.time;
				Notifications.SendNotification("You left the server.", 4f);
			}
		}

		public static void ServerStarted()
		{
			Notifications.SendNotification("Server started!", 4f);
		}

		public static void ServerStopped()
		{
			Notifications.SendNotification("Server stopped!", 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 = null;

		public static Assembly entanglementAssembly;

		public static bool hasUnpatched = false;

		private static bool _isLevelChanging = false;

		private static float _levelChangeTimeout = 0f;

		private const float LEVEL_CHANGE_TIMEOUT = 10f;

		private static float _npcOptimizeTimer = 0f;

		private const float NPC_OPTIMIZE_INTERVAL = 2f;

		private static readonly HashSet<int> _optimizedNpcRoots = new HashSet<int>();

		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;
			}
			VoiceChatManager.Initialize();
			EntangleLogger.Log("Entanglement: Redux - Voice chat initialized!");
			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();
				PlayerRepresentation.SyncAnimationState();
				DataTransaction.Process();
				VoiceChatManager.Tick();
			}
		}

		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;
			}
			try
			{
				EntangleLogger.Log("═══════════════════════════════════════════════════════", ConsoleColor.Cyan);
				EntangleLogger.Log($"[LEVEL CHANGE] OnSceneWasInitialized: {sceneName} (Index: {buildIndex})", ConsoleColor.Cyan);
				EntangleLogger.Log("═══════════════════════════════════════════════════════", ConsoleColor.Cyan);
				try
				{
					ModuleHandler.OnSceneWasInitialized(buildIndex, sceneName);
				}
				catch (Exception ex)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error in ModuleHandler.OnSceneWasInitialized: " + ex.Message);
				}
				try
				{
					EntangleLogger.Log("[LEVEL CHANGE] Getting SpawnableData...", ConsoleColor.Yellow);
					SpawnableData.GetData();
					EntangleLogger.Log("[LEVEL CHANGE] ✓ SpawnableData loaded", ConsoleColor.Green);
				}
				catch (Exception ex2)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error loading SpawnableData: " + ex2.Message + "\n" + ex2.StackTrace);
				}
				try
				{
					EntangleLogger.Log("[LEVEL CHANGE] Getting PlayerScripts...", ConsoleColor.Yellow);
					PlayerScripts.GetPlayerScripts();
					EntangleLogger.Log("[LEVEL CHANGE] ✓ PlayerScripts initialized", ConsoleColor.Green);
				}
				catch (Exception ex3)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error initializing PlayerScripts: " + ex3.Message + "\n" + ex3.StackTrace);
				}
				try
				{
					EntangleLogger.Log("[LEVEL CHANGE] Getting PlayerTransforms...", ConsoleColor.Yellow);
					PlayerRepresentation.GetPlayerTransforms();
					EntangleLogger.Log("[LEVEL CHANGE] ✓ PlayerTransforms loaded", ConsoleColor.Green);
				}
				catch (Exception ex4)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error loading PlayerTransforms: " + ex4.Message + "\n" + ex4.StackTrace);
				}
				try
				{
					EntangleLogger.Log($"[LEVEL CHANGE] Recreating {PlayerRepresentation.representations.Count} player representations...", ConsoleColor.Yellow);
					foreach (PlayerRepresentation item in PlayerRepresentation.representations.Values.ToList())
					{
						try
						{
							item?.RecreateRepresentations();
						}
						catch (Exception ex5)
						{
							EntangleLogger.Error("[LEVEL CHANGE] Error recreating representation for " + item?.playerName + ": " + ex5.Message);
						}
					}
					EntangleLogger.Log("[LEVEL CHANGE] ✓ Player representations recreated", ConsoleColor.Green);
				}
				catch (Exception ex6)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error recreating player representations: " + ex6.Message + "\n" + ex6.StackTrace);
				}
				try
				{
					if (Client.instance != null)
					{
						Client.instance.currentScene = (byte)buildIndex;
						EntangleLogger.Log($"[LEVEL CHANGE] Client scene updated to: {buildIndex}", ConsoleColor.Yellow);
					}
				}
				catch (Exception ex7)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error updating client scene: " + ex7.Message);
				}
				try
				{
					sceneChange = (byte)buildIndex;
					SteamIntegration.targetScene = sceneName.ToLower();
					SteamIntegration.UpdateActivity();
					BroadcastLevelChangeImmediate((byte)buildIndex);
					EntangleLogger.Log($"[LEVEL CHANGE] Set sceneChange flag to {buildIndex}", ConsoleColor.Yellow);
				}
				catch (Exception ex8)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error setting scene change flag: " + ex8.Message);
				}
				_isLevelChanging = false;
				EntangleLogger.Log("[LEVEL CHANGE] Level change initialization complete - Scene ready for play", ConsoleColor.Green);
				EntangleLogger.Log("═══════════════════════════════════════════════════════", ConsoleColor.Cyan);
			}
			catch (Exception ex9)
			{
				EntangleLogger.Error("[LEVEL CHANGE] Critical error in OnSceneWasInitialized: " + ex9.Message + "\n" + ex9.StackTrace);
				_isLevelChanging = false;
			}
		}

		public override void BONEWORKS_OnLoadingScreen()
		{
			if (SteamIntegration.isInvalid)
			{
				return;
			}
			try
			{
				EntangleLogger.Log("═══════════════════════════════════════════════════════", ConsoleColor.Cyan);
				EntangleLogger.Log("[LEVEL CHANGE] BONEWORKS_OnLoadingScreen called - Beginning cleanup phase", ConsoleColor.Cyan);
				EntangleLogger.Log("═══════════════════════════════════════════════════════", ConsoleColor.Cyan);
				_isLevelChanging = true;
				_levelChangeTimeout = 10f;
				try
				{
					ModuleHandler.OnLoadingScreen();
				}
				catch (Exception ex)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error in ModuleHandler.OnLoadingScreen: " + ex.Message);
				}
				try
				{
					LoadingScreen.OverrideScreen();
				}
				catch (Exception ex2)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error overriding loading screen: " + ex2.Message);
				}
				EntangleLogger.Log("[LEVEL CHANGE] Module handlers and loading screen called", ConsoleColor.Yellow);
				try
				{
					EntangleLogger.Log("[LEVEL CHANGE] Clearing ObjectSync...", ConsoleColor.Yellow);
					ObjectSync.OnCleanup();
					ObjectSync.poolPairs.Clear();
					EntangleLogger.Log("[LEVEL CHANGE] ✓ ObjectSync cleared", ConsoleColor.Green);
				}
				catch (Exception ex3)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error clearing ObjectSync: " + ex3.Message + "\n" + ex3.StackTrace);
				}
				try
				{
					EntangleLogger.Log("[LEVEL CHANGE] Clearing StoryModeSync...", ConsoleColor.Yellow);
					StoryModeSync.ClearAll();
					EntangleLogger.Log("[LEVEL CHANGE] ✓ StoryModeSync cleared", ConsoleColor.Green);
				}
				catch (Exception ex4)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error clearing StoryModeSync: " + ex4.Message + "\n" + ex4.StackTrace);
				}
				try
				{
					EntangleLogger.Log("[LEVEL CHANGE] Clearing Poolee caches...", ConsoleColor.Yellow);
					if (PooleeSyncable._Cache != null)
					{
						PooleeSyncable._Cache.Clear();
					}
					if (PooleeSyncable._PooleeLookup != null)
					{
						PooleeSyncable._PooleeLookup.Clear();
					}
					EntangleLogger.Log("[LEVEL CHANGE] ✓ Poolee caches cleared", ConsoleColor.Green);
				}
				catch (Exception ex5)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error clearing Poolee caches: " + ex5.Message + "\n" + ex5.StackTrace);
				}
				try
				{
					EntangleLogger.Log("[LEVEL CHANGE] Cleaning up voice chat...", ConsoleColor.Yellow);
					VoiceChatManager.CleanupVoiceData();
					EntangleLogger.Log("[LEVEL CHANGE] ✓ Voice chat data cleared", ConsoleColor.Green);
				}
				catch (Exception ex6)
				{
					EntangleLogger.Error("[LEVEL CHANGE] Error cleaning up voice chat: " + ex6.Message + "\n" + ex6.StackTrace);
				}
				EntangleLogger.Log("[LEVEL CHANGE] Cleanup phase complete - Ready for new scene", ConsoleColor.Green);
				EntangleLogger.Log("═══════════════════════════════════════════════════════", ConsoleColor.Cyan);
			}
			catch (Exception ex7)
			{
				EntangleLogger.Error("[LEVEL CHANGE] Critical error in BONEWORKS_OnLoadingScreen: " + ex7.Message + "\n" + ex7.StackTrace);
				_isLevelChanging = false;
			}
		}

		private static void BroadcastLevelChangeImmediate(byte sceneIndex)
		{
			if (Server.instance == null)
			{
				return;
			}
			try
			{
				LevelChangeMessageData data = new LevelChangeMessageData
				{
					sceneIndex = sceneIndex,
					sceneReload = true
				};
				byte[] bytes = NetworkMessage.CreateMessage(BuiltInMessageType.LevelChange, data).GetBytes();
				ulong[] array = Server.instance.connectedUsers.ToArray();
				foreach (ulong userId in array)
				{
					Server.instance.SendMessage(userId, NetworkChannel.Reliable, bytes);
				}
				sceneChange = null;
			}
			catch (Exception ex)
			{
				EntangleLogger.Verbose("[LEVEL CHANGE] Immediate broadcast failed: " + ex.Message);
			}
		}

		private static void OptimizeDeadNpcRagdolls()
		{
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			_npcOptimizeTimer += Time.deltaTime;
			if (_npcOptimizeTimer < 2f)
			{
				return;
			}
			_npcOptimizeTimer = 0f;
			Animator[] array = Il2CppArrayBase<Animator>.op_Implicit(Object.FindObjectsOfType<Animator>());
			foreach (Animator val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Transform val2 = (((Object)(object)((Component)val).transform != (Object)null) ? ((Component)val).transform.root : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)val2).gameObject;
				if ((Object)(object)gameObject == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)gameObject).GetInstanceID();
				if (_optimizedNpcRoots.Contains(instanceID))
				{
					continue;
				}
				string text = ((Object)gameObject).name.ToLowerInvariant();
				if (!text.Contains("null") && !text.Contains("omni") && !text.Contains("projector"))
				{
					continue;
				}
				Component component = gameObject.GetComponent("BehaviourBaseNav");
				Behaviour val3 = (Behaviour)(object)((component is Behaviour) ? component : null);
				if ((val3 != null && val3.enabled) || ((Behaviour)val).enabled)
				{
					continue;
				}
				Rigidbody[] array2 = Il2CppArrayBase<Rigidbody>.op_Implicit(gameObject.GetComponentsInChildren<Rigidbody>(true));
				if (array2 == null || array2.Length == 0)
				{
					continue;
				}
				Rigidbody[] array3 = array2;
				foreach (Rigidbody val4 in array3)
				{
					if (!((Object)(object)val4 == (Object)null))
					{
						val4.velocity = Vector3.zero;
						val4.angularVelocity = Vector3.zero;
						val4.isKinematic = true;
						val4.detectCollisions = false;
					}
				}
				_optimizedNpcRoots.Add(instanceID);
			}
		}

		public override void OnApplicationQuit()
		{
			if (!SteamIntegration.isInvalid)
			{
				ModuleHandler.OnApplicationQuit();
				VoiceChatManager.CleanupAll();
				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();
				EntangleNotif.ServerStarted();
			});
			obj.CreateFunctionElement("Stop Server", Color.white, (Action)delegate
			{
				if (Server.instance != null)
				{
					Server.instance.Shutdown();
					EntangleNotif.ServerStopped();
				}
			});
			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 IntElement playerCountElem;

		public static IntElement objectCountElem;

		private static float bandwidthCheckTimer;

		private const float BANDWIDTH_CHECK_INTERVAL = 1f;

		private static float lastDownloadBps;

		private static float lastUploadBps;

		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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MenuCategory obj = category.CreateSubCategory("Net Stats", Color.white);
				obj.CreateIntElement("Bytes Down", Color.white, 0, (Action<int>)null, 1, int.MinValue, int.MaxValue, false);
				MenuElement obj2 = obj.elements.Last();
				downElem = (IntElement)(object)((obj2 is IntElement) ? obj2 : null);
				obj.CreateIntElement("Bytes Up", Color.white, 0, (Action<int>)null, 1, int.MinValue, int.MaxValue, false);
				MenuElement obj3 = obj.elements.Last();
				upElem = (IntElement)(object)((obj3 is IntElement) ? obj3 : null);
				obj.CreateIntElement("Players", Color.white, 0, (Action<int>)null, 1, int.MinValue, int.MaxValue, false);
				MenuElement obj4 = obj.elements.Last();
				playerCountElem = (IntElement)(object)((obj4 is IntElement) ? obj4 : null);
				obj.CreateIntElement("Objects Synced", Color.white, 0, (Action<int>)null, 1, int.MinValue, int.MaxValue, false);
				MenuElement obj5 = obj.elements.Last();
				objectCountElem = (IntElement)(object)((obj5 is IntElement) ? obj5 : null);
				EntangleLogger.Verbose("StatsUI initialized successfully");
			}
			catch (Exception ex)
			{
				EntangleLogger.Error("Failed to create StatsUI: " + ex.Message);
			}
		}

		public static void UpdateUI()
		{
			try
			{
				if (Node.activeNode != null && downElem != null && upElem != null && playerCountElem != null && objectCountElem != null)
				{
					((GenericElement<int>)(object)downElem).SetValue((int)Node.activeNode.recievedByteCount);
					((GenericElement<int>)(object)upElem).SetValue((int)Node.activeNode.sentByteCount);
					bandwidthCheckTimer += Time.deltaTime;
					if (bandwidthCheckTimer >= 1f)
					{
						bandwidthCheckTimer = 0f;
						lastDownloadBps = (float)Node.activeNode.recievedByteCount / 1f;
						lastUploadBps = (float)Node.activeNode.sentByteCount / 1f;
					}
					int count = PlayerRepresentation.representations.Count;
					int count2 = ObjectSync.syncedObjects.Count;
					((GenericElement<int>)(object)playerCountElem).SetValue(count);
					((GenericElement<int>)(object)objectCountElem).SetValue(count2);
					Node.activeNode.recievedByteCount = 0u;
					Node.activeNode.sentByteCount = 0u;
				}
			}
			catch (Exception ex)
			{
				EntangleLogger.Error("Error updating StatsUI: " + ex.Message);
			}
		}
	}
	public static class EntanglementUI
	{
		public static void CreateUI()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MenuCategory val2 = MenuManager.CreateCategory("Entanglement: Redux", Color.white);
				try
				{
					ServerUI.CreateUI(val2);
				}
				catch (Exception ex)
				{
					EntangleLogger.Error("Failed to create ServerUI: " + ex.Message);
				}
				try
				{
					ClientUI.CreateUI(val2);
				}
				catch (Exception ex2)
				{
					EntangleLogger.Error("Failed to create ClientUI: " + ex2.Message);
				}
				try
				{
					BanlistUI.CreateUI(val2);
				}
				catch (Exception ex3)
				{
					EntangleLogger.Error("Failed to create BanlistUI: " + ex3.Message);
				}
				try
				{
					LobbiesUI.CreateUI(val2);
				}
				catch (Exception ex4)
				{
					EntangleLogger.Error("Failed to create LobbiesUI: " + ex4.Message);
				}
				try
				{
					VoiceUI.CreateUI(val2);
				}
				catch (Exception ex5)
				{
					EntangleLogger.Error("Failed to create VoiceUI: " + ex5.Message);
				}
				try
				{
					StatsUI.CreateUI(val2);
				}
				catch (Exception ex6)
				{
					EntangleLogger.Error("Failed to create StatsUI: " + ex6.Message);
				}
				val2.CreateBoolElement("Verbose Network Logging", Color.yellow, EntangleLogger.isVerbose, (Action<bool>)delegate(bool val)
				{
					EntangleLogger.isVerbose = val;
					if (val)
					{
						EntangleLogger.Log("Verbose logging ENABLED. The console will now print detailed connection steps.", ConsoleColor.Green);
					}
					else
					{
						EntangleLogger.Log("Verbose logging DISABLED.", ConsoleColor.Red);
					}
				});
				EntangleLogger.Log("Entanglement UI initialized successfully!", ConsoleColor.Green);
			}
			catch (Exception ex7)
			{
				EntangleLogger.Error("Critical error creating UI: " + ex7.Message);
			}
		}
	}
	public static class VoiceUI
	{
		private static MenuCategory voiceCategory;

		private static MenuCategory playersMuteCategory;

		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)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			voiceCategory = category.CreateSubCategory("Voice Menu", Color.white);
			voiceCategory.CreateEnumElement("Voice Mode", Color.yellow, (Enum)VoiceChatManager.voiceChatMode, (Action<Enum>)delegate(Enum value)
			{
				if (value is VoiceChatManager.VoiceChatMode)
				{
					VoiceChatManager.VoiceChatMode voiceChatMode = (VoiceChatManager.VoiceChatMode)(object)value;
					VoiceChatManager.SetVoiceChatMode(voiceChatMode);
				}
			});
			voiceCategory.CreateFunctionElement("Select Microphone", Color.cyan, (Action)ShowMicrophoneMenu);
			voiceCategory.CreateFloatElement("Mic Volume", Color.yellow, VoiceChatManager.microphoneVolume, (Action<float>)delegate(float value)
			{
				VoiceChatManager.SetMicrophoneVolume(value);
			}, 0.1f, 0f, 1f, false);
			voiceCategory.CreateFloatElement("Output Volume", Color.yellow, VoiceChatManager.outputVolume, (Action<float>)delegate(float value)
			{
				VoiceChatManager.SetOutputVolume(value);
			}, 0.1f, 0f, 1f, false);
			if (VoiceChatManager.voiceChatMode == VoiceChatManager.VoiceChatMode.Proximity)
			{
				voiceCategory.CreateFloatElement("Proximity Range (m)", Color.yellow, VoiceChatManager.proximityRange, (Action<float>)delegate(float value)
				{
					VoiceChatManager.SetProximityRange(value);
				}, 5f, 10f, 500f, false);
			}
			playersMuteCategory = voiceCategory.CreateSubCategory("Player Mute List", Color.red);
			playersMuteCategory.CreateFunctionElement("Refresh", Color.white, (Action)RefreshMuteList);
			RefreshMuteList();
		}

		private static void ShowMicrophoneMenu()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				List<string> availableMicrophones = VoiceChatManager.GetAvailableMicrophones();
				if (availableMicrophones.Count == 0)
				{
					EntangleLogger.Error("No microphones found!");
					return;
				}
				MenuCategory val = MenuManager.CreateCategory("Select Microphone", Color.white);
				for (int i = 0; i < availableMicrophones.Count; i++)
				{
					string micName = availableMicrophones[i];
					int index = i;
					val.CreateFunctionElement(micName, Color.white, (Action)delegate
					{
						VoiceChatManager.SetMicrophone(index);
						EntangleLogger.Log("Selected microphone: " + micName, ConsoleColor.Green);
						MenuManager.OpenCategory(voiceCategory);
					});
				}
				MenuManager.OpenCategory(val);
			}
			catch (Exception ex)
			{
				EntangleLogger.Error("Error showing microphone menu: " + ex.Message);
			}
		}

		private static void RefreshMuteList()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				List<string> list = new List<string>();
				foreach (MenuElement element in playersMuteCategory.elements)
				{
					if (element.displayText != "Refresh")
					{
						list.Add(element.displayText);
					}
				}
				foreach (string item in list)
				{
					playersMuteCategory.RemoveElement(item);
				}
				Dictionary<ulong, string> allPlayersForVoiceMenu = VoiceChatManager.GetAllPlayersForVoiceMenu();
				if (allPlayersForVoiceMenu.Count == 0)
				{
					playersMuteCategory.CreateFunctionElement("No players in game", Color.gray, (Action)delegate
					{
					});
					return;
				}
				foreach (KeyValuePair<ulong, string> item2 in allPlayersForVoiceMenu)
				{
					ulong playerId = item2.Key;
					string playerName = item2.Value;
					bool flag = VoiceChatManager.IsPlayerMuted(playerId);
					Color val = (flag ? Color.red : Color.green);
					playersMuteCategory.CreateFunctionElement(playerName + " " + (flag ? "[MUTED]" : ""), val, (Action)delegate
					{
						TogglePlayerMute(playerId, playerName);
					});
				}
			}
			catch (Exception ex)
			{
				EntangleLogger.Error("Error refreshing mute list: " + ex.Message);
			}
		}

		private static void TogglePlayerMute(ulong playerId, string playerName)
		{
			try
			{
				if (VoiceChatManager.IsPlayerMuted(playerId))
				{
					VoiceChatManager.UnmutePlayer(playerId);
					EntangleLogger.Log("Unmuted " + playerName, ConsoleColor.Green);
				}
				else
				{
					VoiceChatManager.MutePlayer(playerId);
					EntangleLogger.Log("Muted " + playerName, ConsoleColor.Red);
				}
				RefreshMuteList();
			}
			catch (Exception ex)
			{
				EntangleLogger.Error("Error toggling mute for " + playerName + ": " + ex.Message);
			}
		}
	}
}
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;

		private static float lastPlayerSyncTime = 0f;

		private const float PLAYER_SYNC_INTERVAL = 1f / 60f;

		private static float lastAnimationSyncTime = 0f;

		private const float ANIMATION_SYNC_INTERVAL = 1f / 60f;

		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 TMP_Text 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 Vector3 lastSyncPosition = Vector3.zero;

		public Vector3 targetSyncPosition = Vector3.zero;

		public Quaternion lastSyncRotation = Quaternion.identity;

		public Quaternion targetSyncRotation = Quaternion.identity;

		public float interpolationAlpha = 1f;

		public float interpolationSpeed = 10f;

		public float lastSyncReceiveTime;

		public string playerName;

		public ulong playerId;

		public bool isGrounded;

		private Renderer[] _cachedRenderers;

		private float _rendererCheckTimer;

		private float rendererCheckInterval = 0.1f;

		private bool isTalking;

		private float talkingAnimationBlend;

		private float groundedGraceTimer;

		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)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			this.playerName = playerName;
			this.playerId = playerId;
			RecreateRepresentations();
		}

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

		private static void SetLayerRecursive(GameObject obj, int layer)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return;
			}
			obj.layer = layer;
			Transform transform = obj.transform;
			int childCount = transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if ((Object)(object)child != (Object)null)
				{
					SetLayerRecursive(((Component)child).gameObject, layer);
				}
			}
		}

		private static void SetTagRecursive(GameObject obj, string tag)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return;
			}
			obj.tag = tag;
			Transform transform = obj.transform;
			int childCount = transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if ((Object)(object)child != (Object)null)
				{
					SetTagRecursive(((Component)child).gameObject, tag);
				}
			}
		}

		public void RecreateRepresentations()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Expected O, but got Unknown
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_0536: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				EntangleLogger.Verbose($"[RepCreation] Starting for player {playerName} (ID: {playerId})");
				if ((Object)(object)playerRepBundle == (Object)null)
				{
					EntangleLogger.Error("[RepCreation] playerRepBundle is null! Cannot recreate representations.");
					return;
				}
				EntangleLogger.Verbose("[RepCreation]   Loading holographic material...");
				Material val = playerRepBundle.LoadAsset<Material>("PlayerHolographic");
				if ((Object)(object)val == (Object)null)
				{
					EntangleLogger.Warn("▌[RepCreation]   ⚠ PlayerHolographic material not found in bundle");
					repHologram = new Material(Shader.Find("Standard"));
				}
				else
				{
					repHologram = Object.Instantiate<Material>(val);
				}
				EntangleLogger.Verbose("[RepCreation]   Instantiating player representation model...");
				GameObject val2 = playerRepBundle.LoadAsset<GameObject>("PlayerRep");
				if ((Object)(object)val2 == (Object)null)
				{
					EntangleLogger.Error("[RepCreation] PlayerRep prefab not found in bundle!");
					return;
				}
				repFord = Object.Instantiate<GameObject>(val2);
				((Object)repFord).name = $"PlayerRep.{playerId}";
				repRoot = repFord.transform;
				EntangleLogger.Verbose("[RepCreation]   ✓ Model instantiated");
				int num = LayerMask.NameToLayer("Default");
				SetLayerRecursive(((Component)repRoot).gameObject, num);
				SetTagRecursive(((Component)repRoot).gameObject, "Untagged");
				EntangleLogger.Verbose($"[RepCreation]   ✓ Set to layer: {num}");
				EntangleLogger.Verbose("[RepCreation]   Setting up SFX components...");
				Transform val3 = repRoot.Find("GunSFX");
				if ((Object)(object)val3 != (Object)null)
				{
					repGunSFX = ((Component)val3).GetComponent<GunSFX>();
				}
				Transform val4 = repRoot.Find("BalloonSFX");
				if ((Object)(object)val4 != (Object)null)
				{
					repBalloonSFX = ((Component)val4).GetComponent<GunSFX>();
				}
				Transform val5 = repRoot.Find("StabSFX");
				if ((Object)(object)val5 != (Object)null)
				{
					repStabSFX = ((Component)val5).GetComponent<GunSFX>();
				}
				Transform val6 = repRoot.Find("PuncherSFX");
				if ((Object)(object)val6 != (Object)null)
				{
					GravGunSFX component = ((Component)val6).GetComponent<GravGunSFX>();
					if ((Object)(object)component != (Object)null)
					{
						repPowerPunchSFX = component;
					}
					else
					{
						EntangleLogger.Verbose("[RepCreation]   ⚠ GravGunSFX not found on PuncherSFX, attempting GunSFX fallback");
						if ((Object)(object)((Component)val6).GetComponent<GunSFX>() != (Object)null)
						{
							EntangleLogger.Verbose("[RepCreation]   ⚠ Using GunSFX as fallback for PuncherSFX");
						}
					}
				}
				EntangleLogger.Verbose("[RepCreation]   Setting up physics body...");
				Transform val7 = repRoot.Find("Body");
				if ((Object)(object)val7 != (Object)null)
				{
					repBody = ((Component)val7).GetComponent<SLZ_Body>();
					if ((Object)(object)repBody != (Object)null)
					{
						repBody.OnStart();
					}
				}
				Transform val8 = repRoot.Find("Ragdoll");
				if ((Object)(object)val8 != (Object)null)
				{
					ragdollBody = ((Component)val8).GetComponent<SLZ_Body>();
				}
				EntangleLogger.Verbose("[RepCreation]   Setting up animator...");
				Transform val9 = repRoot.Find("Brett@neutral");
				if ((Object)(object)val9 != (Object)null)
				{
					repAnimator = ((Component)val9).GetComponent<Animator>();
					if ((Object)(object)repAnimator != (Object)null)
					{
						if ((Object)(object)PlayerScripts.playerAnimatorController != (Object)null)
						{
							repAnimator.runtimeAnimatorController = PlayerScripts.playerAnimatorController;
							activeAnimator = repAnimator;
							EntangleLogger.Verbose("[RepCreation]   ✓ Animator controller assigned");
						}
						else
						{
							EntangleLogger.Warn("[RepCreation]   ⚠ PlayerAnimatorController is null, using default");
							activeAnimator = repAnimator;
						}
						repAnimationManager = ((Component)val9).GetComponent<CharacterAnimationManager>();
						try
						{
							repAnimator.SetFloat("Speed", 0f);
							repAnimator.SetInteger("AnimState", 0);
							repAnimator.SetLayerWeight(1, 0f);
							EntangleLogger.Verbose("[RepCreation]   ✓ Animator configured");
						}
						catch (Exception ex)
						{
							EntangleLogger.Warn("[RepCreation]   ⚠ Error initializing animator state: " + ex.Message);
						}
					}
					else
					{
						EntangleLogger.Verbose("[RepCreation]   ⚠ Animator component not found on Brett@neutral");
					}
					repGeo = val9.Find("geoGrp");
					repSHJnt = val9.Find("SHJntGrp");
				}
				else
				{
					EntangleLogger.Verbose("[RepCreation]   ⚠ Brett@neutral transform not found");
				}
				EntangleLogger.Verbose("[RepCreation]   Getting transform references...");
				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>());
				EntangleLogger.Verbose($"[RepCreation]   Found {colliders.Length} colliders");
				EntangleLogger.Verbose("[RepCreation]   Creating nametag canvas...");
				repCanvas = new GameObject("RepCanvas");
				repCanvasComponent = repCanvas.AddComponent<Canvas>();
				repCanvasComponent.renderMode = (RenderMode)2;
				repCanvasTransform = repCanvas.transform;
				repCanvasTransform.localScale = Vector3.one / 180f;
				if ((Object)(object)repTransforms[0] != (Object)null)
				{
					repCanvasTransform.SetParent(repTransforms[0], false);
					repCanvasTransform.localPosition = Vector3.up * 0.4f;
					EntangleLogger.Verbose("[RepCreation]   ✓ Nametag parented to head");
				}
				else
				{
					repCanvasTransform.position = repRoot.position + Vector3.up * 0.4f;
					EntangleLogger.Verbose("[RepCreation]   ⚠ Nametag positioned at root");
				}
				GameObject val10 = new GameObject("RepNameText");
				val10.transform.SetParent(repCanvasTransform, false);
				RectTransform val11 = val10.AddComponent<RectTransform>();
				val10.AddComponent<CanvasRenderer>();
				TextMeshProUGUI val12 = val10.AddComponent<TextMeshProUGUI>();
				((Transform)val11).localPosition = Vector3.zero;
				((Transform)val11).localRotation = Quaternion.identity;
				val11.sizeDelta = new Vector2(480f, 120f);
				((TMP_Text)val12).alignment = (TextAlignmentOptions)514;
				((TMP_Text)val12).enableAutoSizing = true;
				((TMP_Text)val12).fontSizeMin = 10f;
				((TMP_Text)val12).fontSizeMax = 24f;
				((TMP_Text)val12).text = playerName;
				repNameText = (TMP_Text)(object)val12;
				repCanvas.AddComponent<NametagBillboard>();
				if (playerId == SteamIntegration.currentUser.m_SteamID)
				{
					repCanvas.SetActive(false);
					EntangleLogger.Verbose($"[RepCreation]   ⚠ Nametag DISABLED for local player: {playerName} (ID: {playerId})");
				}
				else
				{
					repCanvas.SetActive(true);
					EntangleLogger.Verbose($"[RepCreation]   ✓ Nametag ENABLED for remote player: {playerName} (ID: {playerId})");
				}
				foreach (Renderer componentsInChild in ((Component)repRoot).GetComponentsInChildren<Renderer>(true))
				{
					componentsInChild.enabled = true;
					componentsInChild.allowOcclusionWhenDynamic = false;
				}
				if (isCustomSkinned && currentSkinPath != null)
				{
					PlayerSkinLoader.ApplyPlayermodel(this, currentSkinPath);
				}
			}
			catch (Exception ex2)
			{
				EntangleLogger.Error($"Error caught creating rep from user {playerId}: {ex2.Message}\n{ex2.StackTrace}");
			}
		}

		public void CreateRagdoll()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)activeAnimator) || !Object.op_Implicit((Object)(object)ragdollBody))
			{
				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_0012: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = repRoot.position;
			float fixedDeltaTime = Time.fixedDeltaTime;
			Vector3 val = PhysicsData.GetVelocity(position, prevRepRootPos, fixedDeltaTime);
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				val = Vector3.zero;
			}
			if (isGrounded)
			{
				groundedGraceTimer = 0.15f;
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(val.x, 0f, val.z);
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(repInputVel.x, 0f, repInputVel.z);
				val3 = Vector3.Lerp(val3, val2, fixedDeltaTime * 10f);
				float num = Mathf.Clamp(val.y, -3.5f, 3.5f);
				float num2 = Mathf.Lerp(repInputVel.y, num, fixedDeltaTime * 4f);
				repInputVel = new Vector3(val3.x, num2, val3.z);
			}
			else
			{
				groundedGraceTimer -= fixedDeltaTime;
				if (groundedGraceTimer > 0f)
				{
					float num3 = Mathf.Lerp(repInputVel.y, val.y, fixedDeltaTime * 3f);
					Vector3 val4 = default(Vector3);
					((Vector3)(ref val4))..ctor(val.x, 0f, val.z);
					Vector3 val5 = default(Vector3);
					((Vector3)(ref val5))..ctor(repInputVel.x, 0f, repInputVel.z);
					val5 = Vector3.Lerp(val5, val4, fixedDeltaTime * 6f);
					repInputVel = new Vector3(val5.x, num3, val5.z);
				}
				else
				{
					repInputVel = Vector3.Lerp(repInputVel, Vector3.zero, fixedDeltaTime * 8f);
				}
			}
			repSavedVel = repInputVel;
			prevRepRootPos = position;
		}

		public void UpdateIK()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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) || !Object.op_Implicit((Object)(object)repAnimationManager) || !Object.op_Implicit((Object)(object)repBody))
				{
					return;
				}
				activeAnimator.Update(Time.fixedDeltaTime);
				repAnimationManager.OnLateUpdate();
				SaveVelocity();
				repBody.FullBodyUpdate(repInputVel, Vector3.zero);
				if ((Object)(object)repBody.ArtToBlender != (Object)null)
				{
					repBody.ArtToBlender.UpdateBlender();
				}
				if ((Object)(object)repGeo != (Object)null)
				{
					foreach (Renderer componentsInChild in ((Component)repGeo).GetComponentsInChildren<Renderer>(true))
					{
						if ((Object)(object)componentsInChild != (Object)null && !componentsInChild.enabled)
						{
							componentsInChild.enabled = true;
						}
					}
				}
				if ((Object)(object)((Component)repBody).gameObject != (Object)null && !((Component)repBody).gameObject.activeSelf)
				{
					((Component)repBody).gameObject.SetActive(true);
				}
				if (isTalking)
				{
					talkingAnimationBlend = Mathf.Lerp(talkingAnimationBlend, 1f, Time.deltaTime * 5f);
				}
				else
				{
					talkingAnimationBlend = Mathf.Lerp(talkingAnimationBlend, 0f, Time.deltaTime * 5f);
				}
				if ((Object)(object)activeAnimator != (Object)null)
				{
					activeAnimator.SetFloat("Talk", talkingAnimationBlend);
				}
			}
			catch (Exception ex)
			{
				EntangleLogger.Error($"UpdateIK Error for {playerId}: {ex.Message}");
			}
		}

		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_000b: Unknown result type (might be due to invalid IL or missing references)
			CharacterAnimationManager obj = repAnimationManager;
			if (obj != null)
			{
				obj.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 SetTalking(bool talking)
		{
			isTalking = talking;
			EntangleLogger.Verbose("[Talking] " + playerName + " is " + (talking ? "talking" : "silent"));
		}

		public void IgnoreCollision(Rigidbody otherBody, bool ignore)
		{
			if (!Object.op_Implicit((Object)(object)otherBody))
			{
				return;
			}
			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()
		{
			try
			{
				if ((Object)(object)PlayerScripts.playerRig != (Object)null)
				{
					syncedRoot = ((Component)PlayerScripts.playerRig).transform;
					PhysicsRig physicsRig = PlayerScripts.playerRig.physicsRig;
					if ((Object)(object)physicsRig != (Object)null)
					{
						syncedPoints[0] = ((Rig)physicsRig).m_head;
						if ((Object)(object)syncedPoints[0] == (Object)null)
						{
							EntangleLogger.Warn("[PlayerTransforms] Head not found on physicsRig");
						}
						if ((Object)(object)PlayerScripts.playerLeftHand != (Object)null)
						{
							syncedPoints[1] = ((Component)PlayerScripts.playerLeftHand).transform;
						}
						else
						{
							EntangleLogger.Warn("[PlayerTransforms] Left hand not initialized");
						}
						if ((Object)(object)PlayerScripts.playerRightHand != (Object)null)
						{
							syncedPoints[2] = ((Component)PlayerScripts.playerRightHand).transform;
						}
						else
						{
							EntangleLogger.Warn("[PlayerTransforms] Right hand not initialized");
						}
					}
					else
					{
						EntangleLogger.Error("[PlayerTransforms] PhysicsRig is null!");
					}
				}
				else
				{
					EntangleLogger.Verbose("[PlayerTransforms] PlayerScripts.playerRig is null, using fallback");
					RigManager val = Object.FindObjectOfType<RigManager>();
					if ((Object)(object)val != (Object)null && (Object)(object)val.physicsRig != (Object)null)
					{
						syncedRoot = ((Component)val).transform;
						syncedPoints[0] = ((Rig)val.physicsRig).m_head;
						syncedPoints[1] = ((Component)val.physicsRig.leftHand).transform;
						syncedPoints[2] = ((Component)val.physicsRig.rightHand).transform;
						EntangleLogger.Log("[PlayerTransforms] ✓ Fallback transforms initialized");
					}
					else
					{
						EntangleLogger.Error("[PlayerTransforms] Could not find RigManager or PhysicsRig!");
					}
				}
			}
			catch (Exception ex)
			{
				EntangleLogger.Error("[PlayerTransforms] Error getting player transforms: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		private static Transform GetTransformDeep(Transform parent, string name)
		{
			Transform val = parent.Find(name);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(((Component)parent).GetComponentsInChildren<Transform>(true));
			foreach (Transform val2 in array)
			{
				if (((Object)val2).name == name)
				{
					return val2;
				}
			}
			return null;
		}

		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);
			if ((Object)(object)syncedRoot != (Object)null)
			{
				playerRepSyncData.isJumping = !playerRepSyncData.isGrounded;
			}
			return playerRepSyncData;
		}

		public static AnimationSyncData GetAnimationSyncData()
		{
			//IL_0037: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)syncedRoot == (Object)null || (Object)(object)PlayerScripts.playerRig == (Object)null)
			{
				return null;
			}
			AnimationSyncData animationSyncData = new AnimationSyncData();
			animationSyncData.userId = SteamIntegration.currentUser.m_SteamID;
			_ = syncedRoot.position - syncedRoot.position;
			if ((Object)(object)syncedPoints[0] != (Object)null)
			{
				Vector3 position = syncedPoints[0].position;
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(position.x - syncedRoot.position.x, 0f, position.z - syncedRoot.position.z);
				animationSyncData.movementSpeed = ((Vector3)(ref val)).magnitude / Time.deltaTime;
			}
			animationSyncData.movementSpeed = Mathf.Clamp(animationSyncData.movementSpeed, 0f, 10f);
			animationSyncData.isJumping = !PlayerScripts.playerGrounder.isGrounded;
			animationSyncData.isFalling = !PlayerScripts.playerGrounder.isGrounded && animationSyncData.jumpHeight < 0f;
			if ((Object)(object)PlayerScripts.playerLeftHand != (Object)null && (Object)(object)((Component)PlayerScripts.playerLeftHand).GetComponent<Rigidbody>() != (Object)null)
			{
				Rigidbody component = ((Component)PlayerScripts.playerLeftHand).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					animationSyncData.bodyVelocity = component.velocity;
					animationSyncData.jumpHeight = component.velocity.y;
				}
			}
			if (animationSyncData.movementSpeed > 2f)
			{
				animationSyncData.animState = 2;
			}
			else if (animationSyncData.movementSpeed > 0.5f)
			{
				animationSyncData.animState = 1;
			}
			else
			{
				animationSyncData.animState = 0;
			}
			return animationSyncData;
		}

		public static void SyncPlayerReps()
		{
			if (!SteamIntegration.hasLobby || Node.activeNode == null)
			{
				return;
			}
			lastPlayerSyncTime += Time.deltaTime;
			if (lastPlayerSyncTime < 1f / 60f)
			{
				return;
			}
			lastPlayerSyncTime = 0f;
			PlayerRepSyncData playerSyncData = GetPlayerSyncData();
			if (playerSyncData != null)
			{
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.PlayerRepSync, playerSyncData);
				if (networkMessage != null)
				{
					Node.activeNode.BroadcastMessage(NetworkChannel.Unreliable, networkMessage.GetBytes());
				}
			}
			else
			{
				GetPlayerTransforms();
			}
		}

		public static void SyncAnimationState()
		{
			if (!SteamIntegration.hasLobby || Node.activeNode == null)
			{
				return;
			}
			lastAnimationSyncTime += Time.deltaTime;
			if (lastAnimationSyncTime < 1f / 60f)
			{
				return;
			}
			lastAnimationSyncTime = 0f;
			AnimationSyncData animationSyncData = GetAnimationSyncData();
			if (animationSyncData != null)
			{
				NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.AnimationSync, animationSyncData);
				if (networkMessage != null)
				{
					Node.activeNode.BroadcastMessage(NetworkChannel.Unreliable, networkMessage.GetBytes());
				}
			}
		}

		public static void UpdatePlayerReps()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			if ((Object)(object)syncedRoot != (Object)null)
			{
				val = syncedRoot.position;
			}
			else if ((Object)(object)Camera.main != (Object)null)
			{
				val = ((Component)Camera.main).transform.position;
			}
			foreach (PlayerRepresentation value in representations.Values)
			{
				if (value == null || (Object)(object)value.repRoot == (Object)null)
				{
					continue;
				}
				if (!((Component)value.repRoot).gameObject.activeSelf)
				{
					((Component)value.repRoot).gameObject.SetActive(true);
				}
				value._rendererCheckTimer += Time.fixedDeltaTime;
				if (value._rendererCheckTimer >= value.rendererCheckInterval)
				{
					value._rendererCheckTimer = 0f;
					if (value._cachedRenderers == null)
					{
						value._cachedRenderers = Il2CppArrayBase<Renderer>.op_Implicit(((Component)value.repRoot).GetComponentsInChildren<Renderer>(true));
					}
					Renderer[] cachedRenderers = value._cachedRenderers;
					foreach (Renderer val2 in cachedRenderers)
					{
						if ((Object)(object)val2 != (Object)null && !val2.enabled)
						{
							val2.enabled = true;
						}
					}
				}
				if (value.interpolationAlpha < 1f)
				{
					value.interpolationAlpha += Time.fixedDeltaTime * value.interpolationSpeed;
					value.repRoot.position = Vector3.Lerp(value.lastSyncPosition, value.targetSyncPosition, value.interpolationAlpha);
				}
				Vector3 val3 = val - value.repRoot.position;
				_ = ((Vector3)(ref val3)).sqrMagnitude;
				value.UpdateIK();
				if ((Object)(object)value.repCanvasTransform != (Object)null && (Object)(object)((Component)value.repCanvasTransform).gameObject != (Object)null)
				{
					((Component)value.repCanvasTransform).gameObject.SetActive(Client.nameTagsVisible);
				}
			}
		}

		public static void ForceRefreshAllRemoteRepresentations()
		{
			foreach (PlayerRepresentation value in representations.Values)
			{
				if (value == null || (Object)(object)value.repRoot == (Object)null || value.playerId == SteamIntegration.currentUser.m_SteamID)
				{
					continue;
				}
				if (!((Component)value.repRoot).gameObject.activeSelf)
				{
					((Component)value.repRoot).gameObject.SetActive(true);
				}
				Renderer[] array = (value._cachedRenderers = value._cachedRenderers ?? Il2CppArrayBase<Renderer>.op_Implicit(((Component)value.repRoot).GetComponentsInChildren<Renderer>(true)));
				foreach (Renderer val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						val.enabled = true;
						val.allowOcclusionWhenDynamic = false;
					}
				}
				if ((Object)(object)value.repCanvasTransform != (Object)null && (Object)(object)((Component)value.repCanvasTransform).gameObject != (Object)null)
				{
					((Component)value.repCanvasTransform).gameObject.SetActive(Client.nameTagsVisible);
				}
			}
		}
	}
	[RegisterTypeInIl2Cpp]
	public class NametagBillboard : MonoBehaviour
	{
		private Transform cameraTransform;

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

		private void Start()
		{
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				cameraTransform = ((Component)main).transform;
			}
		}

		private void LateUpdate()
		{
			if ((Object)(object)cameraTransform != (Object)null)
			{
				((Component)this).transform.LookAt(cameraTransform);
				((Component)this).transform.Rotate(0f, 180f, 0f);
			}
		}
	}
}
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);
		}
	}
	public static class DestructablePathHelper
	{
		public static string GetGameObjectPath(GameObject obj)
		{
			string text = ((Object)obj).name;
			while ((Object)(object)obj.transform.parent != (Object)null)
			{
				obj = ((Component)obj.transform.parent).gameObject;
				text = ((Object)obj).name + "/" + text;
			}
			return text;
		}
	}
	[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)
			{
				return;
			}
			TransformSyncable transformSyncable = TransformSyncable.DestructCache.Get(((Component)__instance).gameObject);
			if (Object.op_Implicit((Object)(object)transformSyncable))
			{
				if (transformSyncable.IsOwner())
				{
					NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.ObjectDestroy, new ObjectDestroyMessageData
					{
						objectId = transformSyncable.objectId
					});
					Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, networkMessage.GetBytes());
				}
			}
			else if (SteamIntegration.isHost)
			{
				NetworkMessage networkMessage2 = NetworkMessage.CreateMessage(BuiltInMessageType.MapObjectDestroy, new MapObjectDestroyMessageData
				{
					objectPath = DestructablePathHelper.GetGameObjectPath(((Component)__instance).gameObject)
				});
				Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, networkMessage2.GetBytes());
			}
		}
	}
	[HarmonyPatch(typeof(ObjectDestructable), "TakeDamage")]
	public static class DestructablePatch
	{
		public static void Postfix(ObjectDestructable __instance)
		{
			if (!SteamIntegration.hasLobby || !__instance._isDead)
			{
				return;
			}
			TransformSyncable transformSyncable = TransformSyncable.DestructCache.Get(((Component)__instance).gameObject);
			if (Object.op_Implicit((Object)(object)transformSyncable))
			{
				if (transformSyncable.IsOwner())
				{
					NetworkMessage networkMessage = NetworkMessage.CreateMessage(BuiltInMessageType.ObjectDestroy, new ObjectDestroyMessageData
					{
						objectId = transformSyncable.objectId
					});
					Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, networkMessage.GetBytes());
				}
			}
			else if (SteamIntegration.isHost)
			{
				NetworkMessage networkMessage2 = NetworkMessage.CreateMessage(BuiltInMessageType.MapObjectDestroy, new MapObjectDestroyMessageData
				{
					objectPath = DestructablePathHelper.GetGameObjectPath(((Component)__instance).gameObject)
				});
				Node.activeNode.BroadcastMessage(NetworkChannel.Reliable, networkMessage2.GetBytes());
			}
		}
	}
	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))
				{
					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))
				{
					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;
			}