Decompiled source of DeathHeadHopperVRBridge v0.1.2
plugins\DeathHeadHopperVRBridge.dll
Decompiled 2 weeks 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.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DeathHeadHopper.DeathHead; using DeathHeadHopper.DeathHead.Handlers; using DeathHeadHopper.Managers; using DeathHeadHopper.UI; using DeathHeadHopperVRBridge.Modules.Config; using DeathHeadHopperVRBridge.Modules.Logging; using DeathHeadHopperVRBridge.Modules.Spectate; using HarmonyLib; using Microsoft.CodeAnalysis; using RepoXR; using RepoXR.Input; using RepoXR.Managers; using RepoXR.Player; using RepoXR.UI; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; using UnityEngine.XR.Interaction.Toolkit; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 DeathHeadHopperVRBridge { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("AdrenSnyder.DeathHeadHopperVRBridge", "Death Head Hopper - VRBridge", "0.1.1")] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <ApplyOptionalLastChanceCompat>d__6 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Plugin <>4__this; private int <attempt>5__1; private Harmony <harmony>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyOptionalLastChanceCompat>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <harmony>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_0119; } <>1__state = -1; <attempt>5__1 = 1; goto IL_012b; IL_0119: <attempt>5__1++; goto IL_012b; IL_012b: if (<attempt>5__1 <= 4) { <harmony>5__2 = <>4__this._harmony; if (<harmony>5__2 == null) { return false; } if (LastChanceCameraAimCompatPatch.TryApply(<harmony>5__2)) { ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[LastChanceCompat] camera-force patch applied."); <>4__this._lastChanceCompatRoutine = null; return false; } if (Chainloader.PluginInfos.ContainsKey("AdrenSnyder.DHHFLastChanceMode")) { ((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)"[LastChanceCompat] plugin detected but patch target was not found. Keeping compat dormant."); <>4__this._lastChanceCompatRoutine = null; return false; } if (<attempt>5__1 < 4) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[LastChanceCompat] optional plugin not found. LastChance compat patches remain dormant."); <>4__this._lastChanceCompatRoutine = null; <harmony>5__2 = null; goto IL_0119; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string BuildStamp = "C13-ability-pipeline-probe"; private const string HarmonyId = "DeathHeadHopperFix-VR.Spectate"; private const string LastChancePluginGuid = "AdrenSnyder.DHHFLastChanceMode"; private Harmony? _harmony; private Coroutine? _lastChanceCompatRoutine; private void Awake() { //IL_000d: 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_0037: Expected O, but got Unknown ConfigManager.Initialize(((BaseUnityPlugin)this).Config); if (((Enum)Plugin.Flags).HasFlag((Enum)(object)(Flags)1)) { _harmony = new Harmony("DeathHeadHopperFix-VR.Spectate"); _harmony.PatchAll(); _lastChanceCompatRoutine = ((MonoBehaviour)this).StartCoroutine(ApplyOptionalLastChanceCompat()); VanillaAbilityInputBridge.EnsureAttached(((Component)this).gameObject); ((BaseUnityPlugin)this).Logger.LogInfo((object)"DeathHeadHopperFix-VR bridge ready (spectate head bridge enabled). build=C13-ability-pipeline-probe"); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"RepoXR did not initialize VR mode, keeping Bridge disabled."); } } [IteratorStateMachine(typeof(<ApplyOptionalLastChanceCompat>d__6))] private IEnumerator ApplyOptionalLastChanceCompat() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ApplyOptionalLastChanceCompat>d__6(0) { <>4__this = this }; } private void OnDestroy() { if (_lastChanceCompatRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_lastChanceCompatRoutine); _lastChanceCompatRoutine = null; } Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace DeathHeadHopperVRBridge.Modules.Spectate { internal static class DHHInputBridge { internal enum MovementDirectionSource { HeadRaycast, ControllerRaycast } private static readonly FieldInfo? TMainCameraField = AccessTools.Field(typeof(DHHInputManager), "_tMainCamera"); private static readonly FieldInfo? RepoXRLeftInteractorField = AccessTools.Field(typeof(XRRayInteractorManager), "leftInteractor"); private static readonly FieldInfo? RepoXRRightInteractorField = AccessTools.Field(typeof(XRRayInteractorManager), "rightInteractor"); private static readonly FieldInfo? JumpBufferTimerField = AccessTools.Field(typeof(JumpHandler), "jumpBufferTimer"); private static readonly FieldInfo? JumpCooldownTimerField = AccessTools.Field(typeof(JumpHandler), "jumpCooldownTimer"); internal static readonly ManualLogSource Log = MovementAnalog.Log; internal const string ModuleTag = "[DeathHeadHopperFix-VR] [SpectateCam]"; private static Transform? _abilityAimProxy; private static bool _repoXRRayVisible; private static bool _repoXRRayLengthOverridden; private static Transform? _repoXRRayHitMarker; internal static MovementDirectionSource MovementDirection => ParseMovementDirection(); internal static void UpdateCameraReference(DHHInputManager instance) { if ((Object)(object)instance == (Object)null || !SpectateHeadBridge.IsDhhRuntimeInputContextActive()) { return; } Transform val = SpectateHeadBridge.GetHmdCameraTransform() ?? SpectateHeadBridge.GetAlignedCameraTransform(); if (!((Object)(object)val == (Object)null) && !(TMainCameraField == null)) { object? value = TMainCameraField.GetValue(instance); Transform val2 = (Transform)((value is Transform) ? value : null); if (!((Object)(object)val2 == (Object)(object)val)) { TMainCameraField.SetValue(instance, val); } } } internal static bool TryGetAnalogMovement(out Vector2 movement) { return MovementAnalog.TryGetAnalog(out movement); } internal static Vector2 GetLegacyMovement() { //IL_000b: 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_0013: Unknown result type (might be due to invalid IL or missing references) return new Vector2(SemiFunc.InputMovementX(), SemiFunc.InputMovementY()); } internal static Vector3 CalculateMoveDirection(Vector2 input) { //IL_0010: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_0068: 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_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_00f7: 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_00fd: 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_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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_014f: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if ((MovementDirection == MovementDirectionSource.ControllerRaycast || MovementDirection == MovementDirectionSource.HeadRaycast) && Mathf.Abs(input.x) <= Mathf.Clamp01(FeatureFlags.ControllerRaycastXAxisDeadzone) && Mathf.Abs(input.y) > 0.05f) { input.x = 0f; } if (MovementDirection == MovementDirectionSource.ControllerRaycast || MovementDirection == MovementDirectionSource.HeadRaycast) { float num = Mathf.Abs(input.x); float num2 = Mathf.Abs(input.y); float num3 = Mathf.Clamp01(FeatureFlags.ControllerRaycastForwardPriorityMinY); float num4 = Mathf.Clamp(FeatureFlags.ControllerRaycastForwardPriorityRatio, 1f, 3f); if (num2 > num3 && num2 >= num * num4) { input.x = 0f; } } Vector3 val = GetMovementForward(input); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } Vector3 val2 = Vector3.Cross(Vector3.up, val); Vector3 val3 = val * input.y + val2 * input.x; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { return Vector3.zero; } return FeatureFlags.UseAnalogMagnitude ? Vector3.ClampMagnitude(val3, 1f) : ((Vector3)(ref val3)).normalized; } internal static void LogMovement(Vector2 selected, Vector2 legacy, bool analogUsed, Vector3 direction, MovementDirectionSource source) { //IL_003e: 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_0059: Unknown result type (might be due to invalid IL or missing references) if (InternalDebugConfig.DebugMovementDirection && LogLimiter.Allow("MovementInput", 0.5f)) { Log.LogDebug((object)string.Format("{0} Movement selected={1:F3} legacy={2:F3} analogUsed={3} forward={4:F3} source={5}", "[DeathHeadHopperFix-VR] [SpectateCam]", selected, legacy, analogUsed, direction, source)); } } private static Vector3 GetMovementForward(Vector2 input) { //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_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_0052: 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_0065: 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_006a: 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) MovementDirectionSource movementDirection = MovementDirection; if (1 == 0) { } Vector3 val = ((movementDirection != 0) ? GetRaycastAimForward(useControllerSource: true, GetCameraGripSelection(), projectToHorizontal: true, Mathf.Max(1f, FeatureFlags.MovementRaycastDistance), useHorizonRay: false) : GetRaycastAimForward(useControllerSource: false, GetCameraGripSelection(), projectToHorizontal: true, Mathf.Max(1f, FeatureFlags.MovementRaycastDistance), useHorizonRay: false)); if (1 == 0) { } Vector3 val2 = val; return (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) ? SpectateHeadBridge.GetBaseForward() : val2; } internal static Vector3 GetControllerForward(Vector2 movementInput) { //IL_00a9: 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_001c: 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_0026: 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_00b2: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) try { string handName; Transform val = TryGetPreferredControllerTransform(GetCameraGripSelection(), out handName); if ((Object)(object)val != (Object)null) { Vector3 val2 = Vector3.ProjectOnPlane(val.forward, Vector3.up); if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f) { return ((Vector3)(ref val2)).normalized; } } TrackingInput instance = TrackingInput.Instance; Transform val3 = ((instance != null) ? instance.HeadTransform : null); if ((Object)(object)val3 != (Object)null) { Vector3 val4 = Vector3.ProjectOnPlane(val3.forward, Vector3.up); if (((Vector3)(ref val4)).sqrMagnitude > 0.0001f) { return ((Vector3)(ref val4)).normalized; } } } catch { } return SpectateHeadBridge.GetBaseForward(); } internal static Vector3 GetAbilityForward() { //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_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_003e: 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_0057: 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_005c: 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) MovementDirectionSource movementDirection = MovementDirection; if (1 == 0) { } Vector3 val = ((movementDirection != 0) ? GetRaycastAimForward(useControllerSource: true, GetUnifiedRaycastGripSelection(), projectToHorizontal: false, GetUnifiedRaycastDistance(), useHorizonRay: false) : GetRaycastAimForward(useControllerSource: false, GetUnifiedRaycastGripSelection(), projectToHorizontal: false, GetUnifiedRaycastDistance(), useHorizonRay: false)); if (1 == 0) { } Vector3 val2 = val; return (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) ? SpectateHeadBridge.GetAlignedForward() : ((Vector3)(ref val2)).normalized; } internal static bool ShouldSuppressLegacyMovement() { if (!SpectateHeadBridge.IsDhhRuntimeInputContextActive() && !SpectateHeadBridge.IsLocalDeathHeadTriggered()) { return false; } if (!SpectateHeadBridge.IsGripPressedForCamera()) { return false; } if (InternalDebugConfig.DebugSpectateGuard && LogLimiter.Allow("MovementGuard.LegacySuppressed", 0.2f)) { Log.LogInfo((object)"[DeathHeadHopperFix-VR] [SpectateCam] Legacy movement suppressed while spectating head because camera grip is held."); } return true; } private static Vector3 GetHeadAimForward() { //IL_0021: 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_0026: 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) Transform val = SpectateHeadBridge.GetHmdCameraTransform() ?? SpectateHeadBridge.GetAlignedCameraTransform(); return ((Object)(object)val != (Object)null) ? val.forward : SpectateHeadBridge.GetAlignedForward(); } private static Vector3 GetRaycastAimForward(bool useControllerSource, GripSelection controllerPreference, bool projectToHorizontal, float maxDistance, bool useHorizonRay) { //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_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_0050: 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_0021: 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_00a5: 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) //IL_006e: 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_0096: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) if (!TryGetRaySource(useControllerSource, controllerPreference, out Vector3 sourcePosition, out Vector3 sourceForward, out string _)) { DisableControllerRayVisualizer(); return useControllerSource ? GetControllerAimForward() : GetHeadAimForward(); } Vector3 normalized = ((Vector3)(ref sourceForward)).normalized; if (useHorizonRay) { Vector3 val = Vector3.ProjectOnPlane(normalized, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { normalized = ((Vector3)(ref val)).normalized; } } if (((Vector3)(ref normalized)).sqrMagnitude < 0.0001f) { DisableControllerRayVisualizer(); return useControllerSource ? GetControllerAimForward() : GetHeadAimForward(); } Ray ray = default(Ray); ((Ray)(ref ray))..ctor(sourcePosition, normalized); PlayerDeathHead val2 = PlayerAvatar.instance?.playerDeathHead; Vector3 targetPoint = ((Ray)(ref ray)).origin + ((Ray)(ref ray)).direction * maxDistance; if (TryGetFirstRaycastHit(ray, maxDistance, out var selectedHit)) { targetPoint = ((RaycastHit)(ref selectedHit)).point; } if (useControllerSource) { SetRepoXRRayVisibility(FeatureFlags.ShowControllerRayLine && SpectateHeadBridge.IsSpectatingHead()); } Vector3 val3 = (((Object)(object)val2 == (Object)null) ? ((Ray)(ref ray)).direction : GetHeadToTargetDirection(((Component)val2).transform.position, targetPoint)); if (projectToHorizontal) { val3 = Vector3.ProjectOnPlane(val3, Vector3.up); } if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { return ((Ray)(ref ray)).direction; } return ((Vector3)(ref val3)).normalized; } private static Vector3 GetHeadToTargetDirection(Vector3 headPosition, Vector3 targetPoint) { //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_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Vector3 val = targetPoint - headPosition; return (((Vector3)(ref val)).sqrMagnitude < 0.0001f) ? Vector3.zero : ((Vector3)(ref val)).normalized; } internal static void UpdateRealtimeControllerRayPreview() { if (!SpectateHeadBridge.IsSpectatingHead()) { DisableControllerRayVisualizer(); SetRepoXRRayHitMarkerVisible(visible: false); } else if (!UsesAnyControllerRay()) { DisableControllerRayVisualizer(); SetRepoXRRayHitMarkerVisible(visible: false); } else { SetRepoXRRayVisibility(FeatureFlags.ShowControllerRayLine); UpdateRepoXRRayHitMarkerPreview(); } } private static void DisableControllerRayVisualizer() { SetRepoXRRayVisibility(visible: false); RestoreRepoXRRayLengthOverride(); SetRepoXRRayHitMarkerVisible(visible: false); } private static void UpdateRepoXRRayHitMarkerPreview() { //IL_0084: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00e5: 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) if (!FeatureFlags.ShowControllerRayHitMarker) { SetRepoXRRayHitMarkerVisible(visible: false); return; } float maxDistance = Mathf.Max(FeatureFlags.ControllerRayLineLength, GetUnifiedRaycastDistance()); if (!TryGetControllerRaycastHit(GetUnifiedRaycastGripSelection(), maxDistance, out var selectedHit)) { SetRepoXRRayHitMarkerVisible(visible: false); return; } EnsureRepoXRRayHitMarker(); if (!((Object)(object)_repoXRRayHitMarker == (Object)null)) { float num = Mathf.Clamp(FeatureFlags.ControllerRayHitMarkerSize, 0.005f, 0.2f); _repoXRRayHitMarker.localScale = Vector3.one * num; _repoXRRayHitMarker.position = ((RaycastHit)(ref selectedHit)).point + ((RaycastHit)(ref selectedHit)).normal * Mathf.Max(0.001f, num * 0.1f); Transform? repoXRRayHitMarker = _repoXRRayHitMarker; Vector3 normal = ((RaycastHit)(ref selectedHit)).normal; repoXRRayHitMarker.rotation = Quaternion.LookRotation((((Vector3)(ref normal)).sqrMagnitude > 0.0001f) ? ((RaycastHit)(ref selectedHit)).normal : Vector3.up); ((Component)_repoXRRayHitMarker).gameObject.SetActive(true); } } private static bool TryGetControllerRaycastHit(GripSelection controllerPreference, float maxDistance, out RaycastHit selectedHit) { //IL_0002: 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_002b: 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_0049: 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_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) selectedHit = default(RaycastHit); if (!TryGetRaySource(useControllerSource: true, controllerPreference, out Vector3 sourcePosition, out Vector3 sourceForward, out string _)) { return false; } Vector3 normalized = ((Vector3)(ref sourceForward)).normalized; if (((Vector3)(ref normalized)).sqrMagnitude < 0.0001f) { return false; } Ray ray = default(Ray); ((Ray)(ref ray))..ctor(sourcePosition, normalized); if (!TryGetFirstRaycastHit(ray, maxDistance, out var selectedHit2)) { return false; } selectedHit = selectedHit2; return true; } private static bool TryGetFirstRaycastHit(Ray ray, float maxDistance, out RaycastHit selectedHit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) selectedHit = default(RaycastHit); RaycastHit[] array = Physics.RaycastAll(ray, maxDistance, -1, (QueryTriggerInteraction)1); if (array == null || array.Length == 0) { return false; } Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); selectedHit = array[0]; return true; } private static void EnsureRepoXRRayHitMarker() { //IL_009a: 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_0092: Expected O, but got Unknown if ((Object)(object)_repoXRRayHitMarker != (Object)null) { return; } GameObject val = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)val).name = "DeathHeadHopperVRBridge_RepoXRRayHitMarker"; val.layer = 0; Object.DontDestroyOnLoad((Object)(object)val); Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = val.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { Shader val2 = Shader.Find("Unlit/Color"); if ((Object)(object)val2 != (Object)null) { component2.material = new Material(val2); } component2.material.color = Color.red; component2.shadowCastingMode = (ShadowCastingMode)0; component2.receiveShadows = false; } val.SetActive(false); _repoXRRayHitMarker = val.transform; } private static void SetRepoXRRayHitMarkerVisible(bool visible) { if (!((Object)(object)_repoXRRayHitMarker == (Object)null)) { ((Component)_repoXRRayHitMarker).gameObject.SetActive(visible); } } private static void SetRepoXRRayVisibility(bool visible) { XRRayInteractorManager instance = XRRayInteractorManager.Instance; if ((Object)(object)instance == (Object)null) { return; } if (!visible) { if (_repoXRRayVisible) { instance.SetVisible(false); } _repoXRRayVisible = false; return; } instance.SetVisible(true); if (SpectateHeadBridge.IsSpectatingHead()) { ApplyRepoXRRayLengthOverride(); XRInteractorLineVisual[] componentsInChildren = ((Component)instance).GetComponentsInChildren<XRInteractorLineVisual>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } if (TryGetVisualizedRepoXRInteractor(out XRRayInteractor interactor) && (Object)(object)interactor != (Object)null) { XRInteractorLineVisual component = ((Component)interactor).GetComponent<XRInteractorLineVisual>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; ApplyActiveVisualStyle(component, Mathf.Max(1f, FeatureFlags.ControllerRayLineLength)); } } } _repoXRRayVisible = true; } private static void ApplyRepoXRRayLengthOverride() { XRRayInteractorManager instance = XRRayInteractorManager.Instance; if ((Object)(object)instance == (Object)null || !TryGetVisualizedRepoXRInteractor(out XRRayInteractor interactor) || (Object)(object)interactor == (Object)null) { return; } XRInteractorLineVisual component = ((Component)interactor).GetComponent<XRInteractorLineVisual>(); if ((Object)(object)component == (Object)null) { return; } float lineLength = Mathf.Max(1f, FeatureFlags.ControllerRayLineLength); ApplyActiveVisualStyle(component, lineLength); if (TryGetNonSelectedRepoXRInteractor(interactor, out XRRayInteractor otherInteractor) && (Object)(object)otherInteractor != (Object)null) { XRInteractorLineVisual component2 = ((Component)otherInteractor).GetComponent<XRInteractorLineVisual>(); if ((Object)(object)component2 != (Object)null) { ApplyInactiveVisualStyle(component2); } } _repoXRRayLengthOverridden = true; } private static void RestoreRepoXRRayLengthOverride() { if (!_repoXRRayLengthOverridden) { return; } XRRayInteractorManager instance = XRRayInteractorManager.Instance; if ((Object)(object)instance == (Object)null) { _repoXRRayLengthOverridden = false; return; } XRRayInteractor item = instance.GetActiveInteractor().Item1; if ((Object)(object)item != (Object)null) { XRInteractorLineVisual component = ((Component)item).GetComponent<XRInteractorLineVisual>(); if ((Object)(object)component != (Object)null) { ApplyActiveVisualStyle(component, 20f); } } if (TryGetNonSelectedRepoXRInteractor(item, out XRRayInteractor otherInteractor) && (Object)(object)otherInteractor != (Object)null) { XRInteractorLineVisual component2 = ((Component)otherInteractor).GetComponent<XRInteractorLineVisual>(); if ((Object)(object)component2 != (Object)null) { ApplyInactiveVisualStyle(component2); } } _repoXRRayLengthOverridden = false; } private static bool TryGetNonSelectedRepoXRInteractor(XRRayInteractor? selectedInteractor, out XRRayInteractor? otherInteractor) { otherInteractor = null; XRRayInteractorManager instance = XRRayInteractorManager.Instance; if ((Object)(object)instance == (Object)null) { return false; } object? obj = RepoXRLeftInteractorField?.GetValue(instance); XRRayInteractor val = (XRRayInteractor)((obj is XRRayInteractor) ? obj : null); object? obj2 = RepoXRRightInteractorField?.GetValue(instance); XRRayInteractor val2 = (XRRayInteractor)((obj2 is XRRayInteractor) ? obj2 : null); if ((Object)(object)selectedInteractor == (Object)null) { return false; } if (selectedInteractor == val) { otherInteractor = val2; return (Object)(object)otherInteractor != (Object)null; } if (selectedInteractor == val2) { otherInteractor = val; return (Object)(object)otherInteractor != (Object)null; } return false; } private static void ApplyActiveVisualStyle(XRInteractorLineVisual visual, float lineLength) { if (!((Object)(object)visual == (Object)null)) { visual.lineLength = Mathf.Max(1f, lineLength); visual.invalidColorGradient = CreateGradient(0.2f, 0.2f); visual.validColorGradient = CreateGradient(1f, 1f); } } private static void ApplyInactiveVisualStyle(XRInteractorLineVisual visual) { if (!((Object)(object)visual == (Object)null)) { visual.lineLength = 1f; Gradient validColorGradient = (visual.invalidColorGradient = CreateGradient(0.05f, 0f, 0.8f, 0.05f, 1f)); visual.validColorGradient = validColorGradient; } } private static Gradient CreateGradient(float startAlpha, float endAlpha) { return CreateGradient(startAlpha, endAlpha, -1f, -1f, -1f); } private static Gradient CreateGradient(float startAlpha, float endAlpha, float middleTime, float middleAlpha, float finalTime) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_007b: 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_008d: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Gradient val = new Gradient(); val.mode = (GradientMode)0; GradientAlphaKey[] array = (GradientAlphaKey[])(object)((!(middleTime >= 0f) || !(middleAlpha >= 0f) || !(finalTime >= 0f)) ? new GradientAlphaKey[2] { new GradientAlphaKey(startAlpha, 0f), new GradientAlphaKey(endAlpha, 1f) } : new GradientAlphaKey[3] { new GradientAlphaKey(startAlpha, 0f), new GradientAlphaKey(middleAlpha, middleTime), new GradientAlphaKey(endAlpha, finalTime) }); val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) }, array); return val; } private static bool TryGetVisualizedRepoXRInteractor(out XRRayInteractor? interactor) { interactor = null; if (SpectateHeadBridge.IsSpectatingHead() && UsesAnyControllerRay()) { return TryGetRepoXRInteractor(GetUnifiedRaycastGripSelection(), out interactor); } XRRayInteractorManager instance = XRRayInteractorManager.Instance; if ((Object)(object)instance == (Object)null) { return false; } interactor = instance.GetActiveInteractor().Item1; return (Object)(object)interactor != (Object)null; } private static bool TryGetRaySource(bool useControllerSource, GripSelection controllerPreference, out Vector3 sourcePosition, out Vector3 sourceForward, out string sourceLabel) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0093: 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_0051: 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_005d: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) sourcePosition = Vector3.zero; sourceForward = Vector3.forward; sourceLabel = "none"; Transform val = SpectateHeadBridge.GetHmdCameraTransform() ?? SpectateHeadBridge.GetAlignedCameraTransform(); if (!useControllerSource) { if ((Object)(object)val == (Object)null) { return false; } sourcePosition = val.position; sourceForward = val.forward; sourceLabel = "head-hmd"; return true; } if (TryGetRepoXRControllerRay(controllerPreference, out Vector3 origin, out Vector3 direction, out Vector3 _, out bool _, out string sourceLabel2)) { sourcePosition = origin; sourceForward = direction; sourceLabel = sourceLabel2; return true; } string handName; Transform val2 = TryGetPreferredControllerTransform(controllerPreference, out handName); if ((Object)(object)val2 == (Object)null) { return false; } sourcePosition = val2.position; sourceForward = val2.forward; sourceLabel = "tracked-" + handName.ToLowerInvariant(); return true; } private static bool TryGetRepoXRInteractor(GripSelection preference, out XRRayInteractor? interactor) { interactor = null; XRRayInteractorManager instance = XRRayInteractorManager.Instance; if ((Object)(object)instance == (Object)null) { return false; } bool flag = GripSelectionHelper.ShouldUseLeft(preference); object? obj = (flag ? RepoXRLeftInteractorField : RepoXRRightInteractorField)?.GetValue(instance); interactor = (XRRayInteractor?)((obj is XRRayInteractor) ? obj : null); if ((Object)(object)interactor != (Object)null) { return true; } object? obj2 = (flag ? RepoXRRightInteractorField : RepoXRLeftInteractorField)?.GetValue(instance); interactor = (XRRayInteractor?)((obj2 is XRRayInteractor) ? obj2 : null); if ((Object)(object)interactor != (Object)null) { return true; } interactor = instance.GetActiveInteractor().Item1; return (Object)(object)interactor != (Object)null; } private static bool TryGetRepoXRControllerRay(GripSelection preference, out Vector3 origin, out Vector3 direction, out Vector3 hitPoint, out bool hasHit, out string sourceLabel) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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) origin = Vector3.zero; direction = Vector3.forward; hitPoint = Vector3.zero; hasHit = false; sourceLabel = "repoxr-none"; if (!TryGetRepoXRInteractor(preference, out XRRayInteractor interactor) || (Object)(object)interactor == (Object)null) { return false; } if (SpectateHeadBridge.IsSpectatingHead()) { interactor.raycastMask = LayerMask.op_Implicit(-1); } origin = ((Component)interactor).transform.position; direction = ((Component)interactor).transform.forward; if (((Vector3)(ref direction)).sqrMagnitude < 0.0001f) { return false; } ((Vector3)(ref direction)).Normalize(); sourceLabel = "repoxr-" + (GripSelectionHelper.ShouldUseLeft(preference) ? "left" : "right"); RaycastHit val = default(RaycastHit); if (interactor.TryGetCurrent3DRaycastHit(ref val)) { hitPoint = ((RaycastHit)(ref val)).point; hasHit = true; } return true; } private static Vector3 GetControllerAimForward() { //IL_0057: 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_001c: 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_0060: 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) try { string handName; Transform val = TryGetPreferredControllerTransform(GetUnifiedRaycastGripSelection(), out handName); if ((Object)(object)val != (Object)null) { return val.forward; } TrackingInput instance = TrackingInput.Instance; Transform val2 = ((instance != null) ? instance.HeadTransform : null); if ((Object)(object)val2 != (Object)null) { return val2.forward; } } catch { } return SpectateHeadBridge.GetAlignedForward(); } private static GripSelection GetCameraGripSelection() { return GripSelectionHelper.Parse(FeatureFlags.CameraGripPreference); } private static Transform? TryGetPreferredControllerTransform(GripSelection preference, out string handName) { TrackingInput instance = TrackingInput.Instance; bool flag = GripSelectionHelper.ShouldUseLeft(preference); handName = (flag ? "Left" : "Right"); Transform val = ((!flag) ? ((instance != null) ? instance.RightHandTransform : null) : ((instance != null) ? instance.LeftHandTransform : null)); if ((Object)(object)val != (Object)null) { return val; } VRSession instance2 = VRSession.Instance; object obj; if (instance2 == null) { obj = null; } else { VRPlayer player = instance2.Player; obj = ((player != null) ? player.SecondaryHand : null); } Transform val2 = (Transform)obj; if ((Object)(object)val2 != (Object)null) { return val2; } handName = "unknown"; return null; } private static MovementDirectionSource ParseMovementDirection() { string text = (FeatureFlags.MovementDirectionSource ?? string.Empty).Trim(); if (text.Equals("Controller", StringComparison.OrdinalIgnoreCase)) { return MovementDirectionSource.ControllerRaycast; } if (text.Equals("Head", StringComparison.OrdinalIgnoreCase)) { return MovementDirectionSource.HeadRaycast; } if (Enum.TryParse<MovementDirectionSource>(text, ignoreCase: true, out var result)) { return result; } return MovementDirectionSource.ControllerRaycast; } private static GripSelection GetUnifiedRaycastGripSelection() { return GetCameraGripSelection(); } private static float GetUnifiedRaycastDistance() { return Mathf.Max(1f, FeatureFlags.MovementRaycastDistance); } private static bool UsesAnyControllerRay() { return MovementDirection == MovementDirectionSource.ControllerRaycast; } internal static bool TrySwapAimCamera(DHHInputManager instance, out Transform? original) { //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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_008a: Expected O, but got Unknown original = null; if (TMainCameraField == null || (Object)(object)instance == (Object)null) { return false; } Vector3 abilityForward = GetAbilityForward(); if (((Vector3)(ref abilityForward)).sqrMagnitude < 0.0001f) { return false; } object? value = TMainCameraField.GetValue(instance); Transform val = (Transform)((value is Transform) ? value : null); if ((Object)(object)val == (Object)null) { return false; } if ((Object)(object)_abilityAimProxy == (Object)null) { GameObject val2 = new GameObject("DeathHeadHopperVRBridge_AbilityAimProxy"); Object.DontDestroyOnLoad((Object)(object)val2); _abilityAimProxy = val2.transform; } original = val; _abilityAimProxy.position = val.position; _abilityAimProxy.rotation = Quaternion.LookRotation(abilityForward, Vector3.up); TMainCameraField.SetValue(instance, _abilityAimProxy); return true; } internal static void RestoreAimCamera(DHHInputManager instance, Transform original) { if (!(TMainCameraField == null) && !((Object)(object)instance == (Object)null) && !((Object)(object)original == (Object)null)) { TMainCameraField.SetValue(instance, original); } } internal static void ExtendJumpBufferIfNeeded(JumpHandler jumpHandler) { if ((Object)(object)jumpHandler == (Object)null || JumpBufferTimerField == null || JumpCooldownTimerField == null || !SpectateHeadBridge.IsSpectatingHead() || (MovementDirection != MovementDirectionSource.ControllerRaycast && MovementDirection != 0)) { return; } float num2 = ((JumpCooldownTimerField.GetValue(jumpHandler) is float num) ? Mathf.Max(0f, num) : 0f); float num3 = Mathf.Max(0.35f, num2 + 0.1f); object value = JumpBufferTimerField.GetValue(jumpHandler); if (value is float) { float num4 = (float)value; if (num4 < num3) { JumpBufferTimerField.SetValue(jumpHandler, num3); } } } } [HarmonyPatch(typeof(DHHInputManager), "Update")] internal static class DHHInputManagerUpdatePatch { private static void Prefix(DHHInputManager __instance) { DHHInputBridge.UpdateCameraReference(__instance); } } [HarmonyPatch(typeof(DHHInputManager), "LateUpdate")] internal static class DHHInputManagerLateUpdatePatch { private static void Prefix(DHHInputManager __instance) { DHHInputBridge.UpdateCameraReference(__instance); } } [HarmonyPatch(typeof(DHHInputManager), "GetMoveDirection")] internal static class DHHInputManagerGetMoveDirectionPatch { private static bool Prefix(ref Vector3 __result) { //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_0030: 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_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_003c: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!SpectateHeadBridge.IsDhhRuntimeInputContextActive()) { return true; } Vector2 movement; bool flag = DHHInputBridge.TryGetAnalogMovement(out movement); Vector2 legacyMovement = DHHInputBridge.GetLegacyMovement(); if (!flag) { movement = legacyMovement; } __result = DHHInputBridge.CalculateMoveDirection(movement); DHHInputBridge.LogMovement(movement, legacyMovement, flag, __result, DHHInputBridge.MovementDirection); return false; } } [HarmonyPatch(typeof(DHHInputManager), "ChargeWindup")] internal static class DHHInputManagerChargeWindupPatch { private static void Prefix(DHHInputManager __instance, ref Transform? __state) { if (SpectateHeadBridge.IsSpectatingHead() && DHHInputBridge.TrySwapAimCamera(__instance, out Transform original)) { __state = original; } } private static void Postfix(DHHInputManager __instance, Transform? __state) { if ((Object)(object)__state != (Object)null) { DHHInputBridge.RestoreAimCamera(__instance, __state); } } } [HarmonyPatch(typeof(DHHInputManager), "UpdateChargeWindup")] internal static class DHHInputManagerUpdateChargeWindupPatch { private static void Prefix(DHHInputManager __instance, ref Transform? __state) { if (SpectateHeadBridge.IsSpectatingHead() && DHHInputBridge.TrySwapAimCamera(__instance, out Transform original)) { __state = original; } } private static void Postfix(DHHInputManager __instance, Transform? __state) { if ((Object)(object)__state != (Object)null) { DHHInputBridge.RestoreAimCamera(__instance, __state); } } } [HarmonyPatch(typeof(SemiFunc), "InputMovementX")] internal static class SemiFuncInputMovementXPatch { private static bool Prefix(ref float __result) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!SpectateHeadBridge.IsDhhRuntimeInputContextActive() && !SpectateHeadBridge.IsLocalDeathHeadTriggered()) { return true; } if (DHHInputBridge.ShouldSuppressLegacyMovement()) { __result = 0f; return false; } if (!MovementAnalog.TryGetAnalog(out var movement)) { return true; } __result = movement.x; return false; } } [HarmonyPatch(typeof(SemiFunc), "InputMovementY")] internal static class SemiFuncInputMovementYPatch { private static bool Prefix(ref float __result) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!SpectateHeadBridge.IsDhhRuntimeInputContextActive() && !SpectateHeadBridge.IsLocalDeathHeadTriggered()) { return true; } if (DHHInputBridge.ShouldSuppressLegacyMovement()) { __result = 0f; return false; } if (!MovementAnalog.TryGetAnalog(out var movement)) { return true; } __result = movement.y; return false; } } [HarmonyPatch(typeof(SemiFunc), "InputDown")] internal static class SemiFuncInputDownDirectionBindingSuppressionPatch { private static bool Prefix(InputKey key, ref bool __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) bool flag = SpectateHeadBridge.IsGripPressedForAbility(); VanillaAbilityInputBridge.NotifyDirectionBindingAttempt(key, flag); InputKey key2; bool flag2 = VanillaAbilityInputBridge.TryGetConfiguredDirectionInputKey(out key2); string directionSuppressionDebugState = VanillaAbilityInputBridge.GetDirectionSuppressionDebugState(key); if (InternalDebugConfig.DebugAbilityInputFlow && SpectateHeadBridge.IsLocalDeathHeadTriggered() && flag && VanillaAbilityInputBridge.IsDebugBurstLoggingActive() && flag2 && key == key2 && LogLimiter.Allow("AbilityFlow.InputDownObserved", 0.2f)) { DHHInputBridge.Log.LogInfo((object)string.Format("{0} InputDown observed for configured direction binding key. grip={1} {2}", "[DeathHeadHopperFix-VR] [SpectateCam]", flag, directionSuppressionDebugState)); } if (VanillaAbilityInputBridge.ShouldSuppressDirectionBindingInputDownThisFrame(key)) { if (InternalDebugConfig.DebugAbilityInputFlow && SpectateHeadBridge.IsLocalDeathHeadTriggered() && LogLimiter.Allow("AbilityFlow.SuppressApplied", 0.2f)) { DHHInputBridge.Log.LogInfo((object)string.Format("{0} Suppressed SemiFunc.InputDown({1}) for direction-slot redirect.", "[DeathHeadHopperFix-VR] [SpectateCam]", key)); } __result = false; return false; } return true; } } [HarmonyPatch(typeof(SemiFunc), "InputHold")] internal static class SemiFuncInputHoldDirectionBindingSuppressionPatch { private static bool Prefix(InputKey key, ref bool __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (VanillaAbilityInputBridge.ShouldSuppressDirectionBindingInputHoldThisFrame(key)) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(SemiFunc), "InputUp")] internal static class SemiFuncInputUpDirectionBindingSuppressionPatch { private static bool Prefix(InputKey key, ref bool __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (VanillaAbilityInputBridge.ShouldSuppressDirectionBindingInputUpThisFrame(key)) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(SpectateCamera), "LateUpdate")] internal static class SpectateCameraLateUpdateControllerRayPreviewPatch { private static void Postfix() { DHHInputBridge.UpdateRealtimeControllerRayPreview(); } } [HarmonyPatch(typeof(DHHInputManager), "LateUpdate")] internal static class DHHInputManagerLateUpdateHeldJumpRefreshPatch { private static readonly MethodInfo? JumpMethod = AccessTools.Method(typeof(DHHInputManager), "Jump", (Type[])null, (Type[])null); private static float _nextRefreshTime; private static void Postfix(DHHInputManager __instance) { if (!((Object)(object)__instance == (Object)null) && SpectateHeadBridge.IsDhhRuntimeInputContextActive() && (DHHInputBridge.MovementDirection == DHHInputBridge.MovementDirectionSource.ControllerRaycast || DHHInputBridge.MovementDirection == DHHInputBridge.MovementDirectionSource.HeadRaycast) && !VanillaAbilityInputBridge.IsDirectionAbilityActive() && VanillaAbilityInputBridge.IsDirectionBindingHeld() && !(Time.time < _nextRefreshTime)) { _nextRefreshTime = Time.time + 0.05f; JumpMethod?.Invoke(__instance, null); } } } [HarmonyPatch(typeof(JumpHandler), "JumpHead")] internal static class JumpHandlerJumpHeadBufferPatch { private static void Postfix(JumpHandler __instance) { DHHInputBridge.ExtendJumpBufferIfNeeded(__instance); } } internal enum GripSelection { Auto, Left, Right } internal static class GripSelectionHelper { internal static GripSelection Parse(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return GripSelection.Auto; } if (Enum.TryParse<GripSelection>(raw.Trim(), ignoreCase: true, out var result)) { return result; } return GripSelection.Auto; } internal static bool ShouldUseLeft(GripSelection selection) { if (1 == 0) { } bool result = selection switch { GripSelection.Left => true, GripSelection.Right => false, _ => !VRSession.IsLeftHanded, }; if (1 == 0) { } return result; } } internal static class LastChanceCameraAimCompatPatch { private const string LogKey = "LastChance.CameraForce.Noop.VR"; private const BindingFlags StaticAny = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly string[] CameraForceModuleTypeNames = new string[2] { "DHHFLastChanceMode.Modules.Gameplay.LastChance.Monsters.Pipeline.LastChanceMonstersCameraForceLockModule", "DeathHeadHopperFix.Modules.Gameplay.LastChance.Monsters.Pipeline.LastChanceMonstersCameraForceLockModule" }; private static readonly string[] RuntimeOrchestratorTypeNames = new string[2] { "DHHFLastChanceMode.Modules.Gameplay.LastChance.Runtime.LastChanceRuntimeOrchestrator", "DeathHeadHopperFix.Modules.Gameplay.LastChance.Runtime.LastChanceRuntimeOrchestrator" }; private static PropertyInfo? s_runtimeActiveProperty; private static bool s_applied; internal static bool TryApply(Harmony harmony) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown Harmony harmony2 = harmony; if (s_applied) { return true; } if (!TryResolveTarget(out MethodInfo target)) { return false; } MethodInfo methodInfo = AccessTools.Method(typeof(LastChanceCameraAimCompatPatch), "Prefix", (Type[])null, (Type[])null); if (methodInfo == null) { return false; } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)target); if (patchInfo != null && patchInfo.Prefixes.Any((Patch p) => p.owner == harmony2.Id)) { s_applied = true; return true; } harmony2.Patch((MethodBase)target, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); s_applied = true; return true; } private static bool TryResolveTarget(out MethodInfo? target) { Type type = TryResolveType(CameraForceModuleTypeNames); target = ((type == null) ? null : AccessTools.Method(type, "TryForceSpectateAimTo", new Type[2] { typeof(Vector3), typeof(GameObject) }, (Type[])null)); return target != null; } private static bool Prefix() { if (!SpectateHeadBridge.VrModeActive || !IsLastChanceRuntimeActive()) { return true; } if (LogLimiter.Allow("LastChance.CameraForce.Noop.VR", 5f)) { SpectateHeadBridge.Log.LogInfo((object)"[DeathHeadHopperFix-VR] [SpectateCam] LastChance camera-force disabled in VR to avoid HMD/spectate drift."); } return false; } private static bool IsLastChanceRuntimeActive() { if (s_runtimeActiveProperty == null) { s_runtimeActiveProperty = TryResolveType(RuntimeOrchestratorTypeNames)?.GetProperty("IsRuntimeActive", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } return (s_runtimeActiveProperty?.GetValue(null) as bool?).GetValueOrDefault(); } private static Type? TryResolveType(IReadOnlyList<string> fullNames) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < fullNames.Count; i++) { string name = fullNames[i]; for (int j = 0; j < assemblies.Length; j++) { Type type = assemblies[j].GetType(name, throwOnError: false, ignoreCase: false); if (type != null) { return type; } } } return null; } } internal static class Math { internal static int Max(int x, int y) { return System.Math.Max(x, y); } internal static int Clamp(int value, int min, int max) { if (value < min) { return min; } if (value > max) { return max; } return value; } } internal static class MovementAnalog { private static readonly ManualLogSource LogSource = Logger.CreateLogSource("DeathHeadHopperFix-VR.InputBridge"); internal const string ModuleTag = "[DeathHeadHopperFix-VR] [SpectateCam]"; internal static ManualLogSource Log => LogSource; internal static bool TryGetAnalog(out Vector2 movement) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_008a: Unknown result type (might be due to invalid IL or missing references) movement = Vector2.zero; InputAction val; try { val = Actions.Instance["Movement"]; } catch { val = null; } if (val == null) { return false; } movement = val.ReadValue<Vector2>(); if (((Vector2)(ref movement)).sqrMagnitude > 0.0001f && SpectateHeadBridge.IsSpectatingHead() && InternalDebugConfig.DebugMovementDirection && LogLimiter.Allow("JoystickSpectateLog", 0.5f)) { LogSource.LogInfo((object)string.Format("{0} Joystick moved while spectating head movement={1:F3}", "[DeathHeadHopperFix-VR] [SpectateCam]", movement)); } return ((Vector2)(ref movement)).sqrMagnitude > 0.0001f; } internal static void LogAnalog(Vector2 analog, bool triggered) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (InternalDebugConfig.DebugMovementDirection && LogLimiter.Allow("MovementAnalog", 0.5f)) { LogSource.LogDebug((object)string.Format("{0} Analog movement triggered={1} vector={2:F3}", "[DeathHeadHopperFix-VR] [SpectateCam]", triggered, analog)); } } } internal static class SpectateHeadBridge { internal static readonly ManualLogSource Log = Logger.CreateLogSource("DeathHeadHopperFix-VR.HeadBridge"); internal const string ModuleTag = "[DeathHeadHopperFix-VR] [SpectateCam]"; private static readonly FieldInfo? SpectateCameraMainCameraField = AccessTools.Field(typeof(SpectateCamera), "MainCamera"); private static readonly Type? ActionsType = AccessTools.TypeByName("RepoXR.Input.Actions"); private static readonly PropertyInfo? InstanceProperty = ActionsType?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public); private static readonly PropertyInfo? IndexerProperty = ActionsType?.GetProperty("Item", new Type[1] { typeof(string) }); private static readonly FieldInfo? PlayerDeathHeadGrabField = AccessTools.Field(typeof(PlayerDeathHead), "physGrabObject"); private static readonly FieldInfo? PlayerDeathHeadTriggeredField = AccessTools.Field(typeof(PlayerDeathHead), "triggered"); private static Vector3 _baseForward = Vector3.forward; private static bool _baseForwardSet; private static readonly string[] LeftGripBindings = new string[4] { "GripLeft", "leftGrip", "Grab", "MapGrabLeft" }; private static readonly string[] RightGripBindings = new string[4] { "GripRight", "rightGrip", "Grab", "MapGrabRight" }; internal static readonly FieldInfo? DeathHeadSpectatedField = AccessTools.Field(typeof(DeathHeadController), "spectated"); private static bool _spectatedAnchorActive; internal static bool VrModeActive => VRSession.InVR; private static object? ActionsInstance => InstanceProperty?.GetValue(null); internal static void AlignHeadCamera(bool force) { //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021d: 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_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02be: 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_01fa: Unknown result type (might be due to invalid IL or missing references) if (!VrModeActive) { return; } TraceAlignment($"AlignHeadCamera start force={force}"); LogImmediate($"AlignHeadCamera immediate start force={force}"); LogImmediate($"AlignHeadCamera immediate log force={force}"); SpectateCamera instance = SpectateCamera.instance; PlayerAvatar instance2 = PlayerAvatar.instance; PlayerDeathHead val = instance2?.playerDeathHead; Camera spectateMainCamera = GetSpectateMainCamera(instance); if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null || (Object)(object)spectateMainCamera == (Object)null) { TraceAlignment("AlignHeadCamera aborted: missing context or camera"); return; } bool flag = IsGripPressed(); if (InternalDebugConfig.DebugHeadAlignment && LogLimiter.Allow("AlignHeadCamera", 0.25f)) { Log.LogDebug((object)string.Format("{0} AlignHeadCamera force={1} gripPressed={2}", "[DeathHeadHopperFix-VR] [SpectateCam]", force, flag)); } if (!force && flag) { if (InternalDebugConfig.DebugHeadAlignment && LogLimiter.Allow("HeadAlignmentGuard", 0.5f)) { Log.LogInfo((object)"[DeathHeadHopperFix-VR] [SpectateCam] alignment skipped because grip is pressed"); } return; } object? obj = PlayerDeathHeadGrabField?.GetValue(val); Vector3 val2 = ((PhysGrabObject)(((obj is PhysGrabObject) ? obj : null)?)).centerPoint ?? ((Component)val).transform.position; Vector3 val3 = Vector3.ProjectOnPlane(((Component)val).transform.forward, Vector3.up); if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f && (Object)(object)instance2 != (Object)null) { val3 = Vector3.ProjectOnPlane(((Component)instance2).transform.forward, Vector3.up); } if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Vector3.forward; } ((Vector3)(ref val3)).Normalize(); if (force || !_baseForwardSet) { _baseForward = val3; _baseForwardSet = true; } float headCameraDistance = FeatureFlags.HeadCameraDistance; float headCameraHeightOffset = FeatureFlags.HeadCameraHeightOffset; Vector3 val4 = val2 + Vector3.up * headCameraHeightOffset - val3 * headCameraDistance; Quaternion val5 = Quaternion.LookRotation(val3, Vector3.up); float headCameraLerpSpeed = FeatureFlags.HeadCameraLerpSpeed; float num = Mathf.Clamp01(headCameraLerpSpeed * Time.deltaTime); ((Component)instance).transform.position = Vector3.Lerp(((Component)instance).transform.position, val4, num); ((Component)instance).transform.rotation = Quaternion.Slerp(((Component)instance).transform.rotation, val5, num); ((Component)spectateMainCamera).transform.position = ((Component)instance).transform.position; ((Component)spectateMainCamera).transform.rotation = ((Component)instance).transform.rotation; } internal static bool IsGripPressed() { return IsGripPressedForCamera(); } internal static bool IsGripPressedForCamera() { GripSelection selection = GripSelectionHelper.Parse(FeatureFlags.CameraGripPreference); return IsGripPressed(selection); } internal static bool IsGripPressedForAbility() { GripSelection selection = GripSelectionHelper.Parse(FeatureFlags.AbilityGripPreference); return IsGripPressed(selection); } private static bool IsGripPressed(GripSelection selection) { bool flag = GripSelectionHelper.ShouldUseLeft(selection); string[] array = (flag ? LeftGripBindings : RightGripBindings); string[] array2 = array; foreach (string text in array2) { object action = GetAction(text); if (IsActionPressed(action)) { if (InternalDebugConfig.DebugHeadAlignment && LogLimiter.Allow("IsGripPressed", 0.5f)) { Log.LogDebug((object)string.Format("{0} Grip detected on binding {1} (leftGrip={2}) using {3}", "[DeathHeadHopperFix-VR] [SpectateCam]", text, flag, selection)); } return true; } } return false; } private static Camera? GetSpectateMainCamera(SpectateCamera? spectate) { if ((Object)(object)spectate == (Object)null || SpectateCameraMainCameraField == null) { return null; } object? value = SpectateCameraMainCameraField.GetValue(spectate); return (Camera?)((value is Camera) ? value : null); } internal static Vector3 GetBaseForward() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) return _baseForwardSet ? _baseForward : GetAlignedForward(); } internal static bool IsSpectatingHead() { if (!VrModeActive) { return false; } SpectateCamera instance = SpectateCamera.instance; if ((Object)(object)instance != (Object)null && instance.CheckState((State)2)) { TraceAlignment("SpectateCamera reports State.Head"); return true; } PlayerDeathHead val = PlayerAvatar.instance?.playerDeathHead; if ((Object)(object)val != (Object)null) { DeathHeadController val2 = null; DeathHeadController val3 = default(DeathHeadController); if (((Component)val).TryGetComponent<DeathHeadController>(ref val3)) { val2 = val3; } if ((Object)(object)val2 != (Object)null && DeathHeadSpectatedField != null && DeathHeadSpectatedField.GetValue(val2) is bool flag) { TraceAlignment($"DeathHeadController.spectated={flag}"); if (flag) { return true; } } FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerDeathHead), "overrideSpectated"); bool flag2 = default(bool); int num; if (fieldInfo != null) { object value = fieldInfo.GetValue(val); if (value is bool) { flag2 = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } if (((uint)num & (flag2 ? 1u : 0u)) != 0) { TraceAlignment("PlayerDeathHead.overrideSpectated true"); return true; } } return false; } internal static bool IsDhhSpectateContextActive() { if (!VrModeActive) { return false; } if ((Object)(object)DHHInputManager.instance == (Object)null) { return false; } PlayerDeathHead val = PlayerAvatar.instance?.playerDeathHead; if ((Object)(object)val == (Object)null || PlayerDeathHeadTriggeredField == null) { return false; } return (PlayerDeathHeadTriggeredField.GetValue(val) as bool?).GetValueOrDefault(); } internal static bool IsLocalDeathHeadTriggered() { if (!VrModeActive || (Object)(object)DHHInputManager.instance == (Object)null) { return false; } PlayerDeathHead val = PlayerAvatar.instance?.playerDeathHead; if ((Object)(object)val == (Object)null || PlayerDeathHeadTriggeredField == null) { return false; } return (PlayerDeathHeadTriggeredField.GetValue(val) as bool?).GetValueOrDefault(); } internal static bool IsDhhRuntimeInputContextActive() { if (!VrModeActive || (Object)(object)DHHInputManager.instance == (Object)null) { return false; } if (IsDhhSpectateContextActive()) { return true; } return IsSpectatingHead(); } internal static Transform? GetAlignedCameraTransform() { SpectateCamera instance = SpectateCamera.instance; Camera spectateMainCamera = GetSpectateMainCamera(instance); if ((Object)(object)spectateMainCamera != (Object)null) { return ((Component)spectateMainCamera).transform; } return (instance != null) ? ((Component)instance).transform : null; } internal static Vector3 GetAlignedForward() { //IL_001c: 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_0026: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0042: 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_005f: Unknown result type (might be due to invalid IL or missing references) Transform alignedCameraTransform = GetAlignedCameraTransform(); if ((Object)(object)alignedCameraTransform == (Object)null) { return Vector3.forward; } Vector3 val = Vector3.ProjectOnPlane(alignedCameraTransform.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = alignedCameraTransform.forward; val.y = 0f; } return ((Vector3)(ref val)).normalized; } private static object? GetAction(string name) { object actionsInstance = ActionsInstance; if (actionsInstance == null || IndexerProperty == null) { return null; } try { return IndexerProperty.GetValue(actionsInstance, new object[1] { name }); } catch { return null; } } private static bool IsActionPressed(object? action) { if (action == null) { return false; } MethodInfo method = action.GetType().GetMethod("IsPressed", Type.EmptyTypes); if (method == null) { return false; } try { object obj = method.Invoke(action, null); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } internal static Transform? GetHmdCameraTransform() { if (!VrModeActive || (Object)(object)VRSession.Instance == (Object)null) { return null; } Camera mainCamera = VRSession.Instance.MainCamera; return (mainCamera != null) ? ((Component)mainCamera).transform : null; } internal static void TraceAlignment(string message) { if (InternalDebugConfig.DebugHeadAlignment && LogLimiter.Allow("AlignTrace", 0.5f)) { Log.LogInfo((object)("[DeathHeadHopperFix-VR] [SpectateCam] " + message)); } } internal static void LogImmediate(string message) { if (InternalDebugConfig.DebugHeadAlignment) { Log.LogInfo((object)("[DeathHeadHopperFix-VR] [SpectateCam] " + message)); } } private static void LogAnchorCameraState(string message, SpectateCamera? spectate) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0046: Unknown result type (might be due to invalid IL or missing references) if (InternalDebugConfig.DebugHeadAlignment) { Camera spectateMainCamera = GetSpectateMainCamera(spectate); Vector3 val = ((spectateMainCamera != null) ? ((Component)spectateMainCamera).transform.forward : ((spectate != null) ? ((Component)spectate).transform.forward : Vector3.zero)); Vector3 val2 = ((spectateMainCamera != null) ? ((Component)spectateMainCamera).transform.position : ((spectate != null) ? ((Component)spectate).transform.position : Vector3.zero)); Log.LogInfo((object)string.Format("{0} {1} pos={2:F3} forward={3:F3}", "[DeathHeadHopperFix-VR] [SpectateCam]", message, val2, val)); } } internal static void OnSpectatedAnchor(bool value) { if (value && !_spectatedAnchorActive) { _spectatedAnchorActive = true; TraceAlignment("Spectated anchor activated"); LogImmediate("Spectated anchor activated"); AlignHeadCamera(force: true); LogAnchorCameraState("Spectated anchor camera", SpectateCamera.instance); } else if (!value && _spectatedAnchorActive) { _spectatedAnchorActive = false; TraceAlignment("Spectated anchor cleared"); LogImmediate("Spectated anchor cleared"); } } } [HarmonyPatch(typeof(SpectateCamera), "StateHead")] internal static class SpectateCameraStateHeadPatch { private static void Postfix() { SpectateHeadBridge.TraceAlignment("SpectateCamera.StateHead Postfix triggered"); SpectateHeadBridge.LogImmediate("SpectateCamera.StateHead Postfix triggered"); if (InternalDebugConfig.DebugHeadAlignment && LogLimiter.Allow("StateHead.Enter", 0.5f)) { SpectateHeadBridge.Log.LogDebug((object)"[DeathHeadHopperFix-VR] [SpectateCam] SpectateCamera.StateHead entered, queuing head alignment"); } SpectateHeadBridge.AlignHeadCamera(force: false); } } [HarmonyPatch(typeof(SpectateCamera), "UpdateState")] internal static class SpectateCameraUpdateStatePatch { private static State _previousState; private static void Postfix(State _state) { //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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 _previousState = _state; if ((int)_state == 2) { SpectateHeadBridge.AlignHeadCamera(force: false); } } } [HarmonyPatch(typeof(PlayerDeathHead), "OverrideSpectatedReset")] internal static class PlayerDeathHeadResetPatch { private static void Postfix() { SpectateHeadBridge.TraceAlignment("PlayerDeathHead.OverrideSpectatedReset Postfix triggered"); SpectateHeadBridge.LogImmediate("PlayerDeathHead.OverrideSpectatedReset Postfix triggered"); } } [HarmonyPatch(typeof(DeathHeadController), "SetSpectated")] internal static class DeathHeadControllerSetSpectatedPatch { private static void Postfix(DeathHeadController __instance, bool value) { SpectateHeadBridge.LogImmediate($"DeathHeadController.SetSpectated value={value}"); SpectateHeadBridge.OnSpectatedAnchor(value); } } [HarmonyPatch(typeof(PlayerDeathHead), "SpectatedSet")] internal static class PlayerDeathHeadSpectatedSetPatch { private static void Postfix(PlayerDeathHead __instance, bool _active) { SpectateHeadBridge.LogImmediate($"PlayerDeathHead.SpectatedSet _active={_active}"); if (_active) { SpectateHeadBridge.OnSpectatedAnchor(value: true); } } } [HarmonyPatch] internal static class HeadCameraTurnGripGuard { private static readonly Type? SpectatePatchesType = AccessTools.TypeByName("RepoXR.Patches.SpectatePatches"); private static MethodBase? TargetMethod() { if (SpectatePatchesType == null) { return null; } return AccessTools.Method(SpectatePatchesType, "HeadCameraTurnPatch", (Type[])null, (Type[])null); } private static bool Prefix() { bool flag = SpectateHeadBridge.IsGripPressedForCamera(); if (InternalDebugConfig.DebugHeadAlignment && LogLimiter.Allow("HeadCameraTurnGuard", 0.5f)) { SpectateHeadBridge.Log.LogDebug((object)string.Format("{0} HeadCameraTurnPatch guard gripPressed={1}", "[DeathHeadHopperFix-VR] [SpectateCam]", flag)); } return flag; } } [HarmonyPatch] internal static class SpectateMovementGuard { [HarmonyPatch] internal static class SpectateMovementGuardY { private static MethodBase? TargetMethod() { Type type = AccessTools.TypeByName("RepoXR.Patches.SpectatePatches"); return (type == null) ? null : AccessTools.Method(type, "<InputPatch>g__GetRotationY|5_1", (Type[])null, (Type[])null); } private static bool Prefix(ref float __result) { return TryGuard(ref __result); } } private static readonly ManualLogSource Log = Logger.CreateLogSource("DeathHeadHopperFix-VR.HeadBridge"); private static MethodBase? TargetMethod() { Type type = AccessTools.TypeByName("RepoXR.Patches.SpectatePatches"); return (type == null) ? null : AccessTools.Method(type, "<InputPatch>g__GetRotationX|5_0", (Type[])null, (Type[])null); } private static bool Prefix(ref float __result) { return TryGuard(ref __result); } private static bool TryGuard(ref float result) { if (SpectateHeadBridge.IsGripPressedForCamera()) { return true; } if (InternalDebugConfig.DebugSpectateGuard && LogLimiter.Allow("MovementGuard.Override", 0.25f)) { Log.LogDebug((object)"[DeathHeadHopperFix-VR] [SpectateCam] Movement guard zeroed rotation because grip is not pressed"); } result = 0f; return false; } } internal sealed class VanillaAbilityInputBridge : MonoBehaviour { private readonly struct RuntimeInputBindingResolution { internal InputKey Key { get; } internal InputAction Action { get; } internal int BindingIndex { get; } internal string ControlScheme { get; } internal string EffectivePath { get; } internal RuntimeInputBindingResolution(InputKey key, InputAction action, int bindingIndex, string controlScheme, string effectivePath) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) Key = key; Action = action; BindingIndex = bindingIndex; ControlScheme = controlScheme; EffectivePath = effectivePath; } } private sealed class CustomInputActionEntry { internal InputAction Action = null; internal string EffectivePath = string.Empty; internal string ControlScheme = string.Empty; } [CompilerGenerated] private sealed class <DiscoverRepoXRActionNames>d__69 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IDisposable, IEnumerator { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private object <inputSystem>5__1; private InputActionAsset <inputActions>5__2; private Enumerator<InputActionMap> <>s__3; private InputActionMap <map>5__4; private string <mapName>5__5; private Enumerator<InputAction> <>s__6; private InputAction <action>5__7; private string <actionName>5__8; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DiscoverRepoXRActionNames>d__69(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { //IL_0053: 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) int num = <>1__state; if ((uint)(num - -4) <= 1u || (uint)(num - 1) <= 1u) { try { if (num == -4 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <inputSystem>5__1 = null; <inputActions>5__2 = null; <>s__3 = default(Enumerator<InputActionMap>); <map>5__4 = null; <mapName>5__5 = null; <>s__6 = default(Enumerator<InputAction>); <action>5__7 = null; <actionName>5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_021a: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00b8: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <inputSystem>5__1 = null; <inputActions>5__2 = null; try { <inputSystem>5__1 = RepoXRInputSystemInstance?.GetValue(null); ref InputActionAsset reference = ref <inputActions>5__2; object? obj = RepoXRInputSystemActions?.GetValue(<inputSystem>5__1); reference = (InputActionAsset)((obj is InputActionAsset) ? obj : null); } catch { return false; } if ((Object)(object)<inputActions>5__2 == (Object)null) { return false; } <>s__3 = <inputActions>5__2.actionMaps.GetEnumerator(); <>1__state = -3; goto IL_01fd; case 1: <>1__state = -4; if (!string.IsNullOrWhiteSpace(<mapName>5__5)) { <>2__current = <mapName>5__5 + "/" + <actionName>5__8; <>1__state = 2; return true; } goto IL_01bc; case 2: { <>1__state = -4; goto IL_01bc; } IL_01cb: while (<>s__6.MoveNext()) { <action>5__7 = <>s__6.Current; <actionName>5__8 = <action>5__7.name; if (string.IsNullOrWhiteSpace(<actionName>5__8)) { continue; } <>2__current = <actionName>5__8; <>1__state = 1; return true; } <>m__Finally2(); <>s__6 = default(Enumerator<InputAction>); <mapName>5__5 = null; <map>5__4 = null; goto IL_01fd; IL_01bc: <actionName>5__8 = null; <action>5__7 = null; goto IL_01cb; IL_01fd: if (<>s__3.MoveNext()) { <map>5__4 = <>s__3.Current; <mapName>5__5 = <map>5__4.name ?? string.Empty; <>s__6 = <map>5__4.actions.GetEnumerator(); <>1__state = -4; goto IL_01cb; } <>m__Finally1(); <>s__3 = default(Enumerator<InputActionMap>); return false; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__3).Dispose(); } private void <>m__Finally2() { <>1__state = -3; ((IDisposable)<>s__6).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <DiscoverRepoXRActionNames>d__69(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <ParseActionNames>d__57 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IDisposable, IEnumerator { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private string raw; public string <>3__raw; private string[] <>s__1; private int <>s__2; private string <part>5__3; private string <trimmed>5__4; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ParseActionNames>d__57(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>s__1 = null; <part>5__3 = null; <trimmed>5__4 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_00b6; } <>1__state = -1; if (string.IsNullOrWhiteSpace(raw)) { return false; } <>s__1 = raw.Split(new char[2] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries); <>s__2 = 0; goto IL_00d3; IL_00b6: <trimmed>5__4 = null; <part>5__3 = null; <>s__2++; goto IL_00d3; IL_00d3: if (<>s__2 < <>s__1.Length) { <part>5__3 = <>s__1[<>s__2]; <trimmed>5__4 = <part>5__3.Trim(); if (!string.IsNullOrEmpty(<trimmed>5__4)) { <>2__current = <trimmed>5__4; <>1__state = 1; return true; } goto IL_00b6; } <>s__1 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { <ParseActionNames>d__57 <ParseActionNames>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <ParseActionNames>d__ = this; } else { <ParseActionNames>d__ = new <ParseActionNames>d__57(0); } <ParseActionNames>d__.raw = <>3__raw; return <ParseActionNames>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } private const int SlotCount = 3; private static readonly Type? RepoXRActionsType = AccessTools.TypeByName("RepoXR.Input.Actions"); private static readonly PropertyInfo? RepoXRActionsInstance = RepoXRActionsType?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public); private static readonly PropertyInfo? RepoXRActionsIndexer = RepoXRActionsType?.GetProperty("Item", new Type[1] { typeof(string) }); private static readonly Type? RepoXRInputSystemType = AccessTools.TypeByName("RepoXR.Input.VRInputSystem"); private static readonly PropertyInfo? RepoXRInputSystemInstance = RepoXRInputSystemType?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public); private static readonly PropertyInfo? RepoXRInputSystemActions = RepoXRInputSystemType?.GetProperty("Actions", BindingFlags.Instance | BindingFlags.Public); private static readonly PropertyInfo? RepoXRInputSystemCurrentControlScheme = RepoXRInputSystemType?.GetProperty("CurrentControlScheme", BindingFlags.Instance | BindingFlags.Public); private static readonly Type? InputActionRuntimeType = AccessTools.TypeByName("UnityEngine.InputSystem.InputAction"); private static readonly MethodInfo? WasPressedMethod = InputActionRuntimeType?.GetMethod("WasPressedThisFrame", Type.EmptyTypes); private static readonly MethodInfo? WasReleasedMethod = InputActionRuntimeType?.GetMethod("WasReleasedThisFrame", Type.EmptyTypes); private static readonly MethodInfo? IsPressedMethod = InputActionRuntimeType?.GetMethod("IsPressed", Type.EmptyTypes); private static readonly PropertyInfo? DhhInstanceProperty = AccessTools.Property(typeof(DHHAbilityManager), "instance"); private static readonly FieldInfo? AbilitySpotsField = AccessTools.Field(typeof(DHHAbilityManager), "abilitySpots"); private static readonly MethodInfo? HandleInputDownMethod = AccessTools.Method(typeof(DHHAbilityManager), "HandleInputDown", new Type[1] { typeof(AbilitySpot) }, (Type[])null); private static readonly MethodInfo? HandleInputHoldMethod = AccessTools.Method(typeof(DHHAbilityManager), "HandleInputHold", new Type[1] { typeof(AbilitySpot) }, (Type[])null); private static readonly MethodInfo? HandleInputUpMethod = AccessTools.Method(typeof(DHHAbilityManager), "HandleInputUp", new Type[1] { typeof(AbilitySpot) }, (Type[])null); private static readonly MethodInfo? HasEquippedAbilityMethod = AccessTools.Method(typeof(DHHAbilityManager), "HasEquippedAbility", (Type[])null, (Type[])null); private static readonly FieldInfo? BackgroundIconField = AccessTools.Field(typeof(AbilitySpot), "backgroundIcon"); private static readonly string[] FallbackActivateActionNames = new string[7] { "VR Actions/ResetHeight", "VR Actions/Grab", "VR Actions/Interact", "VR Actions/Push", "VR Actions/Movement", "VR Actions/Turn", "ResetHeight" }; private static readonly HashSet<string> ExcludedActionNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Movement", "Turn", "Scroll", "Map", "GripLeft", "leftGrip", "GripRight", "rightGrip", "MapGrabLeft", "MapGrabRight", "VR Actions/Movement", "VR Actions/Turn", "VR Actions/Map", "VR Actions/GripLeft", "VR Actions/leftGrip", "VR Actions/GripRight", "VR Actions/rightGrip", "VR Actions/MapGrabLeft", "VR Actions/MapGrabRight" }; internal static readonly ManualLogSource Log = Logger.CreateLogSource("DeathHeadHopperFix-VR.VanillaAbility"); internal const string