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();
}
}
}