Decompiled source of Speedometer v1.2.5

BepInEx/plugins/Speedometer/Speedometer.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Speedometer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Speedometer")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyInformationalVersion("1.2.3")]
[assembly: AssemblyProduct("Speedometer")]
[assembly: AssemblyTitle("Speedometer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 Speedometer
{
	[BepInPlugin("Speedometer", "Speedometer", "1.2.3")]
	public class Plugin : BaseUnityPlugin
	{
		private enum DisplayMode
		{
			None,
			MpS,
			KmH,
			MpH
		}

		private static Image _speedBar;

		private static TextMeshProUGUI _speedLabel;

		private static TextMeshProUGUI _zipLabel;

		private static ConfigFile _config;

		private static ConfigEntry<bool> _useTotalSpeed;

		private static ConfigEntry<float> _customSpeedCap;

		private static float _customSpeedCapKmh;

		private static ConfigEntry<bool> _zipSpeedEnabled;

		private static ConfigEntry<DisplayMode> _displayMode;

		private static ConfigEntry<Color> _speedBarColor;

		private static ConfigEntry<bool> _displayOverMaxColor;

		private static ConfigEntry<Color> _overMaxColor;

		private static ConfigEntry<bool> _outlineEnabled;

		private static Material _outlineMaterial;

		private static ConfigEntry<bool> _useMonoSpace;

		private const float KmhFactor = 3.6f;

		private const float MphFactor = 2.236936f;

		private const string SpeedLabelFormat = "{0} {1}";

		private const string CloseMonoTag = "</mspace>";

		private const string StartMonoTag = "<mspace=1.133em>";

		private const string SpeedLabelFormatMono = "<mspace=1.133em>{0}</mspace> {1}";

		private const string MpsLabel = "M/S";

		private const string KmhLabel = "KM/H";

		private const string MphLabel = "MPH";

		private static readonly CultureInfo _labelCulture = CultureInfo.InvariantCulture;

		private static StringBuilder _labelBuilder;

		private static bool _speedOverMax;

		private const string SettingsHeader = "Settings";

		private const string CosmeticHeader = "Cosmetic/Visual";

		private const string TotalSpeedSetting = "Whether to use the lateral (forward) speed or the total speed of movement.";

		private const string ZipSpeedSetting = "Whether to display the stored speed for a billboard zip glitch or not.";

		private const string CustomCapSetting = "When set to above 0, the speed bar will use this value instead of the game's max speed value to calculate the fill percentage (in km/h).\nIf you use Movement Plus, a value of 400 is a good starting point.";

		private const string DisplaySetting = "How to display the speed as text.";

		private const string OverMaxSetting = "Whether to change the speedometers color when going over the maximum speed.";

		private const string OutlineSetting = "Enables an outline around the speed and trick counter label, for better readability.";

		private const string MonoSpaceSetting = "Makes it so numbers are mono-spaced, preventing jittery text when it changes frequently.";

		private static Plugin _instance;

		private void Awake()
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Speedometer is loaded!");
			_instance = this;
			_config = ((BaseUnityPlugin)this).Config;
			_useTotalSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Use Total Speed?", false, "Whether to use the lateral (forward) speed or the total speed of movement.");
			_customSpeedCap = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Custom Speed Cap", 67.5f, "When set to above 0, the speed bar will use this value instead of the game's max speed value to calculate the fill percentage (in km/h).\nIf you use Movement Plus, a value of 400 is a good starting point.");
			_zipSpeedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Display Stored Zip Speed?", false, "Whether to display the stored speed for a billboard zip glitch or not.");
			_displayMode = ((BaseUnityPlugin)this).Config.Bind<DisplayMode>("Cosmetic/Visual", "Speed Display Mode", DisplayMode.KmH, "How to display the speed as text.");
			_speedBarColor = _config.Bind<Color>("Cosmetic/Visual", "Speedometer Color", new Color(0.839f, 0.349f, 0.129f), (ConfigDescription)null);
			_displayOverMaxColor = _config.Bind<bool>("Cosmetic/Visual", "Display Threshold Color?", true, "Whether to change the speedometers color when going over the maximum speed.");
			_overMaxColor = _config.Bind<Color>("Cosmetic/Visual", "Threshold Color", new Color(0.898f, 0.098f, 0.443f), (ConfigDescription)null);
			_outlineEnabled = _config.Bind<bool>("Cosmetic/Visual", "Enable Text Outline?", true, "Enables an outline around the speed and trick counter label, for better readability.");
			_useMonoSpace = _config.Bind<bool>("Cosmetic/Visual", "Enable Monospace Numbers?", true, "Makes it so numbers are mono-spaced, preventing jittery text when it changes frequently.");
			_customSpeedCapKmh = ((_customSpeedCap.Value > 0.001f) ? (_customSpeedCap.Value / 3.6f) : 0f);
			Harmony val = new Harmony("sgiygas.speedometer");
			val.PatchAll();
		}

		public static void InitializeUI(Transform speedBarBackground, Image speedBar, TextMeshProUGUI tricksLabel)
		{
			//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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			if (_useMonoSpace.Value)
			{
				_labelBuilder = new StringBuilder();
			}
			((Object)speedBarBackground).name = "speedBarBackground";
			((Object)speedBar).name = "speedBar";
			speedBarBackground.position += Vector3.down * 7.5f;
			speedBarBackground.localScale = new Vector3(1.02f, 1.16f, 1f);
			_speedBar = speedBar;
			((Graphic)_speedBar).color = _speedBarColor.Value;
			if (_outlineEnabled.Value)
			{
				TMProFontLocalizer component = ((Component)tricksLabel).GetComponent<TMProFontLocalizer>();
				((Behaviour)component).enabled = false;
				if ((Object)(object)_outlineMaterial == (Object)null)
				{
					_outlineMaterial = ((TMP_Text)tricksLabel).fontMaterial;
					_outlineMaterial.EnableKeyword(ShaderUtilities.Keyword_Outline);
					_outlineMaterial.SetColor(ShaderUtilities.ID_OutlineColor, Color.black);
					_outlineMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0.075f);
				}
				((TMP_Text)tricksLabel).fontMaterial = _outlineMaterial;
			}
			if (_displayMode.Value != 0)
			{
				_speedLabel = Object.Instantiate<TextMeshProUGUI>(tricksLabel, ((TMP_Text)tricksLabel).transform.parent);
				((TMP_Text)_speedLabel).transform.localPosition = ((TMP_Text)tricksLabel).transform.localPosition;
				Transform transform = ((TMP_Text)tricksLabel).transform;
				transform.localPosition += Vector3.up * 32f;
				if (_zipSpeedEnabled.Value)
				{
					_zipLabel = Object.Instantiate<TextMeshProUGUI>(tricksLabel, ((TMP_Text)tricksLabel).transform.parent);
					((TMP_Text)_zipLabel).transform.localPosition = ((TMP_Text)tricksLabel).transform.localPosition;
					UpdateLastSpeed(0f);
					Transform transform2 = ((TMP_Text)tricksLabel).transform;
					transform2.localPosition += Vector3.up * 32f;
				}
			}
		}

		public static void UpdateSpeedBar(Player player)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			float num = ((_customSpeedCapKmh > 0.001f) ? _customSpeedCapKmh : player.maxMoveSpeed);
			float num2 = (_useTotalSpeed.Value ? player.GetTotalSpeed() : player.GetForwardSpeed());
			num2 = Mathf.Max(0f, num2);
			_speedBar.fillAmount = num2 / (num - 0.01f);
			if (_displayOverMaxColor.Value)
			{
				if (num2 > num + 0.01f)
				{
					if (!_speedOverMax)
					{
						_speedOverMax = true;
						((Graphic)_speedBar).color = _overMaxColor.Value;
					}
				}
				else if (_speedOverMax)
				{
					_speedOverMax = false;
					((Graphic)_speedBar).color = _speedBarColor.Value;
				}
			}
			if (!((Object)(object)_speedLabel == (Object)null))
			{
				SetSpeedLabelFormatted(num2, _speedLabel);
			}
		}

		public static void UpdateLastSpeed(float speed)
		{
			if (_zipSpeedEnabled.Value && !((Object)(object)_zipLabel == (Object)null))
			{
				SetSpeedLabelFormatted(speed, _zipLabel);
			}
		}

		private static void SetSpeedLabelFormatted(float speed, TextMeshProUGUI label)
		{
			string format = (_useMonoSpace.Value ? "<mspace=1.133em>{0}</mspace> {1}" : "{0} {1}");
			string arg = "M/S";
			if (_displayMode.Value == DisplayMode.KmH)
			{
				speed *= 3.6f;
				arg = "KM/H";
			}
			else if (_displayMode.Value == DisplayMode.MpH)
			{
				speed *= 2.236936f;
				arg = "MPH";
			}
			string text = string.Format(_labelCulture, "{0:0.0}", speed);
			if (_useMonoSpace.Value)
			{
				_labelBuilder.Clear();
				int num = text.IndexOf(_labelCulture.NumberFormat.NumberDecimalSeparator);
				_labelBuilder.Append(text);
				_labelBuilder.Insert(num, "</mspace>");
				_labelBuilder.Insert(num + "</mspace>".Length + 1, "<mspace=1.133em>");
				text = _labelBuilder.ToString();
			}
			((TMP_Text)label).SetText(string.Format(_labelCulture, format, text, arg), true);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Speedometer";

		public const string PLUGIN_NAME = "Speedometer";

		public const string PLUGIN_VERSION = "1.2.3";
	}
}
namespace Speedometer.Patches
{
	[HarmonyPatch(typeof(GameplayUI), "Init")]
	public class GameplayUIInit
	{
		public static void Postfix(Image ___chargeBar, TextMeshProUGUI ___tricksInComboLabel)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			GameObject gameObject = ((Component)((Component)___chargeBar).transform.parent).gameObject;
			Image component = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent).GetComponent<Image>();
			((Component)component).transform.SetSiblingIndex(gameObject.transform.GetSiblingIndex());
			Object.DestroyImmediate((Object)(object)((Component)((Component)component).transform.GetChild(0)).gameObject);
			Image val = null;
			foreach (Transform item in ((Component)component).transform)
			{
				Transform val2 = item;
				val = ((Component)val2).GetComponent<Image>();
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			((Graphic)val).material = ((Graphic)component).material;
			Plugin.InitializeUI(((Component)component).transform, val, ___tricksInComboLabel);
		}
	}
	[HarmonyPatch(typeof(Player), "ChargeAndSpeedDisplayUpdate")]
	public class ChargeAndSpeedDisplayUpdatePatch
	{
		public static void Postfix(Player __instance)
		{
			Plugin.UpdateSpeedBar(__instance);
		}
	}
	[HarmonyPatch(typeof(WallrunLineAbility), "FixedUpdateAbility")]
	public class WallrunLineAbilityFixedUpdate
	{
		public static void Postfix(float ___lastSpeed)
		{
			Plugin.UpdateLastSpeed(___lastSpeed);
		}
	}
	[HarmonyPatch(typeof(WallrunLineAbility), "Jump")]
	public class WallrunLineAbilityJump
	{
		public static void Postfix(float ___lastSpeed)
		{
			Plugin.UpdateLastSpeed(___lastSpeed);
		}
	}
}