Decompiled source of LocalMirror v1.0.0

Mods/LocalMirror.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.BoneMenu.UI;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSLZ.VRMK;
using Il2CppSystem;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using LabFusion.Entities;
using LabFusion.Marrow.Integration;
using LabFusion.Player;
using LabFusion.SDK.Cosmetics;
using LabFusion.SDK.Points;
using LocalMirrorMod;
using LocalMirrorMod.Fixes;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("LocalMirror")]
[assembly: AssemblyDescription("Standalone Local Mirror mod for BONELAB")]
[assembly: AssemblyProduct("LocalMirror")]
[assembly: AssemblyCopyright("Copyright 2026")]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: MelonInfo(typeof(Main), "LocalMirror", "1.0.0", "MrYetiSpaghetti", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonPriority(-230)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LocalMirrorMod
{
	public static class Config
	{
		private const string CategoryId = "LocalMirror";

		public static MelonPreferences_Category _category;

		public static MelonPreferences_Entry<float> MirrorDistance;

		public static MelonPreferences_Entry<bool> MirrorScaleByHeight;

		public static MelonPreferences_Entry<bool> MirrorFollowHead;

		public static MelonPreferences_Entry<bool> MirrorStayInPlace;

		public static MelonPreferences_Entry<bool> LocalMirrorHeldItemAwarenessEnabled;

		public static MelonPreferences_Entry<bool> LocalMirrorSeatAwarenessEnabled;

		public static MelonPreferences_Entry<bool> LocalMirrorProximityAwarenessEnabled;

		public static MelonPreferences_Entry<float> LocalMirrorProximityRadius;

		public static MelonPreferences_Entry<bool> LocalMirrorProximityVisualEnabled;

		public static MelonPreferences_Entry<bool> LocalMirrorIncludeOthersEnabled;

		public static MelonPreferences_Entry<bool> LocalMirrorShowHolsteredEnabled;

		public static MelonPreferences_Entry<bool> ShowFusionCosmeticsEnabled;

		private static BoolElement _localMirrorToggleElement;

		private static BoolElement _mirrorScaleByHeightElement;

		private static BoolElement _mirrorFollowHeadElement;

		private static BoolElement _mirrorStayInPlaceElement;

		private static BoolElement _showHolsteredElement;

		private static BoolElement _heldItemAwarenessElement;

		private static BoolElement _seatAwarenessElement;

		private static BoolElement _proximityAwarenessElement;

		private static BoolElement _proximityVisualElement;

		private static BoolElement _includeOthersElement;

		private static BoolElement _showFusionCosmeticsElement;

		public static void Initialize()
		{
			_category = MelonPreferences.CreateCategory("LocalMirror");
			_category.SetFilePath("UserData/LocalMirror.cfg", true, false);
			MirrorDistance = _category.CreateEntry<float>("MirrorDistance", 1.5f, "Distance in meters from the player chest to the mirror clone", (string)null, false, false, (ValueValidator)null, (string)null);
			MirrorScaleByHeight = _category.CreateEntry<bool>("MirrorScaleByHeight", true, "Scale the mirror distance proportionally to the player's avatar height", (string)null, false, false, (ValueValidator)null, (string)null);
			MirrorFollowHead = _category.CreateEntry<bool>("MirrorFollowHead", false, "Mirror tracks head facing live; when off, facing direction is frozen at enable time", (string)null, false, false, (ValueValidator)null, (string)null);
			MirrorStayInPlace = _category.CreateEntry<bool>("MirrorStayInPlace", false, "Spawn the mirror once at correct distance facing the player, then keep it stationary", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirrorHeldItemAwarenessEnabled = _category.CreateEntry<bool>("HeldItemAwareness", true, "Mirror whichever spawnable the player's hand is currently grabbing onto the clone", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirrorSeatAwarenessEnabled = _category.CreateEntry<bool>("SeatAwareness", true, "Mirror the vehicle / seat the player is sitting in onto the clone", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirrorProximityAwarenessEnabled = _category.CreateEntry<bool>("ProximityAwareness", false, "Mirror any spawnable inside the configured radius of the player onto the clone", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirrorProximityRadius = _category.CreateEntry<float>("ProximityRadius", 2f, "Proximity Awareness radius in meters", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirrorProximityVisualEnabled = _category.CreateEntry<bool>("ProximityVisual", true, "Render a white circle ring at the proximity radius around the player", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirrorIncludeOthersEnabled = _category.CreateEntry<bool>("IncludeOthers", false, "Include other players' rigs as eligible for the LocalMirror item awareness toggles (held / proximity)", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirrorShowHolsteredEnabled = _category.CreateEntry<bool>("ShowHolstered", true, "Show holstered items on the LocalMirror clone (and on remote rig clones when Include Others is on)", (string)null, false, false, (ValueValidator)null, (string)null);
			ShowFusionCosmeticsEnabled = _category.CreateEntry<bool>("ShowFusionCosmetics", false, "Mirror the local player's equipped Fusion cosmetics (and remote players' when Include Others is on) onto the mirror clones", (string)null, false, false, (ValueValidator)null, (string)null);
			LocalMirror.Distance = MirrorDistance.Value;
			LocalMirror.ScaleByAvatarHeight = MirrorScaleByHeight.Value;
			LocalMirror.FollowHead = MirrorFollowHead.Value;
			LocalMirror.StayInPlace = MirrorStayInPlace.Value;
			BuildBoneMenu();
		}

		private static void BuildBoneMenu()
		{
			//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_0030: 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)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			Color endColor = default(Color);
			((Color)(ref endColor))..ctor(0.75f, 0.75f, 0.75f, 1f);
			Page val2 = Page.Root.CreatePage(BuildGradientText("LocalMirror", Color.white, endColor), Color.white, 0, true);
			BoneMenuScrollClamp.Register(val2);
			BoneMenuScrollButtons.Register(val2);
			_localMirrorToggleElement = val2.CreateBool("Local Mirror", Color.green, LocalMirror.Enabled, (Action<bool>)delegate(bool val)
			{
				if (val)
				{
					LocalMirror.Enable();
				}
				else
				{
					LocalMirror.Disable();
				}
			});
			try
			{
				LocalMirror.OnEnabledChanged += delegate(bool newState)
				{
					try
					{
						if (_localMirrorToggleElement != null)
						{
							_localMirrorToggleElement.Value = newState;
						}
					}
					catch
					{
					}
				};
			}
			catch
			{
			}
			MenuSliderHelper.RegisterSliderWithType(val2, "Mirror Distance", MirrorDistance.Value, 0.1f, 0.3f, 3f, delegate(float val)
			{
				MirrorDistance.Value = val;
				_category.SaveToFile(false);
				LocalMirror.Distance = val;
			});
			_mirrorScaleByHeightElement = val2.CreateBool("Distance scales with height", Color.green, MirrorScaleByHeight.Value, (Action<bool>)delegate(bool val)
			{
				MirrorScaleByHeight.Value = val;
				_category.SaveToFile(false);
				LocalMirror.ScaleByAvatarHeight = val;
			});
			_mirrorFollowHeadElement = val2.CreateBool("Mirror follows head", Color.green, MirrorFollowHead.Value, (Action<bool>)delegate(bool val)
			{
				MirrorFollowHead.Value = val;
				_category.SaveToFile(false);
				LocalMirror.FollowHead = val;
			});
			_mirrorStayInPlaceElement = val2.CreateBool("Mirror stays in place", Color.green, MirrorStayInPlace.Value, (Action<bool>)delegate(bool val)
			{
				MirrorStayInPlace.Value = val;
				_category.SaveToFile(false);
				LocalMirror.StayInPlace = val;
			});
			_showHolsteredElement = val2.CreateBool("Show Holstered Items", Color.green, LocalMirrorShowHolsteredEnabled.Value, (Action<bool>)delegate(bool val)
			{
				LocalMirrorShowHolsteredEnabled.Value = val;
				_category.SaveToFile(false);
			});
			_heldItemAwarenessElement = val2.CreateBool("Held Item Awareness", Color.green, LocalMirrorHeldItemAwarenessEnabled.Value, (Action<bool>)delegate(bool val)
			{
				LocalMirrorHeldItemAwarenessEnabled.Value = val;
				_category.SaveToFile(false);
			});
			_seatAwarenessElement = val2.CreateBool("Seat Awareness", Color.green, LocalMirrorSeatAwarenessEnabled.Value, (Action<bool>)delegate(bool val)
			{
				LocalMirrorSeatAwarenessEnabled.Value = val;
				_category.SaveToFile(false);
			});
			_proximityAwarenessElement = val2.CreateBool("Proximity Awareness", Color.green, LocalMirrorProximityAwarenessEnabled.Value, (Action<bool>)delegate(bool val)
			{
				LocalMirrorProximityAwarenessEnabled.Value = val;
				_category.SaveToFile(false);
			});
			MenuSliderHelper.RegisterSliderWithType(val2, "Proximity Radius (m)", LocalMirrorProximityRadius.Value, 0.1f, 0.1f, 30f, delegate(float val)
			{
				LocalMirrorProximityRadius.Value = val;
				_category.SaveToFile(false);
			});
			_proximityVisualElement = val2.CreateBool("Proximity Visual", Color.green, LocalMirrorProximityVisualEnabled.Value, (Action<bool>)delegate(bool val)
			{
				LocalMirrorProximityVisualEnabled.Value = val;
				_category.SaveToFile(false);
			});
			_includeOthersElement = val2.CreateBool("Include Others", Color.green, LocalMirrorIncludeOthersEnabled.Value, (Action<bool>)delegate(bool val)
			{
				LocalMirrorIncludeOthersEnabled.Value = val;
				_category.SaveToFile(false);
			});
			_showFusionCosmeticsElement = val2.CreateBool("Show Fusion Cosmetics", Color.green, ShowFusionCosmeticsEnabled.Value, (Action<bool>)delegate(bool val)
			{
				ShowFusionCosmeticsEnabled.Value = val;
				_category.SaveToFile(false);
			});
			val2.CreateFunction("Reset To Default", Color.red, (Action)ResetAllTogglesToDefault);
		}

		private static void ResetAllTogglesToDefault()
		{
			try
			{
				LocalMirror.Disable();
			}
			catch
			{
			}
			ApplySliderPref(MirrorDistance, 1.5f);
			LocalMirror.Distance = 1.5f;
			MenuSliderHelper.ResetSlider("Mirror Distance", 1.5f);
			ApplyBoolDefault(_mirrorScaleByHeightElement, MirrorScaleByHeight, defaultValue: true, delegate
			{
				LocalMirror.ScaleByAvatarHeight = true;
			}, delegate
			{
				LocalMirror.ScaleByAvatarHeight = false;
			});
			ApplyBoolDefault(_mirrorFollowHeadElement, MirrorFollowHead, defaultValue: false, delegate
			{
				LocalMirror.FollowHead = true;
			}, delegate
			{
				LocalMirror.FollowHead = false;
			});
			ApplyBoolDefault(_mirrorStayInPlaceElement, MirrorStayInPlace, defaultValue: false, delegate
			{
				LocalMirror.StayInPlace = true;
			}, delegate
			{
				LocalMirror.StayInPlace = false;
			});
			ApplyBoolDefault(_showHolsteredElement, LocalMirrorShowHolsteredEnabled, defaultValue: true, null, null);
			ApplyBoolDefault(_heldItemAwarenessElement, LocalMirrorHeldItemAwarenessEnabled, defaultValue: true, null, null);
			ApplyBoolDefault(_seatAwarenessElement, LocalMirrorSeatAwarenessEnabled, defaultValue: true, null, null);
			ApplyBoolDefault(_proximityAwarenessElement, LocalMirrorProximityAwarenessEnabled, defaultValue: false, null, null);
			ApplySliderPref(LocalMirrorProximityRadius, 2f);
			MenuSliderHelper.ResetSlider("Proximity Radius (m)", 2f);
			ApplyBoolDefault(_proximityVisualElement, LocalMirrorProximityVisualEnabled, defaultValue: true, null, null);
			ApplyBoolDefault(_includeOthersElement, LocalMirrorIncludeOthersEnabled, defaultValue: false, null, null);
			ApplyBoolDefault(_showFusionCosmeticsElement, ShowFusionCosmeticsEnabled, defaultValue: false, null, null);
			_category.SaveToFile(false);
		}

		private static void ApplyBoolDefault(BoolElement element, MelonPreferences_Entry<bool> pref, bool defaultValue, Action apply, Action revert)
		{
			if (pref != null)
			{
				pref.Value = defaultValue;
			}
			if (element != null)
			{
				element.Value = defaultValue;
			}
			try
			{
				if (defaultValue)
				{
					apply?.Invoke();
				}
				else
				{
					revert?.Invoke();
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror] Reset toggle apply failed: " + ex.Message);
			}
		}

		private static void ApplySliderPref(MelonPreferences_Entry<float> pref, float defaultValue)
		{
			if (pref != null)
			{
				pref.Value = defaultValue;
			}
		}

		private static string BuildGradientText(string text, Color startColor, Color endColor)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			StringBuilder stringBuilder = new StringBuilder(text.Length * 22);
			int length = text.Length;
			for (int i = 0; i < length; i++)
			{
				float num = ((length > 1) ? ((float)i / (float)(length - 1)) : 0f);
				Color val = Color.Lerp(startColor, endColor, num);
				int num2 = Mathf.Clamp((int)(val.r * 255f), 0, 255);
				int num3 = Mathf.Clamp((int)(val.g * 255f), 0, 255);
				int num4 = Mathf.Clamp((int)(val.b * 255f), 0, 255);
				stringBuilder.Append("<color=#").Append(num2.ToString("X2")).Append(num3.ToString("X2"))
					.Append(num4.ToString("X2"))
					.Append('>')
					.Append(text[i])
					.Append("</color>");
			}
			return stringBuilder.ToString();
		}
	}
	public class Main : MelonMod
	{
		public const string Version = "1.0.0";

		public override void OnInitializeMelon()
		{
			((MelonBase)this).LoggerInstance.Msg("LocalMirror v1.0.0 loading...");
			Config.Initialize();
			Hooking.OnLevelLoaded += OnLevelLoaded;
			Hooking.OnSwitchAvatarPostfix += OnAvatarChanged;
			((MelonBase)this).LoggerInstance.Msg("LocalMirror v1.0.0 loaded!");
		}

		public override void OnUpdate()
		{
			try
			{
				LocalMirror.OnUpdate();
			}
			catch
			{
			}
			try
			{
				RadialToggle.OnUpdate();
			}
			catch
			{
			}
			try
			{
				BoneMenuScrollClamp.OnUpdate();
			}
			catch
			{
			}
			try
			{
				MenuSliderHelper.OnUpdate();
			}
			catch
			{
			}
		}

		public override void OnFixedUpdate()
		{
		}

		public override void OnLateUpdate()
		{
			try
			{
				LocalMirror.LateEnforce();
			}
			catch
			{
			}
		}

		private static void OnLevelLoaded(LevelInfo levelInfo)
		{
			try
			{
				LocalMirror.OnLevelLoaded();
			}
			catch
			{
			}
			try
			{
				RadialToggle.OnLevelLoaded();
			}
			catch
			{
			}
		}

		private static void OnAvatarChanged(Avatar avatar)
		{
			try
			{
				LocalMirror.OnAvatarChanged(avatar);
			}
			catch
			{
			}
		}
	}
}
namespace LocalMirrorMod.Fixes
{
	public static class BoneMenuScrollButtons
	{
		private static Page _page;

		private static GameObject _navContainer;

		private static Sprite _fillSprite;

		private static Sprite _borderSprite;

		public static void Register(Page page)
		{
			_page = page;
			Menu.OnPageOpened += OnPageOpened;
		}

		private static void OnPageOpened(Page page)
		{
			if (page == _page)
			{
				if ((Object)(object)_navContainer == (Object)null)
				{
					CreateNavButtons();
				}
				if ((Object)(object)_navContainer != (Object)null)
				{
					_navContainer.SetActive(true);
				}
			}
			else if ((Object)(object)_navContainer != (Object)null)
			{
				_navContainer.SetActive(false);
			}
		}

		private static void CreateNavButtons()
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: 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_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: 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_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: 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_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GUIMenu instance = GUIMenu.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				Transform val = ((Component)instance).transform.Find("Page/Content");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Transform val2 = val.Find("Interaction");
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				Transform val3 = val2.Find("ScrollUp");
				Transform val4 = val2.Find("ScrollDown");
				if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
				{
					return;
				}
				Transform val5 = val.Find("Viewport");
				ScrollRect scrollRect = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponent<ScrollRect>() : null);
				if ((Object)(object)scrollRect == (Object)null)
				{
					return;
				}
				TMP_FontAsset val6 = null;
				TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					val6 = ((TMP_Text)componentInChildren).font;
				}
				RectTransform component = ((Component)val3).GetComponent<RectTransform>();
				RectTransform component2 = ((Component)val4).GetComponent<RectTransform>();
				float y = component.anchoredPosition.y;
				float y2 = component2.anchoredPosition.y;
				float num = component.sizeDelta.y;
				float num2 = component.sizeDelta.x;
				if (num2 < 1f)
				{
					num2 = 40f;
				}
				if (num < 1f)
				{
					num = 40f;
				}
				EnsureSprites();
				float num3 = (y + y2) / 2f;
				float num4 = y - num * component.pivot.y;
				float num5 = y2 + num * (1f - component2.pivot.y);
				float num6 = Mathf.Abs(num4 - num5);
				float num7 = 2f;
				float num8 = num2 * 6f;
				_navContainer = new GameObject("LocalMirror_NavButtons");
				_navContainer.transform.SetParent(val2, false);
				RectTransform obj = _navContainer.AddComponent<RectTransform>();
				obj.anchorMin = component.anchorMin;
				obj.anchorMax = component.anchorMax;
				obj.pivot = new Vector2(0.5f, 0.5f);
				obj.anchoredPosition = new Vector2(component.anchoredPosition.x, num3);
				obj.sizeDelta = new Vector2(num8, num6);
				VerticalLayoutGroup obj2 = _navContainer.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)obj2).childAlignment = (TextAnchor)4;
				((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj2).spacing = num7;
				string[] array = new string[5] { "Top", "Upper", "Middle", "Lower", "Bottom" };
				float[] array2 = new float[5] { 0f, 0.25f, 0.5f, 0.75f, 1f };
				GameObject gameObject = ((Component)val3).gameObject;
				for (int i = 0; i < 5; i++)
				{
					float num9 = array2[i];
					string text = array[i];
					GameObject val7 = Object.Instantiate<GameObject>(gameObject, _navContainer.transform);
					((Object)val7).name = text;
					val7.transform.localRotation = Quaternion.identity;
					LayoutElement component3 = val7.GetComponent<LayoutElement>();
					if ((Object)(object)component3 != (Object)null)
					{
						Object.Destroy((Object)(object)component3);
					}
					BoxCollider component4 = val7.GetComponent<BoxCollider>();
					if ((Object)(object)component4 != (Object)null)
					{
						float num10 = (num6 - num7 * 4f) / 5f;
						component4.size = new Vector3(num8, num10, component4.size.z);
						component4.center = Vector3.zero;
					}
					Button component5 = val7.GetComponent<Button>();
					if ((Object)(object)component5 != (Object)null)
					{
						((UnityEventBase)component5.onClick).RemoveAllListeners();
						float capturedFrac = num9;
						((UnityEvent)component5.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
						{
							//IL_001c: Unknown result type (might be due to invalid IL or missing references)
							//IL_0031: Unknown result type (might be due to invalid IL or missing references)
							scrollRect.normalizedPosition = new Vector2(0f, 1f - capturedFrac);
							scrollRect.velocity = Vector2.zero;
						}));
						ColorBlock colors = ((Selectable)component5).colors;
						((ColorBlock)(ref colors)).normalColor = new Color(1f, 1f, 1f, 0.06f);
						((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 1f, 1f, 0.25f);
						((ColorBlock)(ref colors)).pressedColor = new Color(1f, 1f, 1f, 1f);
						((ColorBlock)(ref colors)).selectedColor = new Color(1f, 1f, 1f, 0.06f);
						((ColorBlock)(ref colors)).colorMultiplier = 1f;
						((ColorBlock)(ref colors)).fadeDuration = 0.08f;
						((Selectable)component5).colors = colors;
					}
					for (int num11 = val7.transform.childCount - 1; num11 >= 0; num11--)
					{
						Object.Destroy((Object)(object)((Component)val7.transform.GetChild(num11)).gameObject);
					}
					Image component6 = val7.GetComponent<Image>();
					if ((Object)(object)component6 != (Object)null)
					{
						if ((Object)(object)_fillSprite != (Object)null)
						{
							component6.sprite = _fillSprite;
							component6.type = (Type)1;
						}
						((Graphic)component6).color = Color.white;
						((Graphic)component6).raycastTarget = true;
					}
					GameObject val8 = new GameObject("Border");
					val8.transform.SetParent(val7.transform, false);
					RectTransform obj3 = val8.AddComponent<RectTransform>();
					obj3.anchorMin = Vector2.zero;
					obj3.anchorMax = Vector2.one;
					obj3.sizeDelta = Vector2.zero;
					obj3.anchoredPosition = Vector2.zero;
					Image val9 = val8.AddComponent<Image>();
					if ((Object)(object)_borderSprite != (Object)null)
					{
						val9.sprite = _borderSprite;
						val9.type = (Type)1;
					}
					((Graphic)val9).color = Color.white;
					((Graphic)val9).raycastTarget = false;
					GameObject val10 = new GameObject("Text");
					val10.transform.SetParent(val7.transform, false);
					RectTransform obj4 = val10.AddComponent<RectTransform>();
					obj4.anchorMin = Vector2.zero;
					obj4.anchorMax = Vector2.one;
					obj4.sizeDelta = Vector2.zero;
					obj4.anchoredPosition = Vector2.zero;
					TextMeshProUGUI val11 = val10.AddComponent<TextMeshProUGUI>();
					((TMP_Text)val11).text = text;
					((TMP_Text)val11).alignment = (TextAlignmentOptions)514;
					((Graphic)val11).color = Color.white;
					((TMP_Text)val11).enableAutoSizing = true;
					((TMP_Text)val11).fontSizeMin = 6f;
					((TMP_Text)val11).fontSizeMax = 42f;
					if ((Object)(object)val6 != (Object)null)
					{
						((TMP_Text)val11).font = val6;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[BoneMenuScrollButtons] CreateNavButtons: " + ex.Message);
			}
		}

		private static void EnsureSprites()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_009b: 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)
			if ((Object)(object)_fillSprite != (Object)null)
			{
				return;
			}
			int num = 64;
			int num2 = 12;
			int num3 = 3;
			Texture2D val = new Texture2D(num, num, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			Texture2D val2 = new Texture2D(num, num, (TextureFormat)4, false);
			((Texture)val2).filterMode = (FilterMode)1;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num4 = RoundedRectSDF(j, i, num, num, num2);
					bool flag = num4 <= 0f;
					bool flag2 = flag && num4 > (float)(-num3);
					val.SetPixel(j, i, flag ? Color.white : Color.clear);
					val2.SetPixel(j, i, flag2 ? Color.white : Color.clear);
				}
			}
			val.Apply();
			val2.Apply();
			float num5 = (float)num2 + 1f;
			Vector4 val3 = default(Vector4);
			((Vector4)(ref val3))..ctor(num5, num5, num5, num5);
			_fillSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val3);
			_borderSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val3);
		}

		private static float RoundedRectSDF(int px, int py, int w, int h, int r)
		{
			bool num = px < r || px > w - r - 1;
			bool flag = py < r || py > h - r - 1;
			if (num && flag)
			{
				float num2 = ((px < r) ? r : (w - r - 1));
				float num3 = ((py < r) ? r : (h - r - 1));
				float num4 = (float)px - num2;
				float num5 = (float)py - num3;
				return Mathf.Sqrt(num4 * num4 + num5 * num5) - (float)r;
			}
			float num6 = px;
			float num7 = w - 1 - px;
			float num8 = py;
			float num9 = h - 1 - py;
			return 0f - Mathf.Min(Mathf.Min(num6, num7), Mathf.Min(num8, num9));
		}
	}
	public static class BoneMenuScrollClamp
	{
		private static Page _ourPage;

		private static bool _hooked;

		private static bool _active;

		private static ScrollRect _scrollRect;

		private const float TargetVelocity = 1500f;

		public static void Register(Page page)
		{
			_ourPage = page;
			if (!_hooked)
			{
				Menu.OnPageOpened += OnPageOpened;
				_hooked = true;
			}
		}

		private static void OnPageOpened(Page page)
		{
			_active = page == _ourPage;
			if (_active && (Object)(object)_scrollRect == (Object)null)
			{
				CacheScrollRect();
			}
		}

		private static void CacheScrollRect()
		{
			try
			{
				GUIMenu instance = GUIMenu.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					Transform val = ((Component)instance).transform.Find("Page/Content/Viewport");
					if ((Object)(object)val != (Object)null)
					{
						_scrollRect = ((Component)val).GetComponent<ScrollRect>();
					}
				}
			}
			catch
			{
			}
		}

		public static void OnUpdate()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			if (!_active || (Object)(object)_scrollRect == (Object)null)
			{
				return;
			}
			try
			{
				Vector2 velocity = _scrollRect.velocity;
				if (Mathf.Abs(velocity.y) > 1f)
				{
					_scrollRect.velocity = new Vector2(velocity.x, Mathf.Sign(velocity.y) * 1500f);
				}
			}
			catch
			{
			}
		}
	}
	public static class LocalMirror
	{
		private struct HeldItemState
		{
			public int PlayerItemId;

			public GameObject CloneVisual;

			public GameObject PlayerSourceRoot;

			public ItemPersistentSync PersistentSync;
		}

		private struct SeatedItemState
		{
			public int PlayerSeatRootId;

			public GameObject CloneVisual;

			public GameObject PlayerSourceRoot;

			public ItemPersistentSync PersistentSync;
		}

		private class RemoteRigClone
		{
			public RigManager SourceRig;

			public int SourceRigId;

			public GameObject Visual;

			public Transform SourceAvatarT;

			public List<Transform> SrcBones = new List<Transform>();

			public List<Transform> DstBones = new List<Transform>();

			public List<(SkinnedMeshRenderer src, SkinnedMeshRenderer dst)> RendererPairs = new List<(SkinnedMeshRenderer, SkinnedMeshRenderer)>();

			public float LastProxTime;

			public float LastHeldTime;

			public Dictionary<int, HolsterVisual> HolsterVisuals;

			public Dictionary<string, GameObject> RemoteCosmetics;

			public HashSet<string> RemoteCosmeticsLoading;

			public int FrameCounter;

			public bool Functional;
		}

		private class HolsterVisual
		{
			public int HostId;

			public GameObject Visual;
		}

		private class ItemPersistentSync
		{
			public List<(Transform src, Transform dst)> Bones = new List<(Transform, Transform)>();

			public List<(SkinnedMeshRenderer src, SkinnedMeshRenderer dst)> SkinnedRenderers = new List<(SkinnedMeshRenderer, SkinnedMeshRenderer)>();

			public List<(MeshRenderer src, MeshRenderer dst)> MeshRenderers = new List<(MeshRenderer, MeshRenderer)>();
		}

		private static bool _enabled;

		private static bool _fusionLoadedChecked;

		private static bool _fusionLoadedCached;

		private static bool _firstEnableFixDone;

		private static GameObject _root;

		private static Transform _volumeTran;

		private static Transform _reflectTran;

		private static Transform _reflectionInitalTran;

		private static Transform _avatarsTran;

		private static Mirror _mirror;

		public static float Distance = 1.5f;

		public static bool ScaleByAvatarHeight = true;

		public static bool FollowHead = false;

		private static Vector3? _frozenFwd;

		public static bool StayInPlace = false;

		private const float BaseAvatarHeight = 1.75f;

		private static bool _waitingForClone;

		private static readonly List<Transform> _srcBones = new List<Transform>();

		private static readonly List<Transform> _dstBones = new List<Transform>();

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

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

		private static readonly List<(SkinnedMeshRenderer src, SkinnedMeshRenderer dst)> _rendererPairs = new List<(SkinnedMeshRenderer, SkinnedMeshRenderer)>();

		private static bool _localAvatarFunctional;

		private static int _localStateSyncFrameCounter;

		private const int LocalStateSyncPeriod = 6;

		private static readonly Dictionary<int, GameObject> _cosmeticMirrorCopies = new Dictionary<int, GameObject>();

		private static HeldItemState _leftHeldState;

		private static HeldItemState _rightHeldState;

		private static SeatedItemState _seatedState;

		private static readonly Dictionary<int, GameObject> _proximityVisuals = new Dictionary<int, GameObject>();

		private static readonly Dictionary<int, ItemPersistentSync> _proximityPersistentSync = new Dictionary<int, ItemPersistentSync>();

		private static readonly Dictionary<int, GameObject> _proximitySourceRoots = new Dictionary<int, GameObject>();

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

		private const int RemoteRigSlowSyncPeriod = 6;

		private static readonly Dictionary<int, HolsterVisual> _localHolsterVisuals = new Dictionary<int, HolsterVisual>();

		private static readonly Dictionary<int, RemoteRigClone> _remoteRigClones = new Dictionary<int, RemoteRigClone>();

		private static float _remoteEligibilityNextTime;

		private const float EligibilityScanPeriod = 0.1f;

		private static bool _remoteScanForcedOnce;

		private const float ProximityGrace = 0.5f;

		private const float HeldGrace = 0.25f;

		private static int _remoteCloneLastWarnFrame = -1;

		private static GameObject _proximityCircleGo;

		private static LineRenderer _proximityCircleLine;

		private const int ProximityCircleSegments = 64;

		private static Transform _playerLeftHandTransform;

		private static Transform _playerRightHandTransform;

		private static Transform _cloneLeftHandTransform;

		private static Transform _cloneRightHandTransform;

		private static FieldInfo _fAccessoryInstances;

		private static bool _accessoryInstancesResolveAttempted;

		private static FieldInfo _fCosmeticSpawnableCrateRef;

		private static bool _cosmeticSpawnableCrateRefResolved;

		private static bool _poseCopyActive;

		private static int _pendingRebuildFrames;

		private const int RebuildDelayFrames = 6;

		private static FieldInfo _fReflectTran;

		private static FieldInfo _fReflectionInital;

		private static FieldInfo _fRigManager;

		private static FieldInfo _fAvatarsTran;

		private static FieldInfo _fCachedReflections;

		private static PropertyInfo _pReflectTran;

		private static PropertyInfo _pReflectionInital;

		private static PropertyInfo _pRigManager;

		private static PropertyInfo _pAvatarsTran;

		private static PropertyInfo _pCachedReflections;

		private static MethodInfo _mSwapNoArg;

		private static bool _accessorsResolved;

		private static int _lastPreCullFrame = -1;

		private static bool _preCullHooked;

		private static Action<Camera> _preCullDelegate;

		private static bool _gripHooksInstalled;

		private static Action<Grip, Hand> _gripAttachedDelegate;

		private static Action<Grip, Hand> _gripDetachedDelegate;

		private static readonly HashSet<string> _functionalDriverComponentNames = new HashSet<string> { "UltEventHolder", "DelayedUltEventHolder", "LifeCycleEvents", "UpdateEvents", "ZoneEvents" };

		private static FieldInfo[] _cachedGripEventFields;

		private static readonly HashSet<string> _mirrorBlacklistBarcodes = new HashSet<string> { "Lakatrazz.FusionContent.Spawnable.FusionMenu", "InnocentCitizen.Helldivers2StratagemBall.Spawnable.Helldivers2StratagemBall1" };

		public static bool Enabled => _enabled;

		public static event Action<bool> OnEnabledChanged;

		private static bool IsFusionLoaded()
		{
			if (_fusionLoadedChecked)
			{
				return _fusionLoadedCached;
			}
			_fusionLoadedChecked = true;
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					if (assemblies[i].GetName().Name == "LabFusion")
					{
						_fusionLoadedCached = true;
						break;
					}
				}
			}
			catch
			{
			}
			return _fusionLoadedCached;
		}

		private static void RemoteWarn(string msg)
		{
			int num = -1;
			try
			{
				num = Time.frameCount;
			}
			catch
			{
			}
			if (num == _remoteCloneLastWarnFrame)
			{
				return;
			}
			_remoteCloneLastWarnFrame = num;
			try
			{
				MelonLogger.Warning("[LocalMirror.IncludeOthers] " + msg);
			}
			catch
			{
			}
		}

		public static void Enable()
		{
			if (_enabled)
			{
				return;
			}
			try
			{
				BuildRig();
				_enabled = true;
				HookPreCull();
				HookGripEvents();
				try
				{
					LocalMirror.OnEnabledChanged?.Invoke(obj: true);
				}
				catch
				{
				}
				if (!_firstEnableFixDone)
				{
					_firstEnableFixDone = true;
					try
					{
						MelonCoroutines.Start(FirstEnableShake());
						return;
					}
					catch (Exception ex)
					{
						MelonLogger.Warning("[LocalMirror] FirstEnableShake start threw: " + ex.Message);
						return;
					}
				}
			}
			catch (Exception ex2)
			{
				MelonLogger.Warning("[LocalMirror] enable threw: " + ex2.Message);
				Cleanup();
			}
		}

		private static IEnumerator FirstEnableShake()
		{
			int waited = 0;
			while ((!_enabled || !_poseCopyActive) && waited++ < 600)
			{
				yield return null;
			}
			if (!_enabled)
			{
				yield break;
			}
			if (waited >= 600)
			{
				MelonLogger.Warning("[LocalMirror] FirstEnableShake: step1 timed out waiting for initial settle");
				yield break;
			}
			Disable();
			waited = 0;
			while ((_enabled || _poseCopyActive) && waited++ < 600)
			{
				yield return null;
			}
			if (waited >= 600)
			{
				MelonLogger.Warning("[LocalMirror] FirstEnableShake: step2 timed out waiting for disable settle");
				yield break;
			}
			Enable();
			waited = 0;
			while ((!_enabled || !_poseCopyActive) && waited++ < 600)
			{
				yield return null;
			}
			if (waited >= 600)
			{
				MelonLogger.Warning("[LocalMirror] FirstEnableShake: step3 timed out waiting for second enable settle");
			}
		}

		public static void Disable()
		{
			if (!_enabled)
			{
				return;
			}
			_enabled = false;
			UnhookPreCull();
			UnhookGripEvents();
			Cleanup();
			try
			{
				LocalMirror.OnEnabledChanged?.Invoke(obj: false);
			}
			catch
			{
			}
		}

		private static void HookPreCull()
		{
			if (_preCullHooked)
			{
				return;
			}
			try
			{
				_preCullDelegate = OnAnyCameraPreCull;
				Camera.onPreCull += CameraCallback.op_Implicit(_preCullDelegate);
				_preCullHooked = true;
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror] HookPreCull threw: " + ex.Message);
			}
		}

		private static void UnhookPreCull()
		{
			if (!_preCullHooked)
			{
				return;
			}
			try
			{
				if (_preCullDelegate != null)
				{
					Camera.onPreCull -= CameraCallback.op_Implicit(_preCullDelegate);
				}
			}
			catch
			{
			}
			_preCullDelegate = null;
			_preCullHooked = false;
			_lastPreCullFrame = -1;
		}

		private static void OnAnyCameraPreCull(Camera _)
		{
			if (!_enabled || !_poseCopyActive)
			{
				return;
			}
			int frameCount = Time.frameCount;
			if (frameCount == _lastPreCullFrame)
			{
				return;
			}
			_lastPreCullFrame = frameCount;
			try
			{
				CopyPose();
			}
			catch
			{
			}
		}

		private static void HookGripEvents()
		{
			if (_gripHooksInstalled)
			{
				return;
			}
			try
			{
				_gripAttachedDelegate = OnGripAttachedRemote;
				_gripDetachedDelegate = OnGripDetachedRemote;
				Hooking.OnGripAttached += _gripAttachedDelegate;
				Hooking.OnGripDetached += _gripDetachedDelegate;
				_gripHooksInstalled = true;
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror] HookGripEvents threw: " + ex.Message);
			}
		}

		private static void UnhookGripEvents()
		{
			if (!_gripHooksInstalled)
			{
				return;
			}
			try
			{
				if (_gripAttachedDelegate != null)
				{
					Hooking.OnGripAttached -= _gripAttachedDelegate;
				}
				if (_gripDetachedDelegate != null)
				{
					Hooking.OnGripDetached -= _gripDetachedDelegate;
				}
			}
			catch
			{
			}
			_gripAttachedDelegate = null;
			_gripDetachedDelegate = null;
			_gripHooksInstalled = false;
		}

		private static void OnGripAttachedRemote(Grip grip, Hand hand)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			if ((Object)(object)grip == (Object)null || (Object)(object)hand == (Object)null)
			{
				return;
			}
			try
			{
				if (!Config.LocalMirrorIncludeOthersEnabled.Value || !Config.LocalMirrorHeldItemAwarenessEnabled.Value)
				{
					return;
				}
			}
			catch
			{
				return;
			}
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.physicsRig == (Object)null)
			{
				return;
			}
			int num = 0;
			try
			{
				num = ((Object)(Component)hand).GetInstanceID();
			}
			catch
			{
				return;
			}
			int num2 = 0;
			int num3 = 0;
			try
			{
				if ((Object)(object)rigManager.physicsRig.leftHand != (Object)null)
				{
					num2 = ((Object)(Component)rigManager.physicsRig.leftHand).GetInstanceID();
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)rigManager.physicsRig.rightHand != (Object)null)
				{
					num3 = ((Object)(Component)rigManager.physicsRig.rightHand).GetInstanceID();
				}
			}
			catch
			{
			}
			if (num != num2 && num != num3)
			{
				return;
			}
			Transform val = null;
			try
			{
				val = ((Component)grip).transform;
			}
			catch
			{
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			RigManager val2 = null;
			try
			{
				val2 = ((Component)val).GetComponentInParent<RigManager>();
			}
			catch
			{
				return;
			}
			if (!((Object)(object)val2 == (Object)null))
			{
				int instanceID = ((Object)((Component)rigManager).gameObject).GetInstanceID();
				if (((Object)((Component)val2).gameObject).GetInstanceID() != instanceID)
				{
					_remoteEligibilityNextTime = 0f;
					_remoteScanForcedOnce = true;
				}
			}
		}

		private static void OnGripDetachedRemote(Grip grip, Hand hand)
		{
			//IL_00a0: 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_003c: 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)
			try
			{
				if ((Object)(object)grip == (Object)null || (Object)(object)hand == (Object)null)
				{
					return;
				}
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.physicsRig == (Object)null)
				{
					return;
				}
				int num = 0;
				try
				{
					num = ((Object)(Component)hand).GetInstanceID();
				}
				catch
				{
					return;
				}
				int num2 = 0;
				int num3 = 0;
				try
				{
					if ((Object)(object)rigManager.physicsRig.leftHand != (Object)null)
					{
						num2 = ((Object)(Component)rigManager.physicsRig.leftHand).GetInstanceID();
					}
				}
				catch
				{
				}
				try
				{
					if ((Object)(object)rigManager.physicsRig.rightHand != (Object)null)
					{
						num3 = ((Object)(Component)rigManager.physicsRig.rightHand).GetInstanceID();
					}
				}
				catch
				{
				}
				if (num != num2 && num != num3)
				{
					return;
				}
				Transform val = null;
				try
				{
					val = ((Component)grip).transform;
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				RigManager val2 = null;
				try
				{
					val2 = ((Component)val).GetComponentInParent<RigManager>();
				}
				catch
				{
				}
				if (!((Object)(object)val2 == (Object)null))
				{
					int instanceID = ((Object)((Component)val2).gameObject).GetInstanceID();
					if (instanceID != ((Object)((Component)rigManager).gameObject).GetInstanceID() && _remoteRigClones.TryGetValue(instanceID, out var value) && value != null)
					{
						value.LastHeldTime = -1E+09f;
						_remoteEligibilityNextTime = 0f;
						_remoteScanForcedOnce = true;
					}
				}
			}
			catch
			{
			}
		}

		public static void Toggle()
		{
			if (_enabled)
			{
				Disable();
			}
			else
			{
				Enable();
			}
		}

		public static void OnLevelLoaded()
		{
			if (_enabled)
			{
				Disable();
				Enable();
			}
			_pendingRebuildFrames = 0;
			_firstEnableFixDone = false;
		}

		public static void OnAvatarChanged(Avatar avatar)
		{
			if (!_enabled || (Object)(object)avatar == (Object)null)
			{
				return;
			}
			try
			{
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager == (Object)null)
				{
					return;
				}
				RigManager componentInParent = ((Component)avatar).GetComponentInParent<RigManager>();
				if ((Object)(object)componentInParent == (Object)null || ((Object)componentInParent).GetInstanceID() != ((Object)rigManager).GetInstanceID())
				{
					return;
				}
			}
			catch
			{
				return;
			}
			_pendingRebuildFrames = 6;
		}

		public static void LateEnforce()
		{
			if (!_enabled || !_poseCopyActive)
			{
				return;
			}
			try
			{
				CopyPose();
			}
			catch
			{
			}
		}

		public static void OnUpdate()
		{
			if (!_enabled)
			{
				return;
			}
			if (_pendingRebuildFrames > 0)
			{
				_pendingRebuildFrames--;
				if (_pendingRebuildFrames == 0)
				{
					try
					{
						RigManager rigManager = Player.RigManager;
						if ((Object)(object)rigManager != (Object)null && (Object)(object)rigManager.avatar != (Object)null && (Object)(object)((Component)rigManager.avatar).transform != (Object)null)
						{
							Disable();
							Enable();
							return;
						}
						_pendingRebuildFrames = 2;
					}
					catch (Exception ex)
					{
						MelonLogger.Warning("[LocalMirror] avatar-swap rebuild threw: " + ex.Message);
					}
				}
			}
			if ((Object)(object)_root == (Object)null)
			{
				Disable();
				return;
			}
			try
			{
				FollowPlayer();
			}
			catch
			{
			}
			if (_waitingForClone && HasActiveClone())
			{
				_waitingForClone = false;
				TakeOverPoseCopy();
			}
			if (!_poseCopyActive)
			{
				return;
			}
			try
			{
				CopyPose();
			}
			catch
			{
			}
		}

		private static bool HasActiveClone()
		{
			if ((Object)(object)_avatarsTran == (Object)null)
			{
				return false;
			}
			try
			{
				for (int i = 0; i < _avatarsTran.childCount; i++)
				{
					Transform child = _avatarsTran.GetChild(i);
					if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeInHierarchy)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static void TakeOverPoseCopy()
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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)
			try
			{
				Object.Destroy((Object)(object)_mirror);
			}
			catch
			{
			}
			_mirror = null;
			_srcBones.Clear();
			_dstBones.Clear();
			_skipPositionCopy.Clear();
			_headRegionInstanceIds.Clear();
			try
			{
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.avatar == (Object)null)
				{
					MelonLogger.Warning("[LocalMirror] take-over skipped: no player avatar.");
					return;
				}
				Transform val = null;
				if ((Object)(object)_avatarsTran != (Object)null)
				{
					for (int i = 0; i < _avatarsTran.childCount; i++)
					{
						Transform child = _avatarsTran.GetChild(i);
						if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeInHierarchy)
						{
							val = child;
							break;
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					MelonLogger.Warning("[LocalMirror] take-over skipped: no active clone under AVATARS.");
					return;
				}
				try
				{
					Vector3 localScale = ((Component)rigManager.avatar).transform.localScale;
					val.localScale = new Vector3(0f - localScale.x, localScale.y, localScale.z);
				}
				catch (Exception ex)
				{
					MelonLogger.Warning("[LocalMirror] could not set clone scale: " + ex.Message);
				}
				try
				{
					Avatar component = ((Component)val).GetComponent<Avatar>();
					if ((Object)(object)component != (Object)null)
					{
						component.eyeOffset = 0f;
					}
				}
				catch (Exception ex2)
				{
					MelonLogger.Warning("[LocalMirror] eyeOffset reset threw: " + ex2.Message);
				}
				try
				{
					BuildRendererPairs(((Component)rigManager.avatar).transform, val);
					SyncRendererStates();
				}
				catch (Exception ex3)
				{
					MelonLogger.Warning("[LocalMirror] renderer pair build threw: " + ex3.Message);
				}
				try
				{
					DisableCloneGrips(val);
				}
				catch (Exception ex4)
				{
					MelonLogger.Warning("[LocalMirror] DisableCloneGrips threw: " + ex4.Message);
				}
				try
				{
					_localAvatarFunctional = IsAvatarFunctional(((Component)rigManager.avatar).transform);
					_localStateSyncFrameCounter = 0;
				}
				catch (Exception ex5)
				{
					MelonLogger.Warning("[LocalMirror] IsAvatarFunctional threw: " + ex5.Message + " — defaulting to functional");
					_localAvatarFunctional = true;
				}
				ResolveHumanoidHeadInstanceIds(val);
				ResolveHumanoidHandTransforms(((Component)rigManager.avatar).transform, val);
				BuildBoneMap(((Component)rigManager.avatar).transform, val);
				_poseCopyActive = true;
			}
			catch (Exception ex6)
			{
				MelonLogger.Warning("[LocalMirror] TakeOverPoseCopy threw: " + ex6.Message);
			}
		}

		private static void BuildBoneMap(Transform src, Transform dst)
		{
			if ((Object)(object)src == (Object)null || (Object)(object)dst == (Object)null)
			{
				return;
			}
			int childCount = src.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = src.GetChild(i);
				if (!((Object)(object)child == (Object)null))
				{
					Transform val = dst.Find(((Object)child).name);
					if (!((Object)(object)val == (Object)null))
					{
						BuildBoneMapInternal(child, val);
					}
				}
			}
		}

		private static void BuildBoneMapInternal(Transform src, Transform dst)
		{
			if ((Object)(object)src == (Object)null || (Object)(object)dst == (Object)null)
			{
				return;
			}
			int count = _srcBones.Count;
			_srcBones.Add(src);
			_dstBones.Add(dst);
			try
			{
				if (_headRegionInstanceIds.Contains(((Object)dst).GetInstanceID()))
				{
					_skipPositionCopy.Add(count);
				}
			}
			catch
			{
			}
			int childCount = src.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = src.GetChild(i);
				if (!((Object)(object)child == (Object)null))
				{
					Transform val = dst.Find(((Object)child).name);
					if (!((Object)(object)val == (Object)null))
					{
						BuildBoneMapInternal(child, val);
					}
				}
			}
		}

		private static void ResolveHumanoidHeadInstanceIds(Transform cloneRoot)
		{
			if ((Object)(object)cloneRoot == (Object)null)
			{
				return;
			}
			try
			{
				Animator val = ((Component)cloneRoot).GetComponent<Animator>();
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)cloneRoot).GetComponentInChildren<Animator>(true);
				}
				if (!((Object)(object)val == (Object)null))
				{
					bool flag = false;
					try
					{
						flag = val.isHuman;
					}
					catch
					{
					}
					if (flag)
					{
						AddHumanoidBone(val, (HumanBodyBones)10);
						AddHumanoidBone(val, (HumanBodyBones)9);
						AddHumanoidBone(val, (HumanBodyBones)23);
						AddHumanoidBone(val, (HumanBodyBones)21);
						AddHumanoidBone(val, (HumanBodyBones)22);
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror] ResolveHumanoidHeadInstanceIds threw: " + ex.Message);
			}
		}

		private static void AddHumanoidBone(Animator animator, HumanBodyBones bone)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform boneTransform = animator.GetBoneTransform(bone);
				if ((Object)(object)boneTransform != (Object)null)
				{
					_headRegionInstanceIds.Add(((Object)boneTransform).GetInstanceID());
				}
			}
			catch
			{
			}
		}

		private static void ResolveHumanoidHandTransforms(Transform playerAvatarT, Transform cloneAvatarT)
		{
			_playerLeftHandTransform = null;
			_playerRightHandTransform = null;
			_cloneLeftHandTransform = null;
			_cloneRightHandTransform = null;
			try
			{
				Animator val = ((playerAvatarT != null) ? ((Component)playerAvatarT).GetComponent<Animator>() : null);
				if ((Object)(object)val == (Object)null)
				{
					val = ((playerAvatarT != null) ? ((Component)playerAvatarT).GetComponentInChildren<Animator>(true) : null);
				}
				if ((Object)(object)val != (Object)null && val.isHuman)
				{
					try
					{
						_playerLeftHandTransform = val.GetBoneTransform((HumanBodyBones)17);
					}
					catch
					{
					}
					try
					{
						_playerRightHandTransform = val.GetBoneTransform((HumanBodyBones)18);
					}
					catch
					{
					}
				}
				Animator val2 = ((cloneAvatarT != null) ? ((Component)cloneAvatarT).GetComponent<Animator>() : null);
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((cloneAvatarT != null) ? ((Component)cloneAvatarT).GetComponentInChildren<Animator>(true) : null);
				}
				if ((Object)(object)val2 != (Object)null && val2.isHuman)
				{
					try
					{
						_cloneLeftHandTransform = val2.GetBoneTransform((HumanBodyBones)17);
					}
					catch
					{
					}
					try
					{
						_cloneRightHandTransform = val2.GetBoneTransform((HumanBodyBones)18);
						return;
					}
					catch
					{
						return;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror] ResolveHumanoidHandTransforms threw: " + ex.Message);
			}
		}

		private static void BuildRendererPairs(Transform playerRoot, Transform cloneRoot)
		{
			_rendererPairs.Clear();
			if ((Object)(object)playerRoot == (Object)null || (Object)(object)cloneRoot == (Object)null)
			{
				return;
			}
			Il2CppArrayBase<SkinnedMeshRenderer> componentsInChildren = ((Component)playerRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			Il2CppArrayBase<SkinnedMeshRenderer> componentsInChildren2 = ((Component)cloneRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			if (componentsInChildren == null || componentsInChildren2 == null)
			{
				return;
			}
			Dictionary<string, SkinnedMeshRenderer> dictionary = new Dictionary<string, SkinnedMeshRenderer>();
			for (int i = 0; i < componentsInChildren.Count; i++)
			{
				SkinnedMeshRenderer val = componentsInChildren[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = null;
					try
					{
						text = ((Object)((Component)val).gameObject).name;
					}
					catch
					{
					}
					if (!string.IsNullOrEmpty(text) && !dictionary.ContainsKey(text))
					{
						dictionary[text] = val;
					}
				}
			}
			for (int j = 0; j < componentsInChildren2.Count; j++)
			{
				SkinnedMeshRenderer val2 = componentsInChildren2[j];
				if (!((Object)(object)val2 == (Object)null))
				{
					string text2 = null;
					try
					{
						text2 = ((Object)((Component)val2).gameObject).name;
					}
					catch
					{
					}
					if (!string.IsNullOrEmpty(text2) && dictionary.TryGetValue(text2, out var value) && !((Object)(object)value == (Object)null))
					{
						_rendererPairs.Add((value, val2));
					}
				}
			}
		}

		private static void SyncRendererStates()
		{
			bool flag = _localAvatarFunctional && _localStateSyncFrameCounter % 6 == 0;
			int count = _rendererPairs.Count;
			for (int i = 0; i < count; i++)
			{
				var (val, val2) = _rendererPairs[i];
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
				{
					continue;
				}
				bool flag2 = true;
				try
				{
					flag2 = ((Renderer)val).enabled;
				}
				catch
				{
				}
				try
				{
					if (((Renderer)val2).enabled != flag2)
					{
						((Renderer)val2).enabled = flag2;
					}
				}
				catch
				{
				}
				try
				{
					if (((Renderer)val2).forceRenderingOff)
					{
						((Renderer)val2).forceRenderingOff = false;
					}
				}
				catch
				{
				}
				if (!flag)
				{
					continue;
				}
				try
				{
					Mesh sharedMesh = val.sharedMesh;
					if (!((Object)(object)sharedMesh != (Object)null) || !((Object)(object)val2.sharedMesh != (Object)null))
					{
						continue;
					}
					int blendShapeCount = sharedMesh.blendShapeCount;
					for (int j = 0; j < blendShapeCount; j++)
					{
						float blendShapeWeight;
						try
						{
							blendShapeWeight = val.GetBlendShapeWeight(j);
						}
						catch
						{
							continue;
						}
						float blendShapeWeight2;
						try
						{
							blendShapeWeight2 = val2.GetBlendShapeWeight(j);
						}
						catch
						{
							continue;
						}
						if (Mathf.Abs(blendShapeWeight2 - blendShapeWeight) > 0.001f)
						{
							try
							{
								val2.SetBlendShapeWeight(j, blendShapeWeight);
							}
							catch
							{
							}
						}
					}
				}
				catch
				{
				}
			}
		}

		private static void DisableCloneGrips(Transform cloneRoot)
		{
			if ((Object)(object)cloneRoot == (Object)null)
			{
				return;
			}
			Il2CppArrayBase<Grip> componentsInChildren = ((Component)cloneRoot).GetComponentsInChildren<Grip>(true);
			if (componentsInChildren == null)
			{
				return;
			}
			for (int i = 0; i < componentsInChildren.Count; i++)
			{
				Grip val = componentsInChildren[i];
				if (!((Object)(object)val == (Object)null))
				{
					try
					{
						((Behaviour)val).enabled = false;
					}
					catch
					{
					}
				}
			}
		}

		private static bool IsAvatarFunctional(Transform avatarRoot)
		{
			if ((Object)(object)avatarRoot == (Object)null)
			{
				return false;
			}
			try
			{
				Il2CppArrayBase<Grip> componentsInChildren = ((Component)avatarRoot).GetComponentsInChildren<Grip>(true);
				if (componentsInChildren != null)
				{
					int count = componentsInChildren.Count;
					for (int i = 0; i < count; i++)
					{
						Grip val = componentsInChildren[i];
						if (!((Object)(object)val == (Object)null) && GripHasWiredEvents(val))
						{
							return true;
						}
					}
				}
				Il2CppArrayBase<Component> componentsInChildren2 = ((Component)avatarRoot).GetComponentsInChildren<Component>(true);
				if (componentsInChildren2 != null)
				{
					int count2 = componentsInChildren2.Count;
					for (int j = 0; j < count2; j++)
					{
						Component val2 = componentsInChildren2[j];
						if ((Object)(object)val2 == (Object)null)
						{
							continue;
						}
						string text = null;
						try
						{
							text = ((MemberInfo)((Object)val2).GetIl2CppType()).Name;
						}
						catch
						{
						}
						if (text == null)
						{
							try
							{
								text = ((object)val2).GetType().Name;
							}
							catch
							{
							}
						}
						if (text != null && _functionalDriverComponentNames.Contains(text))
						{
							return true;
						}
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror.Functional] IsAvatarFunctional threw: " + ex.Message);
			}
			return false;
		}

		private static bool GripHasWiredEvents(Grip g)
		{
			if ((Object)(object)g == (Object)null)
			{
				return false;
			}
			try
			{
				if (_cachedGripEventFields == null)
				{
					FieldInfo[] fields = typeof(Grip).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					List<FieldInfo> list = new List<FieldInfo>();
					if (fields != null)
					{
						foreach (FieldInfo fieldInfo in fields)
						{
							if (!(fieldInfo == null) && typeof(UnityEventBase).IsAssignableFrom(fieldInfo.FieldType))
							{
								list.Add(fieldInfo);
							}
						}
					}
					_cachedGripEventFields = list.ToArray();
				}
				int num = _cachedGripEventFields.Length;
				for (int j = 0; j < num; j++)
				{
					FieldInfo fieldInfo2 = _cachedGripEventFields[j];
					object obj = null;
					try
					{
						obj = fieldInfo2.GetValue(g);
					}
					catch
					{
						continue;
					}
					UnityEventBase val = (UnityEventBase)((obj is UnityEventBase) ? obj : null);
					if (val != null)
					{
						int num2 = 0;
						try
						{
							num2 = val.GetPersistentEventCount();
						}
						catch
						{
						}
						if (num2 > 0)
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static void SyncProximityMirror()
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: 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)
			bool flag = false;
			try
			{
				flag = Config.LocalMirrorProximityAwarenessEnabled.Value;
			}
			catch
			{
			}
			if (!flag)
			{
				if (_proximityVisuals.Count > 0)
				{
					ClearProximityVisuals();
				}
				return;
			}
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.avatar == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)rigManager.avatar).transform;
			Transform val = null;
			if ((Object)(object)_avatarsTran != (Object)null)
			{
				for (int i = 0; i < _avatarsTran.childCount; i++)
				{
					Transform child = _avatarsTran.GetChild(i);
					if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeInHierarchy)
					{
						val = child;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			float num = 5f;
			try
			{
				num = Config.LocalMirrorProximityRadius.Value;
			}
			catch
			{
			}
			if (num <= 0.0001f)
			{
				if (_proximityVisuals.Count > 0)
				{
					ClearProximityVisuals();
				}
				return;
			}
			Vector3 val2;
			try
			{
				Transform transform2 = ((Component)((Rig)rigManager.physicsRig).m_chest).transform;
				val2 = (((Object)(object)transform2 != (Object)null) ? transform2.position : transform.position);
			}
			catch
			{
				val2 = transform.position;
			}
			int instanceID = ((Object)((Component)rigManager).gameObject).GetInstanceID();
			Il2CppReferenceArray<Collider> val3 = Physics.OverlapSphere(val2, num);
			HashSet<int> hashSet = new HashSet<int>();
			if (val3 != null)
			{
				int length = ((Il2CppArrayBase<Collider>)(object)val3).Length;
				for (int j = 0; j < length; j++)
				{
					Collider val4 = ((Il2CppArrayBase<Collider>)(object)val3)[j];
					if ((Object)(object)val4 == (Object)null)
					{
						continue;
					}
					GameObject gameObject = ((Component)val4).gameObject;
					if ((Object)(object)gameObject == (Object)null)
					{
						continue;
					}
					Poolee val5 = null;
					try
					{
						val5 = gameObject.GetComponentInParent<Poolee>();
					}
					catch
					{
					}
					if ((Object)(object)val5 == (Object)null)
					{
						continue;
					}
					GameObject val6 = null;
					try
					{
						val6 = ((Component)val5).gameObject;
					}
					catch
					{
					}
					if (!((Object)(object)val6 == (Object)null) && ShouldMirrorPoolee(val5, val6, instanceID))
					{
						int instanceID2 = ((Object)val6).GetInstanceID();
						if (hashSet.Add(instanceID2))
						{
							UpdateProximityVisual(val6, instanceID2, transform, val);
							_claimedRootIds.Add(instanceID2);
						}
					}
				}
			}
			try
			{
				if ((Object)(object)rigManager.physicsRig != (Object)null)
				{
					IncludeHandHeldInProximity(rigManager.physicsRig.leftHand, val2, num, instanceID, hashSet, transform, val);
					IncludeHandHeldInProximity(rigManager.physicsRig.rightHand, val2, num, instanceID, hashSet, transform, val);
				}
				Seat val7 = null;
				try
				{
					val7 = rigManager.activeSeat;
				}
				catch
				{
				}
				if ((Object)(object)val7 != (Object)null)
				{
					GameObject val8 = null;
					try
					{
						val8 = ((Component)val7).gameObject;
					}
					catch
					{
					}
					if ((Object)(object)val8 != (Object)null)
					{
						Poolee poolee = null;
						try
						{
							poolee = val8.GetComponentInParent<Poolee>();
						}
						catch
						{
						}
						IncludePooleeInProximity(poolee, val2, num, instanceID, hashSet, transform, val);
					}
				}
			}
			catch
			{
			}
			List<int> list = null;
			foreach (KeyValuePair<int, GameObject> proximityVisual in _proximityVisuals)
			{
				if (!hashSet.Contains(proximityVisual.Key))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(proximityVisual.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			for (int k = 0; k < list.Count; k++)
			{
				int key = list[k];
				if (_proximityVisuals.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
				{
					try
					{
						Object.Destroy((Object)(object)value);
					}
					catch
					{
					}
				}
				_proximityVisuals.Remove(key);
				_proximityPersistentSync.Remove(key);
				_proximitySourceRoots.Remove(key);
			}
		}

		private static void UpdateProximityVisual(GameObject src, int rootId, Transform playerAvatarT, Transform cloneAvatarT)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			//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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			if (!_proximityVisuals.TryGetValue(rootId, out var value) || (Object)(object)value == (Object)null)
			{
				value = BuildHeldVisual(src);
				if ((Object)(object)value == (Object)null)
				{
					return;
				}
				_proximityVisuals[rootId] = value;
				_proximitySourceRoots[rootId] = src;
				_proximityPersistentSync[rootId] = null;
			}
			Transform transform = src.transform;
			Vector3 localPosition = playerAvatarT.InverseTransformPoint(transform.position);
			Quaternion localRotation = Quaternion.Inverse(playerAvatarT.rotation) * transform.rotation;
			Transform transform2 = value.transform;
			if ((Object)(object)transform2.parent != (Object)(object)cloneAvatarT)
			{
				try
				{
					transform2.SetParent(cloneAvatarT, false);
				}
				catch
				{
				}
			}
			transform2.localPosition = localPosition;
			transform2.localRotation = localRotation;
			Vector3 lossyScale = transform.lossyScale;
			Vector3 lossyScale2 = cloneAvatarT.lossyScale;
			float num = Mathf.Abs(lossyScale2.x);
			if (num < 0.0001f)
			{
				num = 1f;
			}
			float num2 = Mathf.Abs(lossyScale2.y);
			if (num2 < 0.0001f)
			{
				num2 = 1f;
			}
			float num3 = Mathf.Abs(lossyScale2.z);
			if (num3 < 0.0001f)
			{
				num3 = 1f;
			}
			transform2.localScale = new Vector3(lossyScale.x / num, lossyScale.y / num2, lossyScale.z / num3);
			if (!value.activeSelf)
			{
				value.SetActive(true);
			}
			ItemPersistentSync value2 = null;
			_proximityPersistentSync.TryGetValue(rootId, out value2);
			ApplyPersistentItemUpdate(src, value, ref value2);
			_proximityPersistentSync[rootId] = value2;
		}

		private static void IncludeHandHeldInProximity(Hand hand, Vector3 origin, float radius, int localRigId, HashSet<int> seen, Transform playerAvatarT, Transform cloneAvatarT)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hand == (Object)null)
			{
				return;
			}
			GameObject val = null;
			try
			{
				val = hand.m_CurrentAttachedGO;
			}
			catch
			{
			}
			if (!((Object)(object)val == (Object)null))
			{
				Poolee poolee = null;
				try
				{
					poolee = val.GetComponentInParent<Poolee>();
				}
				catch
				{
				}
				IncludePooleeInProximity(poolee, origin, radius, localRigId, seen, playerAvatarT, cloneAvatarT);
			}
		}

		private static void IncludePooleeInProximity(Poolee poolee, Vector3 origin, float radius, int localRigId, HashSet<int> seen, Transform playerAvatarT, Transform cloneAvatarT)
		{
			//IL_000d: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)poolee == (Object)null)
			{
				return;
			}
			GameObject val = null;
			try
			{
				val = ((Component)poolee).gameObject;
			}
			catch
			{
			}
			if (!((Object)(object)val == (Object)null) && ShouldMirrorPoolee(poolee, val, localRigId))
			{
				int instanceID = ((Object)val).GetInstanceID();
				float num = val.transform.position.x - origin.x;
				float num2 = val.transform.position.y - origin.y;
				float num3 = val.transform.position.z - origin.z;
				if (!(num * num + num2 * num2 + num3 * num3 > radius * radius) && seen.Add(instanceID))
				{
					UpdateProximityVisual(val, instanceID, playerAvatarT, cloneAvatarT);
					_claimedRootIds.Add(instanceID);
				}
			}
		}

		private static void ClearProximityVisuals()
		{
			foreach (KeyValuePair<int, GameObject> proximityVisual in _proximityVisuals)
			{
				if ((Object)(object)proximityVisual.Value != (Object)null)
				{
					try
					{
						Object.Destroy((Object)(object)proximityVisual.Value);
					}
					catch
					{
					}
				}
			}
			_proximityVisuals.Clear();
			_proximityPersistentSync.Clear();
			_proximitySourceRoots.Clear();
		}

		private static void SyncProximityVisual()
		{
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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)
			bool flag = false;
			bool flag2 = false;
			try
			{
				flag = Config.LocalMirrorProximityAwarenessEnabled.Value;
			}
			catch
			{
			}
			try
			{
				flag2 = Config.LocalMirrorProximityVisualEnabled.Value;
			}
			catch
			{
			}
			if (!flag || !flag2)
			{
				if ((Object)(object)_proximityCircleGo != (Object)null && _proximityCircleGo.activeSelf)
				{
					_proximityCircleGo.SetActive(false);
				}
				return;
			}
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.physicsRig == (Object)null)
			{
				return;
			}
			Transform val = null;
			try
			{
				val = ((Component)((Rig)rigManager.physicsRig).m_chest).transform;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				try
				{
					Avatar avatar = rigManager.avatar;
					val = ((avatar != null) ? ((Component)avatar).transform : null);
				}
				catch
				{
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			float num = 5f;
			try
			{
				num = Config.LocalMirrorProximityRadius.Value;
			}
			catch
			{
			}
			EnsureProximityCircle();
			if (!((Object)(object)_proximityCircleGo == (Object)null) && !((Object)(object)_proximityCircleLine == (Object)null))
			{
				if (!_proximityCircleGo.activeSelf)
				{
					_proximityCircleGo.SetActive(true);
				}
				Vector3 position = val.position;
				float num2 = 0.02f;
				_proximityCircleLine.startWidth = num2;
				_proximityCircleLine.endWidth = num2;
				for (int i = 0; i < 64; i++)
				{
					float num3 = (float)i / 64f * (float)Math.PI * 2f;
					_proximityCircleLine.SetPosition(i, new Vector3(position.x + Mathf.Cos(num3) * num, position.y, position.z + Mathf.Sin(num3) * num));
				}
			}
		}

		private static void EnsureProximityCircle()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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)
			if ((Object)(object)_proximityCircleGo != (Object)null && (Object)(object)_proximityCircleGo != (Object)null)
			{
				return;
			}
			try
			{
				_proximityCircleGo = new GameObject("LocalMirror_ProximityCircle");
				Object.DontDestroyOnLoad((Object)(object)_proximityCircleGo);
				_proximityCircleLine = _proximityCircleGo.AddComponent<LineRenderer>();
				_proximityCircleLine.useWorldSpace = true;
				_proximityCircleLine.loop = true;
				_proximityCircleLine.positionCount = 64;
				((Renderer)_proximityCircleLine).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)_proximityCircleLine).receiveShadows = false;
				Shader val = Shader.Find("Sprites/Default");
				if ((Object)(object)val != (Object)null)
				{
					Material val2 = new Material(val);
					val2.color = Color.white;
					((Renderer)_proximityCircleLine).material = val2;
					_proximityCircleLine.startColor = Color.white;
					_proximityCircleLine.endColor = Color.white;
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror] EnsureProximityCircle threw: " + ex.Message);
			}
		}

		private static void DestroyProximityCircle()
		{
			if ((Object)(object)_proximityCircleGo != (Object)null)
			{
				try
				{
					Object.Destroy((Object)(object)_proximityCircleGo);
				}
				catch
				{
				}
				_proximityCircleGo = null;
				_proximityCircleLine = null;
			}
		}

		private static void SyncHeldItemMirror()
		{
			bool flag = false;
			try
			{
				flag = Config.LocalMirrorHeldItemAwarenessEnabled.Value;
			}
			catch
			{
			}
			if (!flag)
			{
				if ((Object)(object)_leftHeldState.CloneVisual != (Object)null)
				{
					TearDownHeldVisual(ref _leftHeldState);
				}
				if ((Object)(object)_rightHeldState.CloneVisual != (Object)null)
				{
					TearDownHeldVisual(ref _rightHeldState);
				}
			}
			else
			{
				RigManager rigManager = Player.RigManager;
				if (!((Object)(object)rigManager == (Object)null) && !((Object)(object)rigManager.physicsRig == (Object)null))
				{
					UpdateHeldHand(rigManager.physicsRig.leftHand, _playerLeftHandTransform, _cloneLeftHandTransform, ref _leftHeldState, ref _rightHeldState);
					UpdateHeldHand(rigManager.physicsRig.rightHand, _playerRightHandTransform, _cloneRightHandTransform, ref _rightHeldState, ref _leftHeldState);
				}
			}
		}

		private static void UpdateHeldHand(Hand hand, Transform playerHandBone, Transform cloneHandBone, ref HeldItemState state, ref HeldItemState otherState)
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: 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)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)playerHandBone == (Object)null || (Object)(object)cloneHandBone == (Object)null)
			{
				if ((Object)(object)state.CloneVisual != (Object)null)
				{
					TearDownHeldVisual(ref state);
				}
				return;
			}
			GameObject val = ResolveHeldItemRoot(hand);
			if ((Object)(object)val == (Object)null)
			{
				if ((Object)(object)state.CloneVisual != (Object)null)
				{
					TearDownHeldVisual(ref state);
				}
				return;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (_claimedRootIds.Contains(instanceID))
			{
				if ((Object)(object)state.CloneVisual != (Object)null)
				{
					TearDownHeldVisual(ref state);
				}
				return;
			}
			_claimedRootIds.Add(instanceID);
			if (state.PlayerItemId != instanceID || (Object)(object)state.CloneVisual == (Object)null)
			{
				if ((Object)(object)state.CloneVisual != (Object)null)
				{
					TearDownHeldVisual(ref state);
				}
				GameObject val2 = BuildHeldVisual(val);
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				state.PlayerItemId = instanceID;
				state.CloneVisual = val2;
				state.PlayerSourceRoot = val;
				state.PersistentSync = null;
			}
			Transform transform = val.transform;
			Vector3 localPosition = playerHandBone.InverseTransformPoint(transform.position);
			Quaternion localRotation = Quaternion.Inverse(playerHandBone.rotation) * transform.rotation;
			Transform transform2 = state.CloneVisual.transform;
			if ((Object)(object)transform2.parent != (Object)(object)cloneHandBone)
			{
				try
				{
					transform2.SetParent(cloneHandBone, false);
				}
				catch
				{
				}
			}
			transform2.localPosition = localPosition;
			transform2.localRotation = localRotation;
			Vector3 lossyScale = transform.lossyScale;
			Vector3 lossyScale2 = cloneHandBone.lossyScale;
			float num = Mathf.Abs(lossyScale2.x);
			if (num < 0.0001f)
			{
				num = 1f;
			}
			float num2 = Mathf.Abs(lossyScale2.y);
			if (num2 < 0.0001f)
			{
				num2 = 1f;
			}
			float num3 = Mathf.Abs(lossyScale2.z);
			if (num3 < 0.0001f)
			{
				num3 = 1f;
			}
			transform2.localScale = new Vector3(lossyScale.x / num, lossyScale.y / num2, lossyScale.z / num3);
			if (!state.CloneVisual.activeSelf)
			{
				state.CloneVisual.SetActive(true);
			}
			ApplyPersistentItemUpdate(state.PlayerSourceRoot, state.CloneVisual, ref state.PersistentSync);
		}

		private static bool ShouldMirrorPoolee(Poolee poolee, GameObject pgo, int localRigId)
		{
			if ((Object)(object)poolee == (Object)null || (Object)(object)pgo == (Object)null)
			{
				return false;
			}
			if (localRigId != 0 && ((Object)pgo).GetInstanceID() == localRigId)
			{
				return false;
			}
			try
			{
				if ((Object)(object)poolee.SpawnableCrate == (Object)null)
				{
					return false;
				}
			}
			catch
			{
				return false;
			}
			try
			{
				if ((Object)(object)pgo.GetComponent<RigManager>() != (Object)null)
				{
					return false;
				}
			}
			catch
			{
			}
			try
			{
				string iD = ((Scannable)poolee.SpawnableCrate).Barcode.ID;
				if (!string.IsNullOrEmpty(iD) && _mirrorBlacklistBarcodes.Contains(iD))
				{
					return false;
				}
			}
			catch
			{
			}
			return true;
		}

		private static GameObject ResolveHeldItemRoot(Hand hand)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)hand == (Object)null)
			{
				return null;
			}
			GameObject val = null;
			try
			{
				val = hand.m_CurrentAttachedGO;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Poolee val2 = null;
			try
			{
				val2 = val.GetComponentInParent<Poolee>();
			}
			catch
			{
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObject val3 = null;
			try
			{
				val3 = ((Component)val2).gameObject;
			}
			catch
			{
			}
			if ((Object)(object)val3 == (Object)null)
			{
				return null;
			}
			int localRigId = 0;
			try
			{
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager != (Object)null)
				{
					localRigId = ((Object)((Component)rigManager).gameObject).GetInstanceID();
				}
			}
			catch
			{
			}
			if (!ShouldMirrorPoolee(val2, val3, localRigId))
			{
				return null;
			}
			return val3;
		}

		private static GameObject BuildHeldVisual(GameObject src)
		{
			if ((Object)(object)src == (Object)null)
			{
				return null;
			}
			try
			{
				GameObject obj = Object.Instantiate<GameObject>(src);
				((Object)obj).name = ((Object)src).name + " (LocalMirrorHeld)";
				Object.DontDestroyOnLoad((Object)(object)obj);
				StripHeldVisual(obj);
				ForceRenderingOnAll(obj);
				return obj;
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[LocalMirror] BuildHeldVisual threw: " + ex.Message);
				return null;
			}
		}

		private static void StripHeldVisual(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			try
			{
				Il2CppArrayBase<Joint> componentsInChildren = root.GetComponentsInChildren<Joint>(true);
				if (componentsInChildren != null)
				{
					for (int i = 0; i < componentsInChildren.Count; i++)
					{
						Joint val = componentsInChildren[i];
						if (!((Object)(object)val == (Object)null))
						{
							try
							{
								Object.Destroy((Object)(object)val);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Grip> componentsInChildren2 = root.GetComponentsInChildren<Grip>(true);
				if (componentsInChildren2 != null)
				{
					for (int j = 0; j < componentsInChildren2.Count; j++)
					{
						Grip val2 = componentsInChildren2[j];
						if (!((Object)(object)val2 == (Object)null))
						{
							try
							{
								Object.Destroy((Object)(object)val2);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<InteractableHost> componentsInChildren3 = root.GetComponentsInChildren<InteractableHost>(true);
				if (componentsInChildren3 != null)
				{
					for (int k = 0; k < componentsInChildren3.Count; k++)
					{
						InteractableHost val3 = componentsInChildren3[k];
						if (!((Object)(object)val3 == (Object)null))
						{
							try
							{
								Object.Destroy((Object)(object)val3);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Rigidbody> componentsInChildren4 = root.GetComponentsInChildren<Rigidbody>(true);
				if (componentsInChildren4 != null)
				{
					for (int l = 0; l < componentsInChildren4.Count; l++)
					{
						Rigidbody val4 = componentsInChildren4[l];
						if (!((Object)(object)val4 == (Object)null))
						{
							try
							{
								val4.isKinematic = true;
							}
							catch
							{
							}
							try
							{
								val4.detectCollisions = false;
							}
							catch
							{
							}
							try
							{
								Object.Destroy((Object)(object)val4);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Collider> componentsInChildren5 = root.GetComponentsInChildren<Collider>(true);
				if (componentsInChildren5 != null)
				{
					for (int m = 0; m < componentsInChildren5.Count; m++)
					{
						Collider val5 = componentsInChildren5[m];
						if (!((Object)(object)val5 == (Object)null))
						{
							try
							{
								Object.Destroy((Object)(object)val5);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<AudioSource> componentsInChildren6 = root.GetComponentsInChildren<AudioSource>(true);
				if (componentsInChildren6 != null)
				{
					for (int n = 0; n < componentsInChildren6.Count; n++)
					{
						AudioSource val6 = componentsInChildren6[n];
						if (!((Object)(object)val6 == (Object)null))
						{
							try
							{
								val6.Stop();
							}
							catch
							{
							}
							try
							{
								Object.Destroy((Object)(object)val6);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Light> componentsInChildren7 = root.GetComponentsInChildren<Light>(true);
				if (componentsInChildren7 != null)
				{
					for (int num = 0; num < componentsInChildren7.Count; num++)
					{
						Light val7 = componentsInChildren7[num];
						if (!((Object)(object)val7 == (Object)null))
						{
							try
							{
								Object.Destroy((Object)(object)val7);
							}
							catch
							{
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				Il2CppArrayBase<Poolee> componentsInChildren8 = root.GetComponentsInChildren<Poolee>(true);
				if (componentsInChildren8 == null)
				{
					return;
				}
				for (int num2 = 0; num2 < componentsInChildren8.Count; num2++)
				{
					Poolee val8 = componentsInChildren8[num2];
					if (!((Object)(object)val8 == (Object)null))
					{
						try
						{
							Object.Destroy((Object)(object)val8);
						}
						catch
						{
						}
					}
				}
			}
			catch
			{
			}
		}

		private static void ForceRenderingOnAll(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			try
			{
				Il2CppArrayBase<Renderer> componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
				if (componentsInChildren == null)
				{
					return;
				}
				int count = componentsInChildren.Count;
				for (int i = 0; i < count; i++)
				{
					Renderer val = componentsInChildren[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					try
					{
						if (val.forceRenderingOff)
						{
							val.forceRenderingOff = false;
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}

		private static void TearDownHeldVisual(ref HeldItemState state)
		{
			if ((Object)(object)state.CloneVisual != (Object)null)
			{
				try
				{
					Object.Destroy((Object)(object)state.CloneVisual);
				}
				catch
				{
				}
			}
			state.CloneVisual = null;
			state.PlayerItemId = 0;
			state.PlayerSourceRoot = null;
			state.PersistentSync = null;
		}

		private static void SyncSeatMirror()
		{
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			try
			{
				flag = Config.LocalMirrorSeatAwarenessEnabled.Value;
			}
			catch
			{
			}
			if (!flag)
			{
				if ((Object)(object)_seatedState.CloneVisual != (Object)null)
				{
					TearDownSeatVisual();
				}
				return;
			}
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.avatar == (Object)null)
			{
				return;
			}
			Transform transform = ((Component)rigManager.avatar).transform;
			Transform val = null;
			if ((Object)(object)_avatarsTran != (Object)null)
			{
				for (int i = 0; i < _avatarsTran.childCount; i++)
				{
					Transform child = _avatarsTran.GetChild(i);
					if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeInHierarchy)
					{
						val = child;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Seat val2 = null;
			try
			{
				val2 = rigManager.activeSeat;
			}
			catch
			{
			}
			if ((Object)(object)val2 == (Object)null)
			{
				if ((Object)(object)_seatedState.CloneVisual != (Object)null)
				{
					TearDownSeatVisual();
				}
				return;
			}
			GameObject val3 = ResolveSeatSpawnableRoot(val2);
			if ((Object)(object)val3 == (Object)null)
			{
				if ((Object)(object)_seatedState.CloneVisual != (Object)null)
				{
					TearDownSeatVisual();
				}
				return;
			}
			int instanceID = ((Object)val3).GetInstanceID();
			if (_claimedRootIds.Contains(instanceID))
			{
				if ((Object)(object)_seatedState.CloneVisual != (Object)null)
				{
					TearDownSeatVisual();
				}
				return;
			}
			_claimedRootIds.Add(instanceID);
			if (_seatedState.PlayerSeatRootId != instanceID || (Object)(object)_seatedState.CloneVisual == (Object)null)
			{
				if ((Object)(object)_seatedState.CloneVisual != (Object)null)
				{
					TearDownSeatVisual();
				}
				GameObject val4 = BuildHeldVisual(val3);
				if ((Object)(object)val4 == (Object)null)
				{
					return;
				}
				_seatedState.PlayerSeatRootId = instanceID;
				_seatedState.CloneVisual = val4;
				_seatedState.PlayerSourceRoot = val3;
				_seatedState.PersistentSync = null;
			}
			Transform transform2 = val3.transform;
			Vector3 localPosition = transform.InverseTransformPoint(transform2.position);
			Quaternion localRotation = Quaternion.Inverse(transform.rotation) * transform2.rotation;
			Transform transform3 = _seatedState.CloneVisual.transform;
			if ((Object)(object)transform3.parent != (Object)(object)val)
			{
				try
				{
					transform3.SetParent(val, false);
				}
				catch
				{
				}
			}
			transform3.localPosition = localPosition;
			transform3.localRotation = localRotation;
			Vector3 lossyScale = transform2.lossyScale;
			Vector3 lossyScale2 = val.lossyScale;
			float num = Mathf.Abs(lossyScale2.x);
			if (num < 0.0001f)
			{
				num = 1f;
			}
			float num2 = Mathf.Abs(lossyScale2.y);
			if (num2 < 0.0001f)
			{
				num2 = 1f;
			}
			float num3 = Mathf.Abs(lossyScale2.z);
			if (num3 < 0.0001f)
			{
				num3 = 1f;
			}
			transform3.localScale = new Vector3(lossyScale.x / num, lossyScale.y / num2, lossyScale.z / num3);
			if (!_seatedState.CloneVisual.activeSelf)
			{
				_seatedState.CloneVisual.SetActive(true);
			}
			ApplyPersistentItemUpdate(_seatedState.PlayerSourceRoot, _seatedState.CloneVisual, ref _seatedState.PersistentSync);
		}

		private static GameObject ResolveSeatSpawnableRoot(Seat seat)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0013: 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)
			if ((Object)seat == (Object)null)
			{
				return null;
			}
			GameObject val = null;
			try
			{
				val = ((Component)seat).gameObject;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Poolee val2 = null;
			try
			{
				val2 = val.GetComponentInParent<Poolee>();
			}
			catch
			{
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObject val3 = null;
			try
			{
				val3 = ((Component)val2).gameObject;
			}
			catch
			{
			}
			if ((Object)(object)val3 == (Object)null)
			{
				return null;
			}
			int localRigId = 0;
			try
			{
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager != (Object)null)
				{
					localRigId = ((Object)((Component)rigManager).gameObject).GetInstanceID();
				}
			}
			catch
			{
			}
			if (!ShouldMirrorPoolee(val2, val3, localRigId))
			{
				return null;
			}
			return val3;
		}

		private static void TearDownSeatVisual()
		{
			if ((Object)(object)_seatedState.CloneVisual != (Object)null)
			{
				try
				{
					Object.Destroy((Object)(object)_seatedState.CloneVisual);
				}
				catch
				{
				}
			}
			_seatedState.CloneVisual = null;
			_seatedState.PlayerSeatRootId = 0;
			_seatedState.PlayerSourceRoot = null;
			_seatedState.PersistentSync = null;
		}

		private static void SyncRemoteRigClones()
		{
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Expected O, but got Unknown
			bool flag = false;
			try
			{
				flag = Config.LocalMirrorIncludeOthersEnabled.Value;
			}
			catch
			{
			}
			if (!flag)
			{
				if (_remoteRigClones.Count > 0)
				{
					ClearRemoteRigClones();
				}
				return;
			}
			bool flag2 = false;
			try
			{
				flag2 = IsFusionLoaded();
			}
			catch
			{
			}
			if (!flag2)
			{
				if (_remoteRigClones.Count > 0)
				{
					ClearRemoteRigClones();
				}
				return;
			}
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.avatar == (Object)null)
			{
				if (_remoteRigClones.Count > 0)
				{
					ClearRemoteRigClones();
				}
				return;
			}
			Transform transform = ((Component)rigManager.avatar).transform;
			Transform val = null;
			if ((Object)(object)_avatarsTran != (Object)null)
			{
				for (int i = 0; i < _avatarsTran.childCount; i++)
				{
					Transform child = _avatarsTran.GetChild(i);
					if ((Object)(object)child != (Object)null && ((Component)child).gameObject.activeInHierarchy)
					{
						val = child;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			float num = 0f;
			try
			{
				num = Time.realtimeSinceStartup;
			}
			catch
			{
			}
			bool flag3 = false;
			try
			{
				flag3 = Config.LocalMirrorProximityAwarenessEnabled.Value;
			}
			catch
			{
			}
			if ((flag3 || _remoteRigClones.Count > 0 || _remoteScanForcedOnce) && num >= _remoteEligibilityNextTime)
			{
				_remoteEligibilityNextTime = num + 0.1f;
				bool num2 = flag3 || _remoteScanForcedOnce;
				_remoteScanForcedOnce = false;
				if (num2)