using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Multigrasp")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+beb441afe3bfba81768632e6b8c827ea6dc0490f")] [assembly: AssemblyProduct("Multigrasp")] [assembly: AssemblyTitle("Multigrasp")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 Multigrasp { internal sealed class BeamRenderer { private static readonly Color VanillaOrangeStart = new Color(1f, 0.1856f, 0f, 0.95f); private static readonly Color VanillaOrangeEnd = new Color(1f, 0.1856f, 0f, 0.65f); private readonly string _name; private GameObject _beamObject; private LineRenderer _beam; private Material _ownedMaterial; private float _textureOffset; internal BeamRenderer(string name) { _name = name; } internal void Tick(PhysGrabber primary, Transform fallbackCamera, Vector3 end) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Ensure(primary); if (!((Object)_beam == (Object)null)) { Vector3 beamStart = GetBeamStart(primary, fallbackCamera); Draw(beamStart, end); } } private void Draw(Vector3 start, Vector3 end) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_011f: Unknown result type (might be due to invalid IL or missing references) float num = Vector3.Distance(start, end); Vector3 val = Vector3.Lerp(start, end, 0.5f) + Vector3.down * Mathf.Min(0.45f, num * 0.06f); _beamObject.SetActive(true); ((Renderer)_beam).enabled = true; _beam.positionCount = 16; for (int i = 0; i < _beam.positionCount; i++) { float num2 = ((_beam.positionCount <= 1) ? 1f : ((float)i / (float)(_beam.positionCount - 1))); Vector3 val2 = Vector3.Lerp(start, val, num2); Vector3 val3 = Vector3.Lerp(val, end, num2); _beam.SetPosition(i, Vector3.Lerp(val2, val3, num2)); } Material val4 = _ownedMaterial ?? ((Renderer)_beam).material; if ((Object)val4 != (Object)null) { _textureOffset -= Time.deltaTime * 2.5f; val4.mainTextureOffset = new Vector2(_textureOffset, 0f); } } internal void Destroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown if ((Object)_beamObject != (Object)null) { Object.Destroy((Object)_beamObject); } if ((Object)_ownedMaterial != (Object)null) { Object.Destroy((Object)_ownedMaterial); } _beamObject = null; _beam = null; _ownedMaterial = null; } private void Ensure(PhysGrabber primary) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown if (!((Object)_beamObject != (Object)null) || !((Object)_beam != (Object)null)) { Destroy(); _beamObject = new GameObject(_name); Object.DontDestroyOnLoad((Object)_beamObject); _beamObject.SetActive(true); _beam = _beamObject.AddComponent(); _beam.useWorldSpace = true; _beam.positionCount = 16; _beam.numCapVertices = 4; _beam.numCornerVertices = 4; ApplyVanillaLikeStyle(primary); ((Renderer)_beam).enabled = false; } } private void ApplyVanillaLikeStyle(PhysGrabber primary) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: 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_01be: Expected O, but got Unknown //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) LineRenderer sourceLine = GetSourceLine(primary); if ((Object)sourceLine != (Object)null) { if ((Object)((Renderer)sourceLine).sharedMaterial != (Object)null) { SetOwnedMaterial(new Material(((Renderer)sourceLine).sharedMaterial)); } if (sourceLine.startWidth > 0.001f && sourceLine.startWidth < 0.25f) { _beam.startWidth = sourceLine.startWidth; _beam.endWidth = ((sourceLine.endWidth > 0.001f && sourceLine.endWidth < 0.25f) ? sourceLine.endWidth : (sourceLine.startWidth * 0.55f)); } } if ((Object)_ownedMaterial == (Object)null) { Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Legacy Shaders/Particles/Additive"); if ((Object)val != (Object)null) { SetOwnedMaterial(new Material(val)); } } if (_beam.startWidth <= 0.001f || _beam.startWidth > 0.25f) { _beam.startWidth = 0.035f; } if (_beam.endWidth <= 0.001f || _beam.endWidth > 0.25f) { _beam.endWidth = 0.018f; } _beam.startColor = VanillaOrangeStart; _beam.endColor = VanillaOrangeEnd; if ((Object)_ownedMaterial != (Object)null) { if (_ownedMaterial.HasProperty("_Color")) { _ownedMaterial.SetColor("_Color", VanillaOrangeStart); } if (_ownedMaterial.HasProperty("_EmissionColor")) { _ownedMaterial.SetColor("_EmissionColor", VanillaOrangeStart); } _beam.textureMode = (LineTextureMode)1; } } private void SetOwnedMaterial(Material material) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: 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_002a: Expected O, but got Unknown //IL_002a: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if ((Object)_ownedMaterial != (Object)null && (Object)_ownedMaterial != (Object)material) { Object.Destroy((Object)_ownedMaterial); } _ownedMaterial = material; if ((Object)_beam != (Object)null) { ((Renderer)_beam).sharedMaterial = _ownedMaterial; } } private static LineRenderer GetSourceLine(PhysGrabber primary) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if ((Object)(primary?.physGrabBeam) == (Object)null) { return null; } return primary.physGrabBeam.GetComponent() ?? primary.physGrabBeam.GetComponentInChildren(); } private static Vector3 GetBeamStart(PhysGrabber primary, Transform fallbackCamera) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_002c: 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) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) Transform val = primary?.physGrabBeamComponent?.PhysGrabPointOrigin; if ((Object)val != (Object)null) { return val.position; } PhysGrabBeam val2 = (((Object)(primary?.physGrabBeam) != (Object)null) ? primary.physGrabBeam.GetComponent() : null); val = val2?.PhysGrabPointOrigin ?? val2?.PhysGrabPointOriginLocal; if ((Object)val != (Object)null) { return val.position; } if ((Object)(primary?.physGrabPoint) != (Object)null) { return primary.physGrabPoint.position; } return ((Object)fallbackCamera != (Object)null) ? fallbackCamera.position : Vector3.zero; } } internal static class HudNotifier { private const float VisibleSeconds = 2f; private static readonly Vector2 HiddenPosition = new Vector2(24f, -36f); private static readonly Vector2 VisiblePosition = new Vector2(24f, 80f); private static GameObject _canvasObject; private static TextMeshProUGUI _text; private static float _hideAt; private static float _showStartedAt; internal static void Show(string message, Color color) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { EnsureOverlay(); if ((Object)_text == (Object)null) { MultigraspPlugin.LogWarning("HUD unavailable for message: " + message); return; } _canvasObject.SetActive(true); ((TMP_Text)_text).text = message; ((Graphic)_text).color = color; ((Behaviour)_text).enabled = true; ((TMP_Text)_text).rectTransform.anchoredPosition = HiddenPosition; _showStartedAt = Time.unscaledTime; _hideAt = Time.unscaledTime + 2f; } catch (Exception ex) { MultigraspPlugin.LogError("HUD message failed", ex); } } internal static void Tick() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)_text == (Object)null) && ((Behaviour)_text).enabled) { float num = Mathf.Clamp01((Time.unscaledTime - _showStartedAt) / 0.28f); num = 1f - Mathf.Pow(1f - num, 3f); ((TMP_Text)_text).rectTransform.anchoredPosition = Vector2.LerpUnclamped(HiddenPosition, VisiblePosition, num); if (Time.unscaledTime >= _hideAt) { ((Behaviour)_text).enabled = false; } } } internal static void DestroyOwnedObjects() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if ((Object)_canvasObject != (Object)null) { Object.Destroy((Object)_canvasObject); } _canvasObject = null; _text = null; } private static void EnsureOverlay() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00c1: 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_00e2: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown if (!((Object)_canvasObject != (Object)null) || !((Object)_text != (Object)null)) { if ((Object)_canvasObject != (Object)null) { Object.Destroy((Object)_canvasObject); } _canvasObject = null; _text = null; _canvasObject = new GameObject("Multigrasp HUD"); Object.DontDestroyOnLoad((Object)_canvasObject); Canvas val = _canvasObject.AddComponent(); val.renderMode = (RenderMode)0; val.sortingOrder = 32760; CanvasScaler val2 = _canvasObject.AddComponent(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); _canvasObject.AddComponent(); GameObject val3 = new GameObject("Multigrasp HUD Text"); val3.transform.SetParent(_canvasObject.transform, false); _text = val3.AddComponent(); ((TMP_Text)_text).fontSize = 28f; ((TMP_Text)_text).alignment = (TextAlignmentOptions)513; ((Graphic)_text).raycastTarget = false; ((TMP_Text)_text).text = string.Empty; ((Behaviour)_text).enabled = false; RectTransform rectTransform = ((TMP_Text)_text).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.zero; rectTransform.pivot = Vector2.zero; rectTransform.anchoredPosition = HiddenPosition; rectTransform.sizeDelta = new Vector2(700f, 80f); } } } internal sealed class MultigraspManager : MonoBehaviour { internal sealed class PendingAnchorData { internal readonly PhysGrabObject PhysGrabObject; internal readonly Rigidbody Body; internal readonly Transform TargetTransform; internal readonly Vector3 LocalGrabPosition; internal readonly Vector3 PlayerLocalBodyPosition; internal readonly Quaternion PlayerLocalBodyRotation; internal bool IsValid => (Object)PhysGrabObject != (Object)null && (Object)Body != (Object)null && (Object)TargetTransform != (Object)null && ((Behaviour)PhysGrabObject).enabled && !PhysGrabObject.dead && !Body.isKinematic && ((Component)Body).gameObject.activeInHierarchy; internal PendingAnchorData(PhysGrabObject physGrabObject, Rigidbody body, Transform targetTransform, Vector3 localGrabPosition, Vector3 playerLocalBodyPosition, Quaternion playerLocalBodyRotation) { //IL_001e: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) PhysGrabObject = physGrabObject; Body = body; TargetTransform = targetTransform; LocalGrabPosition = localGrabPosition; PlayerLocalBodyPosition = playerLocalBodyPosition; PlayerLocalBodyRotation = playerLocalBodyRotation; } } private sealed class Anchor { private const float MaxVelocityChange = 10f; private const float MaxAngularVelocityChange = 30f; private const float AnchoredMaxAngularVelocity = 50f; internal readonly PhysGrabObject PhysGrabObject; internal readonly Transform TargetTransform; private readonly Rigidbody _body; private readonly Vector3 _localGrabPosition; private readonly Vector3 _localBodyGrabPosition; private Vector3 _playerLocalBodyPosition; private Quaternion _playerLocalBodyRotation; private Vector3 _worldBodyPosition; private Quaternion _worldBodyRotation; private bool _followPlayer; private readonly float _originalMaxAngularVelocity; private readonly bool _changedMaxAngularVelocity; private readonly bool _originalDetectCollisions; private bool _changedDetectCollisions; private readonly BeamRenderer _beam; private bool _loggedGrabPause; internal bool IsValid => (Object)PhysGrabObject != (Object)null && (Object)_body != (Object)null && (Object)TargetTransform != (Object)null && ((Behaviour)PhysGrabObject).enabled && !PhysGrabObject.dead && !_body.isKinematic && ((Component)_body).gameObject.activeInHierarchy; internal string TargetName => ((Object)TargetTransform != (Object)null) ? ((Object)TargetTransform).name : ""; internal Anchor(PhysGrabObject physGrabObject, Rigidbody body, Transform targetTransform, Vector3 localGrabPosition, Vector3 playerLocalBodyPosition, Quaternion playerLocalBodyRotation, bool followPlayer, bool passthrough, string beamName) { //IL_001e: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) PhysGrabObject = physGrabObject; _body = body; TargetTransform = targetTransform; _localGrabPosition = localGrabPosition; _localBodyGrabPosition = ((Component)body).transform.InverseTransformPoint(targetTransform.TransformPoint(localGrabPosition)); _playerLocalBodyPosition = playerLocalBodyPosition; _playerLocalBodyRotation = playerLocalBodyRotation; _worldBodyPosition = body.position; _worldBodyRotation = body.rotation; _followPlayer = followPlayer; _originalMaxAngularVelocity = body.maxAngularVelocity; _originalDetectCollisions = body.detectCollisions; if (IsFinite(_originalMaxAngularVelocity) && body.maxAngularVelocity < 50f) { body.maxAngularVelocity = 50f; _changedMaxAngularVelocity = true; } _beam = new BeamRenderer(beamName); MaintainHeldByLocalPlayer(); SetPassthroughMode(passthrough); } internal bool Matches(PhysGrabObject physGrabObject, Transform targetTransform) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_004b: Expected O, but got Unknown return ((Object)physGrabObject != (Object)null && (Object)PhysGrabObject == (Object)physGrabObject) || ((Object)targetTransform != (Object)null && (Object)TargetTransform == (Object)targetTransform); } internal bool SetFollowPlayer(bool followPlayer, Transform player) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if ((Object)player == (Object)null || !IsValid) { return false; } if (followPlayer) { _playerLocalBodyPosition = player.InverseTransformPoint(_body.position); _playerLocalBodyRotation = Quaternion.Inverse(player.rotation) * _body.rotation; } else { _worldBodyPosition = _body.position; _worldBodyRotation = _body.rotation; } _followPlayer = followPlayer; return true; } internal bool TickBeam(PhysGrabber primary, Transform fallbackCamera, Transform player) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)player == (Object)null || !IsValid) { return false; } MaintainHeldByLocalPlayer(); _beam.Tick(primary, fallbackCamera, GetBeamEnd(player)); return true; } internal bool SetPassthroughMode(bool passthrough) { if (!IsValid) { return false; } if (passthrough) { if (_body.detectCollisions) { _body.detectCollisions = false; } _changedDetectCollisions = true; return true; } if (_changedDetectCollisions) { _body.detectCollisions = _originalDetectCollisions; _changedDetectCollisions = false; } return true; } private Vector3 GetBeamEnd(Transform player) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_002d: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (IsGrabbedByBlockingPlayer(blockLocalActiveGrabber: false)) { return TargetTransform.TransformPoint(_localGrabPosition); } Vector3 val = (_followPlayer ? player.TransformPoint(_playerLocalBodyPosition) : _worldBodyPosition); Quaternion val2 = (_followPlayer ? (player.rotation * _playerLocalBodyRotation) : _worldBodyRotation); if (!IsFinite(val) || !IsFinite(val2)) { return TargetTransform.TransformPoint(_localGrabPosition); } return val + val2 * _localBodyGrabPosition; } internal bool ApplyForce(Transform player) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown if ((Object)player == (Object)null || !IsValid) { MultigraspPlugin.LogVerbose("Removing local anchor: invalid state target=" + TargetName); return false; } if (IsGrabbedByBlockingPlayer(blockLocalActiveGrabber: true)) { if (!_loggedGrabPause) { MultigraspPlugin.LogVerbose("Paused local anchor force while grabbed target=" + TargetName); _loggedGrabPause = true; } return true; } if (_loggedGrabPause) { MultigraspPlugin.LogVerbose("Resumed local anchor force target=" + TargetName); _loggedGrabPause = false; } MaintainHeldByLocalPlayer(); ApplyVelocityCorrection(player); return true; } private void ApplyVelocityCorrection(Transform player) { //IL_0039: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) float fixedDeltaTime = Time.fixedDeltaTime; if (!IsFinite(fixedDeltaTime) || fixedDeltaTime <= 0f) { return; } Vector3 val = (_followPlayer ? player.TransformPoint(_playerLocalBodyPosition) : _worldBodyPosition); if (IsFinite(val)) { Vector3 val2 = (val - _body.position) / fixedDeltaTime; Vector3 val3 = val2 - _body.velocity; if (IsFinite(val3)) { val3 = Vector3.ClampMagnitude(val3, 10f); if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f) { _body.AddForce(val3, (ForceMode)2); } } } Quaternion val4 = (_followPlayer ? (player.rotation * _playerLocalBodyRotation) : _worldBodyRotation); if (!IsFinite(val4)) { return; } Quaternion val5 = val4 * Quaternion.Inverse(_body.rotation); float num = default(float); Vector3 val6 = default(Vector3); ((Quaternion)(ref val5)).ToAngleAxis(ref num, ref val6); if (num > 180f) { num -= 360f; } if (!IsFinite(num) || !IsFinite(val6) || !(((Vector3)(ref val6)).sqrMagnitude > 0.0001f)) { return; } ((Vector3)(ref val6)).Normalize(); Vector3 val7 = val6 * (num * (MathF.PI / 180f) / fixedDeltaTime); Vector3 val8 = val7 - _body.angularVelocity; if (IsFinite(val8)) { val8 = Vector3.ClampMagnitude(val8, 30f); if (((Vector3)(ref val8)).sqrMagnitude > 0.0001f) { _body.AddTorque(val8, (ForceMode)2); } } } internal void DestroyOwnedObjects() { RestoreDetectCollisions(); RestoreMaxAngularVelocity(); RestoreHeldByLocalPlayer(); _beam.Destroy(); } private void RestoreDetectCollisions() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown if (_changedDetectCollisions && (Object)_body != (Object)null) { _body.detectCollisions = _originalDetectCollisions; _changedDetectCollisions = false; } } private void RestoreMaxAngularVelocity() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown if (_changedMaxAngularVelocity && (Object)_body != (Object)null && IsFinite(_originalMaxAngularVelocity) && Mathf.Approximately(_body.maxAngularVelocity, 50f)) { _body.maxAngularVelocity = _originalMaxAngularVelocity; } } private void MaintainHeldByLocalPlayer() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown if ((Object)PhysGrabObject != (Object)null) { ReflectionCache.SetField(PhysGrabObject, "heldByLocalPlayer", value: true); } } private void RestoreHeldByLocalPlayer() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown if (!((Object)PhysGrabObject == (Object)null) && !IsVanillaCurrentLocalGrab(PhysGrabObject)) { ReflectionCache.SetField(PhysGrabObject, "heldByLocalPlayer", value: false); } } private bool IsGrabbedByBlockingPlayer(bool blockLocalActiveGrabber) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown object field = ReflectionCache.GetField(PhysGrabObject, "playerGrabbing"); if (!(field is IEnumerable enumerable) || field is string) { return false; } foreach (object item in enumerable) { Object val = (Object)((item is Object) ? item : null); if (val != null) { if (val == (Object)null) { continue; } } else if (item == null) { continue; } PhysGrabber val2 = (PhysGrabber)((item is PhysGrabber) ? item : null); if ((Object)val2 != (Object)null) { if (IsActiveGrabberForObject(val2, PhysGrabObject)) { if (!IsLocalGrabEntry(val2)) { return true; } if (blockLocalActiveGrabber) { return true; } } } else { if (!IsLocalGrabEntry(item)) { return true; } if (blockLocalActiveGrabber) { return true; } } } return false; } private static bool IsActiveGrabberForObject(PhysGrabber grabber, PhysGrabObject physGrabObject) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_004d: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_009a: Expected O, but got Unknown if ((Object)grabber == (Object)null || !grabber.grabbed || (Object)physGrabObject == (Object)null) { return false; } PhysGrabObject field = ReflectionCache.GetField(grabber, "grabbedPhysGrabObject"); if ((Object)field == (Object)physGrabObject) { return true; } Transform grabbedObjectTransform = grabber.grabbedObjectTransform; if ((Object)grabbedObjectTransform == (Object)null) { return false; } PhysGrabObject val = ((Component)grabbedObjectTransform).GetComponent() ?? ((Component)grabbedObjectTransform).GetComponentInParent(); return (Object)val == (Object)physGrabObject; } private static bool IsLocalGrabEntry(object entry) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown PhysGrabber val = (PhysGrabber)((entry is PhysGrabber) ? entry : null); if ((Object)val != (Object)null) { return IsLocalAvatar(val.playerAvatar) || IsLocalComponent((Component)val); } PlayerAvatar val2 = (PlayerAvatar)((entry is PlayerAvatar) ? entry : null); if ((Object)val2 != (Object)null) { return IsLocalAvatar(val2); } Component val3 = (Component)((entry is Component) ? entry : null); if ((Object)val3 != (Object)null) { return IsLocalComponent(val3) || IsLocalAvatar(val3.GetComponent() ?? val3.GetComponentInParent()); } GameObject val4 = (GameObject)((entry is GameObject) ? entry : null); return (Object)val4 != (Object)null && IsLocalAvatar(val4.GetComponent() ?? val4.GetComponentInParent()); } private static bool IsLocalAvatar(PlayerAvatar avatar) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown return (Object)avatar != (Object)null && IsLocalComponent((Component)avatar); } private static bool IsLocalComponent(Component component) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_003e: Expected O, but got Unknown PlayerController instance = PlayerController.instance; return (Object)component != (Object)null && (Object)instance != (Object)null && ((Object)component.gameObject == (Object)((Component)instance).gameObject || component.transform.IsChildOf(((Component)instance).transform)); } private static bool IsVanillaCurrentLocalGrab(PhysGrabObject physGrabObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0074: Expected O, but got Unknown PlayerController instance = PlayerController.instance; if ((Object)instance == (Object)null || (Object)physGrabObject == (Object)null) { return false; } GameObject field = ReflectionCache.GetField(instance, "physGrabObject"); if ((Object)field == (Object)null) { return false; } PhysGrabObject val = field.GetComponent() ?? field.GetComponentInParent(); return (Object)val == (Object)physGrabObject; } } private static readonly Color AnchorGreen = new Color(0.25f, 1f, 0.25f, 1f); private static readonly Color ReleaseOrangeRed = new Color(1f, 0.32f, 0f, 1f); private static readonly Color RejectOrange = new Color(1f, 0.55f, 0f, 1f); private const float HoldReleaseSeconds = 0.7f; private readonly List _anchors = new List(); private readonly Dictionary _lastHeldObjectDiagnosticAt = new Dictionary(); private PhysGrabber _primary; private PendingAnchorData _pendingAnchorData; private bool _fHeld; private bool _fConsumed; private float _fDownAt; private bool _anchorFollowPlayer = true; private bool _anchorPassthroughMode; private void CapturePendingAnchor() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown MultigraspPlugin.LogVerbose("CapturePendingAnchor attempt primary=" + ObjectName((Object)_primary)); if (IsPrimaryHolding(_primary)) { Transform val = ResolveAnchorPlayerTransform(_primary); PendingAnchorData pendingAnchorData; if ((Object)val == (Object)null) { MultigraspPlugin.LogVerbose("CapturePendingAnchor failed: player transform unavailable"); } else if (TryCaptureCurrentAnchorData(val, out pendingAnchorData)) { _pendingAnchorData = pendingAnchorData; MultigraspPlugin.LogVerbose("CapturePendingAnchor success target=" + ObjectName(pendingAnchorData.TargetTransform)); LogAnchorDiagnostic($"capture target={ObjectName(pendingAnchorData.TargetTransform)} body={DescribeBody(pendingAnchorData.Body)} grabbedAny={IsGrabbedByAnyPlayer(pendingAnchorData.PhysGrabObject)} object={ObjectName(pendingAnchorData.TargetTransform)}"); } else { MultigraspPlugin.LogVerbose("CapturePendingAnchor failed: current grabbed object could not be captured"); } } else { MultigraspPlugin.LogVerbose("CapturePendingAnchor skipped: primary is not holding an object"); } } private void ClearPendingAnchorData() { _pendingAnchorData = null; } private bool TryCaptureCurrentAnchorData(Transform player, out PendingAnchorData pendingAnchorData) { //IL_0038: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00f9: Expected O, but got Unknown pendingAnchorData = null; if (!TryResolveCurrentGrabbed(_primary, out var physGrabObject, out var targetTransform, out var body)) { MultigraspPlugin.LogVerbose("TryCaptureCurrentAnchorData failed: current grabbed object unresolved"); return false; } Vector3 val = _primary.localGrabPosition; Vector3 currentTargetPoint = GetCurrentTargetPoint(_primary, targetTransform, val); if (val == Vector3.zero) { val = targetTransform.InverseTransformPoint(currentTargetPoint); } Vector3 val2 = player.InverseTransformPoint(body.position); Quaternion val3 = Quaternion.Inverse(player.rotation) * body.rotation; if (!IsFinite(val) || !IsFinite(val2) || !IsFinite(val3)) { MultigraspPlugin.LogVerbose("TryCaptureCurrentAnchorData failed: computed anchor data not finite target=" + ObjectName(targetTransform)); return false; } pendingAnchorData = new PendingAnchorData(physGrabObject, body, targetTransform, val, val2, val3); MultigraspPlugin.LogVerbose("TryCaptureCurrentAnchorData success target=" + ObjectName(targetTransform) + " body=" + ObjectName((Object)body)); return true; } private static bool TryResolveCurrentGrabbed(PhysGrabber primary, out PhysGrabObject physGrabObject, out Transform targetTransform, out Rigidbody body) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown physGrabObject = null; targetTransform = null; body = null; if (!IsPrimaryHolding(primary)) { MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: primary not holding"); return false; } physGrabObject = ReflectionCache.GetField(primary, "grabbedPhysGrabObject"); targetTransform = primary.grabbedObjectTransform; if ((Object)physGrabObject == (Object)null && (Object)targetTransform != (Object)null) { physGrabObject = ((Component)targetTransform).GetComponent() ?? ((Component)targetTransform).GetComponentInParent(); } body = ReflectionCache.GetField(primary, "grabbedObject"); if ((Object)body == (Object)null) { PhysGrabObject val = physGrabObject; object obj = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); if (obj == null) { Transform val2 = targetTransform; obj = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null); if (obj == null) { Transform val3 = targetTransform; obj = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponentInParent() : null); } } body = (Rigidbody)obj; } if ((Object)targetTransform == (Object)null && (Object)body != (Object)null) { targetTransform = ((Component)body).transform; } if ((Object)physGrabObject == (Object)null) { MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: missing PhysGrabObject"); return false; } if ((Object)body == (Object)null) { MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: missing Rigidbody target=" + ObjectName(targetTransform)); return false; } if ((Object)targetTransform == (Object)null) { MultigraspPlugin.LogVerbose("TryResolveCurrentGrabbed failed: missing target transform body=" + ObjectName((Object)body)); return false; } return true; } private static bool IsPendingAnchorDataValid(PendingAnchorData pendingAnchorData) { if (pendingAnchorData == null || !pendingAnchorData.IsValid) { MultigraspPlugin.LogVerbose("Pending anchor invalid: " + GetPendingAnchorInvalidReason(pendingAnchorData)); return false; } if ((MultigraspPlugin.AllowEnemyAnchors == null || !MultigraspPlugin.AllowEnemyAnchors.Value) && IsEnemyObject(pendingAnchorData.PhysGrabObject, pendingAnchorData.TargetTransform, pendingAnchorData.Body)) { MultigraspPlugin.LogVerbose("Refused to fix enemy/monster object: " + ((Object)pendingAnchorData.TargetTransform).name); return false; } return true; } private void CommitAnchor(PendingAnchorData pendingAnchorData) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) int num = FindAnchorIndex(pendingAnchorData.PhysGrabObject, pendingAnchorData.TargetTransform); if (num >= 0) { _anchors[num].DestroyOwnedObjects(); } Anchor anchor = new Anchor(pendingAnchorData.PhysGrabObject, pendingAnchorData.Body, pendingAnchorData.TargetTransform, pendingAnchorData.LocalGrabPosition, pendingAnchorData.PlayerLocalBodyPosition, pendingAnchorData.PlayerLocalBodyRotation, _anchorFollowPlayer, _anchorPassthroughMode, $"Multigrasp Anchor Beam {_anchors.Count + 1}"); LogAnchorDiagnostic($"commit target={ObjectName(pendingAnchorData.TargetTransform)} body={DescribeBody(pendingAnchorData.Body)} grabbedAny={IsGrabbedByAnyPlayer(pendingAnchorData.PhysGrabObject)} object={ObjectName(pendingAnchorData.TargetTransform)}"); if (num >= 0) { _anchors[num] = anchor; MultigraspPlugin.LogVerbose("Updated fixed object anchor target=" + ObjectName(pendingAnchorData.TargetTransform)); } else { _anchors.Add(anchor); MultigraspPlugin.LogVerbose("Fixed object anchor added target=" + ObjectName(pendingAnchorData.TargetTransform)); } HudNotifier.Show("Object fixed", AnchorGreen); } private int FindAnchorIndex(PhysGrabObject physGrabObject, Transform targetTransform) { for (int i = 0; i < _anchors.Count; i++) { if (_anchors[i].Matches(physGrabObject, targetTransform)) { return i; } } return -1; } private void TickBeams() { Transform player = ResolveAnchorPlayerTransform(_primary); Transform cameraTransform = GetCameraTransform(_primary); for (int num = _anchors.Count - 1; num >= 0; num--) { if (!_anchors[num].TickBeam(_primary, cameraTransform, player)) { RemoveAnchorAt(num); } } } private void ApplyAnchorForces() { Transform player = ResolveAnchorPlayerTransform(_primary); for (int num = _anchors.Count - 1; num >= 0; num--) { if (!_anchors[num].ApplyForce(player)) { RemoveAnchorAt(num); } } } private void RemoveAnchorAt(int index) { string arg = ((index >= 0 && index < _anchors.Count) ? _anchors[index].TargetName : ""); MultigraspPlugin.LogVerbose($"Removing anchor at index={index} target={arg} countBefore={_anchors.Count}"); _anchors[index].DestroyOwnedObjects(); _anchors.RemoveAt(index); } internal static bool IsGrabbedByAnyPlayer(PhysGrabObject physGrabObject) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown object field = ReflectionCache.GetField(physGrabObject, "playerGrabbing"); if (!(field is IEnumerable enumerable) || field is string) { return false; } foreach (object item in enumerable) { Object val = (Object)((item is Object) ? item : null); if (val != null) { if (val != (Object)null) { return true; } } else if (item != null) { return true; } } return false; } private void Update() { try { HudNotifier.Tick(); ResolvePrimary(); if (!IsUsablePrimary(_primary)) { ReleaseAllAnchors("primary unavailable"); ResetFState(); return; } if (IsLocalPlayerInvalid(_primary)) { ReleaseAllAnchors("player dead/disabled"); ResetFState(); return; } TickFollowToggleInput(); TickPassthroughToggleInput(); TickReleaseCurrentFixedInput(); TickAnchorInput(); TickBeams(); LogHeldFixedObjectDiagnostics(); } catch (Exception ex) { MultigraspPlugin.LogError("Manager update failed", ex); } } private void FixedUpdate() { try { ApplyAnchorForces(); } catch (Exception ex) { MultigraspPlugin.LogError("Anchor force failed", ex); } } internal void RegisterPrimary(PhysGrabber grabber) { if (IsUsablePrimary(grabber)) { _primary = grabber; MultigraspPlugin.LogVerbose("Registered primary " + ((Object)grabber).name); } } internal void ReleaseAllAnchors(string reason) { ClearPendingAnchorData(); if (_anchors.Count > 0) { MultigraspPlugin.LogVerbose("Released all anchors: " + reason); } for (int i = 0; i < _anchors.Count; i++) { _anchors[i].DestroyOwnedObjects(); } _anchors.Clear(); } internal void DestroyOwnedObjects() { ClearPendingAnchorData(); ReleaseAllAnchors("destroy owned objects"); HudNotifier.DestroyOwnedObjects(); } private void ResolvePrimary() { if (IsUsablePrimary(_primary)) { return; } if (IsUsablePrimary(PhysGrabber.instance)) { _primary = PhysGrabber.instance; return; } PhysGrabber[] array = Object.FindObjectsOfType(); PhysGrabber[] array2 = array; foreach (PhysGrabber val in array2) { if (IsUsablePrimary(val)) { _primary = val; MultigraspPlugin.LogVerbose("Fallback selected primary " + ((Object)val).name); break; } } } internal static void LogAnchorDiagnostic(string message) { MultigraspPlugin.LogVerbose("[anchor] " + message); } internal static string DescribeBody(Rigidbody body) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if ((Object)body == (Object)null) { return "body=none"; } return $"bodyPos={FormatVector(body.position)} bodyVel={FormatVector(body.velocity)} bodyKinematic={body.isKinematic}"; } private static string FormatVector(Vector3 value) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.000},{value.y:0.000},{value.z:0.000})"; } private void LogHeldFixedObjectDiagnostics() { //IL_00d3: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_0101: Expected O, but got Unknown //IL_0149: 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_0118: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) if (MultigraspPlugin.VerboseLogs == null || !MultigraspPlugin.VerboseLogs.Value || !IsPrimaryHolding(_primary) || !TryResolveCurrentGrabbed(_primary, out var physGrabObject, out var targetTransform, out var body)) { return; } int num = FindAnchorIndex(physGrabObject, targetTransform); if (num < 0) { return; } int instanceID = ((Object)physGrabObject).GetInstanceID(); float realtimeSinceStartup = Time.realtimeSinceStartup; if (!_lastHeldObjectDiagnosticAt.TryGetValue(instanceID, out var value) || !(realtimeSinceStartup - value < 0.75f)) { _lastHeldObjectDiagnosticAt[instanceID] = realtimeSinceStartup; PruneBoundedDiagnostics(_lastHeldObjectDiagnosticAt, 64, realtimeSinceStartup, 10f); Vector3 localGrabPosition = _primary.localGrabPosition; Vector3 val = targetTransform.TransformPoint(localGrabPosition); string text = "desired=unavailable reason=no reliable PhysGrabber.physGrabPoint"; if ((Object)_primary.physGrabPoint != (Object)null) { Vector3 position = _primary.physGrabPoint.position; text = $"desiredSource=physGrabPoint desired={FormatVector(position)} error={Vector3.Distance(val, position):0.000}"; } LogAnchorDiagnostic($"held-fixed-object actualGrab={FormatVector(val)} {text} body={DescribeBody(body)} grabbedAny={IsGrabbedByAnyPlayer(physGrabObject)} object={ObjectName(targetTransform)}"); } } private static void PruneBoundedDiagnostics(Dictionary values, int maxCount, float now, float maxAgeSeconds) { if (values.Count <= maxCount) { return; } foreach (int item in new List(values.Keys)) { if (now - values[item] > maxAgeSeconds) { values.Remove(item); } } while (values.Count > maxCount) { int key = 0; float num = float.MaxValue; foreach (KeyValuePair value in values) { if (value.Value < num) { key = value.Key; num = value.Value; } } values.Remove(key); } } private static string GetPendingAnchorInvalidReason(PendingAnchorData data) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown if (data == null) { return "data is null"; } if ((Object)data.PhysGrabObject == (Object)null) { return "missing PhysGrabObject"; } if ((Object)data.Body == (Object)null) { return "missing Rigidbody"; } if ((Object)data.TargetTransform == (Object)null) { return "missing target transform"; } if (!((Behaviour)data.PhysGrabObject).enabled || data.PhysGrabObject.dead) { return "PhysGrabObject disabled/dead target=" + ObjectName(data.TargetTransform); } if (data.Body.isKinematic || !((Component)data.Body).gameObject.activeInHierarchy) { return "Rigidbody kinematic/inactive target=" + ObjectName(data.TargetTransform); } return "unknown target=" + ObjectName(data.TargetTransform); } private static string ObjectName(Transform transform) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown return ((Object)transform != (Object)null) ? ((Object)transform).name : ""; } private static string ObjectName(Object unityObject) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown return (unityObject != (Object)null) ? unityObject.name : ""; } private static Transform ResolveAnchorPlayerTransform(PhysGrabber primary) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0074: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_0097: Expected O, but got Unknown if ((Object)primary == (Object)null || (Object)primary.playerAvatar == (Object)null) { return null; } PlayerController instance = PlayerController.instance; if ((Object)instance != (Object)null) { PlayerAvatar playerAvatarScript = instance.playerAvatarScript; if ((Object)playerAvatarScript != (Object)null && ((Object)primary.playerAvatar == (Object)playerAvatarScript || (Object)((Component)primary.playerAvatar).gameObject == (Object)((Component)playerAvatarScript).gameObject)) { return ((Component)instance).transform; } } return ((Component)primary.playerAvatar).transform; } private static bool IsUsablePrimary(PhysGrabber grabber) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown return (Object)grabber != (Object)null && grabber.isLocal && (Object)grabber.playerAvatar != (Object)null && (Object)grabber.playerAvatar.localCamera != (Object)null; } private static bool IsLocalPlayerInvalid(PhysGrabber grabber) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown if ((Object)grabber == (Object)null || !grabber.isLocal) { return true; } PlayerAvatar playerAvatar = grabber.playerAvatar; if ((Object)playerAvatar == (Object)null) { return true; } GameObject gameObject = ((Component)playerAvatar).gameObject; if ((Object)gameObject == (Object)null || !gameObject.activeInHierarchy) { return true; } return ReflectionCache.GetField(playerAvatar, "deadSet") || ReflectionCache.GetField(playerAvatar, "isDisabled"); } internal static bool IsEnemyObject(PhysGrabObject physGrabObject, Transform targetTransform, Rigidbody body) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown if (HasEnemyComponent(((Object)physGrabObject != (Object)null) ? ((Component)physGrabObject).transform : null) || HasEnemyComponent(targetTransform) || HasEnemyComponent(((Object)body != (Object)null) ? ((Component)body).transform : null)) { return true; } return HasEnemyName(((Object)physGrabObject != (Object)null) ? ((Object)physGrabObject).name : null) || HasEnemyName(((Object)targetTransform != (Object)null) ? ((Object)targetTransform).name : null) || HasEnemyName(((Object)targetTransform != (Object)null && (Object)targetTransform.root != (Object)null) ? ((Object)targetTransform.root).name : null) || HasEnemyName(((Object)body != (Object)null) ? ((Object)body).name : null); } private static bool HasEnemyComponent(Transform transform) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown if ((Object)transform == (Object)null) { return false; } return (Object)((Component)transform).GetComponentInParent(true) != (Object)null || (Object)((Component)transform).GetComponentInChildren(true) != (Object)null || (Object)((Component)transform).GetComponentInParent(true) != (Object)null || (Object)((Component)transform).GetComponentInChildren(true) != (Object)null || (Object)((Component)transform).GetComponentInParent(true) != (Object)null; } private static bool HasEnemyName(string objectName) { return objectName != null && (objectName.IndexOf("Enemy", StringComparison.OrdinalIgnoreCase) >= 0 || objectName.IndexOf("Monster", StringComparison.OrdinalIgnoreCase) >= 0); } private static bool IsPrimaryHolding(PhysGrabber primary) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown return (Object)primary != (Object)null && primary.grabbed && (Object)primary.grabbedObjectTransform != (Object)null; } private static Transform GetCameraTransform(PhysGrabber primary) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown try { object obj; if ((Object)(object)primary == (Object)null) { obj = null; } else { PlayerAvatar playerAvatar = primary.playerAvatar; if ((Object)(object)playerAvatar == (Object)null) { obj = null; } else { PlayerLocalCamera localCamera = playerAvatar.localCamera; obj = (((Object)(object)localCamera != (Object)null) ? localCamera.GetOverrideTransform() : null); } } return (Transform)obj; } catch { object obj3; if ((Object)(object)primary == (Object)null) { obj3 = null; } else { PlayerAvatar playerAvatar2 = primary.playerAvatar; if ((Object)(object)playerAvatar2 == (Object)null) { obj3 = null; } else { PlayerLocalCamera localCamera2 = playerAvatar2.localCamera; obj3 = (((Object)(object)localCamera2 != (Object)null) ? ((Component)localCamera2).transform : null); } } return (Transform)obj3; } } private static Vector3 GetCurrentTargetPoint(PhysGrabber primary, Transform targetTransform, Vector3 localGrabPosition) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)primary.physGrabPoint != (Object)null) { return primary.physGrabPoint.position; } return targetTransform.TransformPoint(localGrabPosition); } internal static bool IsFinite(float value) { return !float.IsNaN(value) && !float.IsInfinity(value); } internal static bool IsFinite(Vector3 value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return IsFinite(value.x) && IsFinite(value.y) && IsFinite(value.z); } internal static bool IsFinite(Quaternion value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return IsFinite(value.x) && IsFinite(value.y) && IsFinite(value.z) && IsFinite(value.w); } private void TickAnchorInput() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown((KeyCode)102)) { ResetFState(); _fHeld = true; _fConsumed = false; _fDownAt = Time.unscaledTime; CapturePendingAnchor(); } if (_fHeld && !_fConsumed && Input.GetKey((KeyCode)102) && Time.unscaledTime - _fDownAt >= 0.7f) { ClearPendingAnchorData(); ReleaseAllAnchors("F held"); HudNotifier.Show("All fixed objects released", ReleaseOrangeRed); _fConsumed = true; } if (!Input.GetKeyUp((KeyCode)102)) { return; } if (!_fConsumed && _pendingAnchorData != null) { PendingAnchorData pendingAnchorData = _pendingAnchorData; ClearPendingAnchorData(); if (IsPendingAnchorDataValid(pendingAnchorData)) { CommitAnchor(pendingAnchorData); } else { HudNotifier.Show("Cannot fix object", RejectOrange); } } ResetFState(); } private void ResetFState() { ClearPendingAnchorData(); _fHeld = false; _fConsumed = false; _fDownAt = 0f; } private void TickFollowToggleInput() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (!Input.GetKeyDown((KeyCode)114)) { return; } Transform val = ResolveAnchorPlayerTransform(_primary); if ((Object)val == (Object)null) { return; } bool anchorFollowPlayer = !_anchorFollowPlayer; _anchorFollowPlayer = anchorFollowPlayer; for (int num = _anchors.Count - 1; num >= 0; num--) { if (!_anchors[num].SetFollowPlayer(_anchorFollowPlayer, val)) { RemoveAnchorAt(num); } } HudNotifier.Show(_anchorFollowPlayer ? "Fixed objects follow player" : "Fixed objects stay in world", AnchorGreen); MultigraspPlugin.LogVerbose(_anchorFollowPlayer ? "Fixed object follow enabled" : "Fixed object follow disabled"); } private void TickPassthroughToggleInput() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (!Input.GetKeyDown((KeyCode)118)) { return; } _anchorPassthroughMode = !_anchorPassthroughMode; for (int num = _anchors.Count - 1; num >= 0; num--) { if (!_anchors[num].SetPassthroughMode(_anchorPassthroughMode)) { RemoveAnchorAt(num); } } HudNotifier.Show(_anchorPassthroughMode ? "Fixed objects ignore obstacles" : "Fixed objects collide normally", AnchorGreen); MultigraspPlugin.LogVerbose(_anchorPassthroughMode ? "Fixed object passthrough enabled" : "Fixed object passthrough disabled"); } private void TickReleaseCurrentFixedInput() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown((KeyCode)99) && TryResolveCurrentGrabbed(_primary, out var physGrabObject, out var targetTransform, out var _)) { int num = FindAnchorIndex(physGrabObject, targetTransform); if (num >= 0) { RemoveAnchorAt(num); HudNotifier.Show("Object released", ReleaseOrangeRed); MultigraspPlugin.LogVerbose("Released current fixed object anchor"); } } } } [BepInPlugin("com.zhuanban.repo.multigrasp", "Multigrasp", "1.0.0")] public sealed class MultigraspPlugin : BaseUnityPlugin { public const string PluginGuid = "com.zhuanban.repo.multigrasp"; public const string PluginName = "Multigrasp"; public const string PluginVersion = "1.0.0"; private Harmony _harmony; private MultigraspManager _manager; internal static MultigraspPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry VerboseLogs { get; private set; } internal static ConfigEntry EnableScrollDistanceOverride { get; private set; } internal static ConfigEntry AllowEnemyAnchors { get; private set; } private void Awake() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; VerboseLogs = ((BaseUnityPlugin)this).Config.Bind("Logging", "VerboseLogs", false, "When true, console receives verbose logs for Multigrasp debugging."); EnableScrollDistanceOverride = ((BaseUnityPlugin)this).Config.Bind("Gameplay", "EnableScrollDistanceOverride", true, "When true, objects that force grab distance every frame can still be adjusted with push/pull or mouse scroll while held locally."); AllowEnemyAnchors = ((BaseUnityPlugin)this).Config.Bind("Gameplay", "AllowEnemyAnchors", false, "When true, Multigrasp allows fixing enemy/monster PhysGrabObjects locally."); LogVerbose($"Startup config: VerboseLogs={VerboseLogs.Value}, EnableScrollDistanceOverride={EnableScrollDistanceOverride.Value}, AllowEnemyAnchors={AllowEnemyAnchors.Value}"); ReflectionCache.Initialize(); _harmony = new Harmony("com.zhuanban.repo.multigrasp"); _harmony.PatchAll(); _manager = ((Component)this).gameObject.AddComponent(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Multigrasp loaded. Safe local-only anchors active by default."); } private void OnDestroy() { _manager?.DestroyOwnedObjects(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Instance = null; } internal static void LogInfo(string message) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[Multigrasp] " + message)); } } internal static void LogVerbose(string message) { ConfigEntry verboseLogs = VerboseLogs; if (verboseLogs != null && verboseLogs.Value) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[Multigrasp verbose] " + message)); } } } internal static void LogWarning(string message) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[Multigrasp] " + message)); } } internal static void LogError(string message, Exception ex = null) { ManualLogSource log = Log; if (log != null) { log.LogError((object)((ex == null) ? ("[Multigrasp] " + message) : $"[Multigrasp] {message}: {ex}")); } } } [HarmonyPatch(typeof(PhysGrabber), "OverrideGrabDistance")] internal static class PhysGrabberOverrideGrabDistancePatch { private sealed class OffsetState { internal Transform TargetTransform; internal float LastForcedDistance; internal float Offset; } private const float PullPushDistanceStep = 0.2f; private static readonly Dictionary OffsetStates = new Dictionary(); private static void Prefix(PhysGrabber __instance, ref float dist) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown PruneDestroyedStates(); ConfigEntry enableScrollDistanceOverride = MultigraspPlugin.EnableScrollDistanceOverride; if (enableScrollDistanceOverride == null || !enableScrollDistanceOverride.Value) { return; } if (!IsLocalGrabActive(__instance, out var targetTransform)) { if ((Object)__instance != (Object)null) { OffsetStates.Remove(__instance); } return; } OffsetState state = GetState(__instance, targetTransform, dist); float pullPushInput = GetPullPushInput(); if (IsFinite(pullPushInput) && Mathf.Abs(pullPushInput) > 0.0001f) { state.Offset += Mathf.Sign(pullPushInput) * 0.2f; } float num = dist + state.Offset; if (TryGetDistanceBounds(__instance, out var minimumDistance, out var maximumDistance)) { num = Mathf.Clamp(num, minimumDistance, maximumDistance); state.Offset = num - dist; } if (IsFinite(num)) { dist = num; } } private static void PruneDestroyedStates() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown foreach (PhysGrabber item in new List(OffsetStates.Keys)) { if ((Object)item == (Object)null) { OffsetStates.Remove(item); } } } private static bool IsLocalGrabActive(PhysGrabber grabber, out Transform targetTransform) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown targetTransform = null; if ((Object)grabber == (Object)null || !grabber.isLocal || !grabber.grabbed || (Object)grabber.grabbedObjectTransform == (Object)null) { return false; } targetTransform = grabber.grabbedObjectTransform; return true; } private static OffsetState GetState(PhysGrabber grabber, Transform targetTransform, float forcedDistance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0040: Expected O, but got Unknown if (!OffsetStates.TryGetValue(grabber, out var value)) { value = new OffsetState(); OffsetStates[grabber] = value; } if ((Object)value.TargetTransform != (Object)targetTransform || !Mathf.Approximately(value.LastForcedDistance, forcedDistance)) { value.TargetTransform = targetTransform; value.Offset = 0f; } value.LastForcedDistance = forcedDistance; return value; } private static float GetPullPushInput() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown try { return ((Object)InputManager.instance != (Object)null) ? InputManager.instance.KeyPullAndPush() : 0f; } catch { return 0f; } } private static bool TryGetDistanceBounds(PhysGrabber grabber, out float minimumDistance, out float maximumDistance) { minimumDistance = ReflectionCache.GetField(grabber, "minDistanceFromPlayer"); float field = ReflectionCache.GetField(grabber, "grabRange"); float field2 = ReflectionCache.GetField(grabber, "maxDistanceFromPlayer"); maximumDistance = ((field2 > 0f) ? field2 : field); if (field > 0f && maximumDistance > 0f) { maximumDistance = Mathf.Min(field, maximumDistance); } return IsFinite(minimumDistance) && IsFinite(maximumDistance) && maximumDistance > minimumDistance; } private static bool IsFinite(float value) { return !float.IsNaN(value) && !float.IsInfinity(value); } } [HarmonyPatch(typeof(PhysGrabber), "Start")] internal static class PhysGrabberStartPatch { private static void Postfix(PhysGrabber __instance) { MultigraspPlugin instance = MultigraspPlugin.Instance; if ((Object)(object)instance != (Object)null) { ((Component)instance).GetComponent()?.RegisterPrimary(__instance); } } } internal static class ReflectionCache { private struct FieldKey : IEquatable { private readonly Type _type; private readonly string _name; internal FieldKey(Type type, string name) { _type = type; _name = name; } public bool Equals(FieldKey other) { return _type == other._type && _name == other._name; } public override bool Equals(object obj) { return obj is FieldKey other && Equals(other); } public override int GetHashCode() { return (((_type != null) ? _type.GetHashCode() : 0) * 397) ^ ((_name != null) ? _name.GetHashCode() : 0); } } private static readonly BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly HashSet WarnedMissingMembers = new HashSet(); private static readonly Dictionary CachedFields = new Dictionary(); internal static void Initialize() { WarnedMissingMembers.Clear(); CachedFields.Clear(); } internal static T GetField(object target, string name) { FieldInfo fieldInfo = GetFieldInfo(target, name); if (fieldInfo == null) { return default(T); } try { return (fieldInfo.GetValue(target) is T val) ? val : default(T); } catch (Exception ex) { MultigraspPlugin.LogError("Reflection get failed for " + target.GetType().Name + "." + name, ex); return default(T); } } internal static bool SetField(object target, string name, T value) { FieldInfo fieldInfo = GetFieldInfo(target, name); if (fieldInfo == null) { return false; } try { fieldInfo.SetValue(target, value); return true; } catch (Exception ex) { MultigraspPlugin.LogError("Reflection set failed for " + target.GetType().Name + "." + name, ex); return false; } } private static FieldInfo GetFieldInfo(object target, string name) { if (target == null) { return null; } Type type = target.GetType(); FieldKey key = new FieldKey(type, name); if (CachedFields.TryGetValue(key, out var value)) { return value; } FieldInfo field = type.GetField(name, Flags); CachedFields[key] = field; if (field == null) { WarnMissing(type.Name + "." + name); } return field; } private static void WarnMissing(string member) { if (WarnedMissingMembers.Add(member)) { MultigraspPlugin.LogVerbose("Optional reflection member unavailable: " + member); } } } }