Decompiled source of Void Crew VR UI Fix v3.14.1

plugins/VoidCrewVRUIFix.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CG.Client;
using HarmonyLib;
using UI;
using UI.Core;
using UI.Core.Audio;
using UI.Settings;
using Unity.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Experimental.Rendering;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.UIElements;
using UnityEngine.Video;
using UnityEngine.XR;
using Valve.VR;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Void Crew VR UI Fix")]
[assembly: AssemblyDescription("BepInEx plugin that fixes the UI of Void Crew when played in VR with UUVR")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Atlas Playbook v0.5.0")]
[assembly: AssemblyProduct("VoidCrewVRUIFix")]
[assembly: AssemblyCopyright("Copyright © Atlas Playbook v0.5.0 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f67e7b4f-8569-4360-9b28-23e6b320f49b")]
[assembly: AssemblyFileVersion("3.14.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("3.14.1.0")]
namespace VoidCrewVRUIFix;

internal sealed class CanvasMover
{
	private readonly List<Canvas> _moved = new List<Canvas>();

	private readonly HashSet<string> _reportedNames = new HashSet<string>();

	private readonly List<string> _newlyReported = new List<string>();

	public int MovedCount => _moved.Count;

	public void Scan()
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Invalid comparison between Unknown and I4
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (!Settings.MoveCameraCanvasesToPanel.Value)
		{
			return;
		}
		_moved.RemoveAll((Canvas c) => (Object)(object)c == (Object)null);
		Canvas[] array = Object.FindObjectsOfType<Canvas>();
		foreach (Canvas val in array)
		{
			if (!val.isRootCanvas || (int)val.renderMode != 1)
			{
				continue;
			}
			Camera worldCamera = val.worldCamera;
			if (!((Object)(object)worldCamera != (Object)null) || (!((Object)(object)worldCamera.targetTexture != (Object)null) && (int)worldCamera.stereoTargetEye != 0))
			{
				val.renderMode = (RenderMode)0;
				_moved.Add(val);
				if (_reportedNames.Add(((Object)val).name))
				{
					_newlyReported.Add(((Object)val).name);
				}
				else
				{
					Log.Verbose("Moved canvas '" + ((Object)val).name + "' onto the VR UI panel again.");
				}
			}
		}
		if (_newlyReported.Count > 0)
		{
			Log.Info("Moved " + _newlyReported.Count + " camera-space canvas(es) onto the VR UI panel: " + string.Join(", ", _newlyReported.ToArray()));
			_newlyReported.Clear();
		}
	}

	public void RestoreAll()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		foreach (Canvas item in _moved)
		{
			if ((Object)(object)item != (Object)null && (int)item.renderMode == 0)
			{
				item.renderMode = (RenderMode)1;
			}
		}
		_moved.Clear();
	}
}
internal sealed class CursorOverlay
{
	private readonly Canvas _canvas;

	private readonly RawImage _image;

	private readonly RectTransform _rect;

	private Texture _texture;

	private bool _usingGameTexture;

	public bool Visible => ((Behaviour)_canvas).enabled;

	public CursorOverlay(Transform parent)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("VoidCrewVRUIFix_Cursor");
		val.transform.SetParent(parent, false);
		_canvas = val.AddComponent<Canvas>();
		_canvas.renderMode = (RenderMode)0;
		_canvas.sortingOrder = 32767;
		((Behaviour)_canvas).enabled = false;
		GameObject val2 = new GameObject("Cursor", new Type[1] { typeof(RectTransform) });
		val2.transform.SetParent(val.transform, false);
		_image = val2.AddComponent<RawImage>();
		((Graphic)_image).raycastTarget = false;
		_rect = (RectTransform)val2.transform;
		_rect.anchorMin = Vector2.zero;
		_rect.anchorMax = Vector2.zero;
		_rect.pivot = new Vector2(0f, 1f);
	}

	public string Describe()
	{
		return string.Format("visible {0}, texture {1}", Visible, ((Object)(object)_texture == (Object)null) ? "none" : ((_usingGameTexture ? "game cursor " : "built-in arrow ") + _texture.width + "x" + _texture.height));
	}

	public void Update(bool show)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		Mouse current = Mouse.current;
		if (show && current != null)
		{
			EnsureTexture();
			float value = Settings.CursorScale.Value;
			_rect.anchoredPosition = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
			_rect.sizeDelta = new Vector2((float)_texture.width * value, (float)_texture.height * value);
		}
		else
		{
			show = false;
		}
		if (((Behaviour)_canvas).enabled != show)
		{
			((Behaviour)_canvas).enabled = show;
		}
	}

	private void EnsureTexture()
	{
		if (!_usingGameTexture || !((Object)(object)_texture != (Object)null))
		{
			Texture2D gameCursorTexture = GamePatches.GameCursorTexture;
			if ((Object)(object)gameCursorTexture != (Object)null)
			{
				_texture = (Texture)(object)gameCursorTexture;
				_usingGameTexture = true;
				_image.texture = (Texture)(object)gameCursorTexture;
				Log.Verbose("VR cursor is using the game's cursor image (" + ((Texture)gameCursorTexture).width + "x" + ((Texture)gameCursorTexture).height + ").");
			}
			else if ((Object)(object)_texture == (Object)null)
			{
				_texture = (Texture)(object)CreateArrowTexture();
				_image.texture = _texture;
				Log.Verbose("Game cursor image not available yet; using the built-in arrow.");
			}
		}
	}

	private static Texture2D CreateArrowTexture()
	{
		//IL_0012: 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_0028: 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_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: 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)
		//IL_006a: 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_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_0096: 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_00a7: 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_00b7: 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)
		//IL_00c7: Expected O, but got Unknown
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		Vector2[] polygon = (Vector2[])(object)new Vector2[7]
		{
			new Vector2(1f, 1f),
			new Vector2(1f, 23f),
			new Vector2(7f, 17f),
			new Vector2(11f, 27f),
			new Vector2(15f, 25f),
			new Vector2(11f, 16f),
			new Vector2(19f, 16f)
		};
		Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false)
		{
			name = "VoidCrewVRUIFix Cursor",
			hideFlags = (HideFlags)61,
			filterMode = (FilterMode)1
		};
		Color32[] array = (Color32[])(object)new Color32[1024];
		Color32 val2 = default(Color32);
		for (int i = 0; i < 32; i++)
		{
			for (int j = 0; j < 32; j++)
			{
				((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
				if (Inside(polygon, (float)j + 0.5f, (float)i + 0.5f))
				{
					((Color32)(ref val2))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
				}
				else if (NearInside(polygon, (float)j + 0.5f, (float)i + 0.5f))
				{
					((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, byte.MaxValue);
				}
				array[(31 - i) * 32 + j] = val2;
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		return val;
	}

	private static bool NearInside(Vector2[] polygon, float x, float y)
	{
		for (int i = -1; i <= 1; i++)
		{
			for (int j = -1; j <= 1; j++)
			{
				if (Inside(polygon, x + (float)j, y + (float)i))
				{
					return true;
				}
			}
		}
		return false;
	}

	private static bool Inside(Vector2[] polygon, float x, float y)
	{
		//IL_000e: 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_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_004a: 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_0059: Unknown result type (might be due to invalid IL or missing references)
		bool flag = false;
		int num = 0;
		int num2 = polygon.Length - 1;
		while (num < polygon.Length)
		{
			Vector2 val = polygon[num];
			Vector2 val2 = polygon[num2];
			if (val.y > y != val2.y > y && x < (val2.x - val.x) * (y - val.y) / (val2.y - val.y) + val.x)
			{
				flag = !flag;
			}
			num2 = num++;
		}
		return flag;
	}
}
internal sealed class DesktopView
{
	private static readonly List<XRDisplaySubsystem> Displays = new List<XRDisplaySubsystem>();

	private readonly CommandBuffer _commands = new CommandBuffer
	{
		name = "VoidCrewVRUIFix desktop view"
	};

	private RenderTexture _frame;

	private Material _uiMaterial;

	private Mesh _quad;

	private Rect _uiRect = new Rect(0f, 0f, 1f, 1f);

	private bool _sceneReady;

	private bool _sceneDrawn;

	private Material _fillMaterial;

	private readonly List<Material> _layerMaterials = new List<Material>();

	public Color Fill;

	public bool UiInSceneImage;

	public int LastDrawnFrame { get; private set; } = -1;

	public string Problem { get; private set; }

	public float ViewWidthDegrees { get; private set; }

	public float ViewAimDegrees { get; private set; }

	public string Describe()
	{
		return string.Format("mode {0}, last drawn frame {1}, view {2:0}° wide aimed {3:0.0}° up, UI area x {4:0.00}-{5:0.00} y {6:0.00}-{7:0.00}{8}", Settings.DesktopView.Value, LastDrawnFrame, ViewWidthDegrees, ViewAimDegrees, ((Rect)(ref _uiRect)).xMin, ((Rect)(ref _uiRect)).xMax, ((Rect)(ref _uiRect)).yMin, ((Rect)(ref _uiRect)).yMax, (Problem != null) ? (", problem: " + Problem) : "");
	}

	public void DrawScene(ScriptableRenderContext context, Camera camera)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if (EnsureFrame())
		{
			_commands.Clear();
			_uiRect = new Rect(0f, 0f, 1f, 1f);
			if (!(_sceneDrawn = Settings.DesktopView.Value == DesktopViewMode.PanelView && TryAddEyeImage(camera)))
			{
				_commands.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)_frame));
				_commands.ClearRenderTarget(false, true, Color.black);
			}
			((ScriptableRenderContext)(ref context)).ExecuteCommandBuffer(_commands);
			_commands.Clear();
			_sceneReady = true;
		}
	}

	public void Composite(CommandBuffer commands, RenderTexture ui, HudLayer[] layers)
	{
		//IL_005d: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: 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_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: 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_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: 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_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
		if (!_sceneReady || (Object)(object)_frame == (Object)null)
		{
			return;
		}
		_sceneReady = false;
		if ((Object)(object)_uiMaterial == (Object)null)
		{
			_uiMaterial = RenderUtil.CreateUiMaterial("VoidCrewVRUIFix Desktop UI");
		}
		if ((Object)(object)_quad == (Object)null)
		{
			_quad = RenderUtil.CreateQuad(flipped: false);
		}
		commands.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)_frame));
		commands.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.Ortho(0f, 1f, 0f, 1f, -1f, 1f));
		bool flag = UiInSceneImage && _sceneDrawn;
		if (Fill.a > 0.003f && !flag)
		{
			if ((Object)(object)_fillMaterial == (Object)null)
			{
				_fillMaterial = RenderUtil.CreateUiMaterial("VoidCrewVRUIFix Desktop Fill");
				_fillMaterial.mainTexture = (Texture)(object)Texture2D.whiteTexture;
			}
			_fillMaterial.color = Fill;
			commands.DrawMesh(_quad, Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0f), Quaternion.identity, Vector3.one), _fillMaterial, 0, 0);
		}
		if ((Object)(object)ui != (Object)null && !flag)
		{
			_uiMaterial.mainTexture = (Texture)(object)ui;
			commands.DrawMesh(_quad, Matrix4x4.TRS(new Vector3(((Rect)(ref _uiRect)).center.x, ((Rect)(ref _uiRect)).center.y, 0f), Quaternion.identity, new Vector3(((Rect)(ref _uiRect)).width, ((Rect)(ref _uiRect)).height, 1f)), _uiMaterial, 0, 0);
			int num = 0;
			Vector2 val2 = default(Vector2);
			while (layers != null && num < layers.Length)
			{
				HudLayer hudLayer = layers[num];
				if (hudLayer.Extracting && !((Object)(object)hudLayer.CopyTexture == (Object)null))
				{
					while (_layerMaterials.Count <= num)
					{
						_layerMaterials.Add(RenderUtil.CreateUiMaterial("VoidCrewVRUIFix Desktop HUD piece " + _layerMaterials.Count));
					}
					Material val = _layerMaterials[num];
					val.mainTexture = hudLayer.CopyTexture;
					Rect uvRect = hudLayer.UvRect;
					((Vector2)(ref val2))..ctor(((Rect)(ref _uiRect)).x + ((Rect)(ref uvRect)).center.x * ((Rect)(ref _uiRect)).width, ((Rect)(ref _uiRect)).y + ((Rect)(ref uvRect)).center.y * ((Rect)(ref _uiRect)).height);
					commands.DrawMesh(_quad, Matrix4x4.TRS(new Vector3(val2.x, val2.y, 0f), Quaternion.identity, new Vector3(((Rect)(ref uvRect)).width * ((Rect)(ref _uiRect)).width, ((Rect)(ref uvRect)).height * ((Rect)(ref _uiRect)).height, 1f)), val, 0, 0);
				}
				num++;
			}
		}
		commands.Blit((Texture)(object)_frame, new RenderTargetIdentifier(Display.main.colorBuffer, 0, (CubemapFace)(-1), 0));
		LastDrawnFrame = Time.frameCount;
	}

	public void Release()
	{
		if ((Object)(object)_frame != (Object)null)
		{
			_frame.Release();
			Object.Destroy((Object)(object)_frame);
			_frame = null;
		}
		if ((Object)(object)_uiMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)_uiMaterial);
		}
		if ((Object)(object)_fillMaterial != (Object)null)
		{
			Object.Destroy((Object)(object)_fillMaterial);
		}
		foreach (Material layerMaterial in _layerMaterials)
		{
			Object.Destroy((Object)(object)layerMaterial);
		}
		_layerMaterials.Clear();
		if ((Object)(object)_quad != (Object)null)
		{
			Object.Destroy((Object)(object)_quad);
		}
		_uiMaterial = null;
		_fillMaterial = null;
		_quad = null;
	}

	private bool TryAddEyeImage(Camera camera)
	{
		//IL_005d: 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)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: 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_0088: 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_00a4: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: 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_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
		XRDisplaySubsystem runningDisplay = GetRunningDisplay();
		if (runningDisplay == null)
		{
			Problem = "no running VR display";
			return false;
		}
		int renderPassCount = runningDisplay.GetRenderPassCount();
		if (renderPassCount == 0)
		{
			Problem = "the VR display has no render passes";
			return false;
		}
		XRRenderPass val = default(XRRenderPass);
		runningDisplay.GetRenderPass(renderPassCount - 1, ref val);
		int renderParameterCount = ((XRRenderPass)(ref val)).GetRenderParameterCount();
		if (renderParameterCount == 0)
		{
			Problem = "the VR render pass has no eye parameters";
			return false;
		}
		XRRenderParameter val2 = default(XRRenderParameter);
		((XRRenderPass)(ref val)).GetRenderParameter(camera, renderParameterCount - 1, ref val2);
		Matrix4x4 projection = val2.projection;
		float num = Mathf.Min((1f + projection.m02) / projection.m00, (1f - projection.m02) / projection.m00);
		float num2 = (1f + projection.m12) / projection.m11;
		float num3 = (1f - projection.m12) / projection.m11;
		float num4 = PanelLayout.HeightOffset / PanelLayout.Distance + Mathf.Tan(Mathf.Clamp(Settings.DesktopViewHeight.Value, -30f, 30f) * ((float)Math.PI / 180f));
		num4 = Mathf.Clamp(num4, -0.8f * num3, 0.8f * num2);
		float num5 = Mathf.Min(num2 - num4, num3 + num4);
		float num6 = (float)((Texture)_frame).width / (float)((Texture)_frame).height;
		float num7 = Mathf.Tan(Mathf.Clamp(Settings.DesktopViewWidth.Value, 30f, 170f) * 0.5f * ((float)Math.PI / 180f));
		float num8 = num7 / num6;
		float num9 = Mathf.Min(1f, Mathf.Min(num / num7, num5 / num8));
		num7 *= num9;
		num8 *= num9;
		ViewWidthDegrees = 2f * Mathf.Atan(num7) * 57.29578f;
		ViewAimDegrees = Mathf.Atan(num4) * 57.29578f;
		float num10 = 0.5f + 0.5f * (projection.m00 * (0f - num7) - projection.m02);
		float num11 = 0.5f + 0.5f * (projection.m00 * num7 - projection.m02);
		float num12 = 0.5f + 0.5f * (projection.m11 * (num4 - num8) - projection.m12);
		float num13 = 0.5f + 0.5f * (projection.m11 * (num4 + num8) - projection.m12);
		_commands.Blit(val.renderTarget, RenderTargetIdentifier.op_Implicit((Texture)(object)_frame), new Vector2(num11 - num10, num12 - num13), new Vector2(num10, 1f - num12), Mathf.Max(0, val2.textureArraySlice), 0);
		float num14 = (PanelLayout.HeightOffset / PanelLayout.Distance - num4) / num8;
		float num15 = PanelLayout.TanHalfWidth / num7;
		float num16 = PanelLayout.TanHalfHeight / num8;
		_uiRect = Rect.MinMaxRect(0.5f - 0.5f * num15, 0.5f + 0.5f * (num14 - num16), 0.5f + 0.5f * num15, 0.5f + 0.5f * (num14 + num16));
		Problem = null;
		return true;
	}

	private bool EnsureFrame()
	{
		//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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Expected O, but got Unknown
		int width = Screen.width;
		int height = Screen.height;
		if (width <= 0 || height <= 0)
		{
			return false;
		}
		if ((Object)(object)_frame != (Object)null && ((Texture)_frame).width == width && ((Texture)_frame).height == height && _frame.IsCreated())
		{
			return true;
		}
		if ((Object)(object)_frame != (Object)null)
		{
			_frame.Release();
			Object.Destroy((Object)(object)_frame);
		}
		_frame = new RenderTexture(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2)
		{
			name = "VoidCrewVRUIFix_Desktop",
			hideFlags = (HideFlags)61
		};
		_frame.Create();
		return true;
	}

	private static XRDisplaySubsystem GetRunningDisplay()
	{
		Displays.Clear();
		SubsystemManager.GetInstances<XRDisplaySubsystem>(Displays);
		foreach (XRDisplaySubsystem display in Displays)
		{
			if (((IntegratedSubsystem)display).running)
			{
				return display;
			}
		}
		return null;
	}
}
internal static class Diagnostics
{
	private static readonly List<RaycastResult> Hits = new List<RaycastResult>();

	private static Type _stateMachineType;

	private static PropertyInfo _currentStateProperty;

	private static Object _stateMachine;

	public static string SnapshotPath => Path.Combine(Path.Combine(Application.persistentDataPath, "VoidCrewVRUIFix"), "vr-ui-snapshot.png");

	public unsafe static void Write(VrUiRuntime runtime)
	{
		//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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_077a: Unknown result type (might be due to invalid IL or missing references)
		//IL_077f: Unknown result type (might be due to invalid IL or missing references)
		//IL_086e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0873: Unknown result type (might be due to invalid IL or missing references)
		//IL_08af: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a60: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a65: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ab3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ab8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b51: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b56: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dc9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d24: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d29: Unknown result type (might be due to invalid IL or missing references)
		StringBuilder stringBuilder = new StringBuilder(8192);
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("==================== Void Crew VR UI Fix diagnostics ====================");
		Section(stringBuilder, "Environment");
		Line(stringBuilder, "Plugin", "3.14.1 | Unity " + Application.unityVersion + " | " + ((object)SystemInfo.graphicsDeviceType/*cast due to .constrained prefix*/).ToString() + " | " + SystemInfo.graphicsDeviceName);
		Line(stringBuilder, "Window", Screen.width + "x" + Screen.height + " " + ((object)Screen.fullScreenMode/*cast due to .constrained prefix*/).ToString() + " | frame " + Time.frameCount + " | " + (1f / Mathf.Max(Time.smoothDeltaTime, 0.0001f)).ToString("0") + " FPS");
		Line(stringBuilder, "VR", "active " + XrState.IsActive + ", device '" + XrState.DeviceName + "', eye texture " + XRSettings.eyeTextureWidth + "x" + XRSettings.eyeTextureHeight + ", desktop shows VR view " + XRSettings.showDeviceView);
		Line(stringBuilder, "UUVR", UuvrCompat.Installed ? (UuvrCompat.Version + ", VR API " + UuvrCompat.VrApi + ", camera tracking " + UuvrCompat.CameraTracking + ", UUVR UI mode " + UuvrCompat.UiPatchMode + " | UI handling turned off " + UuvrCompat.DisabledUiManagers + "x, helper cameras disabled " + UuvrCompat.DisabledHelperCameras + " (" + UuvrCompat.Mode + ")") : "not installed");
		Line(stringBuilder, "Game state", GameStateName());
		Section(stringBuilder, "Performance");
		Line(stringBuilder, "Game", (1f / Mathf.Max(Time.smoothDeltaTime, 0.0001f)).ToString("0") + " FPS (" + (Time.smoothDeltaTime * 1000f).ToString("0.0") + " ms per frame) | VR render scale " + XRSettings.eyeTextureResolutionScale.ToString("0.00"));
		Line(stringBuilder, "Monitor sync", VrPerformance.DescribeMonitorSync());
		Line(stringBuilder, "FPS counter", Settings.ShowFpsCounter.Value ? ("on, last shown " + runtime.Fps.LastFps + " FPS") : "off");
		Line(stringBuilder, "Monitor picture", (runtime.PictureShown ? "on" : "off (window left black)") + " | setting " + (Settings.DesktopViewOn.Value ? "on" : "off") + ", hotkey " + ((object)Settings.KeyDesktopView.Value/*cast due to .constrained prefix*/).ToString() + ", headset " + HeadsetPresence.Describe() + (Settings.DesktopViewWhenHeadsetOff.Value ? " (picture comes back while it is off)" : ""));
		if (XrState.IsActive && XrState.IsOpenVr)
		{
			Line(stringBuilder, "SteamVR", SteamVrTimingReport());
		}
		Line(stringBuilder, "HDRP VR", VrPerformance.DescribeHdrpXr(runtime.MainCamera));
		Line(stringBuilder, "DLSS", Settings.DisableDlss.Value ? "removed from the options (VR tab > Allow DLSS is off)" : ("allowed, " + DlssEyes.Describe()));
		Section(stringBuilder, "VR UI");
		IUiDisplay display = runtime.Display;
		Line(stringBuilder, "Display", (display == null) ? "none (VR inactive or still starting)" : (display.Name + ": " + display.Status));
		Line(stringBuilder, "Panel", PanelLayout.Describe() + ", flipped " + Settings.FlipVertically.Value);
		UiCapture capture = runtime.Capture;
		Line(stringBuilder, "Capture", (((Object)(object)capture.Texture == (Object)null) ? "no texture" : ("texture " + ((Texture)capture.Texture).width + "x" + ((Texture)capture.Texture).height)) + ", last captured frame " + capture.LastCaptureFrame + ", total captures " + capture.CaptureCount + ", screen camera '" + (((Object)(object)capture.LastScreenCamera != (Object)null) ? ((Object)capture.LastScreenCamera).name : "none") + "', backdrop " + capture.BackdropOpacity.ToString("0.00"));
		Line(stringBuilder, "Player camera", ((Object)(object)runtime.MainCamera != (Object)null) ? Describe(runtime.MainCamera) : "none");
		HudLayer[] all = HudLayers.All;
		foreach (HudLayer hudLayer in all)
		{
			Line(stringBuilder, PieceName(hudLayer.Placement), hudLayer.Describe());
		}
		Line(stringBuilder, PieceName(Settings.FpsPlacement), (Settings.ShowFpsCounter.Value ? "on" : "off") + " | " + Settings.FpsPlacement.Describe());
		Line(stringBuilder, "Modify UI window", UiEditorWindow.AnyOpen ? "open" : "closed");
		Line(stringBuilder, "Turret aim", TurretAim.Describe());
		Line(stringBuilder, "Wheels", PingWheel.Describe() + " | dark layer behind wheels " + WheelBackdrop.Describe());
		Line(stringBuilder, "Aiming", (Settings.AimWithHead.Value ? "with your head" : "with the mouse") + " | aiming with the head now " + HeadAim.Aiming + ", UI screen follows the head now " + HeadAim.PanelFollowsHead + (HeadAim.InVehicleView ? ", turret or ship camera view (crosshair on the game camera's centre line)" : ""));
		Line(stringBuilder, "Player modes", PlayerModes.Describe() + " | turret screen border " + (Settings.HideTurretScreenBorder.Value ? "hidden in VR" : "shown (game default)"));
		Line(stringBuilder, "Cursor", runtime.Cursor.Describe() + " | game wants cursor " + Cursor.visible + ", lock " + ((object)Cursor.lockState/*cast due to .constrained prefix*/).ToString());
		Line(stringBuilder, "Desktop view", runtime.Desktop.Describe() + ", Unity mirror " + XRSettings.showDeviceView);
		Section(stringBuilder, "Input");
		Line(stringBuilder, "Game window focused", Application.isFocused + " (clicks only reach the game while its window is focused)");
		EventSystem current = EventSystem.current;
		Line(stringBuilder, "Event system", ((Object)(object)current == (Object)null) ? "none" : ("'" + ((Object)current).name + "' using " + (((Object)(object)current.currentInputModule != (Object)null) ? ((object)current.currentInputModule).GetType().Name : "no input module")));
		Line(stringBuilder, "Mouse position", (Mouse.current != null) ? ((object)((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue()/*cast due to .constrained prefix*/).ToString() : "no mouse");
		Line(stringBuilder, "uGUI/panels under mouse", DescribeUiUnderMouse(5));
		Line(stringBuilder, "UI Toolkit under mouse", DescribeUiToolkitUnderMouse());
		List<string> list = new List<string>();
		Enumerator<InputDevice> enumerator = InputSystem.devices.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				InputDevice current2 = enumerator.Current;
				list.Add(((InputControl)current2).displayName ?? ((InputControl)current2).name);
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
		Line(stringBuilder, "Input devices", string.Join(", ", list.ToArray()));
		Line(stringBuilder, "Canvases moved to panel", runtime.Canvases.MovedCount.ToString());
		Line(stringBuilder, "Intro video", IntroVideo.Describe());
		Line(stringBuilder, "Terminal screens", (Settings.KeepTerminalScreensInWorld.Value ? "kept on their terminals in VR" : "attached to the camera (game default)") + ", kept " + TerminalScreens.KeptInWorld + " time(s) this session" + (Settings.SnapUiToTerminalScreens.Value ? ", UI panel moves onto them" : "") + (PanelLayout.OnTerminalScreen ? " (it is on one now)" : ""));
		Line(stringBuilder, "Marker alignment", MarkerAlignment.Active ? ("on (camera '" + (((Object)(object)MarkerAlignment.PlayerCamera != (Object)null) ? ((Object)MarkerAlignment.PlayerCamera).name : "none") + "')") : "off");
		SupportedRenderingFeatures active = SupportedRenderingFeatures.active;
		Line(stringBuilder, "UI overlay owner", (active != null && active.rendersUIOverlay) ? "render pipeline" : "Unity (normal for VR)");
		Section(stringBuilder, "Cameras (enabled first)");
		Camera[] array = Resources.FindObjectsOfTypeAll<Camera>();
		Scene scene;
		foreach (Camera val in array)
		{
			scene = ((Component)val).gameObject.scene;
			if (((Scene)(ref scene)).IsValid() && ((Behaviour)val).isActiveAndEnabled)
			{
				Line(stringBuilder, " +", Describe(val));
			}
		}
		array = Resources.FindObjectsOfTypeAll<Camera>();
		foreach (Camera val2 in array)
		{
			scene = ((Component)val2).gameObject.scene;
			if (((Scene)(ref scene)).IsValid() && !((Behaviour)val2).isActiveAndEnabled)
			{
				Line(stringBuilder, " -", Describe(val2));
			}
		}
		Section(stringBuilder, "Canvases (root)");
		Canvas[] array2 = Object.FindObjectsOfType<Canvas>(true);
		foreach (Canvas val3 in array2)
		{
			if (val3.isRootCanvas)
			{
				Line(stringBuilder, ((Behaviour)val3).isActiveAndEnabled ? " +" : " -", PathOf(((Component)val3).transform) + " | " + ((object)val3.renderMode/*cast due to .constrained prefix*/).ToString() + " | order " + val3.sortingOrder + (((Object)(object)val3.worldCamera != (Object)null) ? (" | camera '" + ((Object)val3.worldCamera).name + "'") : ""));
			}
		}
		Section(stringBuilder, "UI Toolkit documents");
		UIDocument[] array3 = Object.FindObjectsOfType<UIDocument>(true);
		foreach (UIDocument val4 in array3)
		{
			PanelSettings panelSettings = val4.panelSettings;
			Line(stringBuilder, ((Behaviour)val4).isActiveAndEnabled ? " +" : " -", PathOf(((Component)val4).transform) + " | panel '" + (((Object)(object)panelSettings != (Object)null) ? ((Object)panelSettings).name : "none") + "'" + (((Object)(object)panelSettings != (Object)null) ? (" order " + panelSettings.sortingOrder + (((Object)(object)panelSettings.targetTexture != (Object)null) ? (" -> texture '" + ((Object)panelSettings.targetTexture).name + "'") : " -> screen")) : ""));
		}
		Section(stringBuilder, "Video players");
		VideoPlayer[] array4 = Object.FindObjectsOfType<VideoPlayer>(true);
		foreach (VideoPlayer val5 in array4)
		{
			Line(stringBuilder, ((Behaviour)val5).isActiveAndEnabled ? " +" : " -", PathOf(((Component)val5).transform) + " | " + ((object)val5.renderMode/*cast due to .constrained prefix*/).ToString() + " | playing " + val5.isPlaying + (((Object)(object)val5.targetCamera != (Object)null) ? (" | camera '" + ((Object)val5.targetCamera).name + "'") : ""));
		}
		Section(stringBuilder, "HDRP");
		RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
		HDRenderPipelineAsset val6 = (HDRenderPipelineAsset)(object)((currentRenderPipeline is HDRenderPipelineAsset) ? currentRenderPipeline : null);
		if ((Object)(object)val6 != (Object)null)
		{
			RenderPipelineSettings currentPlatformRenderPipelineSettings = val6.currentPlatformRenderPipelineSettings;
			Line(stringBuilder, "Asset", ((Object)val6).name + ", colour buffer " + ((object)(*(ColorBufferFormat*)(&currentPlatformRenderPipelineSettings.colorBufferFormat))/*cast due to .constrained prefix*/).ToString() + ", custom passes " + currentPlatformRenderPipelineSettings.supportCustomPass + ", dynamic resolution " + currentPlatformRenderPipelineSettings.dynamicResolutionSettings.enabled + ", DLSS hardware " + HDDynamicResolutionPlatformCapabilities.DLSSDetected);
		}
		else
		{
			Line(stringBuilder, "Asset", ((Object)(object)GraphicsSettings.currentRenderPipeline != (Object)null) ? ((object)GraphicsSettings.currentRenderPipeline).GetType().Name : "none");
		}
		Section(stringBuilder, "Recent warnings and errors");
		bool flag = false;
		foreach (string recentProblem in Log.RecentProblems)
		{
			stringBuilder.AppendLine("  " + recentProblem);
			flag = true;
		}
		foreach (KeyValuePair<string, int> failureTotal in Log.FailureTotals)
		{
			stringBuilder.AppendLine("  " + failureTotal.Key + ": failed " + failureTotal.Value + " time(s)");
			flag = true;
		}
		if (!flag)
		{
			stringBuilder.AppendLine("  none");
		}
		stringBuilder.Append("==================== end of diagnostics ====================");
		Log.Info(stringBuilder.ToString());
		SaveSnapshot(capture.Texture, capture.BackdropOpacity);
	}

	private static string PieceName(LayerPlacement placement)
	{
		string text = placement.Title.ToLowerInvariant().Replace("hud", "HUD").Replace("fps", "FPS");
		return char.ToUpperInvariant(text[0]) + text.Substring(1);
	}

	private static void SaveSnapshot(RenderTexture texture, float backdrop)
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)texture == (Object)null)
		{
			Log.Info("No VR UI texture exists yet, so no snapshot was saved.");
			return;
		}
		if (!SystemInfo.supportsAsyncGPUReadback)
		{
			Log.Info("This system can't read textures back from the GPU, so no snapshot was saved.");
			return;
		}
		int width = ((Texture)texture).width;
		int height = ((Texture)texture).height;
		byte backdropAlpha = (byte)Mathf.RoundToInt(Mathf.Clamp01(backdrop) * 255f);
		AsyncGPUReadback.Request((Texture)(object)texture, 0, (TextureFormat)4, (Action<AsyncGPUReadbackRequest>)delegate(AsyncGPUReadbackRequest request)
		{
			//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_0059: 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_005f: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0078: Expected O, but got Unknown
			try
			{
				if (((AsyncGPUReadbackRequest)(ref request)).hasError)
				{
					Log.Warn("Reading the VR UI texture back from the GPU failed, so no snapshot was saved.");
				}
				else
				{
					NativeArray<byte> data = ((AsyncGPUReadbackRequest)(ref request)).GetData<byte>(0);
					int num = 0;
					for (int i = 3; i < data.Length; i += 4)
					{
						if (data[i] > backdropAlpha + 8)
						{
							num++;
						}
					}
					Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
					val.LoadRawTextureData<byte>(data);
					val.Apply(false);
					byte[] bytes = ImageConversion.EncodeToPNG(val);
					Object.Destroy((Object)val);
					Directory.CreateDirectory(Path.GetDirectoryName(SnapshotPath));
					File.WriteAllBytes(SnapshotPath, bytes);
					Log.Info($"Saved the VR UI snapshot ({100.0 * (double)num / (double)Math.Max(1, width * height):0.0}% of pixels contain UI) to {SnapshotPath}");
				}
			}
			catch (Exception e)
			{
				Log.Failure("Saving the VR UI snapshot", e);
			}
		});
	}

	public static string DescribeUiUnderMouse(int max)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_003c: Expected O, but got Unknown
		//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_00cf: 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)
		EventSystem current = EventSystem.current;
		Mouse current2 = Mouse.current;
		if ((Object)(object)current == (Object)null)
		{
			return "no event system";
		}
		if (current2 == null)
		{
			return "no mouse";
		}
		PointerEventData val = new PointerEventData(current)
		{
			position = ((InputControl<Vector2>)(object)((Pointer)current2).position).ReadValue()
		};
		Hits.Clear();
		current.RaycastAll(val, Hits);
		if (Hits.Count == 0)
		{
			return "nothing";
		}
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < Hits.Count && i < max; i++)
		{
			RaycastResult val2 = Hits[i];
			if (i > 0)
			{
				stringBuilder.Append(" > ");
			}
			stringBuilder.Append('\'').Append(((Object)(object)((RaycastResult)(ref val2)).gameObject != (Object)null) ? PathOf(((RaycastResult)(ref val2)).gameObject.transform) : "?").Append("' (")
				.Append(((Object)(object)val2.module != (Object)null) ? ((object)val2.module).GetType().Name : "?")
				.Append(')');
		}
		if (Hits.Count > max)
		{
			stringBuilder.Append(" and ").Append(Hits.Count - max).Append(" more");
		}
		return stringBuilder.ToString();
	}

	private static string DescribeUiToolkitUnderMouse()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: 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_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0078: Unknown result type (might be due to invalid IL or missing references)
		Mouse current = Mouse.current;
		if (current == null)
		{
			return "no mouse";
		}
		Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
		List<string> list = new List<string>();
		UIDocument[] array = Object.FindObjectsOfType<UIDocument>();
		foreach (UIDocument val2 in array)
		{
			VisualElement rootVisualElement = val2.rootVisualElement;
			IPanel val3 = ((rootVisualElement != null) ? rootVisualElement.panel : null);
			if (val3 != null)
			{
				Vector2 val4 = RuntimePanelUtils.ScreenToPanel(val3, new Vector2(val.x, (float)Screen.height - val.y));
				VisualElement val5 = val3.Pick(val4);
				if (val5 != null && val5 != rootVisualElement)
				{
					list.Add(((Object)val2).name + ": " + ((object)val5).GetType().Name + (string.IsNullOrEmpty(val5.name) ? "" : (" '" + val5.name + "'")));
				}
			}
		}
		if (list.Count != 0)
		{
			return string.Join(" | ", list.ToArray());
		}
		return "nothing";
	}

	private static string Describe(Camera camera)
	{
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append(PathOf(((Component)camera).transform));
		stringBuilder.Append(" | depth ").Append(camera.depth);
		stringBuilder.Append(" | ").Append(((Object)(object)camera.targetTexture != (Object)null) ? ("texture '" + ((Object)camera.targetTexture).name + "' " + ((Texture)camera.targetTexture).width + "x" + ((Texture)camera.targetTexture).height) : "screen/headset");
		stringBuilder.Append(" | eyes ").Append(camera.stereoTargetEye);
		stringBuilder.Append(" | mask 0x").Append(camera.cullingMask.ToString("X8"));
		HDAdditionalCameraData component = ((Component)camera).GetComponent<HDAdditionalCameraData>();
		if ((Object)(object)component != (Object)null)
		{
			stringBuilder.Append(" | clear ").Append(component.clearColorMode);
			stringBuilder.Append(", AA ").Append(component.antialiasing);
			stringBuilder.Append(", DLSS ").Append(component.allowDeepLearningSuperSampling);
			stringBuilder.Append(", dyn-res ").Append(component.allowDynamicResolution);
		}
		MonoBehaviour[] components = ((Component)camera).GetComponents<MonoBehaviour>();
		foreach (MonoBehaviour val in components)
		{
			if ((Object)(object)val != (Object)null && ((object)val).GetType().Namespace != null && ((object)val).GetType().Namespace.StartsWith("Uuvr"))
			{
				stringBuilder.Append(" | UUVR ").Append(((object)val).GetType().Name);
			}
		}
		return stringBuilder.ToString();
	}

	private static string SteamVrTimingReport()
	{
		try
		{
			return SteamVrTiming.Describe();
		}
		catch (Exception ex)
		{
			return "unavailable (" + ex.GetType().Name + ": " + ex.Message + ")";
		}
	}

	private static string GameStateName()
	{
		try
		{
			if (_stateMachineType == null)
			{
				_stateMachineType = AccessTools.TypeByName("CG.GameLoopStateMachine.GameStateMachine");
				if (_stateMachineType == null)
				{
					return "unknown";
				}
				_currentStateProperty = AccessTools.Property(_stateMachineType, "CurrentState");
			}
			if (_stateMachine == (Object)null)
			{
				_stateMachine = Object.FindObjectOfType(_stateMachineType);
			}
			object obj = ((_stateMachine != (Object)null && _currentStateProperty != null) ? _currentStateProperty.GetValue(_stateMachine, null) : null);
			return (obj != null) ? obj.GetType().Name : "none";
		}
		catch (Exception ex)
		{
			return "unknown (" + ex.GetType().Name + ")";
		}
	}

	private static string PathOf(Transform transform)
	{
		string text = ((Object)transform).name;
		Transform parent = transform.parent;
		while ((Object)(object)parent != (Object)null)
		{
			text = ((Object)parent).name + "/" + text;
			parent = parent.parent;
		}
		return text;
	}

	private static void Section(StringBuilder report, string title)
	{
		report.AppendLine("--- " + title + " ---");
	}

	private static void Line(StringBuilder report, string label, string value)
	{
		report.Append("  ").Append(label).Append(": ")
			.AppendLine(value);
	}
}
internal static class DlssEyes
{
	private static Func<HDCamera, XRPass> _xrOf;

	private static Action<XRPass, int> _setPassId;

	private static FieldInfo _layout;

	private static readonly HashSet<int> Reported = new HashSet<int>();

	private static Camera _lastCamera;

	private static int _lastPassId;

	private static int _lastEye;

	private static Camera _runCamera;

	private static int _runFrame = -1;

	private static int _eyesThisFrame;

	private static int _eyesLastFrame;

	private static Vector2Int _renderSize;

	private static Vector2Int _outputSize;

	public static bool Active { get; private set; }

	public static int RenumberedPasses { get; private set; }

	public static bool RanWithin(int frames)
	{
		if ((Object)(object)_runCamera != (Object)null)
		{
			return Time.frameCount - _runFrame <= frames;
		}
		return false;
	}

	public static string Describe()
	{
		if (!Active)
		{
			return "eye fix off";
		}
		string text = (((Object)(object)_runCamera == (Object)null) ? "not running (choose DLSS under Graphics > Upscaling)" : ((Time.frameCount - _runFrame <= 2) ? ("running on '" + ((Object)_runCamera).name + "' for " + Mathf.Max(_eyesThisFrame, _eyesLastFrame) + " eyes per frame, rendering " + ((Vector2Int)(ref _renderSize)).x + "x" + ((Vector2Int)(ref _renderSize)).y + " per eye and upscaling to " + ((Vector2Int)(ref _outputSize)).x + "x" + ((Vector2Int)(ref _outputSize)).y) : ("not running now (last ran " + (Time.frameCount - _runFrame) + " frames ago on '" + ((Object)_runCamera).name + "')")));
		return text + "; eye fix on, " + RenumberedPasses + " eye passes renumbered" + (((Object)(object)_lastCamera != (Object)null) ? (" (last: '" + ((Object)_lastCamera).name + "' pass " + _lastPassId + " -> eye " + _lastEye + ")") : "");
	}

	public static string Resolve()
	{
		MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(HDCamera), "xr");
		MethodInfo methodInfo2 = AccessTools.PropertySetter(typeof(XRPass), "multipassId");
		_layout = AccessTools.Field(typeof(XRSystem), "s_Layout");
		if (methodInfo == null || methodInfo2 == null || _layout == null)
		{
			return "HDCamera.xr, XRPass.multipassId or XRSystem.s_Layout not found";
		}
		_xrOf = (Func<HDCamera, XRPass>)Delegate.CreateDelegate(typeof(Func<HDCamera, XRPass>), methodInfo);
		_setPassId = (Action<XRPass, int>)Delegate.CreateDelegate(typeof(Action<XRPass, int>), methodInfo2);
		Active = true;
		return null;
	}

	public static int UseEyeNumber(HDCamera hdCamera)
	{
		RecordRun(hdCamera);
		XRPass val = _xrOf(hdCamera);
		if (val == null || !val.enabled || val.singlePassEnabled)
		{
			return -1;
		}
		int multipassId = val.multipassId;
		int num = EyeNumber(hdCamera.camera, val);
		if (num < 0 || num > 1 || num == multipassId)
		{
			return -1;
		}
		_setPassId(val, num);
		RenumberedPasses++;
		_lastCamera = hdCamera.camera;
		_lastPassId = multipassId;
		_lastEye = num;
		if (Reported.Add(((Object)hdCamera.camera).GetInstanceID()))
		{
			Log.Info("DLSS in VR: other cameras are drawn before '" + ((Object)hdCamera.camera).name + "', so HDRP numbered its eye " + num + " as pass " + multipassId + ". DLSS now looks each eye up by its eye number, which stops its 'Index was out of range' errors.");
		}
		return multipassId;
	}

	private static void RecordRun(HDCamera hdCamera)
	{
		//IL_0054: 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)
		//IL_0068: 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 frameCount = Time.frameCount;
		if (frameCount != _runFrame)
		{
			_eyesLastFrame = ((_runFrame == frameCount - 1) ? _eyesThisFrame : 0);
			_eyesThisFrame = 0;
			_runFrame = frameCount;
		}
		_eyesThisFrame++;
		_runCamera = hdCamera.camera;
		_renderSize = new Vector2Int(hdCamera.actualWidth, hdCamera.actualHeight);
		DynamicResolutionHandler instance = DynamicResolutionHandler.instance;
		if (instance != null)
		{
			_outputSize = instance.finalViewport;
		}
	}

	public static void Restore(HDCamera hdCamera, int passId)
	{
		if (passId >= 0)
		{
			XRPass val = _xrOf(hdCamera);
			if (val != null)
			{
				_setPassId(val, passId);
			}
		}
	}

	private static int EyeNumber(Camera camera, XRPass pass)
	{
		object? value = _layout.GetValue(null);
		XRLayout val = (XRLayout)((value is XRLayout) ? value : null);
		if (val == null)
		{
			return -1;
		}
		List<(Camera, XRPass)> activePasses = val.GetActivePasses();
		int num = 0;
		for (int i = 0; i < activePasses.Count; i++)
		{
			if (!((Object)(object)activePasses[i].Item1 != (Object)(object)camera))
			{
				if (activePasses[i].Item2 == pass)
				{
					return num;
				}
				num++;
			}
		}
		return -1;
	}
}
internal sealed class FpsCounter
{
	public const float WidthAtOneMetre = 0.13f;

	private const float RefreshInterval = 0.5f;

	private const int MaxCharacters = 7;

	private const int Scale = 4;

	private const int Padding = 6;

	private const int TextureWidth = 176;

	private const int TextureHeight = 40;

	private static readonly Color32 Background = new Color32((byte)0, (byte)0, (byte)0, (byte)150);

	private static readonly Color32 Clear = new Color32((byte)0, (byte)0, (byte)0, (byte)0);

	private static readonly Color32 Green = new Color32((byte)90, (byte)230, (byte)90, byte.MaxValue);

	private static readonly Color32 Yellow = new Color32(byte.MaxValue, (byte)210, (byte)60, byte.MaxValue);

	private static readonly Color32 Red = new Color32(byte.MaxValue, (byte)80, (byte)70, byte.MaxValue);

	private static readonly Color32 White = new Color32((byte)240, (byte)240, (byte)240, byte.MaxValue);

	private static readonly List<XRDisplaySubsystem> Displays = new List<XRDisplaySubsystem>();

	private readonly Color32[] _pixels = (Color32[])(object)new Color32[7040];

	private Texture2D _texture;

	private bool _shown;

	private int _frames;

	private float _elapsed;

	private string _drawnText;

	private Color32 _drawnColour;

	public Texture Texture
	{
		get
		{
			if (!_shown)
			{
				return null;
			}
			return (Texture)(object)_texture;
		}
	}

	public static float Aspect => 5f / 22f;

	public int LastFps { get; private set; }

	public HeadLockedPicture Picture()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		LayerPlacement fpsPlacement = Settings.FpsPlacement;
		HeadLockedPicture result = new HeadLockedPicture
		{
			Texture = Texture,
			Alpha = fpsPlacement.Alpha
		};
		fpsPlacement.Place(out result.Position, out result.Rotation);
		float num = 0.13f * fpsPlacement.EffectiveDistance() * fpsPlacement.Scale;
		result.Size = new Vector2(num, num * Aspect);
		return result;
	}

	public void Update(bool enabled)
	{
		//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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		if (!enabled)
		{
			_shown = false;
			_frames = 0;
			_elapsed = 0f;
			return;
		}
		if ((Object)(object)_texture == (Object)null)
		{
			_texture = new Texture2D(176, 40, (TextureFormat)4, false, false)
			{
				name = "VoidCrewVRUIFix FPS counter",
				hideFlags = (HideFlags)61,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Draw("--", White);
		}
		_shown = true;
		_frames++;
		_elapsed += Time.unscaledDeltaTime;
		if (!(_elapsed < 0.5f))
		{
			int num = Mathf.Clamp(Mathf.RoundToInt((float)_frames / _elapsed), 0, 999);
			_frames = 0;
			_elapsed = 0f;
			LastFps = num;
			Draw(num.ToString(), ColourFor(num));
		}
	}

	public void Release()
	{
		if ((Object)(object)_texture != (Object)null)
		{
			Object.Destroy((Object)(object)_texture);
		}
		_texture = null;
		_shown = false;
	}

	private static Color32 ColourFor(int fps)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		float num = HeadsetRefreshRate();
		if (num <= 0f)
		{
			return White;
		}
		if ((float)fps >= 0.9f * num)
		{
			return Green;
		}
		if ((float)fps >= 0.45f * num)
		{
			return Yellow;
		}
		return Red;
	}

	private static float HeadsetRefreshRate()
	{
		Displays.Clear();
		SubsystemManager.GetInstances<XRDisplaySubsystem>(Displays);
		float num = default(float);
		foreach (XRDisplaySubsystem display in Displays)
		{
			if (((IntegratedSubsystem)display).running && display.TryGetDisplayRefreshRate(ref num) && num > 0f)
			{
				return num;
			}
		}
		return 0f;
	}

	private unsafe void Draw(string number, Color32 colour)
	{
		//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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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_009d: Unknown result type (might be due to invalid IL or missing references)
		string text = number + " FPS";
		if (text == _drawnText && ((object)(*(Color32*)(&colour))/*cast due to .constrained prefix*/).Equals((object?)_drawnColour))
		{
			return;
		}
		_drawnText = text;
		_drawnColour = colour;
		int num = PixelFont.Width(text, 4);
		int num2 = (176 - num) / 2;
		int num3 = Mathf.Max(0, num2 - 6);
		int num4 = Mathf.Min(176, num2 + num + 6);
		for (int i = 0; i < 40; i++)
		{
			for (int j = 0; j < 176; j++)
			{
				_pixels[i * 176 + j] = ((j >= num3 && j < num4) ? Background : Clear);
			}
		}
		PixelFont.Draw(_pixels, 176, 40, text, num2, 6, 4, colour);
		_texture.SetPixels32(_pixels);
		_texture.Apply(false, false);
	}
}
internal sealed class FullscreenFill
{
	private const int Columns = 16;

	private const int Rows = 9;

	private const float AlphaTolerance = 0.08f;

	private const float RequiredShare = 0.85f;

	private readonly List<Color32> _border = new List<Color32>(50);

	private readonly List<float> _sorted = new List<float>(50);

	private RenderTexture _samples;

	private bool _readbackPending;

	public Color Current { get; private set; } = Color.clear;

	public void Sample(CommandBuffer commands, RenderTexture ui)
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		if (!_readbackPending && !((Object)(object)ui == (Object)null) && SystemInfo.supportsAsyncGPUReadback)
		{
			if ((Object)(object)_samples == (Object)null)
			{
				_samples = new RenderTexture(16, 9, 0, (GraphicsFormat)4)
				{
					name = "VoidCrewVRUIFix_EdgeSamples",
					filterMode = (FilterMode)1,
					hideFlags = (HideFlags)61
				};
				_samples.Create();
			}
			commands.Blit((Texture)(object)ui, RenderTargetIdentifier.op_Implicit((Texture)(object)_samples));
			commands.RequestAsyncReadback((Texture)(object)_samples, (Action<AsyncGPUReadbackRequest>)OnReadback);
			_readbackPending = true;
		}
	}

	public void Release()
	{
		if (!((Object)(object)_samples == (Object)null))
		{
			_samples.Release();
			Object.Destroy((Object)(object)_samples);
			_samples = null;
		}
	}

	private void OnReadback(AsyncGPUReadbackRequest request)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: 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_01ef: Unknown result type (might be due to invalid IL or missing references)
		_readbackPending = false;
		if (((AsyncGPUReadbackRequest)(ref request)).hasError)
		{
			return;
		}
		NativeArray<byte> data = ((AsyncGPUReadbackRequest)(ref request)).GetData<byte>(0);
		if (data.Length < 576)
		{
			return;
		}
		_border.Clear();
		for (int i = 0; i < 9; i++)
		{
			for (int j = 0; j < 16; j++)
			{
				if (i == 0 || i == 8 || j == 0 || j == 15)
				{
					int num = (i * 16 + j) * 4;
					_border.Add(new Color32(data[num], data[num + 1], data[num + 2], data[num + 3]));
				}
			}
		}
		float num2 = Median((Color32 c) => (float)(int)c.a / 255f);
		int num3 = 0;
		foreach (Color32 item in _border)
		{
			if (Mathf.Abs((float)(int)item.a / 255f - num2) <= 0.08f)
			{
				num3++;
			}
		}
		if (num2 < 0.03f || (float)num3 < (float)_border.Count * 0.85f)
		{
			Current = Color.clear;
			return;
		}
		float num4 = Mathf.Max(num2, 0.001f);
		Current = new Color(Mathf.Clamp01(Median((Color32 c) => (float)(int)c.r / 255f) / num4), Mathf.Clamp01(Median((Color32 c) => (float)(int)c.g / 255f) / num4), Mathf.Clamp01(Median((Color32 c) => (float)(int)c.b / 255f) / num4), (num2 > 0.97f) ? 1f : num2);
	}

	private float Median(Func<Color32, float> channel)
	{
		//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_0028: Unknown result type (might be due to invalid IL or missing references)
		_sorted.Clear();
		foreach (Color32 item in _border)
		{
			_sorted.Add(channel(item));
		}
		_sorted.Sort();
		if (_sorted.Count != 0)
		{
			return _sorted[_sorted.Count / 2];
		}
		return 0f;
	}
}
internal static class GamePatches
{
	private static FieldInfo _cursorTextureField;

	private static MethodInfo _updateCursorGraphic;

	private static int _dlssPassIdToRestore = -1;

	public static Texture2D GameCursorTexture
	{
		get
		{
			if (!(_cursorTextureField != null))
			{
				return null;
			}
			object? value = _cursorTextureField.GetValue(null);
			return (Texture2D)((value is Texture2D) ? value : null);
		}
	}

	public static void Apply(Harmony harmony)
	{
		List<string> list = new List<string>();
		List<string> list2 = new List<string>();
		Patch(harmony, "SettingUpscaling", "SupportsDLSS", "HideDlss", null, "DLSS option", list, list2);
		Patch(harmony, "SettingUpscaling", "SupportsFSR3", "HideFsr3", null, "FSR3 option", list, list2);
		Patch(harmony, "VideoSwitcher", "SetupAndPlayVideo", null, "RedirectIntroVideo", "intro video", list, list2);
		Patch(harmony, "CG.Input.MouseCursor", "UpdateCursorGraphic", "HideHardwareCursorGraphic", null, "Windows cursor", list, list2);
		Patch(harmony, "UI.Settings.SettingsUIPanel", "OnInitialize", null, "SettingsMenuCreated", "VR settings tab", list, list2);
		Patch(harmony, "UI.Settings.SettingsUIPanel", "OnEnter", null, "SettingsMenuOpened", "VR settings tab refresh", list, list2);
		Patch(harmony, "UI.Settings.SettingsUIPanel", "TryRestore", "SettingsRestoreClicked", null, "VR settings tab restore", list, list2);
		Patch(harmony, "Gameplay.Terminals.TerminalScreen", "DelayedParentWorldUiPanel", "TerminalScreenEntered", null, "terminal screens", list, list2);
		Patch(harmony, "CG.Client.Ship.Modules.Mediators.TerminalModuleMediator", "DelayedParentWorldUiPanel", "ShipTerminalEntered", null, "ship terminal screens", list, list2);
		Patch(harmony, "CG.Client.UI.Terminals.WorldSpaceUI", "TransformPointerEvent", "TerminalScreenPointer", null, "terminal screen clicks", list, list2);
		Patch(harmony, "CG.Client.Player.HUD.WeaponControlScreenBorder", "PlaySequence", "HideTurretBorder", null, "turret screen border", list, list2);
		Patch(harmony, "Opsive.UltimateCharacterController.FirstPersonController.Camera.ViewTypes.FirstPerson", "GetCrosshairsDeltaRotation", null, "AimWhereYouLook", "head aim (weapons)", list, list2);
		PatchLookWithHead(harmony, "CG.Client.Player.Interactions.RaycastHandler", "FindInteractable", "head aim (interactions)", list, list2);
		PatchLookWithHead(harmony, "UI.Ping.PingAbility", "GetPingInfo", "head aim (quick ping)", list, list2);
		PatchLookWithHead(harmony, "UI.Ping.PingDefinition", "GetTarget", "head aim (ping wheel)", list, list2);
		PatchTurretAim(harmony, list, list2);
		Patch(harmony, "PingMenu", "Open", null, "PingWheelOpened", "head aim (ping wheel opened)", list, list2);
		Patch(harmony, "PingMenu", "Close", "PingWheelClosing", null, "head aim (ping wheel let go)", list, list2);
		Patch(harmony, "UI.Ping.RadialSelectionMenuVE", "Display", null, "WheelShown", "wheel backdrop", list, list2);
		PatchDlssEyes(harmony, list, list2);
		if (UuvrCompat.Installed)
		{
			PatchUuvrStartup(harmony, list, list2);
		}
		Type[] array = new Type[1] { typeof(Vector3) };
		Type[] array2 = new Type[2]
		{
			typeof(Vector3),
			typeof(MonoOrStereoscopicEye)
		};
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "WorldToViewportPoint", array, (Type[])null), "WorldToViewportMono", null, "marker alignment", list, list2);
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "WorldToViewportPoint", array2, (Type[])null), "WorldToViewport", null, "marker alignment (eye)", list, list2);
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "WorldToScreenPoint", array, (Type[])null), "WorldToScreenMono", null, "screen alignment", list, list2);
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "WorldToScreenPoint", array2, (Type[])null), "WorldToScreen", null, "screen alignment (eye)", list, list2);
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "ScreenToWorldPoint", array, (Type[])null), "ScreenToWorldMono", null, "terminal mouse aim", list, list2);
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "ScreenToWorldPoint", array2, (Type[])null), "ScreenToWorld", null, "terminal mouse aim (eye)", list, list2);
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "ScreenPointToRay", array, (Type[])null), "ScreenPointToRayMono", null, "mouse rays", list, list2);
		PatchMethod(harmony, AccessTools.Method(typeof(Camera), "ScreenPointToRay", array2, (Type[])null), "ScreenPointToRay", null, "mouse rays (eye)", list, list2);
		Type type = AccessTools.TypeByName("CG.Input.MouseCursor");
		if (type != null)
		{
			_cursorTextureField = AccessTools.Field(type, "_mouseCursorTexture");
			_updateCursorGraphic = AccessTools.Method(type, "UpdateCursorGraphic", (Type[])null, (Type[])null);
		}
		Log.Info("Patched: " + string.Join(", ", list.ToArray()) + ".");
		if (list2.Count > 0)
		{
			Log.Warn("Could not apply: " + string.Join("; ", list2.ToArray()) + ". The game may have been updated; those fixes are inactive, everything else still works.");
		}
	}

	public static void RefreshHardwareCursor()
	{
		if (_updateCursorGraphic == null || (Object)(object)GameCursorTexture == (Object)null)
		{
			return;
		}
		try
		{
			_updateCursorGraphic.Invoke(null, new object[2] { true, true });
		}
		catch (Exception e)
		{
			Log.Failure("Updating the Windows cursor", e);
		}
	}

	private static void Patch(Harmony harmony, string typeName, string methodName, string prefix, string postfix, string label, List<string> applied, List<string> skipped)
	{
		MethodInfo methodInfo;
		try
		{
			Type type = AccessTools.TypeByName(typeName);
			methodInfo = ((type != null) ? AccessTools.DeclaredMethod(type, methodName, (Type[])null, (Type[])null) : null);
		}
		catch (Exception ex)
		{
			skipped.Add(label + " (" + ex.GetType().Name + ": " + ex.Message + ")");
			return;
		}
		if (methodInfo == null)
		{
			skipped.Add(label + " (" + typeName + "." + methodName + " not found)");
		}
		else
		{
			PatchMethod(harmony, methodInfo, prefix, postfix, label, applied, skipped);
		}
	}

	private static void PatchLookWithHead(Harmony harmony, string typeName, string methodName, string label, List<string> applied, List<string> skipped)
	{
		MethodInfo methodInfo;
		try
		{
			Type type = AccessTools.TypeByName(typeName);
			methodInfo = ((type != null) ? AccessTools.DeclaredMethod(type, methodName, (Type[])null, (Type[])null) : null);
		}
		catch (Exception ex)
		{
			skipped.Add(label + " (" + ex.GetType().Name + ": " + ex.Message + ")");
			return;
		}
		if (methodInfo == null)
		{
			skipped.Add(label + " (" + typeName + "." + methodName + " not found)");
		}
		else
		{
			PatchMethod(harmony, methodInfo, "LookWithHead", null, label, applied, skipped, "LookWithHeadEnd");
		}
	}

	private static void PatchTurretAim(Harmony harmony, List<string> applied, List<string> skipped)
	{
		int count = applied.Count;
		Patch(harmony, "ControllingTurret", "TrueUpdate", "TurretControls", null, "head aim (turret controls)", applied, skipped);
		Patch(harmony, "CinemachineBrainUpdater", "LateUpdate", null, "TurretCamera", "head aim (turret camera)", applied, skipped);
		TurretAim.Hooked = applied.Count - count == 2;
	}

	private static void PatchMethod(Harmony harmony, MethodBase target, string prefix, string postfix, string label, List<string> applied, List<string> skipped, string finalizer = null)
	{
		if (target == null)
		{
			skipped.Add(label + " (method not found)");
			return;
		}
		try
		{
			ApplyPatch(harmony, target, prefix, postfix, finalizer);
			applied.Add(label);
		}
		catch (Exception ex)
		{
			skipped.Add(label + " (" + ex.GetType().Name + ": " + ex.Message + ")");
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static void ApplyPatch(Harmony harmony, MethodBase target, string prefix, string postfix, string finalizer)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		PatchProcessor val = harmony.CreateProcessor(target);
		if (prefix != null)
		{
			val.AddPrefix(new HarmonyMethod(typeof(GamePatches), prefix, (Type[])null));
		}
		if (postfix != null)
		{
			val.AddPostfix(new HarmonyMethod(typeof(GamePatches), postfix, (Type[])null));
		}
		if (finalizer != null)
		{
			val.AddFinalizer(new HarmonyMethod(typeof(GamePatches), finalizer, (Type[])null));
		}
		val.Patch();
	}

	private static void PatchDlssEyes(Harmony harmony, List<string> applied, List<string> skipped)
	{
		string text;
		try
		{
			text = DlssEyes.Resolve();
		}
		catch (Exception ex)
		{
			text = ex.GetType().Name + ": " + ex.Message;
		}
		if (text != null)
		{
			skipped.Add("DLSS in VR (" + text + ")");
			return;
		}
		Type type = AccessTools.TypeByName("UnityEngine.Rendering.HighDefinition.DLSSPass+CameraState");
		PatchMethod(harmony, (type != null) ? AccessTools.DeclaredMethod(type, "SubmitCommands", (Type[])null, (Type[])null) : null, "DlssUseEyeNumber", null, "DLSS in VR", applied, skipped, "DlssRestorePassId");
	}

	private static void PatchUuvrStartup(Harmony harmony, List<string> applied, List<string> skipped)
	{
		int count = applied.Count;
		Patch(harmony, "Uuvr.VrUi.VrUiManager", "Start", null, "UuvrUiManagerStarted", "UUVR UI start-up", applied, skipped);
		Patch(harmony, "Uuvr.VrCamera.VrCamera", "Start", null, "UuvrCameraStarted", "UUVR camera start-up", applied, skipped);
		if (applied.Count - count == 2)
		{
			UuvrCompat.MarkHooked();
		}
	}

	private static void UuvrUiManagerStarted(MonoBehaviour __instance)
	{
		try
		{
			UuvrCompat.TurnOffUiManager((Component)(object)__instance);
		}
		catch (Exception e)
		{
			Log.Failure("Turning off UUVR's UI handling", e);
		}
	}

	private static void UuvrCameraStarted(MonoBehaviour __instance)
	{
		try
		{
			UuvrCompat.DisableHelperCamera((Component)(object)__instance);
		}
		catch (Exception e)
		{
			Log.Failure("Disabling UUVR's helper camera", e);
		}
	}

	private static bool HideDlss(ref bool __result)
	{
		if (!UuvrCompat.Installed)
		{
			return true;
		}
		if (!Settings.DisableDlss.Value)
		{
			Log.InfoOnce("dlss-allowed", "DLSS is allowed in VR (experimental). If the game crashes or the image breaks with DLSS on, switch Graphics > Upscaling back to None, or turn off 'Allow DLSS' in the VR tab.");
			return true;
		}
		__result = false;
		Log.InfoOnce("dlss", "DLSS removed from the graphics options because it breaks VR rendering. A saved DLSS setting falls back to 'None'.");
		return false;
	}

	private static bool HideFsr3(ref bool __result)
	{
		if (!Settings.DisableFsr3.Value || !UuvrCompat.Installed)
		{
			return true;
		}
		__result = false;
		Log.InfoOnce("fsr3", "FSR3 removed from the graphics options because it is not built for VR rendering.");
		return false;
	}

	private static void DlssUseEyeNumber(HDCamera camera)
	{
		_dlssPassIdToRestore = DlssEyes.UseEyeNumber(camera);
	}

	private static void DlssRestorePassId(HDCamera camera)
	{
		int dlssPassIdToRestore = _dlssPassIdToRestore;
		_dlssPassIdToRestore = -1;
		DlssEyes.Restore(camera, dlssPassIdToRestore);
	}

	private static bool TerminalScreenEntered(MonoBehaviour __instance, ref IEnumerator __result)
	{
		if (!TerminalScreens.Applies)
		{
			return true;
		}
		__result = TerminalScreens.EnterTerminalScreen(__instance);
		return false;
	}

	private static bool ShipTerminalEntered(MonoBehaviour __instance, ref IEnumerator __result)
	{
		if (!TerminalScreens.Applies)
		{
			return true;
		}
		__result = TerminalScreens.EnterShipTerminal(__instance);
		return false;
	}

	private static void AimWhereYouLook(ref Quaternion __result)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//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)
		if (HeadAim.Aiming)
		{
			Camera playerCamera = MarkerAlignment.PlayerCamera;
			if (!((Object)(object)playerCamera == (Object)null))
			{
				__result = Quaternion.Inverse(((Component)playerCamera).transform.rotation) * HeadAim.AimRotation(playerCamera) * __result;
			}
		}
	}

	private static void LookWithHead(ref Quaternion? __state)
	{
		__state = HeadAim.TurnCamera();
	}

	private static void LookWithHeadEnd(Quaternion? __state)
	{
		HeadAim.TurnCameraBack(__state);
	}

	private static bool TurretControls(object __instance)
	{
		return !TurretAim.TakeOverInput(__instance);
	}

	private static void TurretCamera(CinemachineBrainUpdater __instance)
	{
		if (TurretAim.Steering)
		{
			TurretAim.AfterCameraUpdate(__instance);
		}
	}

	private static void PingWheelOpened(MonoBehaviour __instance)
	{
		PingWheel.Opened((Object)(object)__instance);
	}

	private static void PingWheelClosing(MonoBehaviour __instance)
	{
		PingWheel.Closing((Object)(object)__instance);
	}

	private static void WheelShown(VisualElement __instance)
	{
		if (XrState.IsActive)
		{
			WheelBackdrop.Shown(__instance);
		}
	}

	private static bool TerminalScreenPointer(MonoBehaviour __instance, PointerEventData eventData)
	{
		if (!TerminalScreens.Applies)
		{
			return true;
		}
		try
		{
			return !TerminalScreens.TransformPointerEvent(__instance, eventData);
		}
		catch (Exception e)
		{
			Log.Failure("Mapping the mouse onto a terminal screen", e);
			return true;
		}
	}

	private static void HideTurretBorder(ref float alpha, CanvasGroup ___canvasGroup)
	{
		if (XrState.IsActive && Settings.HideTurretScreenBorder.Value)
		{
			alpha = 0f;
			if ((Object)(object)___canvasGroup != (Object)null)
			{
				___canvasGroup.alpha = 0f;
			}
			Log.InfoOnce("turret-border", "The turret screen's dark border is hidden in VR (it showed as a dark box around the UI).");
		}
	}

	private static void RedirectIntroVideo(MonoBehaviour __instance)
	{
		if (Settings.FixIntroVideo.Value && XrState.IsActive)
		{
			IntroVideo.Redirect(((Component)__instance).GetComponent<VideoPlayer>());
		}
	}

	private static void SettingsMenuCreated(MonoBehaviour __instance)
	{
		try
		{
			InstallVrSettingsTab(__instance);
		}
		catch (Exception ex)
		{
			Log.Warn("Could not add the VR tab to the Settings menu (the game may have been updated): " + ex.GetType().Name + ": " + ex.Message);
		}
	}

	private static void SettingsMenuOpened(MonoBehaviour __instance)
	{
		try
		{
			RefreshVrSettingsTab(__instance);
		}
		catch (Exception e)
		{
			Log.Failure("Refreshing the VR settings tab", e);
		}
	}

	private static bool SettingsRestoreClicked(MonoBehaviour __instance)
	{
		try
		{
			return !RestoreVrSettingsTab(__instance);
		}
		catch (Exception e)
		{
			Log.Failure("Restoring the VR settings", e);
			return true;
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static void InstallVrSettingsTab(MonoBehaviour settingsScreen)
	{
		VrSettingsTab.Install(settingsScreen);
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static void RefreshVrSettingsTab(MonoBehaviour settingsScreen)
	{
		VrSettingsTab.Refresh(settingsScreen);
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	private static bool RestoreVrSettingsTab(MonoBehaviour settingsScreen)
	{
		return VrSettingsTab.TryRestore(settingsScreen);
	}

	private static void HideHardwareCursorGraphic(ref bool showTexture)
	{
		if (XrState.IsActive && Settings.HideHardwareCursor.Value && Settings.ShowVrCursor.Value)
		{
			showTexture = false;
		}
	}

	private static bool WorldToViewportMono(Camera __instance, Vector3 position, ref Vector3 __result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return WorldToViewport(__instance, position, (MonoOrStereoscopicEye)2, ref __result);
	}

	private static bool WorldToViewport(Camera __instance, Vector3 position, MonoOrStereoscopicEye eye, ref Vector3 __result)
	{
		//IL_0001: 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_000e: 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)
		if (!MarkerAlignment.Applies(__instance, eye))
		{
			return true;
		}
		__result = MarkerAlignment.WorldToViewport(__instance, position);
		return false;
	}

	private static bool WorldToScreenMono(Camera __instance, Vector3 position, ref Vector3 __result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return WorldToScreen(__instance, position, (MonoOrStereoscopicEye)2, ref __result);
	}

	private static bool WorldToScreen(Camera __instance, Vector3 position, MonoOrStereoscopicEye eye, ref Vector3 __result)
	{
		//IL_0001: 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_000e: 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)
		if (!MarkerAlignment.Applies(__instance, eye))
		{
			return true;
		}
		__result = MarkerAlignment.WorldToScreen(__instance, position);
		return false;
	}

	private static bool ScreenToWorldMono(Camera __instance, Vector3 position, ref Vector3 __result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return ScreenToWorld(__instance, position, (MonoOrStereoscopicEye)2, ref __result);
	}

	private static bool ScreenToWorld(Camera __instance, Vector3 position, MonoOrStereoscopicEye eye, ref Vector3 __result)
	{
		//IL_0001: 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_000e: 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)
		if (!MarkerAlignment.Applies(__instance, eye))
		{
			return true;
		}
		__result = MarkerAlignment.ScreenToWorld(__instance, position);
		return false;
	}

	private static bool ScreenPointToRayMono(Camera __instance, Vector3 pos, ref Ray __result)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return ScreenPointToRay(__instance, pos, (MonoOrStereoscopicEye)2, ref __result);
	}

	private static bool ScreenPointToRay(Camera __instance, Vector3 pos, MonoOrStereoscopicEye eye, ref Ray __result)
	{
		//IL_0001: 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_000e: 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)
		if (!MarkerAlignment.Applies(__instance, eye))
		{
			return true;
		}
		__result = MarkerAlignment.ScreenToRay(__instance, pos);
		return false;
	}
}
internal static class HdrpTweaks
{
	private static readonly HashSet<string> Reported = new HashSet<string>();

	public static void DisableDlssOnCameras(Camera playerCamera)
	{
		bool flag = !Settings.DisableDlss.Value;
		Camera[] allCameras = Camera.allCameras;
		foreach (Camera val in allCameras)
		{
			if (flag && (Object)(object)val == (Object)(object)playerCamera)
			{
				continue;
			}
			HDAdditionalCameraData component = ((Component)val).GetComponent<HDAdditionalCameraData>();
			if (!((Object)(object)component == (Object)null) && component.allowDeepLearningSuperSampling)
			{
				component.allowDeepLearningSuperSampling = false;
				if (Reported.Add(((Object)val).name))
				{
					Log.Info("Turned off DLSS on camera '" + ((Object)val).name + "'" + (flag ? " (DLSS is only allowed on the player camera)." : " (DLSS is disabled in VR)."));
				}
			}
		}
	}
}
internal static class HeadAim
{
	private static readonly List<InputDevice> Heads = new List<InputDevice>();

	private static bool _turned;

	private static Quaternion _turnedView;

	public static bool PanelFollowsHead { get; private set; }

	public static bool Aiming { get; private set; }

	public static bool InVehicleView { get; private set; }

	public static void Update(bool vrActive, bool menuOpen)
	{
		TurretAim.SetSteering(vrActive && Settings.AimWithHead.Value && !menuOpen && TurretAim.InTurret);
		bool flag = vrActive && !TurretAim.Steering && PlayerModes.InVehicleView();
		if (flag != InVehicleView)
		{
			InVehicleView = flag;
			Log.Verbose(flag ? "Turret or ship camera view: the UI screen stays in front of the game camera, crosshair on its centre line." : "Left the turret or ship camera view.");
		}
		Aiming = vrActive && Settings.AimWithHead.Value && !menuOpen && !PanelLayout.OnTerminalScreen && !InVehicleView;
		PanelFollowsHead = vrActive && !InVehicleView && (Settings.Anchor.Value == PanelAnchor.Head || Aiming);
	}

	public static void Stop()
	{
		Aiming = false;
		PanelFollowsHead = false;
		InVehicleView = false;
		TurretAim.Stop();
	}

	public static Quaternion ViewRotation(Camera camera)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (_turned)
		{
			return _turnedView;
		}
		if (UuvrCompat.TryGetViewRotation(camera, out var rotation))
		{
			return rotation;
		}
		return ((Component)camera).transform.rotation * HeadsetRotation();
	}

	public static Quaternion AimRotation(Camera camera)
	{
		//IL_004c: 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_0052: 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_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		HudLayer turretCrosshair = HudLayers.TurretCrosshair;
		if (TurretAim.Steering && turretCrosshair != null && turretCrosshair.Extracting)
		{
			return ViewRotation(camera) * turretCrosshair.Placement.Rotation;
		}
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(0f, PanelLayout.HeightOffset / PanelLayout.Distance, 1f);
		return ViewRotation(camera) * Quaternion.LookRotation(val);
	}

	public static Quaternion? TurnCamera()
	{
		//IL_003b: 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_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_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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)
		if (!Aiming || _turned)
		{
			return null;
		}
		Camera playerCamera = MarkerAlignment.PlayerCamera;
		if ((Object)(object)playerCamera == (Object)null)
		{
			return null;
		}
		Transform transform = ((Component)playerCamera).transform;
		Quaternion rotation = AimRotation(playerCamera);
		_turnedView = ViewRotation(playerCamera);
		_turned = true;
		Quaternion rotation2 = transform.rotation;
		transform.rotation = rotation;
		return rotation2;
	}

	public static void TurnCameraBack(Quaternion? original)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (original.HasValue)
		{
			_turned = false;
			Camera playerCamera = MarkerAlignment.PlayerCamera;
			if ((Object)(object)playerCamera != (Object)null)
			{
				((Component)playerCamera).transform.rotation = original.Value;
			}
		}
	}

	public static bool TryGetHeadRelativeToGameCamera(Camera camera, out Quaternion relative)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		relative = Quaternion.identity;
		if ((Object)(object)camera == (Object)null)
		{
			return false;
		}
		if (UuvrCompat.TryGetViewRotation(camera, out var rotation))
		{
			relative = Quaternion.Inverse(((Component)camera).transform.rotation) * rotation;
			return true;
		}
		Heads.Clear();
		InputDevices.GetDevicesAtXRNode((XRNode)3, Heads);
		if (Heads.Count == 0)
		{
			return false;
		}
		relative = HeadsetRotation();
		return true;
	}

	private static Quaternion HeadsetRotation()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		Heads.Clear();
		InputDevices.GetDevicesAtXRNode((XRNode)3, Heads);
		Quaternion result = default(Quaternion);
		foreach (InputDevice head in Heads)
		{
			InputDevice current = head;
			if (((InputDevice)(ref current)).isValid && (((InputDevice)(ref current)).TryGetFeatureValue(CommonUsages.centerEyeRotation, ref result) || ((InputDevice)(ref current)).TryGetFeatureValue(CommonUsages.deviceRotation, ref result)))
			{
				return result;
			}
		}
		return Quaternion.identity;
	}
}
internal static class HeadsetPresence
{
	private const float RemovedAfter = 2f;

	private static readonly List<InputDevice> Heads = new List<InputDevice>();

	private static float _notWornSince = -1f;

	public static bool Supported { get; private set; }

	public static bool Removed { get; private set; }

	public static void Update()
	{
		if (!TryReadWorn(out var worn))
		{
			Supported = false;
			Removed = false;
			_notWornSince = -1f;
			return;
		}
		Supported = true;
		if (worn)
		{
			_notWornSince = -1f;
			Removed = false;
			return;
		}
		if (_notWornSince < 0f)
		{
			_notWornSince = Time.unscaledTime;
		}
		if (Time.unscaledTime - _notWornSince >= 2f)
		{
			Removed = true;
		}
	}

	public static void Reset()
	{
		Supported = false;
		Removed = false;
		_notWornSince = -1f;
	}

	public static string Describe()
	{
		if (!Supported)
		{
			return "unknown (the headset or VR runtime doesn't report it)";
		}
		if (!Removed)
		{
			return "worn";
		}
		return "taken off";
	}

	private static bool TryReadWorn(out bool worn)
	{
		//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_0038: Unknown result type (might be due to invalid IL or missing references)
		worn = true;
		Heads.Clear();
		InputDevices.GetDevicesAtXRNode((XRNode)3, Heads);
		foreach (InputDevice head in Heads)
		{
			InputDevice current = head;
			if (((InputDevice)(ref current)).isValid && ((InputDevice)(ref current)).TryGetFeatureValue(CommonUsages.userPresence, ref worn))
			{
				return true;
			}
		}
		return false;
	}
}
internal static class HotkeyCapture
{
	private const float GiveUpAfter = 10f;

	private static ConfigEntry<Key> _entry;

	private static Action _finished;

	private static Func<bool> _stillWanted;

	private static float _giveUpAt;

	public static bool Waiting => _entry != null;

	public static int CapturedFrame { get; private set; } = -1;

	public static bool IsWaitingFor(ConfigEntry<Key> entry)
	{
		if (_entry != null)
		{
			return _entry == entry;
		}
		return false;
	}

	public static void Begin(ConfigEntry<Key> entry, Action finished, Func<bool> stillWanted)
	{
		Cancel();
		_entry = entry;
		_finished = finished;
		_stillWanted = stillWanted;
		_giveUpAt = Time.unscaledTime + 10f;
	}

	public static void Cancel()
	{
		if (_entry != null)
		{
			Finish();
		}
	}

	public static void Update()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Invalid comparison between Unknown and I4
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Invalid comparison between Unknown and I4
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Invalid comparison between Unknown and I4
		//IL_00ba: 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)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		if (_entry == null)
		{
			return;
		}
		if (Time.unscaledTime > _giveUpAt || !StillWanted())
		{
			Finish();
			return;
		}
		Keyboard current = Keyboard.current;
		if (current == null)
		{
			return;
		}
		Enumerator<KeyControl> enumerator = current.allKeys.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				KeyControl current2 = enumerator.Current;
				if (current2 != null && ((ButtonControl)current2).wasPressedThisFrame)
				{
					Key keyCode = current2.keyCode;
					if ((int)keyCode != 60)
					{
						_entry.Value = (Key)(((int)keyCode != 65 && (int)keyCode != 71) ? ((int)keyCode) : 0);
						CapturedFrame = Time.frameCount;
						Log.Info("Hotkey '" + ((ConfigEntryBase)_entry).Definition.Key + "' set to " + ((object)_entry.Value/*cast due to .constrained prefix*/).ToString() + " (saved to the config).");
					}
					Finish();
					break;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
	}

	public unsafe static string KeyName(Key key)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		if ((int)key != 0)
		{
			return ((object)(*(Key*)(&key))/*cast due to .constrained prefix*/).ToString().ToUpperInvariant();
		}
		return "NONE";
	}

	private static bool StillWanted()
	{
		try
		{
			return _stillWanted == null || _stillWanted();
		}
		catch
		{
			return false;
		}
	}

	private static void Finish()
	{
		Action finished = _finished;
		_entry = null;
		_finished = null;
		_stillWanted = null;
		if (finished == null)
		{
			return;
		}
		try
		{
			finished();
		}
		catch (Exception e)
		{
			Log.Failure("Updating the VR tab hotkey row", e);
		}
	}
}
internal struct HeadLockedPicture
{
	public Texture Texture;

	public Vector3 Position;

	public Quaternion Rotation;

	public Vector2 Size;

	public bool Flip;

	public float Alpha;
}
internal abstract class HudLayer
{
	private const float PreviewSeconds = 6f;

	protected const float MaxShareOfScreen = 0.6f;

	public readonly string Id;

	public readonly LayerPlacement Placement;

	private readonly string _placeholderLabel;

	private readonly Vector2 _placeholderShare;

	private readonly int _grid;

	private readonly int _padding;

	private RectInt _pixelRect;

	private bool _extract;

	private RenderTexture _texture;

	private bool _hasCopy;

	private Texture2D _placeholder;

	private float _previewUntil = -1f;

	private Material _clearMaterial;

	private bool _clearLookupDone;

	private Mesh _quad;

	public bool Extracting => _extract;

	public Rect UvRect
	{
		get
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(1, Screen.width);
			float num2 = Mathf.Max(1, Screen.height);
			return new Rect((float)((RectInt)(ref _pixelRect)).x / num, (float)((RectInt)(ref _pixelRect)).y / num2, (float)((RectInt)(ref _pixelRect)).width / num, (float)((RectInt)(ref _pixelRect)).height / num2);
		}
	}

	public Texture CopyTexture => (Texture)(object)_texture;

	public bool Previewing => Time.unscaledTime < _previewUntil;

	public Texture DisplayTexture
	{
		get
		{
			if (!Placement.Enabled)
			{
				return null;
			}
			if (_extract)
			{
				return (Texture)(object)_texture;
			}
			if (!Previewing && !LayerPlacement.Editing)
			{
				return null;
			}
			if (!_hasCopy || !((Object)(object)_texture != (Object)null))
			{
				return Placeholder();
			}
			return (Texture)(object)_texture;
		}
	}

	protected HudLayer(string id, LayerPlacement placement, string placeholderLabel, Vector2 placeholderShare, int grid, int padding)
	{
		//IL_0027: 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)
		Id = id;
		Placement = placement;
		_placeholderLabel = placeholderLabel;
		_placeholderShare = placeholderShare;
		_grid = grid;
		_padding = padding;
	}

	public HeadLockedPicture Picture()
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		HeadLockedPicture result = new HeadLockedPicture
		{
			Texture = DisplayTexture,
			Flip = Settings.FlipVertically.Value,
			Alpha = Placement.Alpha
		};
		Placement.Place(out result.Position, out result.Rotation);
		result.Size = SizeMeters();
		return result;
	}

	public void PreviewOnChange()
	{
		Placement.OnChanged(StartPreview);
	}

	public void StartPreview()
	{
		_previewUntil = Time.unscaledTime + 6f;
	}

	public void Stop()
	{
		_extract = false;
	}

	public string Describe()
	{
		if (!Placement.Enabled)
		{
			return "stays on the UI screen";
		}
		return DescribeSources() + (_extract ? (", copied this frame from " + ((RectInt)(ref _pixelRect)).width + "x" + ((RectInt)(ref _pixelRect)).height + " at " + ((RectInt)(ref _pixelRect)).x + "," + ((RectInt)(ref _pixelRect)).y) : "") + (Previewing ? ", previewing" : "") + " | " + Placement.Describe();
	}

	public void Update(bool menuOpen, bool fullScreenLayer)
	{
		//IL_002e: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		bool extract = _extract;
		_extract = false;
		if (!(!Placement.Enabled || menuOpen || fullScreenLayer) && TryGetContentBounds(out var bounds) && ToPixelRect(bounds, out var rect))
		{
			if (extract && (Object)(object)_texture != (Object)null)
			{
				int num = Mathf.Min(((RectInt)(ref rect)).xMin, ((RectInt)(ref _pixelRect)).xMin);
				int num2 = Mathf.Min(((RectInt)(ref rect)).yMin, ((RectInt)(ref _pixelRect)).yMin);
				((RectInt)(ref rect))..ctor(num, num2, Mathf.Max(((RectInt)(ref rect)).xMax, ((RectInt)(ref _pixelRect)).xMax) - num, Mathf.Max(((RectInt)(ref rect)).yMax, ((RectInt)(ref _pixelRect)).yMax) - num2);
			}
			_pixelRect = rect;
			_extract = EnsureTexture();
		}
	}

	protected abstract bool TryGetContentBounds(out Rect bounds);

	protected abstract string DescribeSources();

	public void Copy(CommandBuffer commands, RenderTexture ui)
	{
		//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_002f: 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_003d: Unknown result type (might be due to invalid IL or missing references)
		if (_extract && !((Object)(object)ui == (Object)null) && !((Object)(object)_texture == (Object)null))
		{
			Rect uvRect = UvRect;
			commands.Blit((Texture)(object)ui, RenderTargetIdentifier.op_Implicit((Texture)(object)_texture), ((Rect)(ref uvRect)).size, ((Rect)(ref uvRect)).position);
			_hasCopy = true;
		}
	}

	public void Cut(CommandBuffer commands, RenderTexture ui)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		if (_extract && !((Object)(object)ui == (Object)null) && !((Object)(object)_texture == (Object)null) && EnsureClearMaterial())
		{
			Rect uvRect = UvRect;
			commands.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)ui));
			commands.SetViewProjectionMatrices(Matrix4x4.identity, Matr