using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CleanStart")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CleanStart")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("08250d92-f453-41d5-9ba6-b215ba66175c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 CleanStart
{
internal static class CleanStartCore
{
private static bool _initialized;
private static string _lastSceneName;
internal static void Init()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (!_initialized)
{
_initialized = true;
LogBridge.Info("Clean Start initialized.");
_lastSceneName = null;
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).IsValid())
{
HandleSceneChange(((Scene)(ref activeScene)).name, force: true);
}
}
}
internal static void Deinit()
{
if (_initialized)
{
MainMenuTweaks.Reset();
_lastSceneName = null;
_initialized = false;
LogBridge.Info("Clean Start deinitialized.");
}
}
internal static void Tick()
{
//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)
if (_initialized)
{
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).IsValid())
{
HandleSceneChange(((Scene)(ref activeScene)).name);
MainMenuTweaks.Tick(Time.realtimeSinceStartup);
}
}
}
private static void HandleSceneChange(string sceneName, bool force = false)
{
if (force || !string.Equals(_lastSceneName, sceneName, StringComparison.Ordinal))
{
_lastSceneName = sceneName;
if (sceneName == "MainMenu")
{
MainMenuTweaks.ScheduleApply();
}
else
{
MainMenuTweaks.Reset();
}
}
}
}
internal static class MainMenuTweaks
{
private const float RetryDelaySeconds = 0.25f;
private const int MaxRetryAttempts = 100;
private static bool _appliedThisScene;
private static bool _pendingApply;
private static float _nextAttemptTime;
private static int _attemptCounter;
private static bool _loggedMainHierarchy;
private static bool _extraButtonsAnchored;
private static bool _leaderboardsAnchored;
private const string MenuPath = "UI/Tabs/Menu";
private const string ContentPath = "UI/Tabs/Menu/Content";
private const string MainPath = "UI/Tabs/Menu/Content/Main";
private const string ButtonsPath = "UI/Tabs/Menu/Content/Main/Buttons";
private const string LeaderboardsPath = "UI/Tabs/Menu/Content/Main/W_Leaderboards";
private const string ExtraButtonsPath = "UI/Tabs/Menu/Content/Main/ExtraButtons/";
private static readonly string ExtraButtonsNodePath = "UI/Tabs/Menu/Content/Main/ExtraButtons/".TrimEnd('/');
private const float PanelScale = 0.65f;
private static readonly Vector3 PanelScaleVector = Vector3.one * 0.65f;
private static readonly Vector3[] ParentCorners = (Vector3[])(object)new Vector3[4];
private static readonly Vector3[] ChildCorners = (Vector3[])(object)new Vector3[4];
internal static void ScheduleApply()
{
if (!_appliedThisScene)
{
_pendingApply = true;
_attemptCounter = 0;
_nextAttemptTime = 0f;
}
}
internal static void Reset()
{
_appliedThisScene = false;
_pendingApply = false;
_attemptCounter = 0;
_nextAttemptTime = 0f;
_loggedMainHierarchy = false;
_extraButtonsAnchored = false;
_leaderboardsAnchored = false;
}
internal static void Tick(float realtimeNow)
{
if (!_pendingApply || _appliedThisScene || realtimeNow < _nextAttemptTime)
{
return;
}
if (TryApply(_attemptCounter >= 99))
{
_appliedThisScene = true;
_pendingApply = false;
return;
}
_attemptCounter++;
if (_attemptCounter >= 100)
{
LogBridge.Warn($"Menu tweaks failed after {100} attempts.");
_pendingApply = false;
}
else
{
_nextAttemptTime = realtimeNow + 0.25f;
}
}
private static bool TryApply(bool logMissingWarnings)
{
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
try
{
GameObject val = GameObject.Find("UI");
if ((Object)(object)val == (Object)null)
{
if (logMissingWarnings)
{
LogBridge.Warn("'UI' root not found in MainMenu.");
}
return false;
}
Transform val2 = val.transform.Find("Cash");
if ((Object)(object)val2 != (Object)null)
{
DisableObject(((Component)val2).gameObject, "UI/Cash");
}
else if (logMissingWarnings)
{
LogBridge.Warn("'UI/Cash' not found.");
}
Transform val3 = val.transform.Find("Tabs");
if ((Object)(object)val3 == (Object)null)
{
if (logMissingWarnings)
{
LogBridge.Warn("'UI/Tabs' not found.");
}
return false;
}
Transform val4 = val3.Find("Menu");
if ((Object)(object)val4 == (Object)null)
{
if (logMissingWarnings)
{
LogBridge.Warn("'UI/Tabs/Menu' not found.");
}
return false;
}
Transform val5 = val4.Find("Logo");
Transform val6 = val4.Find("Content");
if ((Object)(object)val5 == (Object)null)
{
if (logMissingWarnings)
{
LogBridge.Warn("'UI/Tabs/Menu/Logo' not found.");
}
}
else
{
val5.localScale = Vector3.one * 0.25f;
LogBridge.Info("Scaled Logo to 0.25.");
}
if ((Object)(object)val6 == (Object)null)
{
if (logMissingWarnings)
{
LogBridge.Warn("'UI/Tabs/Menu/Content' not found.");
}
return false;
}
Transform val7 = val6.Find("Main");
if ((Object)(object)val7 == (Object)null)
{
if (logMissingWarnings)
{
LogBridge.Warn("'UI/Tabs/Menu/Content/Main' not found.");
}
return false;
}
if (!_loggedMainHierarchy)
{
LogHierarchy(val7, "UI/Tabs/Menu/Content/Main", 2);
_loggedMainHierarchy = true;
}
bool result = DisableQuestWidgets(val7, logMissingWarnings);
DisableExtraButtons(val7, logMissingWarnings);
ApplyTargetScales(val7);
RepositionPanels(val7, logMissingWarnings);
return result;
}
catch (Exception value)
{
LogBridge.Error($"Failed to apply main menu tweaks: {value}");
return false;
}
}
private static bool DisableQuestWidgets(Transform main, bool logWhenMissing)
{
Transform val = main.Find("W_Quests");
if ((Object)(object)val != (Object)null)
{
DisableRelativeChild(val, "WindowLayers/Content", "UI/Tabs/Menu/Content/Main/W_Quests/WindowLayers/Content", logWhenMissing);
DisableRelativeChild(val, "RawImage", "UI/Tabs/Menu/Content/Main/W_Quests/RawImage", logWhenMissing: false);
DisableObject(((Component)val).gameObject, "UI/Tabs/Menu/Content/Main/W_Quests");
return true;
}
return DisableDescendantsByName(main, "W_Quests", "UI/Tabs/Menu/Content/Main", logWhenMissing);
}
private static void DisableExtraButtons(Transform main, bool logWhenMissing)
{
Transform val = main.Find("ExtraButtons");
if ((Object)(object)val == (Object)null)
{
if (logWhenMissing)
{
LogBridge.Warn("'" + ExtraButtonsNodePath + "' not found.");
}
}
else
{
DisableDescendant(val, "B_Credits", "UI/Tabs/Menu/Content/Main/ExtraButtons/", logWhenMissing);
DisableDescendant(val, "B_Discord", "UI/Tabs/Menu/Content/Main/ExtraButtons/", logWhenMissing);
DisableDescendant(val, "B_Language", "UI/Tabs/Menu/Content/Main/ExtraButtons/", logWhenMissing);
}
}
private static void ApplyTargetScales(Transform main)
{
//IL_000b: 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_0035: Unknown result type (might be due to invalid IL or missing references)
ScaleChild(main, "Buttons", "UI/Tabs/Menu/Content/Main/Buttons", PanelScaleVector);
ScaleChild(main, "W_Leaderboards", "UI/Tabs/Menu/Content/Main/W_Leaderboards", PanelScaleVector);
ScaleChild(main, "ExtraButtons", ExtraButtonsNodePath, PanelScaleVector);
}
private static void RepositionPanels(Transform main, bool logWarnings)
{
AlignRectToSide(main, "ExtraButtons", ExtraButtonsNodePath, anchorLeft: true, ref _extraButtonsAnchored, logWarnings);
AlignRectToSide(main, "W_Leaderboards", "UI/Tabs/Menu/Content/Main/W_Leaderboards", anchorLeft: false, ref _leaderboardsAnchored, logWarnings);
}
private static bool DisableDescendant(Transform parent, string childName, string pathPrefix, bool logWhenMissing)
{
Transform val = parent.Find(childName);
string text = pathPrefix + childName;
if ((Object)(object)val == (Object)null)
{
if (logWhenMissing)
{
LogBridge.Warn("'" + text + "' not found.");
}
return false;
}
DisableObject(((Component)val).gameObject, text);
return true;
}
private static bool DisableDescendantsByName(Transform root, string targetName, string rootPath, bool logWhenMissing)
{
bool found = false;
TraverseAndDisable(root, root, targetName, rootPath, ref found);
if (!found && logWhenMissing)
{
LogBridge.Warn($"No '{targetName}' nodes found under '{rootPath}'.");
}
return found;
}
private static void TraverseAndDisable(Transform root, Transform current, string targetName, string rootPath, ref bool found)
{
if ((Object)(object)current == (Object)null)
{
return;
}
for (int i = 0; i < current.childCount; i++)
{
Transform child = current.GetChild(i);
if (!((Object)(object)child == (Object)null))
{
if (((Object)child).name == targetName)
{
string text = BuildRelativePath(child, root);
string fullPath = (string.IsNullOrEmpty(text) ? rootPath : (rootPath + "/" + text));
DisableObject(((Component)child).gameObject, fullPath);
found = true;
}
TraverseAndDisable(root, child, targetName, rootPath, ref found);
}
}
}
private static void DisableObject(GameObject target, string fullPath)
{
if ((Object)(object)target == (Object)null)
{
LogBridge.Warn("'" + fullPath + "' not found.");
}
else if (target.activeSelf)
{
target.SetActive(false);
LogBridge.Info("Disabled " + fullPath + ".");
}
}
private static void DisableRelativeChild(Transform parent, string relativePath, string fullPath, bool logWhenMissing)
{
Transform val = (((Object)(object)parent == (Object)null) ? null : parent.Find(relativePath));
if ((Object)(object)val == (Object)null)
{
if (logWhenMissing)
{
LogBridge.Warn("'" + fullPath + "' not found.");
}
}
else
{
DisableObject(((Component)val).gameObject, fullPath);
}
}
private static void AlignRectToSide(Transform parent, string childName, string fullPath, bool anchorLeft, ref bool alreadyNotified, bool logWarnings)
{
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
Transform val = parent.Find(childName);
if ((Object)(object)val == (Object)null)
{
if (logWarnings)
{
LogBridge.Warn("'" + fullPath + "' not found for alignment.");
}
return;
}
RectTransform component = ((Component)val).GetComponent<RectTransform>();
if ((Object)(object)component == (Object)null)
{
if (logWarnings)
{
LogBridge.Warn("'" + fullPath + "' is missing RectTransform, cannot align.");
}
return;
}
LayoutElement val2 = ((Component)val).GetComponent<LayoutElement>();
if ((Object)(object)val2 == (Object)null)
{
val2 = ((Component)val).gameObject.AddComponent<LayoutElement>();
}
bool flag = false;
if (!val2.ignoreLayout)
{
val2.ignoreLayout = true;
flag = true;
}
float num = (anchorLeft ? 0f : 1f);
float y = component.anchorMin.y;
float y2 = component.anchorMax.y;
float y3 = component.pivot.y;
float y4 = component.anchoredPosition.y;
Vector2 val3 = default(Vector2);
((Vector2)(ref val3))..ctor(num, y);
Vector2 val4 = default(Vector2);
((Vector2)(ref val4))..ctor(num, y2);
Vector2 val5 = default(Vector2);
((Vector2)(ref val5))..ctor(num, y3);
if (component.anchorMin != val3)
{
component.anchorMin = val3;
flag = true;
}
if (component.anchorMax != val4)
{
component.anchorMax = val4;
flag = true;
}
if (component.pivot != val5)
{
component.pivot = val5;
flag = true;
}
Vector2 val6 = default(Vector2);
((Vector2)(ref val6))..ctor(0f, y4);
if (!Approximately(Vector2.op_Implicit(component.anchoredPosition), Vector2.op_Implicit(val6)))
{
component.anchoredPosition = val6;
flag = true;
}
Transform parent2 = ((Transform)component).parent;
RectTransform val7 = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null);
if (val7 != null)
{
val7.GetWorldCorners(Il2CppStructArray<Vector3>.op_Implicit(ParentCorners));
component.GetWorldCorners(Il2CppStructArray<Vector3>.op_Implicit(ChildCorners));
float edgeX = GetEdgeX(ParentCorners, anchorLeft);
float num2 = GetEdgeX(ChildCorners, anchorLeft) - edgeX;
if (Mathf.Abs(num2) > 0.5f)
{
((Transform)component).position = ((Transform)component).position - new Vector3(num2, 0f, 0f);
flag = true;
}
}
if (flag && !alreadyNotified)
{
string value = (anchorLeft ? "left" : "right");
LogBridge.Info($"Positioned {fullPath} at the {value} edge.");
alreadyNotified = true;
}
}
private static void ScaleChild(Transform parent, string childName, string fullPath, Vector3 desiredScale)
{
//IL_0058: 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_003f: 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_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
Transform val = parent.Find(childName);
if ((Object)(object)val == (Object)null)
{
LogBridge.Warn("'" + fullPath + "' not found for scaling.");
return;
}
bool flag = false;
RectTransform component = ((Component)val).GetComponent<RectTransform>();
if ((Object)(object)component != (Object)null)
{
if (!Approximately(((Transform)component).localScale, desiredScale))
{
((Transform)component).localScale = desiredScale;
flag = true;
}
}
else if (!Approximately(val.localScale, desiredScale))
{
val.localScale = desiredScale;
flag = true;
}
if (flag)
{
LogBridge.Info($"Scaled {fullPath} to {0.65f:0.00}.");
}
}
private static string BuildRelativePath(Transform node, Transform stopAt)
{
if ((Object)(object)node == (Object)null)
{
return string.Empty;
}
List<string> list = new List<string>();
Transform val = node;
while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)stopAt)
{
list.Add(((Object)val).name);
val = val.parent;
}
list.Reverse();
return string.Join("/", list);
}
private static void LogHierarchy(Transform root, string currentPath, int depthRemaining)
{
if ((Object)(object)root == (Object)null || depthRemaining < 0)
{
return;
}
for (int i = 0; i < root.childCount; i++)
{
Transform child = root.GetChild(i);
if (!((Object)(object)child == (Object)null))
{
string text = currentPath + "/" + ((Object)child).name;
LogBridge.Info(" -> " + text);
if (depthRemaining > 0)
{
LogHierarchy(child, text, depthRemaining - 1);
}
}
}
}
private static float GetEdgeX(Vector3[] corners, bool left)
{
if (corners == null || corners.Length < 4)
{
return 0f;
}
if (!left)
{
return 0.5f * (corners[2].x + corners[3].x);
}
return 0.5f * (corners[0].x + corners[1].x);
}
private static bool Approximately(Vector3 a, Vector3 b)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: 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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (Mathf.Approximately(a.x, b.x) && Mathf.Approximately(a.y, b.y))
{
return Mathf.Approximately(a.z, b.z);
}
return false;
}
}
internal static class LogBridge
{
private const string Prefix = "[CleanStart] ";
internal static Action<string> Info { get; set; } = delegate(string s)
{
Debug.Log(Object.op_Implicit("[CleanStart] " + s));
};
internal static Action<string> Warn { get; set; } = delegate(string s)
{
Debug.LogWarning(Object.op_Implicit("[CleanStart] " + s));
};
internal static Action<string> Error { get; set; } = delegate(string s)
{
Debug.LogError(Object.op_Implicit("[CleanStart] " + s));
};
internal static void UseUnityLogger()
{
Info = delegate(string s)
{
Debug.Log(Object.op_Implicit("[CleanStart] " + s));
};
Warn = delegate(string s)
{
Debug.LogWarning(Object.op_Implicit("[CleanStart] " + s));
};
Error = delegate(string s)
{
Debug.LogError(Object.op_Implicit("[CleanStart] " + s));
};
}
}
[BepInPlugin("com.yourname.cleanstart", "Clean Start", "1.0.1")]
public sealed class BepEntry : BasePlugin
{
private sealed class UpdateDriver : MonoBehaviour
{
public UpdateDriver(IntPtr handle)
: base(handle)
{
}
private void Update()
{
CleanStartCore.Tick();
}
}
private ManualLogSource _log;
private GameObject _driverHost;
private static bool _driverRegistered;
public override void Load()
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
_log = Logger.CreateLogSource("CleanStart");
LogBridge.Info = delegate(string s)
{
_log.LogInfo((object)s);
};
LogBridge.Warn = delegate(string s)
{
_log.LogWarning((object)s);
};
LogBridge.Error = delegate(string s)
{
_log.LogError((object)s);
};
EnsureDriverRegistered();
_driverHost = new GameObject("CleanStart_UpdateDriver");
Object.DontDestroyOnLoad((Object)(object)_driverHost);
((Object)_driverHost).hideFlags = (HideFlags)61;
_driverHost.AddComponent<UpdateDriver>();
CleanStartCore.Init();
_log.LogInfo((object)"Clean Start (BepInEx) loaded.");
}
public override bool Unload()
{
CleanStartCore.Deinit();
if ((Object)(object)_driverHost != (Object)null)
{
Object.Destroy((Object)(object)_driverHost);
_driverHost = null;
}
LogBridge.UseUnityLogger();
if (_log != null)
{
Logger.Sources.Remove((ILogSource)(object)_log);
_log = null;
}
return true;
}
private static void EnsureDriverRegistered()
{
if (!_driverRegistered)
{
ClassInjector.RegisterTypeInIl2Cpp<UpdateDriver>();
_driverRegistered = true;
}
}
}
}