Decompiled source of LivePOV v0.1.8

plugins/LivePOV.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LivePOV")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LivePOV")]
[assembly: AssemblyTitle("LivePOV")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LivePOV
{
	internal sealed class LivePOVManager : MonoBehaviour
	{
		private sealed class HintMatch
		{
			internal RectTransform Rect;

			internal int Weight;

			internal HintMatch(RectTransform rect, int weight)
			{
				Rect = rect;
				Weight = weight;
			}
		}

		private sealed class HudMoveState
		{
			internal RectTransform Rect;

			internal Transform Parent;

			internal int SiblingIndex;

			internal Vector2 AnchorMin;

			internal Vector2 AnchorMax;

			internal Vector2 Pivot;

			internal Vector2 AnchoredPosition;

			internal Vector2 SizeDelta;

			internal Vector3 LocalScale;

			internal Quaternion LocalRotation;
		}

		private sealed class PovFeed
		{
			internal readonly RectTransform Panel;

			private readonly RawImage _image;

			private readonly Image _brightnessImage;

			private readonly Text _label;

			private readonly RenderTexture _texture;

			private Renderer[] _targetRenderers = (Renderer[])(object)new Renderer[0];

			private bool[] _targetRendererStates = new bool[0];

			private int _cachedTargetId = int.MinValue;

			internal Player Target { get; private set; }

			internal PovFeed(Player target, RectTransform panel, RawImage image, Image brightnessImage, Text label, RenderTexture texture)
			{
				Panel = panel;
				_image = image;
				_brightnessImage = brightnessImage;
				_label = label;
				_texture = texture;
				SetTarget(target);
			}

			internal void SetTarget(Player target)
			{
				Target = target;
				int num = (((Object)(object)target != (Object)null) ? ((Object)target).GetInstanceID() : int.MinValue);
				if (num != _cachedTargetId)
				{
					_cachedTargetId = num;
					RefreshTargetRenderers();
				}
			}

			private void RefreshTargetRenderers()
			{
				if ((Object)(object)Target == (Object)null)
				{
					_targetRenderers = (Renderer[])(object)new Renderer[0];
					_targetRendererStates = new bool[0];
					return;
				}
				try
				{
					_targetRenderers = ((Component)Target).GetComponentsInChildren<Renderer>(true);
					_targetRendererStates = new bool[_targetRenderers.Length];
				}
				catch
				{
					_targetRenderers = (Renderer[])(object)new Renderer[0];
					_targetRendererStates = new bool[0];
				}
			}

			internal void SetLabel(string text, bool show)
			{
				if (!((Object)(object)_label == (Object)null))
				{
					((Behaviour)_label).enabled = show;
					if (show)
					{
						_label.text = text;
					}
				}
			}

			internal void SetDisplayAdjustment(float brightness, float undergroundDarken)
			{
				//IL_0073: 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)
				if (!((Object)(object)_brightnessImage == (Object)null))
				{
					float num = Mathf.Clamp(brightness, 0f, 0.15f);
					float num2 = Mathf.Clamp(undergroundDarken, 0f, 0.5f);
					float num3 = num - num2;
					if (num3 >= 0f)
					{
						((Graphic)_brightnessImage).color = new Color(1f, 1f, 1f, num3);
					}
					else
					{
						((Graphic)_brightnessImage).color = new Color(0f, 0f, 0f, 0f - num3);
					}
				}
			}

			private void HideTargetRenderers()
			{
				if (_targetRenderers == null || _targetRenderers.Length == 0)
				{
					return;
				}
				for (int i = 0; i < _targetRenderers.Length; i++)
				{
					Renderer val = _targetRenderers[i];
					if (!((Object)(object)val == (Object)null))
					{
						_targetRendererStates[i] = val.enabled;
						val.enabled = false;
					}
				}
			}

			private void RestoreTargetRenderers()
			{
				if (_targetRenderers == null || _targetRenderers.Length == 0)
				{
					return;
				}
				for (int i = 0; i < _targetRenderers.Length; i++)
				{
					Renderer val = _targetRenderers[i];
					if (!((Object)(object)val == (Object)null))
					{
						val.enabled = _targetRendererStates[i];
					}
				}
			}

			internal void RenderWithGameCamera(Camera source, float forwardOffset)
			{
				//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_004e: 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_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)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d4: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0196: Unknown result type (might be due to invalid IL or missing references)
				//IL_0199: Invalid comparison between Unknown and I4
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_019e: Invalid comparison between Unknown and I4
				//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Target == (Object)null || (Object)(object)source == (Object)null || (Object)(object)_texture == (Object)null)
				{
					return;
				}
				Transform headTransform = GetHeadTransform(Target);
				if ((Object)(object)headTransform == (Object)null)
				{
					return;
				}
				Vector3 position = ((Component)source).transform.position;
				Quaternion rotation = ((Component)source).transform.rotation;
				RenderTexture targetTexture = source.targetTexture;
				Rect rect = source.rect;
				int cullingMask = source.cullingMask;
				CameraClearFlags clearFlags = source.clearFlags;
				Color backgroundColor = source.backgroundColor;
				float nearClipPlane = source.nearClipPlane;
				bool useOcclusionCulling = source.useOcclusionCulling;
				bool allowMSAA = source.allowMSAA;
				Renderer val = null;
				bool enabled = false;
				Renderer[] array = (Renderer[])(object)new Renderer[0];
				bool[] array2 = new bool[0];
				bool flag = false;
				RenderTexture active = RenderTexture.active;
				try
				{
					float num = Mathf.Clamp(forwardOffset, 0.02f, 0.35f);
					Vector3 val2 = headTransform.position + headTransform.forward * num + headTransform.up * 0.02f;
					((Component)source).transform.SetPositionAndRotation(val2, headTransform.rotation);
					source.targetTexture = _texture;
					source.rect = new Rect(0f, 0f, 1f, 1f);
					source.nearClipPlane = 0.03f;
					source.useOcclusionCulling = false;
					source.allowMSAA = false;
					int num2 = cullingMask;
					if ((Object)(object)Player.localPlayer != (Object)null)
					{
						num2 |= GetHierarchyLayerMask(((Component)Player.localPlayer).transform);
					}
					int num3 = LayerMask.NameToLayer("UI");
					if (num3 >= 0)
					{
						num2 &= ~(1 << num3);
					}
					source.cullingMask = num2;
					if ((int)clearFlags == 3 || (int)clearFlags == 4)
					{
						source.clearFlags = (CameraClearFlags)(((Object)(object)RenderSettings.skybox != (Object)null) ? 1 : 2);
						source.backgroundColor = backgroundColor;
					}
					val = FindLocalBodyRenderer();
					if ((Object)(object)val != (Object)null)
					{
						enabled = val.enabled;
						val.enabled = true;
					}
					array = GetLocalVisorRenderers();
					array2 = new bool[array.Length];
					for (int i = 0; i < array.Length; i++)
					{
						if (!((Object)(object)array[i] == (Object)null))
						{
							array2[i] = array[i].enabled;
							array[i].enabled = true;
						}
					}
					HideTargetRenderers();
					flag = true;
					source.Render();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogDebug((object)("LivePOV render skipped: " + ex.Message));
				}
				finally
				{
					if (flag)
					{
						RestoreTargetRenderers();
					}
					if ((Object)(object)val != (Object)null)
					{
						val.enabled = enabled;
					}
					for (int j = 0; j < array.Length; j++)
					{
						if ((Object)(object)array[j] != (Object)null)
						{
							array[j].enabled = array2[j];
						}
					}
					((Component)source).transform.SetPositionAndRotation(position, rotation);
					source.targetTexture = targetTexture;
					source.rect = rect;
					source.cullingMask = cullingMask;
					source.clearFlags = clearFlags;
					source.backgroundColor = backgroundColor;
					source.nearClipPlane = nearClipPlane;
					source.useOcclusionCulling = useOcclusionCulling;
					source.allowMSAA = allowMSAA;
					RenderTexture.active = active;
				}
			}

			internal void Dispose()
			{
				if ((Object)(object)_image != (Object)null)
				{
					_image.texture = null;
				}
				if ((Object)(object)_texture != (Object)null)
				{
					_texture.Release();
					Object.Destroy((Object)(object)_texture);
				}
				if ((Object)(object)Panel != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)Panel).gameObject);
				}
			}
		}

		private Plugin _plugin;

		private Canvas _canvas;

		private RectTransform _root;

		private readonly Dictionary<int, PovFeed> _feeds = new Dictionary<int, PovFeed>();

		private readonly List<int> _orderedIds = new List<int>();

		private bool _visible;

		private float _nextRefresh;

		private float _nextPovRender;

		private bool _renderScheduled;

		private float _nextHudScan;

		private HudMoveState _movedItemControls;

		private const float RefreshInterval = 0.75f;

		private const float HudScanInterval = 0.5f;

		internal void Initialize(Plugin plugin)
		{
			_plugin = plugin;
			_visible = plugin.EnabledAtStart.Value;
			CreateCanvas();
		}

		private void CreateCanvas()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("LivePOV_Canvas");
			val.transform.SetParent(((Component)this).transform, false);
			_canvas = val.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 5000;
			CanvasScaler obj = val.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.screenMatchMode = (ScreenMatchMode)0;
			obj.matchWidthOrHeight = 0.5f;
			GameObject val2 = new GameObject("Feeds", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			_root = val2.GetComponent<RectTransform>();
			_root.anchorMin = Vector2.zero;
			_root.anchorMax = Vector2.one;
			_root.offsetMin = Vector2.zero;
			_root.offsetMax = Vector2.zero;
			((Behaviour)_canvas).enabled = _visible;
		}

		private void Update()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_plugin == (Object)null)
			{
				return;
			}
			if (Input.GetKeyDown(_plugin.ToggleKey.Value))
			{
				_visible = !_visible;
				if ((Object)(object)_canvas != (Object)null)
				{
					((Behaviour)_canvas).enabled = _visible;
				}
			}
			if (_plugin.MoveItemControls.Value && Time.unscaledTime >= _nextHudScan)
			{
				_nextHudScan = Time.unscaledTime + 0.5f;
				TryRelocateItemControls();
			}
			else if (!_plugin.MoveItemControls.Value && _movedItemControls != null)
			{
				RestoreItemControls();
			}
			if (Time.unscaledTime >= _nextRefresh)
			{
				_nextRefresh = Time.unscaledTime + 0.75f;
				RefreshPlayers();
			}
		}

		private void LateUpdate()
		{
			if (_visible && _feeds.Count != 0 && !_renderScheduled)
			{
				int num = Mathf.Clamp(_plugin.FeedFps.Value, 1, 120);
				float unscaledTime = Time.unscaledTime;
				if (!(unscaledTime < _nextPovRender))
				{
					_nextPovRender = unscaledTime + 1f / (float)num;
					_renderScheduled = true;
					((MonoBehaviour)this).StartCoroutine(RenderFeedsAtEndOfFrame());
				}
			}
		}

		private IEnumerator RenderFeedsAtEndOfFrame()
		{
			yield return (object)new WaitForEndOfFrame();
			try
			{
				if (!_visible || _feeds.Count == 0)
				{
					yield break;
				}
				Camera val = null;
				try
				{
					if ((Object)(object)MainCamera.instance != (Object)null)
					{
						val = ((Component)MainCamera.instance).GetComponent<Camera>();
					}
				}
				catch
				{
				}
				if ((Object)(object)val == (Object)null)
				{
					val = Camera.main;
				}
				if ((Object)(object)val == (Object)null)
				{
					yield break;
				}
				for (int i = 0; i < _orderedIds.Count; i++)
				{
					if (_feeds.TryGetValue(_orderedIds[i], out var value))
					{
						value.RenderWithGameCamera(val, _plugin.CameraForwardOffset.Value);
					}
				}
			}
			finally
			{
				_renderScheduled = false;
			}
		}

		private void RefreshPlayers()
		{
			if ((Object)(object)_root == (Object)null)
			{
				return;
			}
			List<Player> list = new List<Player>();
			try
			{
				if ((Object)(object)PlayerHandler.instance != (Object)null && PlayerHandler.instance.players != null && (Object)(object)Player.localPlayer != (Object)null)
				{
					foreach (Player player in PlayerHandler.instance.players)
					{
						if (!((Object)(object)player == (Object)null) && !((Object)(object)player == (Object)(object)Player.localPlayer))
						{
							list.Add(player);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("LivePOV could not read the current player list yet: " + ex.Message));
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			foreach (Player item in list)
			{
				hashSet.Add(((Object)item).GetInstanceID());
			}
			List<int> list2 = new List<int>();
			foreach (KeyValuePair<int, PovFeed> feed in _feeds)
			{
				if (!hashSet.Contains(feed.Key) || (Object)(object)feed.Value.Target == (Object)null)
				{
					list2.Add(feed.Key);
				}
			}
			foreach (int item2 in list2)
			{
				_feeds[item2].Dispose();
				_feeds.Remove(item2);
			}
			_orderedIds.Clear();
			for (int i = 0; i < list.Count; i++)
			{
				Player val = list[i];
				int instanceID = ((Object)val).GetInstanceID();
				_orderedIds.Add(instanceID);
				if (!_feeds.TryGetValue(instanceID, out var value))
				{
					value = CreateFeed(val);
					_feeds.Add(instanceID, value);
				}
				value.SetTarget(val);
				value.SetLabel(GetPlayerName(val, i + 1), _plugin.ShowNames.Value);
				value.SetDisplayAdjustment(_plugin.BrightnessBoost.Value, IsUndergroundScene() ? _plugin.UndergroundDarken.Value : 0f);
			}
			LayoutFeeds();
		}

		private PovFeed CreateFeed(Player target)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: 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_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Expected O, but got Unknown
			int num = Mathf.Clamp(_plugin.FeedWidth.Value, 160, 960);
			int num2 = Mathf.Clamp(_plugin.FeedHeight.Value, 90, 540);
			int num3 = Mathf.Clamp(_plugin.TextureWidth.Value, 160, 1920);
			int num4 = Mathf.Clamp(_plugin.TextureHeight.Value, 90, 1080);
			GameObject val = new GameObject("LivePOV_Panel", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent((Transform)(object)_root, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2((float)num, (float)num2);
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).color = new Color(0f, 0f, 0f, 0.92f);
			((Graphic)component2).raycastTarget = false;
			GameObject val2 = new GameObject("View", new Type[2]
			{
				typeof(RectTransform),
				typeof(RawImage)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform component3 = val2.GetComponent<RectTransform>();
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.offsetMin = new Vector2(3f, 3f);
			component3.offsetMax = new Vector2(-3f, -3f);
			RawImage component4 = val2.GetComponent<RawImage>();
			((Graphic)component4).raycastTarget = false;
			((Graphic)component4).color = Color.white;
			GameObject val3 = new GameObject("BrightnessLift", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val3.transform.SetParent(val.transform, false);
			RectTransform component5 = val3.GetComponent<RectTransform>();
			component5.anchorMin = Vector2.zero;
			component5.anchorMax = Vector2.one;
			component5.offsetMin = new Vector2(3f, 3f);
			component5.offsetMax = new Vector2(-3f, -3f);
			Image component6 = val3.GetComponent<Image>();
			((Graphic)component6).color = new Color(1f, 1f, 1f, 0f);
			((Graphic)component6).raycastTarget = false;
			GameObject val4 = new GameObject("Name", new Type[2]
			{
				typeof(RectTransform),
				typeof(Text)
			});
			val4.transform.SetParent(val.transform, false);
			RectTransform component7 = val4.GetComponent<RectTransform>();
			component7.anchorMin = new Vector2(0f, 1f);
			component7.anchorMax = new Vector2(1f, 1f);
			component7.pivot = new Vector2(0.5f, 1f);
			component7.sizeDelta = new Vector2(0f, 28f);
			component7.anchoredPosition = new Vector2(0f, -7f);
			Text component8 = val4.GetComponent<Text>();
			component8.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			component8.fontSize = 18;
			component8.alignment = (TextAnchor)0;
			((Graphic)component8).color = Color.white;
			component8.horizontalOverflow = (HorizontalWrapMode)1;
			component8.verticalOverflow = (VerticalWrapMode)1;
			((Graphic)component8).raycastTarget = false;
			RenderTexture val5 = new RenderTexture(num3, num4, 24, (RenderTextureFormat)0);
			((Object)val5).name = "LivePOV_RT_" + ((Object)target).GetInstanceID();
			((Texture)val5).filterMode = (FilterMode)1;
			((Texture)val5).wrapMode = (TextureWrapMode)1;
			val5.useMipMap = false;
			val5.autoGenerateMips = false;
			val5.antiAliasing = 1;
			val5.Create();
			component4.texture = (Texture)(object)val5;
			return new PovFeed(target, component, component4, component6, component8, val5);
		}

		private void LayoutFeeds()
		{
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			int count = _orderedIds.Count;
			if (count == 0)
			{
				return;
			}
			int num = Mathf.Clamp(_plugin.FeedWidth.Value, 160, 960);
			int num2 = Mathf.Clamp(_plugin.FeedHeight.Value, 90, 540);
			int num3 = Mathf.Clamp(_plugin.Margin.Value, 0, 200);
			int num4 = Mathf.Clamp(_plugin.Spacing.Value, 0, 100);
			if ((_plugin.FeedPosition.Value ?? "Top").Trim().Equals("TopRight", StringComparison.OrdinalIgnoreCase))
			{
				int num5 = Mathf.Max(1, Mathf.FloorToInt((1080f - (float)num3 * 2f + (float)num4) / (float)(num2 + num4)));
				for (int i = 0; i < count; i++)
				{
					if (_feeds.TryGetValue(_orderedIds[i], out var value))
					{
						int num6 = i / num5;
						int num7 = i % num5;
						value.Panel.anchorMin = new Vector2(1f, 1f);
						value.Panel.anchorMax = new Vector2(1f, 1f);
						value.Panel.pivot = new Vector2(1f, 1f);
						value.Panel.sizeDelta = new Vector2((float)num, (float)num2);
						value.Panel.anchoredPosition = new Vector2((float)(-num3 - num6 * (num + num4)), (float)(-num3 - num7 * (num2 + num4)));
					}
				}
				return;
			}
			int num8 = Mathf.Max(1, Mathf.FloorToInt((1920f - (float)num3 * 2f + (float)num4) / (float)(num + num4)));
			for (int j = 0; j < count; j++)
			{
				if (_feeds.TryGetValue(_orderedIds[j], out var value2))
				{
					int num9 = j / num8;
					int num10 = j % num8;
					int num11 = num9 * num8;
					int num12 = count - num11;
					int num13 = Mathf.Min(num8, num12);
					float num14 = (0f - (float)(num13 * num + Mathf.Max(0, num13 - 1) * num4)) * 0.5f + (float)num * 0.5f;
					value2.Panel.anchorMin = new Vector2(0.5f, 1f);
					value2.Panel.anchorMax = new Vector2(0.5f, 1f);
					value2.Panel.pivot = new Vector2(0.5f, 1f);
					value2.Panel.sizeDelta = new Vector2((float)num, (float)num2);
					value2.Panel.anchoredPosition = new Vector2(num14 + (float)(num10 * (num + num4)), (float)(-num3 - num9 * (num2 + num4)));
				}
			}
		}

		private static Transform GetHeadTransform(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			try
			{
				if (player.refs != null && (Object)(object)player.refs.headPos != (Object)null)
				{
					return player.refs.headPos;
				}
			}
			catch
			{
			}
			try
			{
				object memberValue = GetMemberValue(GetMemberValue(player, "refs"), "headPos");
				return (Transform)((memberValue is Transform) ? memberValue : null);
			}
			catch
			{
				return null;
			}
		}

		private static string GetPlayerName(Player player, int fallbackIndex)
		{
			try
			{
				object memberValue = GetMemberValue(GetMemberValue(GetMemberValue(GetMemberValue(player, "refs"), "view"), "Owner"), "NickName");
				if (memberValue != null)
				{
					string text = memberValue.ToString();
					if (!string.IsNullOrWhiteSpace(text))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			return "Player " + fallbackIndex;
		}

		private static object GetMemberValue(object instance, string name)
		{
			if (instance == null)
			{
				return null;
			}
			Type type = instance.GetType();
			FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				return field.GetValue(instance);
			}
			PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				return property.GetValue(instance, null);
			}
			return null;
		}

		private static int GetHierarchyLayerMask(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return 0;
			}
			int num = 0;
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					int layer = ((Component)val).gameObject.layer;
					if (layer >= 0 && layer < 32)
					{
						num |= 1 << layer;
					}
				}
			}
			return num;
		}

		private static Renderer FindLocalBodyRenderer()
		{
			try
			{
				if ((Object)(object)Player.localPlayer == (Object)null)
				{
					return null;
				}
				Transform val = ((Component)Player.localPlayer).transform.Find("CharacterModel/BodyRenderer");
				if ((Object)(object)val != (Object)null)
				{
					return ((Component)val).GetComponent<Renderer>();
				}
			}
			catch
			{
			}
			return null;
		}

		private static Renderer[] GetLocalVisorRenderers()
		{
			try
			{
				if ((Object)(object)Player.localPlayer != (Object)null && Player.localPlayer.refs != null && (Object)(object)Player.localPlayer.refs.visor != (Object)null)
				{
					return ((Component)Player.localPlayer.refs.visor).GetComponentsInChildren<Renderer>(true);
				}
			}
			catch
			{
			}
			return (Renderer[])(object)new Renderer[0];
		}

		private static bool IsUndergroundScene()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string text = ((Scene)(ref activeScene)).name ?? string.Empty;
				if (text.IndexOf("Factory", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Mines", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Mine", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Harbour", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Harbor", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("OldWorld", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Underground", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				try
				{
					Type type = typeof(Player).Assembly.GetType("Level");
					if (type != null)
					{
						return Object.FindObjectOfType(type) != (Object)null;
					}
				}
				catch
				{
				}
				return false;
			}
			catch
			{
				return false;
			}
		}

		private void TryRelocateItemControls()
		{
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (_movedItemControls != null)
				{
					if (!((Object)(object)_movedItemControls.Rect == (Object)null))
					{
						ApplyMovedItemControlsPosition(_movedItemControls.Rect);
						return;
					}
					_movedItemControls = null;
				}
				Canvas[] array = Object.FindObjectsOfType<Canvas>();
				RectTransform val = null;
				Canvas val2 = null;
				int num = 0;
				foreach (Canvas val3 in array)
				{
					if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)_canvas || !((Behaviour)val3).isActiveAndEnabled)
					{
						continue;
					}
					List<HintMatch> list = new List<HintMatch>();
					Text[] componentsInChildren = ((Component)val3).GetComponentsInChildren<Text>(true);
					foreach (Text val4 in componentsInChildren)
					{
						if (!((Object)(object)val4 == (Object)null) && ((Component)val4).gameObject.activeInHierarchy)
						{
							int num2 = CountItemControlKeywords(val4.text);
							if (num2 > 0)
							{
								AddHintMatchIfOnRight(list, ((Graphic)val4).rectTransform, num2, val3);
							}
						}
					}
					MonoBehaviour[] componentsInChildren2 = ((Component)val3).GetComponentsInChildren<MonoBehaviour>(true);
					foreach (MonoBehaviour val5 in componentsInChildren2)
					{
						if ((Object)(object)val5 == (Object)null || !((Component)val5).gameObject.activeInHierarchy || !(((object)val5).GetType().FullName ?? string.Empty).StartsWith("TMPro.", StringComparison.Ordinal))
						{
							continue;
						}
						int num3 = CountItemControlKeywords(GetReflectedText((Component)(object)val5));
						if (num3 > 0)
						{
							RectTransform component = ((Component)val5).GetComponent<RectTransform>();
							if ((Object)(object)component != (Object)null)
							{
								AddHintMatchIfOnRight(list, component, num3, val3);
							}
						}
					}
					if (list.Count != 0)
					{
						FindBestHintContainer(val3, list, out var best, out var bestScore);
						if ((Object)(object)best != (Object)null && bestScore > num)
						{
							val = best;
							val2 = val3;
							num = bestScore;
						}
					}
				}
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && num >= 180)
				{
					_movedItemControls = new HudMoveState
					{
						Rect = val,
						Parent = ((Transform)val).parent,
						SiblingIndex = ((Transform)val).GetSiblingIndex(),
						AnchorMin = val.anchorMin,
						AnchorMax = val.anchorMax,
						Pivot = val.pivot,
						AnchoredPosition = val.anchoredPosition,
						SizeDelta = val.sizeDelta,
						LocalScale = ((Transform)val).localScale,
						LocalRotation = ((Transform)val).localRotation
					};
					Rect rect = val.rect;
					Vector2 size = ((Rect)(ref rect)).size;
					((Transform)val).SetParent(((Component)val2).transform, false);
					if (size.x > 1f && size.y > 1f)
					{
						val.sizeDelta = size;
					}
					((Transform)val).SetAsLastSibling();
					ApplyMovedItemControlsPosition(val);
					Plugin.Log.LogInfo((object)("LivePOV moved held-item control hints to the lower-left HUD area: " + ((Object)val).name));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("LivePOV HUD relocation skipped: " + ex.Message));
			}
		}

		private void AddHintMatchIfOnRight(List<HintMatch> matches, RectTransform rect, int weight, Canvas canvas)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rect == (Object)null) && !(RectTransformUtility.WorldToScreenPoint(((int)canvas.renderMode == 0) ? null : canvas.worldCamera, ((Transform)rect).position).x < (float)Screen.width * 0.55f))
			{
				matches.Add(new HintMatch(rect, weight));
			}
		}

		private static int CountItemControlKeywords(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return 0;
			}
			string text2 = text.ToLowerInvariant();
			string[] array = new string[15]
			{
				"drop", "use", "throw", "aim", "zoom", "record", "film", "flash", "place", "pick up",
				"pickup", "charge", "rotate", "switch", "toggle"
			};
			int num = 0;
			for (int i = 0; i < array.Length; i++)
			{
				if (text2.IndexOf(array[i], StringComparison.Ordinal) >= 0)
				{
					num++;
				}
			}
			return num;
		}

		private static string GetReflectedText(Component component)
		{
			try
			{
				if ((Object)(object)component == (Object)null)
				{
					return string.Empty;
				}
				PropertyInfo property = ((object)component).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				object obj = ((property != null) ? property.GetValue(component, null) : null);
				return (obj != null) ? obj.ToString() : string.Empty;
			}
			catch
			{
				return string.Empty;
			}
		}

		private static void FindBestHintContainer(Canvas canvas, List<HintMatch> matches, out RectTransform best, out int bestScore)
		{
			best = null;
			bestScore = 0;
			Dictionary<RectTransform, int> dictionary = new Dictionary<RectTransform, int>();
			Dictionary<RectTransform, int> dictionary2 = new Dictionary<RectTransform, int>();
			for (int i = 0; i < matches.Count; i++)
			{
				HintMatch hintMatch = matches[i];
				RectTransform val = (RectTransform)(((Object)(object)hintMatch.Rect != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
				while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)((Component)canvas).transform)
				{
					if (!IsExcludedHudContainer((((Object)val).name ?? string.Empty).ToLowerInvariant()) && IsReasonableHudContainer(val, canvas))
					{
						dictionary.TryGetValue(val, out var value);
						value = (dictionary[val] = value + hintMatch.Weight * 100);
						dictionary2.TryGetValue(val, out var value2);
						dictionary2[val] = value2 + 1;
					}
					Transform parent = ((Transform)val).parent;
					val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				}
			}
			foreach (KeyValuePair<RectTransform, int> item in dictionary)
			{
				RectTransform key = item.Key;
				int value3 = item.Value;
				int num2 = (dictionary2.ContainsKey(key) ? dictionary2[key] : 0);
				string text = (((Object)key).name ?? string.Empty).ToLowerInvariant();
				value3 += num2 * 35;
				if (text.Contains("item"))
				{
					value3 += 80;
				}
				if (text.Contains("control"))
				{
					value3 += 100;
				}
				if (text.Contains("hint"))
				{
					value3 += 100;
				}
				if (text.Contains("action"))
				{
					value3 += 60;
				}
				if (text.Contains("input"))
				{
					value3 += 40;
				}
				if (value3 > bestScore || (value3 == bestScore && (Object)(object)best != (Object)null && RectArea(key) < RectArea(best)))
				{
					best = key;
					bestScore = value3;
				}
			}
		}

		private static bool IsExcludedHudContainer(string name)
		{
			if (!name.Contains("inventory") && !name.Contains("hotbar") && !name.Contains("oxygen") && !name.Contains("stamina") && !name.Contains("health") && !name.Contains("status") && !name.Contains("chat"))
			{
				return name.Contains("nameplate");
			}
			return true;
		}

		private static bool IsReasonableHudContainer(RectTransform rect, Canvas canvas)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002f: 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_003f: 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)
			try
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				rect.GetWorldCorners(array);
				Camera obj = (((int)canvas.renderMode == 0) ? null : canvas.worldCamera);
				Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, array[0]);
				Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, array[2]);
				float num = Mathf.Abs(val2.x - val.x);
				float num2 = Mathf.Abs(val2.y - val.y);
				if (num > (float)Screen.width * 0.65f || num2 > (float)Screen.height * 0.65f)
				{
					return false;
				}
			}
			catch
			{
			}
			return true;
		}

		private static float RectArea(RectTransform rect)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			if ((Object)(object)rect == (Object)null)
			{
				return float.MaxValue;
			}
			Rect rect2 = rect.rect;
			Vector2 size = ((Rect)(ref rect2)).size;
			return Mathf.Abs(size.x * size.y);
		}

		private void ApplyMovedItemControlsPosition(RectTransform rect)
		{
			//IL_000b: 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_0021: 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)
			if (!((Object)(object)rect == (Object)null))
			{
				rect.anchorMin = Vector2.zero;
				rect.anchorMax = Vector2.zero;
				rect.pivot = Vector2.zero;
				rect.anchoredPosition = new Vector2((float)Mathf.Clamp(_plugin.ItemControlsX.Value, 0, 1800), (float)Mathf.Clamp(_plugin.ItemControlsY.Value, 0, 1000));
			}
		}

		private void RestoreItemControls()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			HudMoveState movedItemControls = _movedItemControls;
			_movedItemControls = null;
			if (movedItemControls == null || (Object)(object)movedItemControls.Rect == (Object)null || (Object)(object)movedItemControls.Parent == (Object)null)
			{
				return;
			}
			try
			{
				((Transform)movedItemControls.Rect).SetParent(movedItemControls.Parent, false);
				((Transform)movedItemControls.Rect).SetSiblingIndex(Mathf.Clamp(movedItemControls.SiblingIndex, 0, Mathf.Max(0, movedItemControls.Parent.childCount - 1)));
				movedItemControls.Rect.anchorMin = movedItemControls.AnchorMin;
				movedItemControls.Rect.anchorMax = movedItemControls.AnchorMax;
				movedItemControls.Rect.pivot = movedItemControls.Pivot;
				movedItemControls.Rect.anchoredPosition = movedItemControls.AnchoredPosition;
				movedItemControls.Rect.sizeDelta = movedItemControls.SizeDelta;
				((Transform)movedItemControls.Rect).localScale = movedItemControls.LocalScale;
				((Transform)movedItemControls.Rect).localRotation = movedItemControls.LocalRotation;
			}
			catch
			{
			}
		}

		private void OnDestroy()
		{
			RestoreItemControls();
			foreach (PovFeed value in _feeds.Values)
			{
				value.Dispose();
			}
			_feeds.Clear();
			_orderedIds.Clear();
		}
	}
	[BepInPlugin("andre.livepov", "LivePOV", "0.1.8")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "andre.livepov";

		public const string PluginName = "LivePOV";

		public const string PluginVersion = "0.1.8";

		internal static ManualLogSource Log;

		internal ConfigEntry<bool> EnabledAtStart;

		internal ConfigEntry<KeyCode> ToggleKey;

		internal ConfigEntry<int> FeedWidth;

		internal ConfigEntry<int> FeedHeight;

		internal ConfigEntry<int> TextureWidth;

		internal ConfigEntry<int> TextureHeight;

		internal ConfigEntry<int> FeedFps;

		internal ConfigEntry<float> CameraForwardOffset;

		internal ConfigEntry<int> Margin;

		internal ConfigEntry<int> Spacing;

		internal ConfigEntry<bool> ShowNames;

		internal ConfigEntry<string> FeedPosition;

		internal ConfigEntry<float> BrightnessBoost;

		internal ConfigEntry<float> UndergroundDarken;

		internal ConfigEntry<bool> MoveItemControls;

		internal ConfigEntry<int> ItemControlsX;

		internal ConfigEntry<int> ItemControlsY;

		private void Awake()
		{
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Expected O, but got Unknown
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			EnabledAtStart = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnabledAtStart", true, "Show the live POV panels automatically when a lobby is loaded.");
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)287, "Toggle all LivePOV panels on/off.");
			FeedWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "FeedWidth", 400, "Width of each POV panel at 1920x1080 reference resolution.");
			FeedHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "FeedHeight", 225, "Height of each POV panel at 1920x1080 reference resolution.");
			Margin = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "Margin", 18, "Distance from the edge of the screen.");
			Spacing = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "Spacing", 10, "Space between POV panels.");
			ShowNames = ((BaseUnityPlugin)this).Config.Bind<bool>("Layout", "ShowNames", true, "Show the player's name on their POV panel.");
			FeedPosition = ((BaseUnityPlugin)this).Config.Bind<string>("Layout", "Position", "TopRight", "Where POV panels are placed. Supported values: Top or TopRight. TopRight puts the feeds back in the corner.");
			MoveItemControls = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "MoveItemControls", true, "Move the vanilla held-item control hints away from the top-right POV panels.");
			ItemControlsX = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "ItemControlsX", 55, "Horizontal position for the moved item-control hints, measured from the bottom-left at 1920x1080 reference resolution.");
			ItemControlsY = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "ItemControlsY", 190, "Vertical position for the moved item-control hints. 190 places them just above the oxygen area on the default HUD.");
			TextureWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "TextureWidth", 960, "Internal render width for each POV.");
			TextureHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "TextureHeight", 540, "Internal render height for each POV.");
			FeedFps = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "FeedFPS", 30, "Maximum FPS for each mini POV. Lower this if performance drops.");
			CameraForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "ForwardOffset", 0.18f, "Moves the POV camera slightly in front of the remote player's head to avoid seeing inside their face model.");
			BrightnessBoost = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "BrightnessBoost", 0f, "Optional brightness lift for the POV panels. 0 = no lift. This is mainly useful on the surface/lobby.");
			UndergroundDarken = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "UndergroundDarken", 0.2f, "Darkens POV panels only in Old World/underground scenes to compensate for the game camera exposure being too bright during manual POV renders. 0 = off, 0.20 = recommended.");
			GameObject val = new GameObject("LivePOV_Manager");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<LivePOVManager>().Initialize(this);
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to toggle POV panels.", "LivePOV", "0.1.8", ToggleKey.Value));
		}
	}
}