Decompiled source of Theanine v1.1.0

Theanine.dll

Decompiled 2 months ago
using System;
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 CMRLib.Core;
using ComputerysModdingUtilities;
using FishNet;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: StraftatMod(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Theanine")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+bdb710dd4568902912c3ec44b7e197fc8b327ac5")]
[assembly: AssemblyProduct("Theanine")]
[assembly: AssemblyTitle("Theanine")]
[assembly: AssemblyVersion("1.1.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 Theanine
{
	internal static class HudHider
	{
		private sealed class Element
		{
			public readonly string Name;

			public Transform Transform;

			public float? OriginalY;

			public bool Included = true;

			public bool OwnSwitch;

			public bool Hide;

			public Element(string name)
			{
				Name = name;
			}
		}

		private const string UiRoot = "---USER INTERFACE---";

		private const string UiCamName = "UICam";

		private const string AmmoPrefix = "GUN_";

		private const float HiddenY = 10000f;

		private const int CheckEveryFrames = 15;

		private static readonly Element MinimalUi = new Element("---MINIMAL UI---");

		private static readonly Element ModeText = new Element("CMR_ModeText");

		private static readonly Element Speedometer = new Element("Speedometer");

		private static readonly Element Crosshair = new Element("Crosshair");

		private static readonly Element GrabPopup = new Element("GrabPopup")
		{
			OwnSwitch = true
		};

		private static readonly Element[] Elements = new Element[5] { MinimalUi, ModeText, Speedometer, Crosshair, GrabPopup };

		private static readonly List<Camera> _disabledCams = new List<Camera>();

		private static Camera[] _cameraBuffer = (Camera[])(object)new Camera[8];

		private static readonly Dictionary<Transform, float> _ammoShift = new Dictionary<Transform, float>();

		private static readonly List<Transform> _ammoHidden = new List<Transform>();

		private static ManualLogSource _log;

		private static bool _enabled;

		private static bool _includeAmmo;

		private static int _lastCheck = -999;

		private static bool _reportCameras;

		public static bool Enabled
		{
			get
			{
				return _enabled;
			}
			set
			{
				if (_enabled != value)
				{
					_enabled = value;
					_reportCameras = value;
					_log.LogInfo((object)("[HudHider] hiding -> " + (value ? "on" : "off")));
					Apply();
				}
			}
		}

		public static bool IncludeSpeedometer
		{
			get
			{
				return Speedometer.Included;
			}
			set
			{
				SetIncluded(Speedometer, value);
			}
		}

		public static bool IncludeCrosshair
		{
			get
			{
				return Crosshair.Included;
			}
			set
			{
				SetIncluded(Crosshair, value);
			}
		}

		public static bool HideGrabPopup
		{
			get
			{
				return GrabPopup.Hide;
			}
			set
			{
				if (GrabPopup.Hide != value)
				{
					GrabPopup.Hide = value;
					_log.LogInfo((object)("[HudHider] " + GrabPopup.Name + " -> " + (value ? "hidden" : "shown")));
					Apply();
				}
			}
		}

		public static bool IncludeAmmo
		{
			get
			{
				return _includeAmmo;
			}
			set
			{
				if (_includeAmmo != value)
				{
					_includeAmmo = value;
					_log.LogInfo((object)("[HudHider] ammo counter -> " + Word(value)));
					Apply();
				}
			}
		}

		public static void Install(ManualLogSource log, bool enabled, bool includeSpeedometer, bool includeCrosshair, bool includeAmmo, bool hideGrabPopup)
		{
			_log = log;
			_enabled = enabled;
			_reportCameras = enabled;
			_includeAmmo = includeAmmo;
			Speedometer.Included = includeSpeedometer;
			Crosshair.Included = includeCrosshair;
			GrabPopup.Hide = hideGrabPopup;
			CmrHost.Tick += OnTick;
			_log.LogInfo((object)("[HudHider] installed, hiding " + (enabled ? "on" : "off") + " (speedometer " + Word(includeSpeedometer) + ", crosshair " + Word(includeCrosshair) + ", ammo counter " + Word(includeAmmo) + "); pickup prompt " + (hideGrabPopup ? "hidden" : "shown")));
		}

		private static string Word(bool included)
		{
			if (!included)
			{
				return "left alone";
			}
			return "included";
		}

		private static void SetIncluded(Element e, bool value)
		{
			if (e.Included != value)
			{
				e.Included = value;
				_log.LogInfo((object)("[HudHider] " + e.Name + " -> " + Word(value)));
				Apply();
			}
		}

		private static void OnTick()
		{
			if (Time.frameCount - _lastCheck >= 15)
			{
				_lastCheck = Time.frameCount;
				Apply();
			}
		}

		private static void Apply()
		{
			Resolve();
			Element[] elements = Elements;
			for (int i = 0; i < elements.Length; i++)
			{
				Move(elements[i]);
			}
			ApplyAmmo();
			ApplyCameras();
		}

		private static void ApplyAmmo()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = MinimalUi.Transform;
			if ((Object)(object)transform == (Object)null || !MinimalUi.OriginalY.HasValue)
			{
				return;
			}
			float num = transform.localPosition.y - MinimalUi.OriginalY.Value;
			bool flag = _enabled && _includeAmmo;
			float wanted = (flag ? 0f : (0f - num));
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if (((Object)child).name.StartsWith("GUN_", StringComparison.Ordinal))
				{
					if (flag && ((Component)child).gameObject.activeSelf)
					{
						SwitchOff(child);
					}
					Shift(child, wanted);
				}
			}
			if (!flag)
			{
				SwitchBackOn();
			}
			PruneAmmoShifts();
		}

		private static void SwitchOff(Transform child)
		{
			((Component)child).gameObject.SetActive(false);
			if (!_ammoHidden.Contains(child))
			{
				_ammoHidden.Add(child);
				_log.LogInfo((object)("[HudHider] ammo counter " + ((Object)child).name + ": switched off"));
			}
		}

		private static void SwitchBackOn()
		{
			if (_ammoHidden.Count == 0)
			{
				return;
			}
			foreach (Transform item in _ammoHidden)
			{
				if ((Object)(object)item != (Object)null)
				{
					((Component)item).gameObject.SetActive(true);
				}
			}
			_log.LogInfo((object)$"[HudHider] ammo counter: {_ammoHidden.Count} object(s) switched back on");
			_ammoHidden.Clear();
		}

		private static void Shift(Transform child, float wanted)
		{
			//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_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_003d: 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)
			if (!_ammoShift.TryGetValue(child, out var value))
			{
				value = 0f;
			}
			float num = wanted - value;
			if (!(Mathf.Abs(num) < 0.1f))
			{
				Vector3 localPosition = child.localPosition;
				child.localPosition = new Vector3(localPosition.x, localPosition.y + num, localPosition.z);
				_ammoShift[child] = wanted;
				_log.LogInfo((object)$"[HudHider] ammo counter {((Object)child).name}: shifted by {num}, now carrying {wanted}");
			}
		}

		private static void PruneAmmoShifts()
		{
			if (_ammoShift.Count <= 8)
			{
				return;
			}
			List<Transform> list = new List<Transform>();
			foreach (KeyValuePair<Transform, float> item in _ammoShift)
			{
				if ((Object)(object)item.Key == (Object)null)
				{
					list.Add(item.Key);
				}
			}
			foreach (Transform item2 in list)
			{
				_ammoShift.Remove(item2);
			}
		}

		private static void Resolve()
		{
			int num = 0;
			Element[] elements = Elements;
			foreach (Element element in elements)
			{
				if (!((Object)(object)element.Transform != (Object)null))
				{
					element.OriginalY = null;
					num++;
					if (element == MinimalUi)
					{
						_ammoShift.Clear();
						_ammoHidden.Clear();
					}
				}
			}
			if (num == 0)
			{
				return;
			}
			Transform val = UiFind.Root("---USER INTERFACE---");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Queue<Transform> queue = new Queue<Transform>();
			queue.Enqueue(val);
			while (queue.Count > 0 && num > 0)
			{
				Transform val2 = queue.Dequeue();
				elements = Elements;
				foreach (Element element2 in elements)
				{
					if (!((Object)(object)element2.Transform != (Object)null) && !(((Object)val2).name != element2.Name))
					{
						element2.Transform = val2;
						Remember(element2);
						num--;
						break;
					}
				}
				for (int j = 0; j < val2.childCount; j++)
				{
					queue.Enqueue(val2.GetChild(j));
				}
			}
		}

		private static void Remember(Element e)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			float y = e.Transform.localPosition.y;
			if (y >= 9999f)
			{
				_log.LogWarning((object)($"[HudHider] {e.Name} found already hidden (Y={y}) - the original is unknown, " + "restoring it will be impossible until the game restarts"));
				return;
			}
			e.OriginalY = y;
			_log.LogInfo((object)$"[HudHider] {e.Name}: found, original Y = {y}");
		}

		private static bool WantsHidden(Element e)
		{
			if (!e.OwnSwitch)
			{
				if (_enabled)
				{
					return e.Included;
				}
				return false;
			}
			return e.Hide;
		}

		private static void Move(Element e)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0069: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)e.Transform == (Object)null)
			{
				return;
			}
			float num;
			if (WantsHidden(e))
			{
				num = 10000f;
			}
			else
			{
				if (!e.OriginalY.HasValue)
				{
					return;
				}
				num = e.OriginalY.Value;
			}
			Vector3 localPosition = e.Transform.localPosition;
			if (!(Mathf.Abs(localPosition.y - num) < 0.1f))
			{
				e.Transform.localPosition = new Vector3(localPosition.x, num, localPosition.z);
				_log.LogInfo((object)$"[HudHider] {e.Name}: Y {localPosition.y} -> {num}");
			}
		}

		private static void ApplyCameras()
		{
			if (!_enabled)
			{
				if (_disabledCams.Count == 0)
				{
					return;
				}
				int num = 0;
				foreach (Camera disabledCam in _disabledCams)
				{
					if (!((Object)(object)disabledCam == (Object)null))
					{
						((Behaviour)disabledCam).enabled = true;
						num++;
					}
				}
				_log.LogInfo((object)string.Format("[HudHider] {0}: {1} camera(s) restored", "UICam", num));
				_disabledCams.Clear();
				return;
			}
			int allCamerasCount = Camera.allCamerasCount;
			if (_cameraBuffer.Length < allCamerasCount)
			{
				_cameraBuffer = (Camera[])(object)new Camera[allCamerasCount + 4];
			}
			allCamerasCount = Camera.GetAllCameras(_cameraBuffer);
			for (int i = 0; i < allCamerasCount; i++)
			{
				Camera val = _cameraBuffer[i];
				if (!((Object)(object)val == (Object)null) && !(((Object)val).name != "UICam"))
				{
					((Behaviour)val).enabled = false;
					if (!_disabledCams.Contains(val))
					{
						_disabledCams.Add(val);
						_log.LogInfo((object)("[HudHider] UICam disabled (" + UiFind.FullPath(((Component)val).transform) + ")"));
					}
				}
			}
			_disabledCams.RemoveAll((Camera c) => (Object)(object)c == (Object)null);
			if (_reportCameras)
			{
				_reportCameras = false;
				_log.LogInfo((object)((_disabledCams.Count > 0) ? string.Format("[HudHider] {0}: {1} camera(s) switched off", "UICam", _disabledCams.Count) : "[HudHider] no UICam in the scene at this moment - the 3D HUD is not up. Later ones are caught as they appear."));
			}
		}
	}
	internal static class Killfeed
	{
		private const string UiRoot = "---USER INTERFACE---";

		private const string LogsName = "LogsPosition";

		private const string StartRoundText = "START ROUND TEXT";

		private const string PlayerNameText = "PlayerNameText";

		private const float HiddenY = 10000f;

		private const int CheckEveryFrames = 30;

		private static ManualLogSource _log;

		private static bool _enabled;

		private static Transform _logs;

		private static Transform _playerName;

		private static float? _logsOriginalY;

		private static float? _playerNameOriginalY;

		private static int _lastCheck = -999;

		public static bool Enabled
		{
			get
			{
				return _enabled;
			}
			set
			{
				if (_enabled != value)
				{
					_enabled = value;
					_log.LogInfo((object)("[Killfeed] hiding -> " + (value ? "on" : "off")));
					Apply();
				}
			}
		}

		public static void Install(ManualLogSource log, bool enabled)
		{
			_log = log;
			_enabled = enabled;
			CmrHost.Tick += OnTick;
			_log.LogInfo((object)("[Killfeed] installed, hiding " + (enabled ? "on" : "off")));
		}

		private static void OnTick()
		{
			if (Time.frameCount - _lastCheck >= 30)
			{
				_lastCheck = Time.frameCount;
				Apply();
			}
		}

		private static void Apply()
		{
			Resolve();
			Move(_logs, _logsOriginalY, "LogsPosition");
			Move(_playerName, _playerNameOriginalY, "PlayerNameText");
		}

		private static void Resolve()
		{
			if ((Object)(object)_logs != (Object)null && (Object)(object)_playerName != (Object)null)
			{
				return;
			}
			Transform val = UiFind.Root("---USER INTERFACE---");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)_logs == (Object)null)
			{
				_logs = UiFind.Descendant(val, "LogsPosition");
				if ((Object)(object)_logs != (Object)null)
				{
					Remember(_logs, ref _logsOriginalY, "LogsPosition");
				}
			}
			if (!((Object)(object)_playerName == (Object)null))
			{
				return;
			}
			Transform val2 = UiFind.Descendant(val, "START ROUND TEXT");
			if ((Object)(object)val2 != (Object)null)
			{
				_playerName = UiFind.Descendant(val2, "PlayerNameText");
				if ((Object)(object)_playerName != (Object)null)
				{
					Remember(_playerName, ref _playerNameOriginalY, "PlayerNameText");
				}
			}
		}

		private static void Remember(Transform t, ref float? slot, string name)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!slot.HasValue)
			{
				float y = t.localPosition.y;
				if (y >= 9999f)
				{
					_log.LogWarning((object)($"[Killfeed] {name} found already hidden (Y={y}) - the original is unknown, " + "restoring it will be impossible until the game restarts"));
					return;
				}
				slot = y;
				_log.LogInfo((object)$"[Killfeed] {name}: remembered original Y = {y}");
			}
		}

		private static void Move(Transform t, float? originalY, string name)
		{
			//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_0034: 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_0057: 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)
			if ((Object)(object)t == (Object)null)
			{
				return;
			}
			float num;
			if (_enabled)
			{
				num = 10000f;
			}
			else
			{
				if (!originalY.HasValue)
				{
					return;
				}
				num = originalY.Value;
			}
			Vector3 localPosition = t.localPosition;
			if (!(Mathf.Abs(localPosition.y - num) < 0.1f))
			{
				t.localPosition = new Vector3(localPosition.x, num, localPosition.z);
				_log.LogInfo((object)$"[Killfeed] {name}: Y {localPosition.y} -> {num}");
			}
		}
	}
	[HarmonyPatch]
	internal static class ModsPopup
	{
		private static readonly string[] Markers = new string[3] { "mods detected", "non-vanilla", "matchmaking pool" };

		private static ManualLogSource _log;

		public static bool Enabled { get; set; }

		public static void Install(ManualLogSource log, bool enabled)
		{
			_log = log;
			Enabled = enabled;
			_log.LogInfo((object)("[Popup] mods warning suppression: " + (enabled ? "on" : "off")));
		}

		[HarmonyPatch(typeof(PauseManager), "ShowInfoPopup")]
		[HarmonyPrefix]
		private static bool Prefix(string __0)
		{
			try
			{
				string text = __0 ?? "";
				if (!Enabled)
				{
					_log.LogInfo((object)("[Popup] shown (suppression off): \"" + Shorten(text) + "\""));
					return true;
				}
				if (!IsAboutMods(text))
				{
					_log.LogInfo((object)("[Popup] passed through (not about mods): \"" + Shorten(text) + "\""));
					return true;
				}
				_log.LogInfo((object)("[Popup] SUPPRESSED: \"" + Shorten(text) + "\""));
				return false;
			}
			catch (Exception ex)
			{
				_log.LogError((object)("[Popup] prefix failed: " + ex.GetType().Name + ": " + ex.Message));
				return true;
			}
		}

		private static bool IsAboutMods(string text)
		{
			string text2 = text.ToLowerInvariant();
			string[] markers = Markers;
			foreach (string value in markers)
			{
				if (text2.Contains(value))
				{
					return true;
				}
			}
			return false;
		}

		private static string Shorten(string s)
		{
			if (s.Length > 60)
			{
				return s.Substring(0, 57) + "...";
			}
			return s;
		}
	}
	internal static class NetGraph
	{
		private const int GraphWidth = 300;

		private const int GraphHeight = 60;

		private const float FpsScaleMax = 200f;

		private const float PingScaleMax = 200f;

		private static ManualLogSource _log;

		private static int _mode;

		private static float _smoothedDelta;

		private static float _fps;

		private static long _ping;

		private static readonly float[] _fpsHistory = new float[300];

		private static readonly float[] _pingHistory = new float[300];

		private static int _cursor;

		private static GUIStyle _style;

		private static Texture2D _dot;

		public static int Mode
		{
			get
			{
				return _mode;
			}
			set
			{
				int num = Mathf.Clamp(value, 0, 2);
				if (_mode != num)
				{
					_mode = num;
					_log.LogInfo((object)$"[NetGraph] mode -> {_mode}");
				}
			}
		}

		public static void Install(ManualLogSource log, int mode)
		{
			_log = log;
			_mode = Mathf.Clamp(mode, 0, 2);
			CmrHost.Tick += OnTick;
			CmrHost.GuiDraw += OnGui;
			_log.LogInfo((object)$"[NetGraph] installed, mode {_mode}");
		}

		private static void OnTick()
		{
			if (_mode != 0)
			{
				_smoothedDelta += (Time.unscaledDeltaTime - _smoothedDelta) * 0.1f;
				_fps = ((_smoothedDelta > 0f) ? (1f / _smoothedDelta) : 0f);
				if ((Object)(object)InstanceFinder.TimeManager != (Object)null)
				{
					_ping = InstanceFinder.TimeManager.RoundTripTime;
				}
				if (_mode >= 2)
				{
					_fpsHistory[_cursor] = _fps;
					_pingHistory[_cursor] = _ping;
					_cursor = (_cursor + 1) % 300;
				}
			}
		}

		private static void OnGui()
		{
			//IL_0019: 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)
			if (_mode != 0)
			{
				EnsureStyles();
				int width = Screen.width;
				int height = Screen.height;
				GUI.color = Color.white;
				GUI.Label(new Rect((float)(width - 310), (float)(height - 100), 300f, 80f), $"FPS: {Mathf.CeilToInt(_fps)}\nMS: {_ping}", _style);
				if (_mode >= 2)
				{
					DrawGraph(width - 310, height - 80);
				}
			}
		}

		private static void DrawGraph(float x, float y)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			float num = y + 60f;
			for (int i = 0; i < 300; i += 2)
			{
				int num2 = (_cursor + i) % 300;
				float num3 = Mathf.Clamp(_fpsHistory[num2] / 200f * 60f, 0f, 60f);
				float num4 = Mathf.Clamp(_pingHistory[num2] / 200f * 60f, 0f, 60f);
				GUI.color = Color.green;
				GUI.DrawTexture(new Rect(x + (float)i, num - num3, 1f, 2f), (Texture)(object)_dot);
				GUI.color = Color.yellow;
				GUI.DrawTexture(new Rect(x + (float)i, num - num4, 1f, 2f), (Texture)(object)_dot);
			}
			GUI.color = Color.white;
		}

		private static void EnsureStyles()
		{
			//IL_0008: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			if (_style == null)
			{
				GUIStyle val = new GUIStyle
				{
					alignment = (TextAnchor)8,
					fontSize = 14
				};
				val.normal.textColor = Color.white;
				_style = val;
				_dot = new Texture2D(1, 1);
				_dot.SetPixel(0, 0, Color.white);
				_dot.Apply();
				((Object)_dot).hideFlags = (HideFlags)61;
			}
		}
	}
	[BepInPlugin("cmr.theanine", "Theanine", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class TheaninePlugin : BaseUnityPlugin
	{
		public const string ModGuid = "cmr.theanine";

		public const string ModName = "Theanine";

		public const string ModVersion = "1.1.0";

		private readonly Harmony _harmony = new Harmony("cmr.theanine");

		private void Awake()
		{
			TheanineSettings.Bind(((BaseUnityPlugin)this).Config);
			Install("UI host", delegate
			{
				CmrHost.Install(((BaseUnityPlugin)this).Logger);
			});
			Install("Killfeed", delegate
			{
				Killfeed.Install(((BaseUnityPlugin)this).Logger, TheanineSettings.DisableKillfeed.Value);
				Wire(TheanineSettings.DisableKillfeed, delegate(bool v)
				{
					Killfeed.Enabled = v;
				});
			});
			Install("Mods popup", delegate
			{
				ModsPopup.Install(((BaseUnityPlugin)this).Logger, TheanineSettings.DisableModsPopout.Value);
				_harmony.PatchAll(typeof(ModsPopup));
				Wire(TheanineSettings.DisableModsPopout, delegate(bool v)
				{
					ModsPopup.Enabled = v;
				});
			});
			Install("HUD hider", delegate
			{
				HudHider.Install(((BaseUnityPlugin)this).Logger, TheanineSettings.DisableHud.Value, TheanineSettings.HudIncludeSpeedometer.Value, TheanineSettings.HudIncludeCrosshair.Value, TheanineSettings.HudIncludeAmmo.Value, TheanineSettings.DisableGrabPopup.Value);
				Wire(TheanineSettings.DisableHud, delegate(bool v)
				{
					HudHider.Enabled = v;
				});
				Wire(TheanineSettings.HudIncludeSpeedometer, delegate(bool v)
				{
					HudHider.IncludeSpeedometer = v;
				});
				Wire(TheanineSettings.HudIncludeCrosshair, delegate(bool v)
				{
					HudHider.IncludeCrosshair = v;
				});
				Wire(TheanineSettings.HudIncludeAmmo, delegate(bool v)
				{
					HudHider.IncludeAmmo = v;
				});
				Wire(TheanineSettings.DisableGrabPopup, delegate(bool v)
				{
					HudHider.HideGrabPopup = v;
				});
			});
			Install("NetGraph", delegate
			{
				NetGraph.Install(((BaseUnityPlugin)this).Logger, TheanineSettings.NetGraphMode.Value);
				Wire(TheanineSettings.NetGraphMode, delegate(int v)
				{
					NetGraph.Mode = v;
				});
			});
			Install("Mod menu (optional)", delegate
			{
				ModMenuDecoration.Apply(typeof(TheaninePlugin), "Theanine.Resources.icon.png", "Interface quality of life.", ((BaseUnityPlugin)this).Logger, Array.Empty<ConfigEntryBase>());
			});
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Theanine 1.1.0 - ready");
		}

		private void Install(string name, Action install)
		{
			try
			{
				install();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[Features] " + name + ": installed"));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Features] " + name + ": NOT installed - " + ex.GetType().Name + ": " + ex.Message));
			}
		}

		private void Wire<T>(ConfigEntry<T> entry, Action<T> apply)
		{
			entry.SettingChanged += delegate
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Settings] {((ConfigEntryBase)entry).Definition.Section}/{((ConfigEntryBase)entry).Definition.Key} -> {entry.Value}");
				apply(entry.Value);
			};
		}
	}
	internal static class TheanineSettings
	{
		public static ConfigEntry<bool> DisableKillfeed { get; private set; }

		public static ConfigEntry<bool> DisableModsPopout { get; private set; }

		public static ConfigEntry<int> NetGraphMode { get; private set; }

		public static ConfigEntry<bool> DisableHud { get; private set; }

		public static ConfigEntry<bool> HudIncludeSpeedometer { get; private set; }

		public static ConfigEntry<bool> HudIncludeCrosshair { get; private set; }

		public static ConfigEntry<bool> HudIncludeAmmo { get; private set; }

		public static ConfigEntry<bool> DisableGrabPopup { get; private set; }

		public static void Bind(ConfigFile cfg)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			DisableKillfeed = cfg.Bind<bool>("UI", "DisableKillfeed", false, "Hide the killfeed.");
			DisableModsPopout = cfg.Bind<bool>("UI", "DisableModsPopout", false, "Hide the game's 'mods detected' warning.");
			NetGraphMode = cfg.Bind<int>("UI", "NetGraph", 0, new ConfigDescription("FPS and ping overlay. 0 = off, 1 = text, 2 = text and graph.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
			DisableHud = cfg.Bind<bool>("UI", "DisableHud", false, "Hide the HUD: the on-screen interface and the 3D display on the weapon.");
			HudIncludeSpeedometer = cfg.Bind<bool>("UI", "HudIncludeSpeedometer", false, "Hide the speedometer too when the HUD is hidden.");
			HudIncludeCrosshair = cfg.Bind<bool>("UI", "HudIncludeCrosshair", false, "Hide the crosshair too when the HUD is hidden.");
			HudIncludeAmmo = cfg.Bind<bool>("UI", "HudIncludeAmmo", true, "Hide the ammo counter too when the HUD is hidden.");
			DisableGrabPopup = cfg.Bind<bool>("UI", "DisableGrabPopup", false, "Hide the \"weapon name [F]\" prompt shown when standing on a pickup.");
		}
	}
}