Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DeathHeadHopperVRBridge v0.1.3
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