Decompiled source of CustomColorUI v2.5.0

Mods/CustomColorUI.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib.BoneMenu;
using CustomColorUI;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
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: MelonInfo(typeof(Main), "Custom ColorUI", "2.5.0", "Rav & claudyboi", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("CustomColorUI")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CustomColorUI")]
[assembly: AssemblyTitle("CustomColorUI")]
[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 CustomColorUI
{
	public class Main : MelonMod
	{
		private class Tracked
		{
			public Color original;

			public Color applied;
		}

		public static Main Inst;

		private MelonPreferences_Category _cfg;

		private MelonPreferences_Entry<bool> _enabled;

		private MelonPreferences_Entry<string> _hex;

		private MelonPreferences_Entry<float> _strength;

		private MelonPreferences_Entry<bool> _tintText;

		private MelonPreferences_Entry<float> _scanInterval;

		private MelonPreferences_Entry<bool> _showPopup;

		private static readonly string[] Names = new string[30]
		{
			"Crimson", "Red", "Blood", "Orange", "Sunset", "Amber", "Gold", "Yellow", "Lime", "Toxic",
			"Green", "Forest", "Mint", "Teal", "Cyan", "Sky", "Ocean", "Blue", "Navy", "Midnight",
			"Indigo", "Purple", "Violet", "Magenta", "Pink", "Hot Pink", "Rose", "Brown", "Silver", "White"
		};

		private static readonly string[] Hexes = new string[30]
		{
			"#E02424", "#FF1744", "#8B0000", "#FF6D00", "#FF7A18", "#FFA000", "#FFC107", "#FFEB3B", "#AEEA00", "#39FF14",
			"#00C853", "#1B5E20", "#69F0AE", "#009688", "#00E5FF", "#4FC3F7", "#1E88E5", "#2962FF", "#0D1B5E", "#1A1F3A",
			"#3F51B5", "#9C27B0", "#B388FF", "#E91E8C", "#FF4FA3", "#FF1493", "#FF8A9B", "#795548", "#B0BEC5", "#FFFFFF"
		};

		private int _index = 0;

		private const float HoldTime = 2f;

		private const float FadeTime = 1f;

		private string _popupTitle = "";

		private string _popupSub = "";

		private float _popupStart = -999f;

		private GUIStyle _titleStyle;

		private GUIStyle _subStyle;

		private readonly Dictionary<int, Tracked> _tracked = new Dictionary<int, Tracked>();

		private Color _target = Color.white;

		private float _nextScan;

		private float _burstUntil;

		private bool _isAndroid;

		private bool _hookActive;

		public override void OnInitializeMelon()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			Inst = this;
			_isAndroid = (int)Application.platform == 11;
			_cfg = MelonPreferences.CreateCategory("CustomColorUI", "Custom ColorUI");
			_enabled = _cfg.CreateEntry<bool>("Enabled", true, "Enable UI recolor", (string)null, false, false, (ValueValidator)null, (string)null);
			_hex = _cfg.CreateEntry<string>("ColorHex", "#E02424", "UI color (hex)", (string)null, false, false, (ValueValidator)null, (string)null);
			_strength = _cfg.CreateEntry<float>("Strength", 0.85f, "Tint strength 0-1", (string)null, false, false, (ValueValidator)null, (string)null);
			_tintText = _cfg.CreateEntry<bool>("TintText", false, "Also tint text", (string)null, false, false, (ValueValidator)null, (string)null);
			_scanInterval = _cfg.CreateEntry<float>("ScanSeconds", 0.5f, "Backup rescan interval (sec)", (string)null, false, false, (ValueValidator)null, (string)null);
			_showPopup = _cfg.CreateEntry<bool>("ShowPopup", true, "Show color name popup (flatscreen)", (string)null, false, false, (ValueValidator)null, (string)null);
			ParseTarget();
			SyncIndexFromHex();
			InstallInstantHook();
			BuildMenu();
			((MelonBase)this).LoggerInstance.Msg("Custom ColorUI 2.5.0 loaded. " + (_hookActive ? "Instant recolor: ON. " : "Instant hook unavailable, using fast scan. ") + (_isAndroid ? "Quest: use BoneMenu > Custom ColorUI." : "BoneMenu > Custom ColorUI, or F5 prev / F6 next / F7 on-off / F8 reload."));
		}

		private void InstallInstantHook()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			try
			{
				MethodInfo method = typeof(Graphic).GetMethod("OnEnable", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo method2 = typeof(Main).GetMethod("OnGraphicEnabled", BindingFlags.Static | BindingFlags.NonPublic);
				if (method == null || method2 == null)
				{
					((MelonBase)this).LoggerInstance.Warning("Could not find Graphic.OnEnable, falling back to fast scanning.");
					return;
				}
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_hookActive = true;
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Instant hook failed (" + ex.Message + "), falling back to fast scanning.");
			}
		}

		private static void OnGraphicEnabled(Graphic __instance)
		{
			Main inst = Inst;
			if (inst == null || (Object)(object)__instance == (Object)null || !inst._enabled.Value)
			{
				return;
			}
			try
			{
				inst.TintOne(__instance, Mathf.Clamp01(inst._strength.Value));
			}
			catch (Exception)
			{
			}
		}

		private void BuildMenu()
		{
			//IL_000b: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			Page val = Page.Root.CreatePage("Custom ColorUI", Color.cyan, 0, true);
			val.CreateBool("Enabled", Color.white, _enabled.Value, (Action<bool>)OnEnabledChanged);
			val.CreateFunction("Next Color", Color.cyan, (Action)delegate
			{
				StepPreset(1);
			});
			val.CreateFunction("Previous Color", Color.cyan, (Action)delegate
			{
				StepPreset(-1);
			});
			Page val2 = val.CreatePage("All Colors", Color.white, 0, true);
			for (int num = 0; num < Names.Length; num++)
			{
				int idx = num;
				val2.CreateFunction(Names[num], MenuColor(Hexes[num]), (Action)delegate
				{
					PickPreset(idx);
				});
			}
			val.CreateFloat("Strength", Color.white, _strength.Value, 0.05f, 0f, 1f, (Action<float>)OnStrengthChanged);
			val.CreateBool("Tint Text", Color.white, _tintText.Value, (Action<bool>)OnTintTextChanged);
			val.CreateBool("Popup (flatscreen)", Color.white, _showPopup.Value, (Action<bool>)OnPopupChanged);
		}

		private static Color MenuColor(string hex)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			if (!ColorUtility.TryParseHtmlString(hex, ref val))
			{
				return Color.white;
			}
			float num = 0.299f * val.r + 0.587f * val.g + 0.114f * val.b;
			return (num < 0.3f) ? Color.Lerp(val, Color.white, 0.55f) : val;
		}

		private void OnEnabledChanged(bool v)
		{
			_enabled.Value = v;
			if (v)
			{
				ForceReapply();
			}
			else
			{
				RestoreAll();
			}
			_cfg.SaveToFile(false);
			ShowPopup(v ? "Custom ColorUI ON" : "Custom ColorUI OFF", v ? Names[_index] : "Original colors restored");
		}

		private void OnStrengthChanged(float v)
		{
			_strength.Value = Mathf.Clamp01(v);
			if (_enabled.Value)
			{
				ForceReapply();
			}
		}

		private void OnTintTextChanged(bool v)
		{
			_tintText.Value = v;
			if (_enabled.Value)
			{
				ForceReapply();
			}
			_cfg.SaveToFile(false);
		}

		private void OnPopupChanged(bool v)
		{
			_showPopup.Value = v;
			_cfg.SaveToFile(false);
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			_tracked.Clear();
			_burstUntil = Time.unscaledTime + 5f;
			_nextScan = 0f;
			if (_enabled.Value)
			{
				ScanAndApply();
			}
		}

		public override void OnUpdate()
		{
			if (!_isAndroid)
			{
				if (Input.GetKeyDown((KeyCode)286))
				{
					StepPreset(-1);
				}
				if (Input.GetKeyDown((KeyCode)287))
				{
					StepPreset(1);
				}
				if (Input.GetKeyDown((KeyCode)288))
				{
					OnEnabledChanged(!_enabled.Value);
				}
				if (Input.GetKeyDown((KeyCode)289))
				{
					_cfg.LoadFromFile(true);
					ParseTarget();
					SyncIndexFromHex();
					ForceReapply();
					ShowPopup("Config reloaded", _hex.Value);
				}
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime >= _nextScan)
			{
				float num = ((unscaledTime < _burstUntil) ? 0.15f : Mathf.Max(0.2f, _scanInterval.Value));
				_nextScan = unscaledTime + num;
				if (_enabled.Value)
				{
					ScanAndApply();
				}
			}
		}

		public override void OnGUI()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: 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_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			if (!_showPopup.Value)
			{
				return;
			}
			float num = Time.unscaledTime - _popupStart;
			if (!(num < 0f) && !(num > 3f))
			{
				float num2 = ((num < 2f) ? 1f : (1f - (num - 2f) / 1f));
				num2 = Mathf.Clamp01(num2);
				if (_titleStyle == null)
				{
					_titleStyle = new GUIStyle(GUI.skin.label);
					_titleStyle.fontSize = 34;
					_titleStyle.fontStyle = (FontStyle)1;
					_titleStyle.alignment = (TextAnchor)4;
					_subStyle = new GUIStyle(GUI.skin.label);
					_subStyle.fontSize = 18;
					_subStyle.alignment = (TextAnchor)4;
				}
				float num3 = 520f;
				float num4 = 110f;
				float num5 = ((float)Screen.width - num3) * 0.5f;
				float num6 = 70f;
				Color color = GUI.color;
				GUI.color = new Color(0f, 0f, 0f, 0.6f * num2);
				GUI.DrawTexture(new Rect(num5, num6, num3, num4), (Texture)(object)Texture2D.whiteTexture);
				Color target = _target;
				GUI.color = new Color(target.r, target.g, target.b, num2);
				GUI.DrawTexture(new Rect(num5, num6, 14f, num4), (Texture)(object)Texture2D.whiteTexture);
				GUI.DrawTexture(new Rect(num5, num6 + num4 - 5f, num3, 5f), (Texture)(object)Texture2D.whiteTexture);
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(num5 + 14f, num6 + 8f, num3 - 14f, 60f);
				_titleStyle.normal.textColor = new Color(0f, 0f, 0f, num2);
				GUI.Label(new Rect(((Rect)(ref val)).x + 2f, ((Rect)(ref val)).y + 2f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), _popupTitle, _titleStyle);
				_titleStyle.normal.textColor = new Color(target.r, target.g, target.b, num2);
				GUI.Label(val, _popupTitle, _titleStyle);
				_subStyle.normal.textColor = new Color(1f, 1f, 1f, 0.9f * num2);
				GUI.Label(new Rect(num5 + 14f, num6 + 64f, num3 - 14f, 30f), _popupSub, _subStyle);
				GUI.color = color;
			}
		}

		private void ShowPopup(string title, string sub)
		{
			_popupTitle = title;
			_popupSub = sub;
			_popupStart = Time.unscaledTime;
		}

		private void StepPreset(int dir)
		{
			PickPreset(((_index + dir) % Hexes.Length + Hexes.Length) % Hexes.Length);
		}

		private void PickPreset(int idx)
		{
			_index = idx;
			_hex.Value = Hexes[_index];
			_enabled.Value = true;
			ParseTarget();
			ForceReapply();
			_cfg.SaveToFile(false);
			ShowPopup(Names[_index], Hexes[_index] + "    (" + (_index + 1) + "/" + Hexes.Length + ")");
			((MelonBase)this).LoggerInstance.Msg("UI color: " + Names[_index] + " " + Hexes[_index]);
		}

		private void ParseTarget()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Color target = default(Color);
			if (ColorUtility.TryParseHtmlString(_hex.Value, ref target))
			{
				_target = target;
				return;
			}
			((MelonBase)this).LoggerInstance.Warning("Bad hex '" + _hex.Value + "', using white.");
			_target = Color.white;
		}

		private void SyncIndexFromHex()
		{
			for (int i = 0; i < Hexes.Length; i++)
			{
				if (string.Equals(Hexes[i], _hex.Value, StringComparison.OrdinalIgnoreCase))
				{
					_index = i;
					break;
				}
			}
		}

		private void ForceReapply()
		{
			RestoreAll();
			ScanAndApply();
			_nextScan = Time.unscaledTime + Mathf.Max(0.2f, _scanInterval.Value);
		}

		private void TintOne(Graphic g, float s)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)g == (Object)null) && ((Object)(object)((Il2CppObjectBase)g).TryCast<Image>() != (Object)null || _tintText.Value))
			{
				int instanceID = ((Object)g).GetInstanceID();
				Color color = g.color;
				if (!_tracked.TryGetValue(instanceID, out var value))
				{
					value = new Tracked
					{
						original = color,
						applied = color
					};
					_tracked[instanceID] = value;
				}
				else if (!Approx(color, value.applied))
				{
					value.original = color;
				}
				Color val = Color.Lerp(value.original, _target, s);
				val.a = value.original.a;
				if (!Approx(color, val))
				{
					g.color = val;
				}
				value.applied = val;
			}
		}

		private void ScanAndApply()
		{
			try
			{
				Il2CppArrayBase<Graphic> val = Object.FindObjectsOfType<Graphic>();
				float s = Mathf.Clamp01(_strength.Value);
				for (int i = 0; i < val.Length; i++)
				{
					TintOne(val[i], s);
				}
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Warning("Scan failed: " + ex.Message);
			}
		}

		private void RestoreAll()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Il2CppArrayBase<Graphic> val = Object.FindObjectsOfType<Graphic>();
				for (int i = 0; i < val.Length; i++)
				{
					Graphic val2 = val[i];
					if (!((Object)(object)val2 == (Object)null) && _tracked.TryGetValue(((Object)val2).GetInstanceID(), out var value))
					{
						val2.color = value.original;
					}
				}
			}
			catch (Exception)
			{
			}
			_tracked.Clear();
		}

		private static bool Approx(Color a, Color b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Abs(a.r - b.r) < 0.004f && Mathf.Abs(a.g - b.g) < 0.004f && Mathf.Abs(a.b - b.b) < 0.004f && Mathf.Abs(a.a - b.a) < 0.004f;
		}

		public override void OnDeinitializeMelon()
		{
			RestoreAll();
		}
	}
}