Decompiled source of BigWalkVRExtras v1.0.0

plugins/BigWalkVRExtras.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BigWalkVR;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: IgnoresAccessChecksTo("BigWalkVR")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : System.Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class RefSafetyRulesAttribute : System.Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BigWalkVRExtras
{
	[BepInPlugin("blowntobytes.bigwalkvr.extras", "Big Walk VR Extras", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class ExtrasPlugin : BasePlugin
	{
		public const string Guid = "blowntobytes.bigwalkvr.extras";

		public const string Name = "Big Walk VR Extras";

		public const string Version = "1.0.0";

		internal static ManualLogSource Logger;

		internal static ConfigEntry<bool> AutoSprint;

		internal static ConfigEntry<bool> StickClickSit;

		internal static ConfigEntry<bool> HoldToRecalibrate;

		internal static ConfigEntry<float> HoldSeconds;

		internal static ConfigEntry<bool> GripToggle;

		internal static ConfigEntry<int> VirtualCrouchMode;

		internal static ConfigEntry<float> VirtualCrouchThreshold;

		internal static ConfigEntry<float> VirtualCrouchCameraDrop;

		private Harmony harmony;

		public override void Load()
		{
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Expected O, but got Unknown
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Expected O, but got Unknown
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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)
			Logger = ((BasePlugin)this).Log;
			AutoSprint = ((BasePlugin)this).Config.Bind<bool>("BigWalkVRExtras", "AutoSprint", false, "Always sprint while the left joystick is pushed (no stick click needed). Toggle in Settings > Big Walk VR > AUTO SPRINT.");
			StickClickSit = ((BasePlugin)this).Config.Bind<bool>("BigWalkVRExtras", "RightStickClickSit", true, "Right joystick click toggles the sitting pose instead of recalibrating height.");
			HoldToRecalibrate = ((BasePlugin)this).Config.Bind<bool>("BigWalkVRExtras", "HoldRightStickToRecalibrate", false, "When true: short click = sit/stand, holding the right stick click recalibrates height (the original behaviour).");
			HoldSeconds = ((BasePlugin)this).Config.Bind<float>("BigWalkVRExtras", "HoldSeconds", 0.5f, "How long the right stick must be held to recalibrate height (only if HoldRightStickToRecalibrate is true).");
			GripToggle = ((BasePlugin)this).Config.Bind<bool>("BigWalkVRExtras", "GripToggle", false, "Grip toggle: press grip once to grab and keep holding an item, press grip again to release it. Toggle in Settings > Big Walk VR > GRIP MODE.");
			VirtualCrouchMode = ((BasePlugin)this).Config.Bind<int>("BigWalkVRExtras", "VirtualCrouchMode", 0, "Virtual crouch with the right joystick pulled back (towards you). 0 = off, 1 = hold (crouch while pulled), 2 = toggle (pull once to crouch, pull again to stand). Set in Settings > Big Walk VR > VIRTUAL CROUCH.");
			VirtualCrouchThreshold = ((BasePlugin)this).Config.Bind<float>("BigWalkVRExtras", "VirtualCrouchThreshold", 0.6f, "How far back the right joystick must be pulled (0..1) to crouch.");
			VirtualCrouchCameraDrop = ((BasePlugin)this).Config.Bind<float>("BigWalkVRExtras", "VirtualCrouchCameraDrop", 0.45f, "How far (metres) the VR camera is lowered while virtually crouching. 0 disables the camera drop.");
			try
			{
				ValueTuple<string, string>[] pauseControls = VrSettingsMenu.PauseControls;
				for (int i = 0; i < pauseControls.Length; i++)
				{
					if (pauseControls[i].Item1 == "Reset height")
					{
						pauseControls[i] = new ValueTuple<string, string>(HoldToRecalibrate.Value ? "Sit / stand (hold: reset height)" : "Sit / stand", "RIGHT STICK");
					}
					else if (pauseControls[i].Item1 == "Grab" && GripToggle.Value)
					{
						pauseControls[i] = new ValueTuple<string, string>("Grab / release (toggle)", "GRIP");
					}
					else if (pauseControls[i].Item1 == "Crouch / sit" && VirtualCrouchMode.Value != 0)
					{
						pauseControls[i] = new ValueTuple<string, string>("Crouch / sit", "CROUCH IRL / R STICK BACK");
					}
				}
			}
			catch (System.Exception ex)
			{
				Logger.LogWarning((object)("Could not update pause control hints: " + ex.Message));
			}
			harmony = new Harmony("blowntobytes.bigwalkvr.extras");
			harmony.PatchAll(typeof(ExtrasPlugin).Assembly);
			ManualLogSource logger = Logger;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(68, 6, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Big Walk VR Extras");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded (AutoSprint=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(AutoSprint.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", StickClickSit=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(StickClickSit.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", GripToggle=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(GripToggle.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", VirtualCrouch=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(VirtualCrouchMode.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
			}
			logger.LogInfo(val);
		}

		public override bool Unload()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(VrLocomotion))]
	internal static class LocomotionPatches
	{
		private static bool wasPressed;

		private static bool longFired;

		private static float pressStart;

		private static bool sitToggleRequested;

		private static bool virtualSit;

		private static bool virtualSitConfirmed;

		private static float virtualSitTime;

		private static bool lastCrouchPressed;

		private static bool lastStickBack;

		private static bool toggleCrouch;

		private static bool virtualCrouchActive;

		private static float crouchCameraBlend;

		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		private static void UpdatePrefix(ref VrControllerState rightController, bool suppressMovement)
		{
			if (!ExtrasPlugin.StickClickSit.Value)
			{
				return;
			}
			bool flag = ((VrControllerState)(ref rightController)).StateIsValid && ((VrControllerState)(ref rightController)).JoystickPressed;
			float unscaledTime = Time.unscaledTime;
			if (flag && !wasPressed)
			{
				pressStart = unscaledTime;
				longFired = false;
			}
			bool flag2 = false;
			if (ExtrasPlugin.HoldToRecalibrate.Value)
			{
				if (flag && !longFired && unscaledTime - pressStart >= ExtrasPlugin.HoldSeconds.Value)
				{
					longFired = true;
					flag2 = true;
				}
				else if (!flag && wasPressed && !longFired && !suppressMovement)
				{
					sitToggleRequested = true;
				}
			}
			else if (flag && !wasPressed && !suppressMovement)
			{
				sitToggleRequested = true;
			}
			wasPressed = flag;
			if (!flag2)
			{
				rightController.JoystickClickActive = 0;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void UpdatePostfix(VrControllerState rightController, bool suppressMovement)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			PlayerCharacter localPlayerCharacter = WorldManager.localPlayerCharacter;
			if ((Object)(object)localPlayerCharacter == (Object)null)
			{
				sitToggleRequested = false;
				return;
			}
			PlayerSitter sitter = localPlayerCharacter.sitter;
			bool flag = sitter != null && sitter.isSittingCorrected;
			if (suppressMovement)
			{
				sitToggleRequested = false;
				return;
			}
			if (ExtrasPlugin.StickClickSit.Value)
			{
				if (sitToggleRequested)
				{
					sitToggleRequested = false;
					virtualSit = !flag;
					virtualSitConfirmed = false;
					virtualSitTime = Time.unscaledTime;
					PulseRightHaptic();
				}
				if (virtualSit)
				{
					if (flag)
					{
						virtualSitConfirmed = true;
					}
					else if (virtualSitConfirmed || Time.unscaledTime - virtualSitTime > 2f)
					{
						virtualSit = false;
					}
				}
				VrLocomotion.sitInputPressed = (VrLocomotion.physicalSitActive || virtualSit) != flag;
			}
			int value = ExtrasPlugin.VirtualCrouchMode.Value;
			if (value != 0)
			{
				bool flag2 = ((VrControllerState)(ref rightController)).StateIsValid && ((VrControllerState)(ref rightController)).Joystick.y < 0f - Mathf.Clamp(ExtrasPlugin.VirtualCrouchThreshold.Value, 0.2f, 0.95f);
				bool flag3;
				if (value == 2)
				{
					if (flag2 && !lastStickBack)
					{
						toggleCrouch = !toggleCrouch;
					}
					if (VrLocomotion.jumpPressedThisFrame)
					{
						toggleCrouch = false;
					}
					flag3 = toggleCrouch;
				}
				else
				{
					toggleCrouch = false;
					flag3 = flag2;
				}
				lastStickBack = flag2;
				virtualCrouchActive = flag3;
				bool num = VrLocomotion.crouchPressed || flag3;
				VrLocomotion.crouchPressedThisFrame = num && !lastCrouchPressed;
				VrLocomotion.crouchPressed = num;
				lastCrouchPressed = num;
			}
			else
			{
				toggleCrouch = false;
				lastStickBack = false;
				virtualCrouchActive = false;
				lastCrouchPressed = VrLocomotion.crouchPressed;
			}
			crouchCameraBlend = Mathf.MoveTowards(crouchCameraBlend, virtualCrouchActive ? 1f : 0f, Time.unscaledDeltaTime / 0.2f);
			if (ExtrasPlugin.AutoSprint.Value && !flag && ((Vector2)(ref VrLocomotion.joystickMoveInput)).sqrMagnitude > 0f)
			{
				VrLocomotion.sprintEnabled = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("get_TrackingOrigin")]
		private static void TrackingOriginPostfix(ref Vector3 __result)
		{
			if (crouchCameraBlend > 0f)
			{
				__result.y += crouchCameraBlend * Mathf.Max(0f, ExtrasPlugin.VirtualCrouchCameraDrop.Value);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Reset")]
		private static void ResetPostfix()
		{
			wasPressed = false;
			longFired = false;
			sitToggleRequested = false;
			virtualSit = false;
			virtualSitConfirmed = false;
			lastCrouchPressed = false;
			lastStickBack = false;
			toggleCrouch = false;
			virtualCrouchActive = false;
			crouchCameraBlend = 0f;
		}

		private static void PulseRightHaptic()
		{
			try
			{
				VrRenderer renderer = BigWalkVrRuntime.renderer;
				if (renderer != null)
				{
					OpenVrClient openVr = renderer.openVr;
					if (openVr != null)
					{
						openVr.PulseRightHaptic();
					}
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(VrGrabbing))]
	internal static class GripTogglePatches
	{
		private enum HandState
		{
			Idle,
			Held,
			Masked
		}

		private sealed class Hand
		{
			public HandState State;

			public bool Armed;

			public bool SecondPress;

			public bool WasPressed;
		}

		private static readonly Hand left = new Hand();

		private static readonly Hand right = new Hand();

		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		private static void UpdatePrefix(VrGrabbing __instance, ref VrControllerState leftController, ref VrControllerState rightController)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between Unknown and I4
			if (!ExtrasPlugin.GripToggle.Value)
			{
				if (left.State != HandState.Idle || right.State != HandState.Idle)
				{
					ResetState();
				}
				return;
			}
			bool flag = (Object)(object)__instance.heldProp != (Object)null;
			TrackedControllerRole holdingHand = __instance.holdingHand;
			SyncHand(left, flag && (int)holdingHand == 1);
			SyncHand(right, flag && (int)holdingHand == 2);
			Apply(left, ref leftController);
			Apply(right, ref rightController);
		}

		private static void SyncHand(Hand hand, bool holdsProp)
		{
			if (holdsProp)
			{
				if (hand.State != HandState.Held)
				{
					hand.State = HandState.Held;
					hand.Armed = false;
					hand.SecondPress = false;
				}
			}
			else if (hand.State == HandState.Held)
			{
				hand.State = (hand.WasPressed ? HandState.Masked : HandState.Idle);
			}
		}

		private static void Apply(Hand hand, ref VrControllerState controller)
		{
			bool flag = ((VrControllerState)(ref controller)).StateIsValid && ((VrControllerState)(ref controller)).GripPressed;
			if (flag)
			{
				_ = !hand.WasPressed;
			}
			else
				_ = 0;
			hand.WasPressed = flag;
			switch (hand.State)
			{
			case HandState.Held:
				if (!flag && !hand.Armed)
				{
					hand.Armed = true;
				}
				if (flag && hand.Armed)
				{
					hand.SecondPress = true;
				}
				if (!flag && hand.SecondPress)
				{
					controller.GripActive = 0;
					hand.State = HandState.Idle;
					hand.Armed = false;
					hand.SecondPress = false;
				}
				else
				{
					controller.GripActive = 1;
				}
				break;
			case HandState.Masked:
				controller.GripActive = 0;
				if (!flag)
				{
					hand.State = HandState.Idle;
				}
				break;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Reset")]
		private static void ResetPostfix()
		{
			ResetState();
		}

		private static void ResetState()
		{
			left.State = HandState.Idle;
			left.Armed = false;
			left.SecondPress = false;
			left.WasPressed = false;
			right.State = HandState.Idle;
			right.Armed = false;
			right.SecondPress = false;
			right.WasPressed = false;
		}
	}
	internal sealed class ExtraRow
	{
		public int TypeId;

		public string Title;

		public string Label0;

		public string Label1;

		public string Label2;

		public Func<int> Get;

		public Action<int> Set;

		public int Count
		{
			get
			{
				if (Label2 != null)
				{
					return 3;
				}
				return 2;
			}
		}

		public string RowName => "BigWalkVR " + Title;
	}
	internal static class ExtraRows
	{
		internal static readonly ExtraRow[] All = new ExtraRow[3]
		{
			new ExtraRow
			{
				TypeId = 121,
				Title = "AUTO SPRINT",
				Label0 = "OFF",
				Label1 = "ON",
				Get = () => ExtrasPlugin.AutoSprint.Value ? 1 : 0,
				Set = delegate(int v)
				{
					ExtrasPlugin.AutoSprint.Value = v != 0;
				}
			},
			new ExtraRow
			{
				TypeId = 122,
				Title = "GRIP MODE",
				Label0 = "HOLD",
				Label1 = "TOGGLE",
				Get = () => ExtrasPlugin.GripToggle.Value ? 1 : 0,
				Set = delegate(int v)
				{
					ExtrasPlugin.GripToggle.Value = v != 0;
				}
			},
			new ExtraRow
			{
				TypeId = 123,
				Title = "VIRTUAL CROUCH",
				Label0 = "OFF",
				Label1 = "HOLD",
				Label2 = "TOGGLE",
				Get = () => Mathf.Clamp(ExtrasPlugin.VirtualCrouchMode.Value, 0, 2),
				Set = delegate(int v)
				{
					ExtrasPlugin.VirtualCrouchMode.Value = v;
				}
			}
		};

		internal static ExtraRow Def(SettingsRow row)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			if ((Object)(object)row == (Object)null)
			{
				return null;
			}
			int num = (int)row.settingsType;
			ExtraRow[] all = All;
			foreach (ExtraRow extraRow in all)
			{
				if (extraRow.TypeId == num)
				{
					return extraRow;
				}
			}
			return null;
		}

		internal static bool IsOurs(SettingsRow row)
		{
			return Def(row) != null;
		}

		internal static void Refresh(SettingsRow row)
		{
			ExtraRow extraRow = Def(row);
			if (extraRow != null)
			{
				int num = extraRow.Get.Invoke();
				row.SetUnderlineSingle(row.label0, num == 0);
				row.SetUnderlineSingle(row.label1, num == 1);
				if (extraRow.Count == 3 && (Object)(object)row.label2 != (Object)null)
				{
					row.SetUnderlineSingle(row.label2, num == 2);
				}
			}
		}

		internal static void Set(SettingsRow row, int value)
		{
			ExtraRow extraRow = Def(row);
			if (extraRow != null)
			{
				value = Mathf.Clamp(value, 0, extraRow.Count - 1);
				if (extraRow.Get.Invoke() != value)
				{
					extraRow.Set.Invoke(value);
					((ConfigEntryBase)ExtrasPlugin.AutoSprint).ConfigFile.Save();
				}
				Refresh(row);
			}
		}

		internal static void Cycle(SettingsRow row, int delta)
		{
			ExtraRow extraRow = Def(row);
			if (extraRow != null)
			{
				int count = extraRow.Count;
				Set(row, ((extraRow.Get.Invoke() + delta) % count + count) % count);
			}
		}

		internal static SettingsRow Find(SettingsCatagory category, ExtraRow def)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			if ((Object)(object)category == (Object)null)
			{
				return null;
			}
			System.Collections.Generic.IEnumerator<SettingsRow> enumerator = ((Component)category).GetComponentsInChildren<SettingsRow>(true).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator).MoveNext())
				{
					SettingsRow current = enumerator.Current;
					if ((Object)(object)current != (Object)null && (int)current.settingsType == def.TypeId)
					{
						return current;
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator)?.Dispose();
			}
			return null;
		}

		internal static int CreateAll(SettingsCatagory category)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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)
			SettingsRow val = null;
			SettingsRow val2 = null;
			System.Collections.Generic.IEnumerator<SettingsRow> enumerator = ((Component)category).GetComponentsInChildren<SettingsRow>(true).GetEnumerator();
			try
			{
				while (((System.Collections.IEnumerator)enumerator).MoveNext())
				{
					SettingsRow current = enumerator.Current;
					if ((int)current.settingsType == 101)
					{
						val = current;
					}
					if ((int)current.settingsType == 104)
					{
						val2 = current;
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator)?.Dispose();
			}
			if ((Object)(object)val == (Object)null)
			{
				ExtrasPlugin.Logger.LogWarning((object)"TURN MODE row not found; extra rows not added.");
				return 0;
			}
			int num = 0;
			ExtraRow[] all = All;
			foreach (ExtraRow extraRow in all)
			{
				if ((Object)(object)Find(category, extraRow) != (Object)null)
				{
					num++;
					continue;
				}
				SettingsRow val3 = ((extraRow.Count == 3 && (Object)(object)val2 != (Object)null) ? val2 : val);
				GameObject obj = Object.Instantiate<GameObject>(((Component)val3).gameObject, ((Component)val3).transform.parent, false);
				((Object)obj).name = extraRow.RowName;
				obj.transform.localPosition = ((Component)val3).transform.localPosition;
				obj.transform.localRotation = ((Component)val3).transform.localRotation;
				obj.transform.localScale = ((Component)val3).transform.localScale;
				obj.transform.SetAsLastSibling();
				SettingsRow component = obj.GetComponent<SettingsRow>();
				component.settingsType = (SettingsType)extraRow.TypeId;
				VrSettingsMenu.SetText(obj, "Title", extraRow.Title);
				if (extraRow.Count == 3)
				{
					if ((Object)(object)component.label2 != (Object)null)
					{
						((Component)component.label2).gameObject.SetActive(true);
					}
					VrSettingsMenu.ConfigureTernaryModeRow(component, extraRow.Label0, extraRow.Label1, extraRow.Label2);
				}
				else
				{
					VrSettingsMenu.ConfigureBinaryModeRow(component, extraRow.Label0, extraRow.Label1);
				}
				obj.SetActive(true);
				Refresh(component);
				num++;
			}
			return num;
		}

		internal static void Link(SettingsCatagory category)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			List<SettingsRow> val = new List<SettingsRow>();
			ExtraRow[] all = All;
			foreach (ExtraRow def in all)
			{
				SettingsRow val2 = Find(category, def);
				if ((Object)(object)val2 != (Object)null)
				{
					val.Add(val2);
				}
			}
			if (val.Count == 0)
			{
				return;
			}
			Il2CppReferenceArray<SettingsRow> rows = category.rows;
			List<SettingsRow> val3 = new List<SettingsRow>();
			if (rows != null)
			{
				System.Collections.Generic.IEnumerator<SettingsRow> enumerator = ((Il2CppArrayBase<SettingsRow>)(object)rows).GetEnumerator();
				try
				{
					while (((System.Collections.IEnumerator)enumerator).MoveNext())
					{
						SettingsRow current = enumerator.Current;
						if ((Object)(object)current != (Object)null && !IsOurs(current))
						{
							val3.Add(current);
						}
					}
				}
				finally
				{
					((System.IDisposable)enumerator)?.Dispose();
				}
			}
			if (val3.Count >= 2)
			{
				Transform transform = ((Component)val3[val3.Count - 1]).transform;
				Transform transform2 = ((Component)val3[val3.Count - 2]).transform;
				Vector3 val4 = transform.localPosition - transform2.localPosition;
				for (int j = 0; j < val.Count; j++)
				{
					((Component)val[j]).transform.localPosition = transform.localPosition + val4 * (float)(j + 1);
				}
			}
			val3.AddRange((System.Collections.Generic.IEnumerable<SettingsRow>)val);
			category.rows = new Il2CppReferenceArray<SettingsRow>(val3.ToArray());
			for (int k = 0; k < val3.Count; k++)
			{
				val3[k].SetNavigation((k > 0) ? val3[k - 1] : null, (k < val3.Count - 1) ? val3[k + 1] : null);
			}
		}
	}
	[HarmonyPatch(typeof(VrSettingsMenu))]
	internal static class SettingsMenuPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("AddVrCategory")]
		private static void AddVrCategoryPostfix(SettingsMenu menu)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			try
			{
				Transform parent = ((Component)menu.catagoryGraphics).transform.parent;
				SettingsCatagory val = null;
				for (int i = 0; i < parent.childCount; i++)
				{
					Transform child = parent.GetChild(i);
					if (((Object)child).name == "BigWalkVR Settings")
					{
						SettingsCatagory component = ((Component)child).GetComponent<SettingsCatagory>();
						if ((Object)(object)component != (Object)null)
						{
							val = component;
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					ExtrasPlugin.Logger.LogWarning((object)"BigWalkVR Settings category not found.");
					return;
				}
				int num = ExtraRows.CreateAll(val);
				if (num > 0)
				{
					ExtraRows.Link(val);
					ManualLogSource logger = ExtrasPlugin.Logger;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(89, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Added ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" extra row(s) (AUTO SPRINT, GRIP MODE, VIRTUAL CROUCH) to the Big Walk VR settings.");
					}
					logger.LogInfo(val2);
				}
			}
			catch (System.Exception ex)
			{
				ExtrasPlugin.Logger.LogError((object)("Failed to add extra settings rows: " + (object)ex));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("RefreshCameraRows")]
		private static void RefreshCameraRowsPostfix(CameraRowSet rows)
		{
			try
			{
				if ((Object)(object)rows?.Category != (Object)null)
				{
					ExtraRows.Link(rows.Category);
				}
			}
			catch (System.Exception ex)
			{
				ExtrasPlugin.Logger.LogError((object)("Failed to relink extra settings rows: " + (object)ex));
			}
		}
	}
	[HarmonyPatch(typeof(SettingsRow))]
	[HarmonyPriority(600)]
	internal static class SettingsRowPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		private static bool Start(SettingsRow __instance)
		{
			if (!ExtraRows.IsOurs(__instance))
			{
				return true;
			}
			__instance.settingsMenu = ((Component)__instance).GetComponentInParent<SettingsMenu>(true);
			ExtraRows.Refresh(__instance);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnEnable")]
		private static bool OnEnable(SettingsRow __instance)
		{
			if (!ExtraRows.IsOurs(__instance))
			{
				return true;
			}
			ExtraRows.Refresh(__instance);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Refresh")]
		private static bool Refresh(SettingsRow __instance)
		{
			if (!ExtraRows.IsOurs(__instance))
			{
				return true;
			}
			ExtraRows.Refresh(__instance);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("ActionCycle")]
		private static bool ActionCycle(SettingsRow __instance, int delta)
		{
			if (!ExtraRows.IsOurs(__instance))
			{
				return true;
			}
			ExtraRows.Cycle(__instance, (delta == 0) ? 1 : delta);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("ActionSelect")]
		private static bool ActionSelect(SettingsRow __instance, int valueIndex)
		{
			if (!ExtraRows.IsOurs(__instance))
			{
				return true;
			}
			ExtraRows.Set(__instance, valueIndex);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("ActionNavigate")]
		private static bool ActionNavigate(SettingsRow __instance)
		{
			return !ExtraRows.IsOurs(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("ActionSetFromSlider")]
		private static bool ActionSetFromSlider(SettingsRow __instance)
		{
			return !ExtraRows.IsOurs(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("ActionBack")]
		private static bool ActionBack(SettingsRow __instance)
		{
			if (!ExtraRows.IsOurs(__instance))
			{
				return true;
			}
			SettingsMenu settingsMenu = __instance.settingsMenu;
			if (settingsMenu != null)
			{
				settingsMenu.GoBackFromCatagory();
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class IgnoresAccessChecksToAttribute : System.Attribute
	{
		[field: CompilerGenerated]
		public string AssemblyName
		{
			[CompilerGenerated]
			get;
		}

		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
			AssemblyName = assemblyName;
		}
	}
}