Decompiled source of PSVR2 v1.2.1

Mods/PSVR2.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using EyeTracking;
using EyeTracking.TrackingProviders;
using HarmonyLib;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Combat;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using PSVR2;
using PSVR2.BoneMenu;
using PSVR2.Features;
using PSVR2.PSVR2Toolkit;
using PSVR2.UserData;
using PSVR2.Utilities;
using PSVR2Toolkit;
using PSVR2Toolkit.Utilities;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "PSVR2", "0.0.1", "Checkerboard", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonOptionalDependencies(new string[] { "EyeTracking" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PSVR2")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5ed171fe7cb514ac846517a07bbfe6c4540e21af")]
[assembly: AssemblyProduct("PSVR2")]
[assembly: AssemblyTitle("PSVR2")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class CrossIPC
{
	private const string LIB_NAME = "libcrossipc";

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr CreateIpcMutex(string name);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void DestroyIpcMutex(IntPtr mutex);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void IpcMutex_Lock(IntPtr mutex);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	[return: MarshalAs(UnmanagedType.I1)]
	public static extern bool IpcMutex_TryLock(IntPtr mutex);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void IpcMutex_Unlock(IntPtr mutex);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr IpcMutex_GetNativeHandle(IntPtr mutex);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr CreateIpcEvent(string name, [MarshalAs(UnmanagedType.I1)] bool manualReset);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void DestroyIpcEvent(IntPtr ev);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void IpcEvent_Set(IntPtr ev);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	[return: MarshalAs(UnmanagedType.I1)]
	public static extern bool IpcEvent_Wait(IntPtr ev, uint timeoutMs);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void IpcEvent_Reset(IntPtr ev);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr IpcEvent_GetNativeHandle(IntPtr ev);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr CreateIpcSharedMemory(string name, UIntPtr size);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void DestroyIpcSharedMemory(IntPtr shm);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr IpcSharedMemory_Map(IntPtr shm);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void IpcSharedMemory_Unmap(IntPtr shm);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr IpcSharedMemory_GetNativeHandle(IntPtr shm);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern IntPtr CreateIpcBroadcast(string name);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void DestroyIpcBroadcast(IntPtr broadcast);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	[return: MarshalAs(UnmanagedType.I1)]
	public static extern bool IpcBroadcast_Wait(IntPtr broadcast, uint timeoutMs);

	[DllImport("libcrossipc", CallingConvention = CallingConvention.Cdecl)]
	public static extern void IpcBroadcast_NotifyAll(IntPtr broadcast);
}
namespace PSVR2Toolkit
{
	public enum VRControllerType : byte
	{
		Left,
		Right,
		Both
	}
	public enum GazeCalibrationReportMode : ushort
	{
		None,
		StartCalibration,
		CollectCalibrationPoint,
		DiscardCalibrationPoint,
		ComputeAndApplyCalibration,
		RetrieveCalibrationData,
		StopCalibration,
		SetEnabledEye,
		HardwareCalibrationRetrieve
	}
	public enum GazeCalibrationStatus : ushort
	{
		EyetrackingInactive,
		EyetrackingActive,
		CalibrationReady,
		DSPBusy,
		Computing,
		ComputeSucceeded,
		ComputeFailed,
		SettingEye
	}
	public enum GazeCalibrationResult : byte
	{
		Success,
		Failure,
		Discarded,
		Waiting
	}
	public enum hmd2_gaze_bool_t : uint
	{
		HMD2_GAZE_BOOL_FALSE,
		HMD2_GAZE_BOOL_TRUE
	}
	public enum hmd2_gaze_enabled_eye_t : byte
	{
		HMD2_GAZE_ENABLED_EYE_LEFT,
		HMD2_GAZE_ENABLED_EYE_RIGHT,
		HMD2_GAZE_ENABLED_EYE_BOTH
	}
	public enum ScePadTriggerEffectMode
	{
		SCE_PAD_TRIGGER_EFFECT_MODE_OFF,
		SCE_PAD_TRIGGER_EFFECT_MODE_FEEDBACK,
		SCE_PAD_TRIGGER_EFFECT_MODE_WEAPON,
		SCE_PAD_TRIGGER_EFFECT_MODE_VIBRATION,
		SCE_PAD_TRIGGER_EFFECT_MODE_MULTIPLE_POSITION_FEEDBACK,
		SCE_PAD_TRIGGER_EFFECT_MODE_SLOPE_FEEDBACK,
		SCE_PAD_TRIGGER_EFFECT_MODE_MULTIPLE_POSITION_VIBRATION
	}
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct hmd2_gaze_vec2_t
	{
		public float x;

		public float y;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct hmd2_gaze_vec3_t
	{
		public float x;

		public float y;

		public float z;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct hmd2_gaze_lens_config_t
	{
		public hmd2_gaze_vec3_t left;

		public hmd2_gaze_vec3_t right;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	public struct hmd2_gaze_wearable_eye_t
	{
		public hmd2_gaze_bool_t is_gaze_origin_valid;

		public hmd2_gaze_vec3_t gaze_origin_mm;

		public hmd2_gaze_bool_t is_gaze_dir_valid;

		public hmd2_gaze_vec3_t gaze_dir_norm;

		public hmd2_gaze_bool_t is_pupil_dia_valid;

		public float pupil_dia_mm;

		public hmd2_gaze_bool_t is_pupil_pos_in_sensor_area_valid;

		public hmd2_gaze_vec2_t pupil_pos_in_sensor_area;

		public hmd2_gaze_bool_t is_pos_guide_valid;

		public hmd2_gaze_vec2_t pos_guide;

		public hmd2_gaze_bool_t is_blink_valid;

		public hmd2_gaze_bool_t blink;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 8)]
	public struct hmd2_gaze_wearable_data_t
	{
		public long timestamp;

		public uint frame_counter;

		public hmd2_gaze_wearable_eye_t left;

		public hmd2_gaze_wearable_eye_t right;

		public hmd2_gaze_bool_t is_gaze_origin_combined_valid;

		public hmd2_gaze_vec3_t gaze_origin_combined_mm;

		public hmd2_gaze_bool_t is_gaze_dir_combined_valid;

		public hmd2_gaze_vec3_t gaze_dir_combined_norm;

		public hmd2_gaze_bool_t is_convergence_distance_valid;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 8)]
	public struct hmd2_gaze_foveated_gaze_t
	{
		public long timestamp;

		public uint frame_counter;

		public uint tracking_state;

		public hmd2_gaze_vec3_t gaze_dir_left_norm;

		public hmd2_gaze_vec3_t gaze_dir_right_norm;

		public hmd2_gaze_vec3_t gaze_dir_combined_norm;

		public float convergence_distance_mm;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 8)]
	public struct hmd2_gaze_status_t
	{
		public byte magic0;

		public byte magic1;

		public ushort version;

		public uint size;

		public float exp_l;

		public float exp_r;

		public uint led_status;

		public uint exp_counter_l;

		public uint exp_counter_r;

		public uint led_counter;

		public int dsp_return_code;

		public hmd2_gaze_lens_config_t lens_config;

		public uint user_calibration_id;

		public hmd2_gaze_vec3_t fr_gaze_origin;

		public hmd2_gaze_enabled_eye_t enabled_eye;

		public byte motor_sequence;

		public byte motor_strength;

		public hmd2_gaze_wearable_data_t wearable;

		public hmd2_gaze_foveated_gaze_t foveated;
	}
	[StructLayout(LayoutKind.Explicit, Size = 48)]
	public struct ScePadTriggerEffectCommandData
	{
		[FieldOffset(0)]
		public byte feedbackPosition;

		[FieldOffset(1)]
		public byte feedbackStrength;

		[FieldOffset(0)]
		public byte weaponStartPosition;

		[FieldOffset(1)]
		public byte weaponEndPosition;

		[FieldOffset(2)]
		public byte weaponStrength;

		[FieldOffset(0)]
		public byte vibrationPosition;

		[FieldOffset(1)]
		public byte vibrationAmplitude;

		[FieldOffset(2)]
		public byte vibrationFrequency;

		[FieldOffset(0)]
		public byte multiplePositionFeedbackStrength0;

		[FieldOffset(1)]
		public byte multiplePositionFeedbackStrength1;

		[FieldOffset(2)]
		public byte multiplePositionFeedbackStrength2;

		[FieldOffset(3)]
		public byte multiplePositionFeedbackStrength3;

		[FieldOffset(4)]
		public byte multiplePositionFeedbackStrength4;

		[FieldOffset(5)]
		public byte multiplePositionFeedbackStrength5;

		[FieldOffset(6)]
		public byte multiplePositionFeedbackStrength6;

		[FieldOffset(7)]
		public byte multiplePositionFeedbackStrength7;

		[FieldOffset(8)]
		public byte multiplePositionFeedbackStrength8;

		[FieldOffset(9)]
		public byte multiplePositionFeedbackStrength9;

		[FieldOffset(0)]
		public byte slopeStartPosition;

		[FieldOffset(1)]
		public byte slopeEndPosition;

		[FieldOffset(2)]
		public byte slopeStartStrength;

		[FieldOffset(3)]
		public byte slopeEndStrength;

		[FieldOffset(0)]
		public byte multiplePositionVibrationFrequency;

		[FieldOffset(1)]
		public byte multiplePositionVibrationAmplitude0;

		[FieldOffset(2)]
		public byte multiplePositionVibrationAmplitude1;

		[FieldOffset(3)]
		public byte multiplePositionVibrationAmplitude2;

		[FieldOffset(4)]
		public byte multiplePositionVibrationAmplitude3;

		[FieldOffset(5)]
		public byte multiplePositionVibrationAmplitude4;

		[FieldOffset(6)]
		public byte multiplePositionVibrationAmplitude5;

		[FieldOffset(7)]
		public byte multiplePositionVibrationAmplitude6;

		[FieldOffset(8)]
		public byte multiplePositionVibrationAmplitude7;

		[FieldOffset(9)]
		public byte multiplePositionVibrationAmplitude8;

		[FieldOffset(10)]
		public byte multiplePositionVibrationAmplitude9;

		public void SetMultiplePositionFeedbackStrength(byte[] strength)
		{
			if (strength == null)
			{
				throw new ArgumentNullException("strength");
			}
			int num = Math.Min(strength.Length, 10);
			if (num > 0)
			{
				multiplePositionFeedbackStrength0 = strength[0];
			}
			if (num > 1)
			{
				multiplePositionFeedbackStrength1 = strength[1];
			}
			if (num > 2)
			{
				multiplePositionFeedbackStrength2 = strength[2];
			}
			if (num > 3)
			{
				multiplePositionFeedbackStrength3 = strength[3];
			}
			if (num > 4)
			{
				multiplePositionFeedbackStrength4 = strength[4];
			}
			if (num > 5)
			{
				multiplePositionFeedbackStrength5 = strength[5];
			}
			if (num > 6)
			{
				multiplePositionFeedbackStrength6 = strength[6];
			}
			if (num > 7)
			{
				multiplePositionFeedbackStrength7 = strength[7];
			}
			if (num > 8)
			{
				multiplePositionFeedbackStrength8 = strength[8];
			}
			if (num > 9)
			{
				multiplePositionFeedbackStrength9 = strength[9];
			}
		}

		public void SetMultiplePositionVibrationAmplitude(byte[] amplitude)
		{
			if (amplitude == null)
			{
				throw new ArgumentNullException("amplitude");
			}
			int num = Math.Min(amplitude.Length, 10);
			if (num > 0)
			{
				multiplePositionVibrationAmplitude0 = amplitude[0];
			}
			if (num > 1)
			{
				multiplePositionVibrationAmplitude1 = amplitude[1];
			}
			if (num > 2)
			{
				multiplePositionVibrationAmplitude2 = amplitude[2];
			}
			if (num > 3)
			{
				multiplePositionVibrationAmplitude3 = amplitude[3];
			}
			if (num > 4)
			{
				multiplePositionVibrationAmplitude4 = amplitude[4];
			}
			if (num > 5)
			{
				multiplePositionVibrationAmplitude5 = amplitude[5];
			}
			if (num > 6)
			{
				multiplePositionVibrationAmplitude6 = amplitude[6];
			}
			if (num > 7)
			{
				multiplePositionVibrationAmplitude7 = amplitude[7];
			}
			if (num > 8)
			{
				multiplePositionVibrationAmplitude8 = amplitude[8];
			}
			if (num > 9)
			{
				multiplePositionVibrationAmplitude9 = amplitude[9];
			}
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	public struct ScePadTriggerEffectCommand
	{
		public ScePadTriggerEffectMode mode;

		public uint padding;

		public ScePadTriggerEffectCommandData commandData;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	public struct TriggerEffectCommandPayload
	{
		public VRControllerType controllerType;

		public ScePadTriggerEffectCommand command;
	}
	[StructLayout(LayoutKind.Explicit, Size = 13)]
	public struct GazeCalibrationPacket
	{
		[FieldOffset(0)]
		public float x;

		[FieldOffset(4)]
		public float y;

		[FieldOffset(8)]
		public float z;

		[FieldOffset(12)]
		public GazeCalibrationResult result;

		[FieldOffset(12)]
		public hmd2_gaze_enabled_eye_t eyeEnabled;
	}
	[StructLayout(LayoutKind.Explicit, Size = 15)]
	public struct GazeCalibrationCommand
	{
		[FieldOffset(0)]
		public GazeCalibrationReportMode reportMode;

		[FieldOffset(0)]
		public GazeCalibrationStatus status;

		[FieldOffset(2)]
		public GazeCalibrationPacket payload;
	}
	public static class PSVR2ToolkitCAPI
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate int psvr2_toolkit_init_delegate();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void psvr2_toolkit_deinit_delegate();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate bool psvr2_toolkit_gaze_status_delegate(ref hmd2_gaze_status_t pGazeStatus, uint timeoutMs);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate bool psvr2_toolkit_gaze_image_delegate(ref IntPtr pGazeImage, uint timeoutMs);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void psvr2_toolkit_write_pcm_delegate(VRControllerType controllerType, IntPtr pcm);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void psvr2_toolkit_wait_for_pcm_delegate();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void psvr2_toolkit_set_trigger_effect_delegate(VRControllerType controllerType, ref ScePadTriggerEffectCommand command);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void psvr2_toolkit_set_hmd_rumble_delegate(byte rumbleHz);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate GazeCalibrationCommand psvr2_toolkit_private_send_gaze_set_command_delegate(GazeCalibrationCommand command);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate GazeCalibrationCommand psvr2_toolkit_private_send_gaze_get_command_delegate(GazeCalibrationCommand command);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void psvr2_toolkit_private_set_usb_connection_state_delegate(bool connected);

		private static psvr2_toolkit_init_delegate _init;

		private static psvr2_toolkit_deinit_delegate _deinit;

		private static psvr2_toolkit_gaze_status_delegate _gaze_status;

		private static psvr2_toolkit_gaze_image_delegate _gaze_image;

		private static psvr2_toolkit_write_pcm_delegate _write_pcm;

		private static psvr2_toolkit_wait_for_pcm_delegate _wait_for_pcm;

		private static psvr2_toolkit_set_trigger_effect_delegate _set_trigger_effect;

		private static psvr2_toolkit_set_hmd_rumble_delegate _set_hmd_rumble;

		private static psvr2_toolkit_private_send_gaze_set_command_delegate _private_send_gaze_set_command;

		private static psvr2_toolkit_private_send_gaze_get_command_delegate _private_send_gaze_get_command;

		private static psvr2_toolkit_private_set_usb_connection_state_delegate _private_set_usb_connection_state;

		private static IntPtr _moduleHandle = IntPtr.Zero;

		private static readonly object _lock = new object();

		public static IntPtr ModuleHandle
		{
			get
			{
				EnsureLoaded();
				return _moduleHandle;
			}
		}

		[DllImport("psvr2_toolkit_capi_loader", CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr psvr2_toolkit_loader_get_module_handle();

		[DllImport("psvr2_toolkit_capi_loader", CallingConvention = CallingConvention.Cdecl)]
		private static extern nuint psvr2_toolkit_loader_get_module_path(IntPtr buffer, nuint bufferSize);

		public static string GetModulePath()
		{
			EnsureLoaded();
			try
			{
				nuint num = psvr2_toolkit_loader_get_module_path(IntPtr.Zero, 0u);
				if (num == 0)
				{
					return string.Empty;
				}
				IntPtr intPtr = Marshal.AllocHGlobal((int)(num + 1));
				try
				{
					psvr2_toolkit_loader_get_module_path(intPtr, num + 1);
					return Marshal.PtrToStringAnsi(intPtr);
				}
				finally
				{
					Marshal.FreeHGlobal(intPtr);
				}
			}
			catch
			{
				return "Unknown (Failed to query loader)";
			}
		}

		private static void EnsureLoaded()
		{
			if (_moduleHandle != IntPtr.Zero)
			{
				return;
			}
			lock (_lock)
			{
				if (!(_moduleHandle != IntPtr.Zero))
				{
					try
					{
						_moduleHandle = psvr2_toolkit_loader_get_module_handle();
					}
					catch (DllNotFoundException inner)
					{
						throw new DllNotFoundException("Could not load the loader library 'psvr2_toolkit_capi_loader'. Make sure 'psvr2_toolkit_capi_loader.dll' is in your application directory or search path.", inner);
					}
					if (_moduleHandle == IntPtr.Zero)
					{
						throw new InvalidOperationException("psvr2_toolkit_loader_get_module_handle returned NULL. Make sure psvr2tk_capi_path.txt contains the correct directory of 'psvr2_toolkit_capi.dll' and the dll exists in that directory.");
					}
					_init = GetExport<psvr2_toolkit_init_delegate>("psvr2_toolkit_init");
					_deinit = GetExport<psvr2_toolkit_deinit_delegate>("psvr2_toolkit_deinit");
					_gaze_status = GetExport<psvr2_toolkit_gaze_status_delegate>("psvr2_toolkit_gaze_status");
					_gaze_image = GetExport<psvr2_toolkit_gaze_image_delegate>("psvr2_toolkit_gaze_image");
					_write_pcm = GetExport<psvr2_toolkit_write_pcm_delegate>("psvr2_toolkit_write_pcm");
					_wait_for_pcm = GetExport<psvr2_toolkit_wait_for_pcm_delegate>("psvr2_toolkit_wait_for_pcm");
					_set_trigger_effect = GetExport<psvr2_toolkit_set_trigger_effect_delegate>("psvr2_toolkit_set_trigger_effect");
					_set_hmd_rumble = GetExport<psvr2_toolkit_set_hmd_rumble_delegate>("psvr2_toolkit_set_hmd_rumble");
					_private_send_gaze_set_command = GetExport<psvr2_toolkit_private_send_gaze_set_command_delegate>("psvr2_toolkit_private_send_gaze_set_command");
					_private_send_gaze_get_command = GetExport<psvr2_toolkit_private_send_gaze_get_command_delegate>("psvr2_toolkit_private_send_gaze_get_command");
					_private_set_usb_connection_state = GetExport<psvr2_toolkit_private_set_usb_connection_state_delegate>("psvr2_toolkit_private_set_usb_connection_state");
				}
			}
		}

		private static T GetExport<T>(string name) where T : Delegate
		{
			IntPtr procAddress = GetProcAddress(_moduleHandle, name);
			if (procAddress == IntPtr.Zero)
			{
				throw new EntryPointNotFoundException("Could not find entry point '" + name + "' in the loaded PSVR2 Toolkit CAPI library.");
			}
			return (T)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(T));
		}

		private static IntPtr GetProcAddress(IntPtr hModule, string procName)
		{
			Type type = Type.GetType("System.Runtime.InteropServices.NativeLibrary, System.Runtime.InteropServices");
			if (type != null)
			{
				MethodInfo method = type.GetMethod("GetExport", new Type[2]
				{
					typeof(IntPtr),
					typeof(string)
				});
				if (method != null)
				{
					try
					{
						return (IntPtr)method.Invoke(null, new object[2] { hModule, procName });
					}
					catch
					{
					}
				}
			}
			if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
			{
				return Win32GetProcAddress(hModule, procName);
			}
			try
			{
				return UnixDlsym(hModule, procName);
			}
			catch
			{
				return UnixDlsym2(hModule, procName);
			}
		}

		[DllImport("kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "GetProcAddress", ExactSpelling = true, SetLastError = true)]
		private static extern IntPtr Win32GetProcAddress(IntPtr hModule, string procName);

		[DllImport("libdl", CharSet = CharSet.Ansi, EntryPoint = "dlsym")]
		private static extern IntPtr UnixDlsym(IntPtr handle, string symbol);

		[DllImport("libdl.so.2", CharSet = CharSet.Ansi, EntryPoint = "dlsym")]
		private static extern IntPtr UnixDlsym2(IntPtr handle, string symbol);

		public static int Init()
		{
			EnsureLoaded();
			return _init();
		}

		public static void Deinit()
		{
			EnsureLoaded();
			_deinit();
		}

		public static bool GetGazeStatus(ref hmd2_gaze_status_t gazeStatus, uint timeoutMs)
		{
			EnsureLoaded();
			return _gaze_status(ref gazeStatus, timeoutMs);
		}

		public static bool GetGazeImage(ref byte[] gazeImage, uint timeoutMs)
		{
			if (gazeImage == null)
			{
				throw new ArgumentNullException("gazeImage");
			}
			if (gazeImage.Length < 2097408)
			{
				throw new ArgumentException("Array size must be at least 0x200100 bytes.", "gazeImage");
			}
			EnsureLoaded();
			IntPtr pGazeImage = IntPtr.Zero;
			bool num = _gaze_image(ref pGazeImage, timeoutMs);
			if (num && pGazeImage != IntPtr.Zero)
			{
				Marshal.Copy(pGazeImage, gazeImage, 0, 2097408);
			}
			return num;
		}

		public static bool GetGazeImage(ref IntPtr pGazeImage, uint timeoutMs)
		{
			EnsureLoaded();
			return _gaze_image(ref pGazeImage, timeoutMs);
		}

		public static void WritePcm(VRControllerType controllerType, byte[] pcm)
		{
			if (pcm == null)
			{
				throw new ArgumentNullException("pcm");
			}
			if (pcm.Length < 32)
			{
				throw new ArgumentException("PCM array must be at least 32 bytes.", "pcm");
			}
			EnsureLoaded();
			GCHandle gCHandle = GCHandle.Alloc(pcm, GCHandleType.Pinned);
			try
			{
				_write_pcm(controllerType, gCHandle.AddrOfPinnedObject());
			}
			finally
			{
				gCHandle.Free();
			}
		}

		public static void WritePcm(VRControllerType controllerType, IntPtr pcm)
		{
			if (pcm == IntPtr.Zero)
			{
				throw new ArgumentNullException("pcm");
			}
			EnsureLoaded();
			_write_pcm(controllerType, pcm);
		}

		public static void WaitForPcm()
		{
			EnsureLoaded();
			_wait_for_pcm();
		}

		public static void SetTriggerEffect(VRControllerType controllerType, ref ScePadTriggerEffectCommand command)
		{
			EnsureLoaded();
			_set_trigger_effect(controllerType, ref command);
		}

		public static void SetHmdRumble(byte rumbleHz)
		{
			EnsureLoaded();
			_set_hmd_rumble(rumbleHz);
		}

		public static GazeCalibrationCommand SendGazeSetCommand(GazeCalibrationCommand command)
		{
			EnsureLoaded();
			return _private_send_gaze_set_command(command);
		}

		public static GazeCalibrationCommand SendGazeGetCommand(GazeCalibrationCommand command)
		{
			EnsureLoaded();
			return _private_send_gaze_get_command(command);
		}

		public static void SetUsbConnectionState(bool connected)
		{
			EnsureLoaded();
			_private_set_usb_connection_state(connected);
		}
	}
}
namespace PSVR2Toolkit.Utilities
{
	public class LowPassFilter
	{
		private readonly float[] _samples;

		private int _index;

		public LowPassFilter(int count)
		{
			_samples = new float[count - 1];
			for (int i = 0; i < count - 1; i++)
			{
				_samples[i] = 0f;
			}
		}

		private float Sum()
		{
			float num = 0f;
			float[] samples = _samples;
			foreach (float num2 in samples)
			{
				num += num2;
			}
			return num;
		}

		public float FilterValue(float newValue)
		{
			_index++;
			if (_samples.Length == _index)
			{
				_index = 0;
			}
			_samples[_index] = newValue;
			return Sum() / (float)_samples.Length;
		}
	}
}
namespace PSVR2
{
	internal class Core : MelonMod
	{
		internal static Core Instance { get; private set; }

		internal PreferencesManager PreferencesManager { get; private set; }

		internal PSVR2ToolKitManager ToolkitManager { get; private set; }

		internal FeatureManager FeatureManager { get; private set; }

		internal BoneMenuManager MenuManager { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			PreferencesManager = new PreferencesManager();
			ToolkitManager = new PSVR2ToolKitManager();
			FeatureManager = new FeatureManager();
			MenuManager = new BoneMenuManager();
		}

		public override void OnUpdate()
		{
			FeatureManager.OnUpdate();
		}
	}
}
namespace PSVR2.Utilities
{
	internal static class MelonUtilities
	{
		internal static bool HasEyeTracking()
		{
			return MelonBase.FindMelon("EyeTracking", "Checkerboard") != null;
		}
	}
}
namespace PSVR2.UserData
{
	internal class PreferencesManager
	{
		internal MelonPreferences_Entry<bool> AdaptiveTriggers;

		internal MelonPreferences_Entry<byte> SingleFireFeedback;

		internal MelonPreferences_Entry<bool> HeadsetVibration;

		internal MelonPreferences_Entry<byte> HeadsetVibrationStrength;

		internal MelonPreferences_Entry<bool> FingerCurl;

		internal MelonPreferences_Entry<bool> EyeLidEstimation;

		private MelonPreferences_Category Category { get; set; }

		internal PreferencesManager()
		{
			Category = MelonPreferences.CreateCategory("PSVR2");
			AdaptiveTriggers = Category.CreateEntry<bool>("AdaptiveTriggers", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			SingleFireFeedback = Category.CreateEntry<byte>("SingleFireFeedback", (byte)4, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			HeadsetVibration = Category.CreateEntry<bool>("HeadsetVibration", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			HeadsetVibrationStrength = Category.CreateEntry<byte>("HeadsetVibrationStrength", (byte)16, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			FingerCurl = Category.CreateEntry<bool>("FingerCurl", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			EyeLidEstimation = Category.CreateEntry<bool>("EyeLidEstimation", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Save();
		}

		internal void Save()
		{
			Category.SaveToFile(false);
		}
	}
}
namespace PSVR2.PSVR2Toolkit
{
	internal class PSVR2ToolKitManager
	{
		internal bool Loaded { get; private set; }

		internal PSVR2ToolKitManager()
		{
			try
			{
				int num = PSVR2ToolkitCAPI.Init();
				((MelonBase)Core.Instance).LoggerInstance.Msg("PSVR2ToolKit init result: " + num);
				if (num != 0)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("PSVR2ToolKit failed to initialize.");
					Loaded = false;
				}
				else
				{
					((MelonBase)Core.Instance).LoggerInstance.Msg("PSVR2ToolKit initialized successfully.");
					Loaded = true;
				}
			}
			catch (Exception ex)
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Failed to start CAPI: " + ex.Message);
			}
		}
	}
}
namespace PSVR2.Features
{
	internal class AdaptiveTriggers : IFeature
	{
		private enum FeedbackMode
		{
			None,
			Weapon,
			Vibration
		}

		private class TriggerState
		{
			public FeedbackMode Mode;

			public byte Start;

			public byte End;

			public byte Strength;

			public byte Position;

			public byte Amplitude;

			public byte Frequency;

			public bool Dirty = true;
		}

		private static class TriggerManager
		{
			private static readonly Dictionary<VRControllerType, TriggerState> States = new Dictionary<VRControllerType, TriggerState>
			{
				{
					VRControllerType.Left,
					new TriggerState()
				},
				{
					VRControllerType.Right,
					new TriggerState()
				}
			};

			internal static void SetNone(VRControllerType controller, bool force = false)
			{
				TriggerState triggerState = States[controller];
				if (force || triggerState.Mode != FeedbackMode.None)
				{
					triggerState.Mode = FeedbackMode.None;
					triggerState.Dirty = true;
				}
			}

			internal static void SetWeapon(VRControllerType controller, byte start, byte end, byte strength)
			{
				TriggerState triggerState = States[controller];
				if (triggerState.Mode != FeedbackMode.Weapon || triggerState.Start != start || triggerState.End != end || triggerState.Strength != strength)
				{
					triggerState.Mode = FeedbackMode.Weapon;
					triggerState.Start = start;
					triggerState.End = end;
					triggerState.Strength = strength;
					triggerState.Dirty = true;
				}
			}

			internal static void SetVibration(VRControllerType controller, byte pos, byte amp, byte freq)
			{
				TriggerState triggerState = States[controller];
				if (triggerState.Mode != FeedbackMode.Vibration || triggerState.Position != pos || triggerState.Amplitude != amp || triggerState.Frequency != freq)
				{
					triggerState.Mode = FeedbackMode.Vibration;
					triggerState.Position = pos;
					triggerState.Amplitude = amp;
					triggerState.Frequency = freq;
					triggerState.Dirty = true;
				}
			}

			internal static void Apply()
			{
				foreach (var (controllerType, triggerState2) in States)
				{
					if (!triggerState2.Dirty)
					{
						continue;
					}
					try
					{
						ScePadTriggerEffectCommand command = default(ScePadTriggerEffectCommand);
						switch (triggerState2.Mode)
						{
						case FeedbackMode.None:
							command.mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_OFF;
							PSVR2ToolkitCAPI.SetTriggerEffect(controllerType, ref command);
							break;
						case FeedbackMode.Weapon:
							command.mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_WEAPON;
							command.commandData.weaponStartPosition = triggerState2.Start;
							command.commandData.weaponEndPosition = triggerState2.End;
							command.commandData.weaponStrength = triggerState2.Strength;
							PSVR2ToolkitCAPI.SetTriggerEffect(controllerType, ref command);
							break;
						case FeedbackMode.Vibration:
							command.mode = ScePadTriggerEffectMode.SCE_PAD_TRIGGER_EFFECT_MODE_VIBRATION;
							command.commandData.vibrationPosition = triggerState2.Position;
							command.commandData.vibrationAmplitude = triggerState2.Amplitude;
							command.commandData.vibrationFrequency = triggerState2.Frequency;
							PSVR2ToolkitCAPI.SetTriggerEffect(controllerType, ref command);
							break;
						}
					}
					catch (Exception ex)
					{
						((MelonBase)Core.Instance).LoggerInstance.Error("Trigger IPC failed: " + ex.Message);
					}
					triggerState2.Dirty = false;
				}
			}

			internal static void ForceDisableAll()
			{
				SetNone(VRControllerType.Left, force: true);
				SetNone(VRControllerType.Right, force: true);
			}
		}

		[HarmonyPatch(typeof(Gun))]
		private static class GunPatches
		{
			[HarmonyPatch("Update")]
			[HarmonyPostfix]
			private static void Update(Gun __instance)
			{
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: 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_008c: Invalid comparison between Unknown and I4
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Invalid comparison between Unknown and I4
				if (!Core.Instance.PreferencesManager.AdaptiveTriggers.Value)
				{
					return;
				}
				Grip triggerGrip = __instance.triggerGrip;
				Hand val = ((triggerGrip != null) ? triggerGrip.GetHand() : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				VRControllerType controller;
				if ((Object)(object)val == (Object)(object)Player.LeftHand)
				{
					controller = VRControllerType.Left;
				}
				else
				{
					if (!((Object)(object)val == (Object)(object)Player.RightHand))
					{
						return;
					}
					controller = VRControllerType.Right;
				}
				if (__instance._magState == null || (Object)(object)__instance._ammoInventory == (Object)null || (Object)(object)__instance.chamberedCartridge == (Object)null)
				{
					TriggerManager.SetNone(controller);
					return;
				}
				FireMode fireMode = __instance.fireMode;
				if ((int)fireMode > 1)
				{
					if ((int)fireMode == 2)
					{
						byte freq = Convert.ToByte(Math.Min(40, (int)Math.Round(__instance.roundsPerMinute / 60f)));
						TriggerManager.SetVibration(controller, VibrationPosition, VibrationAmplitude, freq);
					}
				}
				else
				{
					TriggerManager.SetWeapon(controller, WeaponStart, WeaponEnd, WeaponStrength);
				}
			}

			[HarmonyPatch("OnTriggerGripDetached")]
			[HarmonyPrefix]
			private static void OnTriggerGripDetached(Gun __instance, Hand hand)
			{
				if (!Core.Instance.PreferencesManager.AdaptiveTriggers.Value || (Object)(object)hand == (Object)null)
				{
					return;
				}
				VRControllerType controller;
				if ((Object)(object)hand == (Object)(object)Player.LeftHand)
				{
					controller = VRControllerType.Left;
				}
				else
				{
					if (!((Object)(object)hand == (Object)(object)Player.RightHand))
					{
						return;
					}
					controller = VRControllerType.Right;
				}
				TriggerManager.SetNone(controller);
			}
		}

		internal static byte WeaponStart = 2;

		internal static byte WeaponEnd = 4;

		internal static byte VibrationPosition = 4;

		internal static byte VibrationAmplitude = 8;

		internal static byte WeaponStrength => Core.Instance.PreferencesManager.SingleFireFeedback.Value;

		public void Initialize()
		{
			Hooking.OnLevelLoaded += delegate
			{
				TriggerManager.ForceDisableAll();
			};
			Hooking.OnLevelUnloaded += TriggerManager.ForceDisableAll;
		}

		public void OnUpdate()
		{
			TriggerManager.Apply();
		}
	}
	internal class FeatureManager
	{
		private IFeature adaptiveTriggers { get; set; }

		private IFeature headsetVibration { get; set; }

		private IFeature fingerCurl { get; set; }

		internal FeatureManager()
		{
			adaptiveTriggers = new AdaptiveTriggers();
			headsetVibration = new HeadsetVibration();
			fingerCurl = new FingerCurl();
			adaptiveTriggers.Initialize();
			headsetVibration.Initialize();
			fingerCurl.Initialize();
		}

		internal void OnUpdate()
		{
			adaptiveTriggers.OnUpdate();
			headsetVibration.OnUpdate();
			fingerCurl.OnUpdate();
		}
	}
	internal class FingerCurl : IFeature
	{
		[HarmonyPatch(typeof(OpenController))]
		private static class OpenControllerPatches
		{
			[HarmonyPatch("ProcessFingers")]
			[HarmonyPostfix]
			private static void ProcessFingers(OpenController __instance)
			{
				if (Core.Instance.PreferencesManager.FingerCurl.Value && !((Object)(object)((Rig)((BaseController)__instance).contRig).manager != (Object)(object)Player.RigManager))
				{
					((BaseController)__instance)._processedMiddle = Mathf.Clamp(((BaseController)__instance)._processedMiddle, 0.1f, 1f);
					((BaseController)__instance)._processedIndex = Mathf.Clamp(((BaseController)__instance)._processedIndex, 0.1f, 1f);
					((BaseController)__instance)._processedRing = Mathf.Clamp(((BaseController)__instance)._processedRing, 0.1f, 1f);
					((BaseController)__instance)._processedPinky = Mathf.Clamp(((BaseController)__instance)._processedPinky, 0.1f, 1f);
				}
			}
		}
	}
	internal class HeadsetVibration : IFeature
	{
		[HarmonyPatch(typeof(Player_Health))]
		private static class Player_HealthPatches
		{
			[HarmonyPatch("OnReceivedDamage")]
			[HarmonyPostfix]
			private static void OnReceivedDamage(Player_Health __instance, Attack attack)
			{
				if (Core.Instance.PreferencesManager.HeadsetVibration.Value && !((Object)(object)((Health)__instance)._rigManager != (Object)(object)Player.RigManager))
				{
					PSVR2ToolkitCAPI.SetHmdRumble((byte)Mathf.Clamp((int)Core.Instance.PreferencesManager.HeadsetVibrationStrength.Value, 0, 25));
					_rumbleActive = true;
					_rumbleEndTime = Time.time + 0.5f;
				}
			}
		}

		private static bool _rumbleActive;

		private static float _rumbleEndTime;

		public void OnUpdate()
		{
			if (_rumbleActive && Time.time >= _rumbleEndTime)
			{
				PSVR2ToolkitCAPI.SetHmdRumble(0);
				_rumbleActive = false;
			}
		}
	}
	internal interface IFeature
	{
		internal void Initialize()
		{
		}

		internal void OnUpdate()
		{
		}
	}
	public class PSVR2EyeTracking : TrackingProvider
	{
		private const int noiseFilterSamples = 8;

		private LowPassFilter leftEyeFilter;

		private LowPassFilter rightEyeFilter;

		public override string Name => "PSVR2";

		public override bool SupportsEye => true;

		public override bool SupportsFace => false;

		public override bool IsLoaded => Core.Instance?.ToolkitManager?.Loaded == true;

		public override void Initialize()
		{
			leftEyeFilter = new LowPassFilter(8);
			rightEyeFilter = new LowPassFilter(8);
			Tracking.EyeData.MinDilation = 0f;
			Tracking.EyeData.MaxDilation = 10f;
		}

		public override void Update()
		{
			Core instance = Core.Instance;
			if (instance == null || instance.ToolkitManager?.Loaded != true)
			{
				return;
			}
			hmd2_gaze_status_t gazeStatus = default(hmd2_gaze_status_t);
			if (!PSVR2ToolkitCAPI.GetGazeStatus(ref gazeStatus, 1000u))
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Failed to get gaze status from PSVR2Toolkit.");
				return;
			}
			if (gazeStatus.wearable.left.is_blink_valid == hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE)
			{
				float num = ((gazeStatus.wearable.left.blink != hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE) ? 1 : 0);
				if (leftEyeFilter != null)
				{
					num = leftEyeFilter.FilterValue(num);
				}
				Tracking.EyeData.Left.Openness = num;
			}
			if (gazeStatus.wearable.right.is_blink_valid == hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE)
			{
				float num2 = ((gazeStatus.wearable.right.blink != hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE) ? 1 : 0);
				if (rightEyeFilter != null)
				{
					num2 = rightEyeFilter.FilterValue(num2);
				}
				Tracking.EyeData.Right.Openness = num2;
			}
			if (gazeStatus.wearable.left.is_gaze_dir_valid == hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE)
			{
				Tracking.EyeData.Left.GazeX = 0f - gazeStatus.wearable.left.gaze_dir_norm.x;
				Tracking.EyeData.Left.GazeY = gazeStatus.wearable.left.gaze_dir_norm.y;
			}
			if (gazeStatus.wearable.right.is_gaze_dir_valid == hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE)
			{
				Tracking.EyeData.Right.GazeX = 0f - gazeStatus.wearable.right.gaze_dir_norm.x;
				Tracking.EyeData.Right.GazeY = gazeStatus.wearable.right.gaze_dir_norm.y;
			}
			if (gazeStatus.wearable.left.is_pupil_dia_valid == hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE)
			{
				Tracking.EyeData.Left.PupilDiameterMm = gazeStatus.wearable.left.pupil_dia_mm;
			}
			if (gazeStatus.wearable.right.is_pupil_dia_valid == hmd2_gaze_bool_t.HMD2_GAZE_BOOL_TRUE)
			{
				Tracking.EyeData.Right.PupilDiameterMm = gazeStatus.wearable.right.pupil_dia_mm;
			}
		}
	}
}
namespace PSVR2.BoneMenu
{
	internal class BoneMenuManager
	{
		internal Page Page { get; private set; }

		internal BoolElement AdaptiveTriggers { get; private set; }

		internal BoolElement HeadsetVibration { get; private set; }

		internal IntElement HeadsetVibrationStrength { get; private set; }

		internal BoolElement EyeLidEstimation { get; private set; }

		internal BoneMenuManager()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			Page = Page.Root.CreatePage("PSVR2", Color32.op_Implicit(new Color32((byte)0, (byte)100, (byte)220, byte.MaxValue)), 0, true);
			AdaptiveTriggers = Page.CreateBool("Adaptive Triggers", Color.white, Core.Instance.PreferencesManager.AdaptiveTriggers.Value, (Action<bool>)delegate(bool b)
			{
				PreferencesManager preferencesManager = Core.Instance.PreferencesManager;
				preferencesManager.AdaptiveTriggers.Value = b;
				preferencesManager.Save();
			});
			HeadsetVibration = Page.CreateBool("Headset Vibration", Color.white, Core.Instance.PreferencesManager.HeadsetVibration.Value, (Action<bool>)delegate(bool b)
			{
				PreferencesManager preferencesManager = Core.Instance.PreferencesManager;
				preferencesManager.HeadsetVibration.Value = b;
				preferencesManager.Save();
			});
			HeadsetVibrationStrength = Page.CreateInt("Headset Vibration Strength", Color.white, (int)Core.Instance.PreferencesManager.HeadsetVibrationStrength.Value, 1, 1, 25, (Action<int>)delegate(int i)
			{
				PreferencesManager preferencesManager = Core.Instance.PreferencesManager;
				preferencesManager.HeadsetVibrationStrength.Value = (byte)i;
				preferencesManager.Save();
			});
			if (MelonUtilities.HasEyeTracking())
			{
				EyeLidEstimation = Page.CreateBool("EyeLid Estimation", Color.white, Core.Instance.PreferencesManager.EyeLidEstimation.Value, (Action<bool>)delegate(bool b)
				{
					PreferencesManager preferencesManager = Core.Instance.PreferencesManager;
					preferencesManager.EyeLidEstimation.Value = b;
					preferencesManager.Save();
				});
				((Element)EyeLidEstimation).SetTooltip("Whether to use PSVR2Toolkit EyeLid estimation instead of binary blink for eye tracking. \nWill only work if you have enabled EyeLid estimation in PSVR2Toolkit. \nPlease see their discord for instructions on how to enable this.");
			}
		}
	}
}