Decompiled source of Theanine v1.0.0

Theanine.dll

Decompiled 4 hours ago
using System;
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.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+035ee42632884b38ea937935eb423d7c7e886381")]
[assembly: AssemblyProduct("Theanine")]
[assembly: AssemblyTitle("Theanine")]
[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 Theanine
{
	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.0.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.0.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("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.0.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 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>()));
		}
	}
}