Decompiled source of LocalMirror v1.0.0
Mods/LocalMirror.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
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)