Decompiled source of HonestMainMenu v1.1.0

HonestMainMenu.Il2Cpp.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using HarmonyLib;
using HonestMainMenu;
using HonestMainMenu.Models;
using HonestMainMenu.Patches;
using HonestMainMenu.Services;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.AvatarFramework.Customization;
using Il2CppScheduleOne.Clothing;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Networking;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Tools;
using Il2CppScheduleOne.UI.Input;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(true)]
[assembly: Guid("F2F8CCDD-DA07-47DF-9247-39B991BE39E3")]
[assembly: MelonInfo(typeof(Main), "Honest Main Menu", "1.1.0", "Roach_ (Adrian Nicolae)", "https://github.com/RoachxD/ScheduleOne.HonestMainMenu/releases/latest")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonColor(255, 97, 100, 62)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Roach_")]
[assembly: AssemblyConfiguration("Release_Il2Cpp")]
[assembly: AssemblyCopyright("Copyright © 2025 Roach_ (Adrian Nicolae)")]
[assembly: AssemblyDescription("A MelonLoader mod for Schedule I that adds a true continue button to the main menu.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("HonestMainMenu.Il2Cpp")]
[assembly: AssemblyTitle("HonestMainMenu.Il2Cpp")]
[assembly: NeutralResourcesLanguage("en-GB")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace HonestMainMenu
{
	public class Main : MelonMod
	{
		public override void OnInitializeMelon()
		{
			string text = "IL2CPP";
			Melon<Main>.Logger.Msg("Honest Main Menu (" + text + ") initializing..");
			try
			{
				((MelonBase)this).HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
				IEnumerable<string> values = from p in ((MelonBase)this).HarmonyInstance.GetPatchedMethods()
					select p.DeclaringType.FullName + "." + p.Name;
				string text2 = string.Join(", ", values);
				Melon<Main>.Logger.Msg("Honest Main Menu initialized successfully!");
				Melon<Main>.Logger.Msg("Harmony patches successfully applied: " + text2 + ".");
			}
			catch (Exception ex)
			{
				Melon<Main>.Logger.Error("Failed to apply Harmony patches: " + ex.Message);
				Melon<Main>.Logger.Error((object)ex);
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!sceneName.Equals("Menu", StringComparison.OrdinalIgnoreCase))
			{
				HandleNonMenuScene(sceneName);
				return;
			}
			MainMenuRigLoadStuffPatch.ResetLoadedRigs();
			HandleMenuScene();
		}

		private static void HandleNonMenuScene(string sceneName)
		{
			Melon<Main>.Logger.Msg("Scene '" + sceneName + "' loaded outside the main menu. Stopping menu reactivity and snapshotting live clothing colors.");
			MenuReactivity.Stop();
			MainMenuRigLoadStuffPatch.ResetLoadedRigs();
			ClothingUtility instance = Singleton<ClothingUtility>.Instance;
			if (((instance != null) ? instance.ColorDataList : null) != null)
			{
				ClothingDataService.ExtractAndSaveColorData(instance.ColorDataList);
				Melon<Main>.Logger.Msg($"Captured {instance.ColorDataList.Count} clothing colors before leaving the menu scene.");
			}
			else
			{
				Melon<Main>.Logger.Warning("[Main.OnSceneWasLoaded] ClothingUtility or its ColorDataList is null, skipping color data extraction.");
			}
		}

		private static void HandleMenuScene()
		{
			Melon<Main>.Logger.Msg("Main menu scene ('Menu') loaded. Attempting UI modifications..");
			GameObject val = GameObject.Find("MainMenu");
			if ((Object)(object)val == (Object)null)
			{
				Melon<Main>.Logger.Error("Could not find main menu root object 'MainMenu'. Aborting UI modifications.");
				return;
			}
			Transform transform = val.transform;
			BackButtonPromptSetup.Apply(transform);
			MenuButtons menuButtons = MenuSetup.Build(transform);
			if (menuButtons != null)
			{
				MelonCoroutines.Start(MenuReactivity.Run(menuButtons));
				ContinueScreenSetup.Apply(transform);
				Melon<Main>.Logger.Msg("Honest Main Menu UI modifications applied successfully.");
			}
		}
	}
	public static class UIConstants
	{
		public const string MenuSceneName = "Menu";

		public const string MainMenuObjectName = "MainMenu";

		public const string MenuButtonsParentPath = "Home/Bank";

		public const string ContinueObjectNameAndLabel = "Continue";

		public const string LoadGameObjectName = "LoadGame";

		public const string InputPromptObjectName = "InputPrompt (Back)";

		public const string LoadGameLabel = "Load Game";

		public const string RmbPromptBindingKey = "rightButton";

		public const string TitleObjectName = "Title";
	}
	public static class UIHelper
	{
		public static void SetText(this GameObject gameObject, string text)
		{
			if (!((Object)(object)gameObject == (Object)null))
			{
				TextMeshProUGUI componentInChildren = gameObject.GetComponentInChildren<TextMeshProUGUI>(true);
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					((TMP_Text)componentInChildren).text = text;
				}
			}
		}

		public static bool TryFindChild(Transform parent, string childPath, out Transform child, string failureMessage, bool logWarning = false)
		{
			child = ((parent != null) ? parent.Find(childPath) : null);
			if ((Object)(object)child != (Object)null)
			{
				return true;
			}
			if (logWarning)
			{
				Melon<Main>.Logger.Warning(failureMessage);
			}
			else
			{
				Melon<Main>.Logger.Error(failureMessage);
			}
			return false;
		}
	}
}
namespace HonestMainMenu.Services
{
	internal static class BackButtonPromptSetup
	{
		public static void Apply(Transform menuRoot)
		{
			if (TryGetInputPrompt(menuRoot, out var promptComponent, out var ownerObject) && RemoveActionsMatchingBinding(promptComponent, "rightButton"))
			{
				RefreshPrompt(promptComponent, ownerObject);
			}
		}

		private static bool TryGetInputPrompt(Transform mainMenuRoot, out InputPrompt promptComponent, out GameObject ownerObject)
		{
			promptComponent = null;
			Transform obj = mainMenuRoot.Find("InputPrompt (Back)");
			ownerObject = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)ownerObject == (Object)null)
			{
				Melon<Main>.Logger.Warning("Could not find InputPrompt owner GameObject at 'InputPrompt (Back)'.");
				return false;
			}
			promptComponent = ownerObject.GetComponent<InputPrompt>();
			if ((Object)(object)promptComponent == (Object)null)
			{
				Melon<Main>.Logger.Warning("Could not find 'ScheduleOne.UI.Input.InputPrompt' component on 'InputPrompt (Back)'. Make sure the type name is correct.");
				return false;
			}
			return true;
		}

		private static bool RemoveActionsMatchingBinding(InputPrompt promptComponent, string bindingKeyToRemove)
		{
			List<InputActionReference> actions = promptComponent.Actions;
			bool result = false;
			for (int num = actions.Count - 1; num >= 0; num--)
			{
				if (ShouldRemoveAction(actions[num], bindingKeyToRemove))
				{
					actions.RemoveAt(num);
					result = true;
				}
			}
			return result;
		}

		private static bool ShouldRemoveAction(InputActionReference actionRef, string bindingKeyToRemove)
		{
			if (((actionRef != null) ? actionRef.action : null) == null)
			{
				return false;
			}
			string text = default(string);
			string value = default(string);
			InputActionRebindingExtensions.GetBindingDisplayString(actionRef.action, 0, ref text, ref value, (DisplayStringOptions)0);
			return bindingKeyToRemove.Equals(value, StringComparison.OrdinalIgnoreCase);
		}

		private static void RefreshPrompt(InputPrompt promptComponent, GameObject promptOwnerObject)
		{
			if (promptOwnerObject.activeInHierarchy)
			{
				promptOwnerObject.SetActive(false);
				promptOwnerObject.SetActive(true);
			}
		}
	}
	internal interface IClothingApplicator
	{
		IEnumerator Apply(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings);
	}
	internal static class ClothingApplicatorFactory
	{
		internal static IClothingApplicator Create()
		{
			return new Il2CppClothingApplicator();
		}
	}
	internal abstract class ClothingApplicatorBase : IClothingApplicator
	{
		protected static readonly Encoding Utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

		protected static readonly DataContractJsonSerializerSettings SerializerSettings = new DataContractJsonSerializerSettings
		{
			UseSimpleDictionaryFormat = true
		};

		protected static readonly DataContractJsonSerializer ClothingFileSerializer = new DataContractJsonSerializer(typeof(SerializableClothingFile), SerializerSettings);

		protected static readonly DataContractJsonSerializer ClothingItemSerializer = new DataContractJsonSerializer(typeof(SerializableClothingSaveData), SerializerSettings);

		public abstract IEnumerator Apply(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings);

		protected static SerializableClothingFile LoadClothingFile(string playerSavePath)
		{
			string text = Path.Combine(playerSavePath, "Clothing.json");
			if (!File.Exists(text))
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] Clothing file not found at " + text + ". Skipping.");
				return null;
			}
			try
			{
				using FileStream stream = File.OpenRead(text);
				return ClothingFileSerializer.ReadObject((Stream)stream) as SerializableClothingFile;
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Error($"[ClothingApplicator] Failed to read clothing file at {text}: {value}");
				return null;
			}
		}

		protected static SerializableClothingSaveData DeserializeClothingItem(string json, string sourcePath)
		{
			if (string.IsNullOrWhiteSpace(json))
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] Empty clothing item JSON found in '" + sourcePath + "', skipping.");
				return null;
			}
			try
			{
				using MemoryStream stream = new MemoryStream(Utf8.GetBytes(json));
				return ClothingItemSerializer.ReadObject((Stream)stream) as SerializableClothingSaveData;
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Error($"[ClothingApplicator] Failed to deserialize clothing item ({sourcePath}): {value}");
				return null;
			}
		}
	}
	internal sealed class Il2CppClothingApplicator : ClothingApplicatorBase
	{
		public override IEnumerator Apply(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings)
		{
			yield return null;
			if (!File.Exists(Path.Combine(playerSavePath, "Appearance.json")))
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] Appearance.json not found; skipping clothing application.");
				yield break;
			}
			SerializableClothingFile serializableClothingFile = ClothingApplicatorBase.LoadClothingFile(playerSavePath);
			if (serializableClothingFile?.Items == null || serializableClothingFile.Items.Count == 0)
			{
				yield break;
			}
			PlayerClothing val = ((Component)avatar).GetComponent<PlayerClothing>();
			if (val == null)
			{
				val = ((Component)avatar).gameObject.AddComponent<PlayerClothing>();
			}
			AvatarSettings val2 = Object.Instantiate<AvatarSettings>(basicSettings.GetAvatarSettings());
			int num = 0;
			foreach (string item in serializableClothingFile.Items)
			{
				if (TryBuildInstance(item, playerSavePath, out var instance))
				{
					try
					{
						val.ApplyClothing(val2, instance);
						num++;
					}
					catch (Exception value)
					{
						Melon<Main>.Logger.Warning($"[ClothingApplicator] Failed to apply clothing instance: {value}");
					}
				}
			}
			if (num > 0)
			{
				avatar.LoadAvatarSettings(val2);
				Melon<Main>.Logger.Msg($"[ClothingApplicator] Applied {num} clothing items to the main menu Avatar.");
			}
			else
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] No valid clothing items were applied to the main menu Avatar.");
			}
		}

		private static bool TryBuildInstance(string itemJson, string sourcePath, out ClothingInstance instance)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			instance = null;
			SerializableClothingSaveData serializableClothingSaveData = ClothingApplicatorBase.DeserializeClothingItem(itemJson, sourcePath);
			if (serializableClothingSaveData == null)
			{
				return false;
			}
			if (!string.Equals(serializableClothingSaveData.DataType, "ClothingData", StringComparison.OrdinalIgnoreCase) || !serializableClothingSaveData.TryGetValidColor(out var _))
			{
				return false;
			}
			if (!ClothingDefinitionResolver.TryResolve(serializableClothingSaveData, out var definition, out var resolvedColor))
			{
				Melon<Main>.Logger.Warning($"[ClothingApplicator] Clothing item not found in registry: {serializableClothingSaveData.Id} (source: {sourcePath})");
				return false;
			}
			try
			{
				instance = new ClothingInstance((ItemDefinition)(object)definition, 1, resolvedColor);
				return true;
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Warning($"[ClothingApplicator] Failed to create ClothingInstance for '{serializableClothingSaveData.Id}': {value}");
				return false;
			}
		}
	}
	public static class ClothingDataService
	{
		public static IEnumerator ApplyClothingCoroutine(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings)
		{
			if ((Object)(object)avatar == (Object)null || (Object)(object)basicSettings == (Object)null || string.IsNullOrEmpty(playerSavePath))
			{
				Melon<Main>.Logger.Warning("[ClothingDataService] Missing data needed for clothing application.");
				yield break;
			}
			ClothingUtilitySeeder.EnsureWithColors(ColorDataRepository.Load());
			IClothingApplicator clothingApplicator = ClothingApplicatorFactory.Create();
			yield return clothingApplicator.Apply(avatar, playerSavePath, basicSettings);
		}

		public static void ExtractAndSaveColorData(List<ColorData> liveDataList)
		{
			ColorDataRepository.SaveLiveColors(liveDataList);
		}

		public static List<SerializableColorData> LoadColorData()
		{
			return ColorDataRepository.Load();
		}
	}
	internal static class ClothingDefinitionResolver
	{
		internal unsafe static bool TryResolve(SerializableClothingSaveData clothingData, out ClothingDefinition definition, out EClothingColor resolvedColor)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected I4, but got Unknown
			//IL_0021->IL0021: Incompatible stack types: Ref vs I4
			//IL_001c->IL0021: Incompatible stack types: I4 vs Ref
			//IL_001c->IL0021: Incompatible stack types: Ref vs I4
			ItemDefinition item = Registry.GetItem(clothingData.Id);
			definition = (ClothingDefinition)(object)((item is ClothingDefinition) ? item : null);
			ref EClothingColor reference = ref resolvedColor;
			ClothingDefinition obj = definition;
			int num;
			if (obj != null)
			{
				reference = ref *(EClothingColor*)obj.DefaultColor;
				num = (int)(ref reference);
			}
			else
			{
				num = 0;
				reference = ref *(EClothingColor*)num;
				num = (int)(ref reference);
			}
			*(int*)num = (int)Unsafe.AsPointer(ref reference);
			if ((Object)(object)definition != (Object)null)
			{
				if (clothingData.TryGetValidColor(out var clothingColor))
				{
					resolvedColor = (EClothingColor)(int)clothingColor;
				}
				return true;
			}
			return TryResolveFromRegister(clothingData, out definition, out resolvedColor);
		}

		private unsafe static bool TryResolveFromRegister(SerializableClothingSaveData clothingData, out ClothingDefinition definition, out EClothingColor resolvedColor)
		{
			//IL_0011: 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_0012->IL0012: Incompatible stack types: Ref vs I4
			//IL_0011->IL0012: Incompatible stack types: I4 vs Ref
			//IL_0011->IL0012: Incompatible stack types: Ref vs I4
			definition = null;
			ref EClothingColor reference = ref resolvedColor;
			int num;
			if (clothingData.TryGetValidColor(out var clothingColor))
			{
				reference = ref *(EClothingColor*)clothingColor;
				num = (int)(ref reference);
			}
			else
			{
				num = 0;
				reference = ref *(EClothingColor*)num;
				num = (int)(ref reference);
			}
			*(int*)num = (int)Unsafe.AsPointer(ref reference);
			ItemRegister val = FindRegister(clothingData.Id);
			if (val == null)
			{
				return false;
			}
			string text = NormalizeRegistryAssetPath(val.AssetPath);
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			definition = Resources.Load<ClothingDefinition>(text);
			if ((Object)(object)definition != (Object)null)
			{
				return true;
			}
			if (TryMapItemDefinition(text, out var avatarPath, out var applicationType) && ResourceExists(avatarPath))
			{
				definition = ScriptableObject.CreateInstance<ClothingDefinition>();
				definition.ClothingAssetPath = avatarPath;
				definition.ApplicationType = applicationType;
				definition.Colorable = true;
				return true;
			}
			return false;
		}

		private static ItemRegister FindRegister(string id)
		{
			Registry instance = Singleton<Registry>.Instance;
			if (((instance != null) ? instance.ItemDictionary : null) == null || string.IsNullOrEmpty(id))
			{
				return null;
			}
			Enumerator<int, ItemRegister> enumerator = instance.ItemDictionary.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemRegister val = enumerator.Current?.Value;
				if (val != null && val.ID != null && val.ID.Equals(id, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
			return null;
		}

		private static string NormalizeRegistryAssetPath(string assetPath)
		{
			if (string.IsNullOrWhiteSpace(assetPath))
			{
				return null;
			}
			string text = assetPath.Replace("\\", "/");
			if (text.StartsWith("Assets/Resources/", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring("Assets/Resources/".Length);
			}
			if (text.EndsWith(".asset", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - ".asset".Length);
			}
			return text.Trim('/');
		}

		private static bool TryMapItemDefinition(string normalizedPath, out string avatarPath, out EClothingApplicationType applicationType)
		{
			avatarPath = null;
			applicationType = (EClothingApplicationType)2;
			if (string.IsNullOrWhiteSpace(normalizedPath))
			{
				return false;
			}
			string[] array = normalizedPath.Split(new char[1] { '/' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 3 || !array[0].Equals("Clothing", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			if (array.Length >= 4 && array[1].Equals("Accessories", StringComparison.OrdinalIgnoreCase))
			{
				string value = array[2];
				string value2 = array[3];
				avatarPath = $"Avatar/Accessories/{value}/{value2}/{value2}";
				applicationType = (EClothingApplicationType)2;
				return true;
			}
			string text = array[1];
			string text2 = array[2];
			if (IsAccessoryCategory(text))
			{
				avatarPath = $"Avatar/Accessories/{text}/{text2}/{text2}";
				applicationType = (EClothingApplicationType)2;
				return true;
			}
			applicationType = (EClothingApplicationType)0;
			avatarPath = "Avatar/Layers/" + text + "/" + text2;
			return true;
		}

		private static bool IsAccessoryCategory(string category)
		{
			if (!category.Equals("Head", StringComparison.OrdinalIgnoreCase) && !category.Equals("Face", StringComparison.OrdinalIgnoreCase) && !category.Equals("Feet", StringComparison.OrdinalIgnoreCase) && !category.Equals("Hands", StringComparison.OrdinalIgnoreCase) && !category.Equals("Neck", StringComparison.OrdinalIgnoreCase) && !category.Equals("Back", StringComparison.OrdinalIgnoreCase))
			{
				return category.Equals("Accessory", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool ResourceExists(string resourcePath)
		{
			if (string.IsNullOrEmpty(resourcePath))
			{
				return false;
			}
			return Resources.Load<Object>(resourcePath) != (Object)null;
		}
	}
	internal static class ClothingUtilitySeeder
	{
		private static int? _lastHash;

		internal static ClothingUtility EnsureWithColors(IReadOnlyList<SerializableColorData> colors)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			ClothingUtility val = Singleton<ClothingUtility>.Instance;
			if ((Object)(object)val == (Object)null)
			{
				Melon<Main>.Logger.Msg("[ClothingUtilitySeeder] ClothingUtility instance not found, creating a new one.");
				val = new GameObject("@Clothing").AddComponent<ClothingUtility>();
			}
			Populate(val, colors);
			return val;
		}

		internal static void Populate(ClothingUtility clothingUtility, IReadOnlyList<SerializableColorData> colors)
		{
			if ((Object)(object)clothingUtility == (Object)null)
			{
				Melon<Main>.Logger.Error("[ClothingUtilitySeeder] Cannot populate colors because ClothingUtility is null.");
			}
			else if (colors == null || colors.Count == 0)
			{
				Melon<Main>.Logger.Error("[ClothingUtilitySeeder] No color data provided; ClothingUtility will remain unchanged.");
			}
			else if (!IsAlreadySeeded(clothingUtility, colors))
			{
				PopulateColorList(clothingUtility, colors);
				_lastHash = ComputeHash(colors);
			}
		}

		private static void PopulateColorList(ClothingUtility clothingUtility, IReadOnlyList<SerializableColorData> colors)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			if (clothingUtility.ColorDataList == null)
			{
				List<ColorData> val2 = (clothingUtility.ColorDataList = new List<ColorData>());
			}
			List<ColorData> colorDataList = clothingUtility.ColorDataList;
			colorDataList.Clear();
			foreach (SerializableColorData color in colors)
			{
				if (color != null)
				{
					Color actualColor = color.ToUnityColor();
					colorDataList.Add(new ColorData
					{
						ColorType = color.GetEnumColorType(),
						ActualColor = actualColor
					});
				}
			}
		}

		private static bool IsAlreadySeeded(ClothingUtility clothingUtility, IReadOnlyList<SerializableColorData> colors)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			if (((clothingUtility != null) ? clothingUtility.ColorDataList : null) == null || colors == null)
			{
				return false;
			}
			if (colors.Count == 0)
			{
				return false;
			}
			int num = ComputeHash(colors);
			if (_lastHash.HasValue && _lastHash.Value == num)
			{
				return true;
			}
			if (clothingUtility.ColorDataList.Count != colors.Count)
			{
				return false;
			}
			for (int i = 0; i < colors.Count; i++)
			{
				ColorData val = clothingUtility.ColorDataList[i];
				SerializableColorData serializableColorData = colors[i];
				if (val == null || serializableColorData == null)
				{
					return false;
				}
				if (val.ColorType != serializableColorData.GetEnumColorType())
				{
					return false;
				}
				if (val.ActualColor != serializableColorData.ToUnityColor())
				{
					return false;
				}
			}
			_lastHash = num;
			return true;
		}

		private static int ComputeHash(IReadOnlyList<SerializableColorData> colors)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			int num = 17;
			for (int i = 0; i < colors.Count; i++)
			{
				SerializableColorData serializableColorData = colors[i];
				num = num * 31 + (serializableColorData?.ColorType.GetHashCode() ?? 0);
				Color val = serializableColorData?.ToUnityColor() ?? Color.white;
				num = num * 31 + val.r.GetHashCode();
				num = num * 31 + val.g.GetHashCode();
				num = num * 31 + val.b.GetHashCode();
				num = num * 31 + val.a.GetHashCode();
			}
			return num;
		}
	}
	internal static class ColorDataRepository
	{
		private const string ResourceName = "HonestMainMenu.Resources.ColorData.json";

		private static readonly Encoding Utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

		private static readonly DataContractJsonSerializerSettings SerializerSettings = new DataContractJsonSerializerSettings
		{
			UseSimpleDictionaryFormat = true
		};

		private static readonly DataContractJsonSerializer ColorListSerializer = new DataContractJsonSerializer(typeof(List<SerializableColorData>), SerializerSettings);

		internal static string UserDataPath => Path.Combine(MelonEnvironment.MelonBaseDirectory, "Mods", "HonestMainMenu");

		internal static string ColorDataFilePath => Path.Combine(UserDataPath, "ColorData.json");

		internal static List<SerializableColorData> Load()
		{
			if (File.Exists(ColorDataFilePath))
			{
				try
				{
					using FileStream stream = File.OpenRead(ColorDataFilePath);
					return ReadColorList(stream, ColorDataFilePath);
				}
				catch (Exception value)
				{
					Melon<Main>.Logger.Error($"[ColorDataRepository] Failed to read custom color data '{ColorDataFilePath}': {value}");
				}
			}
			Melon<Main>.Logger.Msg("[ColorDataRepository] Custom color data not found or unreadable. Loading embedded defaults.");
			return LoadEmbeddedDefaults();
		}

		internal static void SaveLiveColors(List<ColorData> liveDataList)
		{
			//IL_0038: 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)
			if (liveDataList == null)
			{
				Melon<Main>.Logger.Warning("[ColorDataRepository] No live color data provided; skipping save.");
				return;
			}
			try
			{
				List<SerializableColorData> list = new List<SerializableColorData>(liveDataList.Count);
				Enumerator<ColorData> enumerator = liveDataList.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ColorData current = enumerator.Current;
					if (current != null)
					{
						list.Add(new SerializableColorData(current.ColorType, current.ActualColor));
					}
				}
				List<SerializableColorData> second = LoadEmbeddedDefaults(cloneList: false);
				if (!list.SequenceEqual(second))
				{
					Melon<Main>.Logger.Warning("[ColorDataRepository] Live color data differs from embedded defaults. Consider updating Resources/ColorData.json.");
				}
				else
				{
					Melon<Main>.Logger.Msg("[ColorDataRepository] Live color data matches embedded defaults.");
				}
				EnsureUserDataDirectory();
				string contents = SerializeColors(list);
				File.WriteAllText(ColorDataFilePath, contents, Utf8);
				Melon<Main>.Logger.Msg($"[ColorDataRepository] Saved {list.Count} colors to '{ColorDataFilePath}'.");
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Error($"[ColorDataRepository] Failed to save live color data: {value}");
			}
		}

		internal static List<SerializableColorData> LoadEmbeddedDefaults(bool cloneList = true)
		{
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("HonestMainMenu.Resources.ColorData.json");
				if (stream == null)
				{
					Melon<Main>.Logger.Error("[ColorDataRepository] Embedded resource 'HonestMainMenu.Resources.ColorData.json' not found.");
					return new List<SerializableColorData>();
				}
				List<SerializableColorData> list = ReadColorList(stream, "HonestMainMenu.Resources.ColorData.json");
				return cloneList ? new List<SerializableColorData>(list) : list;
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Error($"[ColorDataRepository] Failed to read embedded color data '{"HonestMainMenu.Resources.ColorData.json"}': {value}");
				return new List<SerializableColorData>();
			}
		}

		private static List<SerializableColorData> ReadColorList(Stream stream, string source)
		{
			try
			{
				return Normalize(ColorListSerializer.ReadObject(stream) as List<SerializableColorData>);
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Error($"[ColorDataRepository] Failed to deserialize color data ({source}): {value}");
				return new List<SerializableColorData>();
			}
		}

		private static List<SerializableColorData> Normalize(List<SerializableColorData> rawList)
		{
			return rawList?.Where((SerializableColorData entry) => entry != null && entry.ActualColor != null).ToList() ?? new List<SerializableColorData>();
		}

		private static string SerializeColors(IReadOnlyList<SerializableColorData> colors)
		{
			using MemoryStream memoryStream = new MemoryStream();
			ColorListSerializer.WriteObject((Stream)memoryStream, (object?)colors);
			return Utf8.GetString(memoryStream.ToArray());
		}

		private static void EnsureUserDataDirectory()
		{
			if (!Directory.Exists(UserDataPath))
			{
				Directory.CreateDirectory(UserDataPath);
			}
		}
	}
	internal static class ContinueScreenSetup
	{
		public static void Apply(Transform mainMenuRoot)
		{
			if (UIHelper.TryFindChild(mainMenuRoot, "Continue", out var child, "Could not find 'MainMenu/Continue' screen object. Aborting screen configuration."))
			{
				((Object)((Component)child).gameObject).name = "LoadGame";
				if (UIHelper.TryFindChild(child, "Title", out var child2, $"Could not find '{"Title"}' child GameObject under '{((Object)child).name}'. The screen title text will not be updated."))
				{
					((Component)child2).gameObject.SetText("Load Game");
				}
			}
		}
	}
	internal static class MenuReactivity
	{
		private static UnityAction _onSaveInfoLoaded;

		private static bool _continueActionHooked;

		private const string ContinueErrorTitle = "Error";

		private const string ContinueErrorMessage = "An error occurred while trying to continue the last played game. Please try loading it manually from the Load Game menu.";

		public static IEnumerator Run(MenuButtons menuButtons)
		{
			yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)(() => (Object)(object)Singleton<LoadManager>.Instance != (Object)null)));
			if (LoadManager.LastPlayedGame != null)
			{
				UpdateContinueButtonInteractableState(menuButtons);
			}
			else if ((Delegate)(object)_onSaveInfoLoaded == (Delegate)null)
			{
				_onSaveInfoLoaded = UnityAction.op_Implicit((Action)delegate
				{
					Melon<Main>.Logger.Msg("LoadManager.OnSaveInfoLoaded event triggered, updating buttons interactable states.");
					UpdateContinueButtonInteractableState(menuButtons);
					DetachSaveInfoListener();
				});
				Singleton<LoadManager>.Instance.onSaveInfoLoaded.AddListener(_onSaveInfoLoaded);
			}
		}

		public static void Stop()
		{
			DetachSaveInfoListener();
			_continueActionHooked = false;
		}

		private static void UpdateContinueButtonInteractableState(MenuButtons menuButtons)
		{
			if (!_continueActionHooked)
			{
				((UnityEvent)menuButtons.ContinueButton.onClick).AddListener(UnityAction.op_Implicit((Action)PerformNewContinueAction));
				_continueActionHooked = true;
			}
			((Selectable)menuButtons.ContinueButton).interactable = true;
			((Selectable)menuButtons.LoadGameButton).interactable = true;
		}

		private static void PerformNewContinueAction()
		{
			if (!Singleton<Lobby>.Instance.IsHost)
			{
				Singleton<MainMenuPopup>.Instance.Open("Cannot Continue", "You must be the host in order to be able to continue a game.", true);
				return;
			}
			try
			{
				Singleton<LoadManager>.Instance.StartGame(LoadManager.LastPlayedGame, false, true);
			}
			catch (MissingMethodException ex) when (ex.Message.Contains("StartGame") || (ex.StackTrace?.Contains("LoadManager.StartGame") ?? false))
			{
				try
				{
					Singleton<LoadManager>.Instance.StartGame(LoadManager.LastPlayedGame, false, true);
					Melon<Main>.Logger.Warning($"Detected missing method exception while trying to continue the last played game: {ex}. " + "This is likely due to an outdated game build. Please update to the latest version. Continuing with the older method signature.");
				}
				catch (Exception exception)
				{
					ShowContinueFailureDialog("Fallback StartGame call also failed after MissingMethodException", exception);
				}
			}
			catch (Exception exception2)
			{
				ShowContinueFailureDialog("An error occurred while trying to continue the last played game", exception2);
			}
		}

		private static void ShowContinueFailureDialog(string context, Exception exception)
		{
			Melon<Main>.Logger.Error($"{context}: {exception}");
			Singleton<MainMenuPopup>.Instance.Open("Error", "An error occurred while trying to continue the last played game. Please try loading it manually from the Load Game menu.", true);
		}

		private static void DetachSaveInfoListener()
		{
			if (!((Delegate)(object)_onSaveInfoLoaded == (Delegate)null) && !((Object)(object)Singleton<LoadManager>.Instance == (Object)null))
			{
				Singleton<LoadManager>.Instance.onSaveInfoLoaded.RemoveListener(_onSaveInfoLoaded);
				_onSaveInfoLoaded = null;
			}
		}
	}
	internal static class MenuSetup
	{
		public static MenuButtons Build(Transform menuRoot)
		{
			if (!UIHelper.TryFindChild(menuRoot, "Home/Bank", out var child, "Could not find menu buttons parent object at 'MainMenu/Home/Bank', aborting UI modifications!"))
			{
				return null;
			}
			if (!UIHelper.TryFindChild(child, "Continue", out var child2, "Could not find the original 'Continue' button object, aborting UI modifications!"))
			{
				return null;
			}
			MenuButtons menuButtons = new MenuButtons
			{
				ContinueButton = CreateAndConfigureNewContinueButton(((Component)child2).gameObject),
				LoadGameButton = null
			};
			if ((Object)(object)menuButtons.ContinueButton == (Object)null)
			{
				Melon<Main>.Logger.Error("Failed to create and configure the new 'Continue' button, aborting UI modifications!");
				return null;
			}
			menuButtons.LoadGameButton = ConfigureLoadGameButton(((Component)child2).gameObject);
			if ((Object)(object)menuButtons.LoadGameButton == (Object)null)
			{
				Melon<Main>.Logger.Error("Failed to configure the 'LoadGame' button, aborting UI modifications!");
				return null;
			}
			((Selectable)menuButtons.ContinueButton).interactable = false;
			((Selectable)menuButtons.LoadGameButton).interactable = false;
			PositionButtonsAndOffsetSiblings(menuButtons);
			return menuButtons;
		}

		private static Button ConfigureLoadGameButton(GameObject buttonObject)
		{
			Button component = buttonObject.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			((Object)buttonObject).name = "LoadGame";
			buttonObject.SetText("Load Game");
			return component;
		}

		private static Button CreateAndConfigureNewContinueButton(GameObject buttonObject)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(buttonObject, buttonObject.transform.parent);
			((Object)val).name = "Continue";
			val.SetText("Continue");
			Button component = val.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			component.onClick = new ButtonClickedEvent();
			return component;
		}

		private static void PositionButtonsAndOffsetSiblings(MenuButtons menuButtons)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0038: 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_005a: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetRects(menuButtons, out var loadGameRect, out var continueRect, out var parentTransform, out var originalIndex))
			{
				Object.Destroy((Object)(object)((Component)menuButtons.ContinueButton).gameObject);
				return;
			}
			Rect rect = continueRect.rect;
			float height = ((Rect)(ref rect)).height;
			Vector2 anchoredPosition = loadGameRect.anchoredPosition;
			PlaceButton(((Component)menuButtons.ContinueButton).gameObject, continueRect, anchoredPosition, originalIndex);
			PlaceButton(((Component)menuButtons.LoadGameButton).gameObject, loadGameRect, anchoredPosition + new Vector2(0f, 0f - height), originalIndex + 1);
			OffsetRemainingSiblings(parentTransform, originalIndex + 2, height);
			Melon<Main>.Logger.Msg("Positioned new 'Continue' at original spot, shifted 'LoadGame' (Load Game) below it, and offset subsequent buttons.");
		}

		private static bool TryGetRects(MenuButtons menuButtons, out RectTransform loadGameRect, out RectTransform continueRect, out Transform parentTransform, out int originalIndex)
		{
			loadGameRect = ((Component)menuButtons.LoadGameButton).gameObject.GetComponent<RectTransform>();
			continueRect = ((Component)menuButtons.ContinueButton).gameObject.GetComponent<RectTransform>();
			parentTransform = ((Component)menuButtons.LoadGameButton).gameObject.transform.parent;
			originalIndex = ((Component)menuButtons.LoadGameButton).gameObject.transform.GetSiblingIndex();
			if ((Object)(object)loadGameRect != (Object)null && (Object)(object)continueRect != (Object)null && (Object)(object)parentTransform != (Object)null)
			{
				return true;
			}
			Melon<Main>.Logger.Error("Could not get RectTransforms or parent for positioning. Destroying new button.");
			return false;
		}

		private static void PlaceButton(GameObject buttonObject, RectTransform rectTransform, Vector2 anchoredPosition, int siblingIndex)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchoredPosition = anchoredPosition;
			buttonObject.transform.SetSiblingIndex(siblingIndex);
		}

		private static void OffsetRemainingSiblings(Transform parentTransform, int startIndex, float offset)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = startIndex; i < parentTransform.childCount; i++)
			{
				RectTransform component = ((Component)parentTransform.GetChild(i)).GetComponent<RectTransform>();
				if (component != null)
				{
					component.anchoredPosition = new Vector2(component.anchoredPosition.x, component.anchoredPosition.y - offset);
				}
			}
		}
	}
}
namespace HonestMainMenu.Patches
{
	[HarmonyPatch(typeof(MainMenuRig), "LoadStuff")]
	public static class MainMenuRigLoadStuffPatch
	{
		private static readonly HashSet<int> LoadedRigs = new HashSet<int>();

		private static readonly object LoadedRigsLock = new object();

		public static bool Prefix(MainMenuRig __instance)
		{
			try
			{
				if (!TryBeginRigLoad(__instance))
				{
					return false;
				}
				bool flag = false;
				if (LoadManager.LastPlayedGame != null)
				{
					string text = Path.Combine(LoadManager.LastPlayedGame.SavePath, "Players", "Player_0");
					string path = Path.Combine(text, "Appearance.json");
					BasicAvatarSettings val = ScriptableObject.CreateInstance<BasicAvatarSettings>();
					if (File.Exists(path))
					{
						JsonUtility.FromJsonOverwrite(File.ReadAllText(path), (Object)(object)val);
						__instance.Avatar.LoadAvatarSettings(val.GetAvatarSettings());
						MelonCoroutines.Start(ClothingDataService.ApplyClothingCoroutine(__instance.Avatar, text, val));
						flag = true;
					}
					else
					{
						Melon<Main>.Logger.Warning("[MainMenuRigLoadStuffPatch] Appearance.json not found, skipping avatar appearance load.");
					}
					float num = LoadManager.LastPlayedGame.Networth;
					for (int i = 0; i < ((Il2CppArrayBase<CashPile>)(object)__instance.CashPiles).Length; i++)
					{
						float displayedAmount = Mathf.Clamp(num, 0f, 100000f);
						((Il2CppArrayBase<CashPile>)(object)__instance.CashPiles)[i].SetDisplayedAmount(displayedAmount);
						num -= 100000f;
						if (num <= 0f)
						{
							break;
						}
					}
					Melon<Main>.Logger.Msg("[MainMenuRigLoadStuffPatch] Completed loading Main Menu Rig and started Avatar appearance application..");
				}
				if (!flag)
				{
					((Component)__instance.Avatar).gameObject.SetActive(false);
				}
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Error($"[MainMenuRigLoadStuffPatch] An error occurred in the Prefix: {value}");
				return true;
			}
			return false;
		}

		private static bool TryBeginRigLoad(MainMenuRig rig)
		{
			if ((Object)(object)rig == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)rig).GetInstanceID();
			lock (LoadedRigsLock)
			{
				if (LoadedRigs.Contains(instanceID))
				{
					return false;
				}
				LoadedRigs.Add(instanceID);
				return true;
			}
		}

		public static void ResetLoadedRigs()
		{
			lock (LoadedRigsLock)
			{
				LoadedRigs.Clear();
			}
		}
	}
	[HarmonyPatch(typeof(ClothingUtility), "Awake")]
	public static class ClothingUtilityAwakePatch
	{
		[HarmonyPrefix]
		public static void Prefix(ClothingUtility __instance)
		{
			try
			{
				List<SerializableColorData> list = ClothingDataService.LoadColorData();
				if (list != null && list.Count != 0)
				{
					ClothingUtilitySeeder.Populate(__instance, list);
				}
			}
			catch (Exception value)
			{
				Melon<Main>.Logger.Warning($"[ClothingService] Failed to seed ClothingUtility colors before Awake: {value}");
			}
		}
	}
	[HarmonyPatch(typeof(SceneManager), "LoadScene", new Type[] { typeof(string) })]
	public static class SceneManagerLoadScenePatch
	{
		private static string _lastSceneName = string.Empty;

		private static bool Prefix(string sceneName)
		{
			if (!string.IsNullOrEmpty(_lastSceneName) && (_lastSceneName.Equals(sceneName, StringComparison.OrdinalIgnoreCase) || _lastSceneName.Equals("Assets/Scenes/" + sceneName + ".unity", StringComparison.OrdinalIgnoreCase)))
			{
				return false;
			}
			_lastSceneName = sceneName;
			return true;
		}
	}
}
namespace HonestMainMenu.Models
{
	[Serializable]
	[DataContract]
	public sealed class SerializableClothingFile
	{
		[DataMember(Name = "Items")]
		public List<string> Items { get; private set; } = new List<string>();


		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (Items == null)
			{
				List<string> list2 = (Items = new List<string>());
			}
		}
	}
	[Serializable]
	[DataContract]
	public sealed class SerializableClothingSaveData
	{
		private const string ClothingDataType = "ClothingData";

		private static readonly Type ColorEnumType = typeof(EClothingColor);

		private static readonly Array EnumValues = Enum.GetValues(ColorEnumType);

		private static readonly EClothingColor DefaultColor = (EClothingColor)((EnumValues.Length > 0) ? ((int)(EClothingColor)EnumValues.GetValue(0)) : 0);

		private static readonly HashSet<int> ValidColorValues = BuildValidColorSet();

		[DataMember(Name = "DataType")]
		public string DataType { get; set; } = "ClothingData";


		[DataMember(Name = "ID")]
		public string Id { get; set; }

		[DataMember(Name = "Color")]
		public int Color { get; set; }

		public bool IsValid
		{
			get
			{
				EClothingColor clothingColor;
				return TryGetValidColor(out clothingColor);
			}
		}

		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (DataType == null)
			{
				string text2 = (DataType = "ClothingData");
			}
		}

		public bool TryGetValidColor(out EClothingColor clothingColor)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected I4, but got Unknown
			if (!string.Equals(DataType, "ClothingData", StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(Id))
			{
				clothingColor = (EClothingColor)(int)DefaultColor;
				return false;
			}
			return TryGetColor(out clothingColor);
		}

		public bool TryGetColor(out EClothingColor clothingColor)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected I4, but got Unknown
			if (ValidColorValues.Contains(Color))
			{
				clothingColor = (EClothingColor)Color;
				return true;
			}
			clothingColor = (EClothingColor)(int)DefaultColor;
			return false;
		}

		private static HashSet<int> BuildValidColorSet()
		{
			HashSet<int> hashSet = new HashSet<int>();
			foreach (object enumValue in EnumValues)
			{
				hashSet.Add((int)enumValue);
			}
			return hashSet;
		}
	}
	[Serializable]
	[DataContract]
	public sealed class SerializableColor : IEquatable<SerializableColor>
	{
		private float _alpha = 1f;

		private bool _alphaExplicitlySet;

		[DataMember(Name = "r")]
		public float R { get; private set; }

		[DataMember(Name = "g")]
		public float G { get; private set; }

		[DataMember(Name = "b")]
		public float B { get; private set; }

		[DataMember(Name = "a")]
		public float A
		{
			get
			{
				return _alpha;
			}
			private set
			{
				_alpha = value;
				_alphaExplicitlySet = true;
			}
		}

		public SerializableColor()
		{
		}

		public SerializableColor(float r, float g, float b, float a = 1f)
		{
			R = r;
			G = g;
			B = b;
			A = a;
		}

		public SerializableColor(Color color)
		{
			//IL_0012: 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_002a: 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)
			R = color.r;
			G = color.g;
			B = color.b;
			A = color.a;
		}

		public Color ToUnityColor()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Color(R, G, B, A);
		}

		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (!_alphaExplicitlySet)
			{
				_alpha = 1f;
			}
		}

		public bool Equals(SerializableColor other)
		{
			if (other == null)
			{
				return false;
			}
			if (this == other)
			{
				return true;
			}
			if (R.Equals(other.R) && G.Equals(other.G) && B.Equals(other.B))
			{
				return A.Equals(other.A);
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (obj.GetType() != GetType())
			{
				return false;
			}
			return Equals((SerializableColor)obj);
		}

		public override int GetHashCode()
		{
			return (((17 * 23 + R.GetHashCode()) * 23 + G.GetHashCode()) * 23 + B.GetHashCode()) * 23 + A.GetHashCode();
		}
	}
	[Serializable]
	[DataContract]
	public sealed class SerializableColorData : IEquatable<SerializableColorData>
	{
		[NonSerialized]
		private Color? _cachedUnityColor;

		[DataMember(Name = "ColorType")]
		public int ColorType { get; private set; }

		[DataMember(Name = "ActualColor")]
		public SerializableColor ActualColor { get; private set; } = new SerializableColor();


		public SerializableColorData()
		{
		}

		public SerializableColorData(int colorType, SerializableColor actualColor)
		{
			ColorType = colorType;
			ActualColor = actualColor ?? new SerializableColor();
		}

		public SerializableColorData(int colorType, Color actualColor)
			: this(colorType, new SerializableColor(actualColor))
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)


		public SerializableColorData(EClothingColor colorType, Color actualColor)
			: this((int)colorType, actualColor)
		{
		}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected I4, but got Unknown


		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (ActualColor == null)
			{
				SerializableColor serializableColor2 = (ActualColor = new SerializableColor());
			}
			_cachedUnityColor = null;
		}

		public EClothingColor GetEnumColorType()
		{
			return (EClothingColor)ColorType;
		}

		public Color ToUnityColor()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!_cachedUnityColor.HasValue)
			{
				_cachedUnityColor = ActualColor?.ToUnityColor() ?? Color.white;
			}
			return _cachedUnityColor.Value;
		}

		public bool Equals(SerializableColorData other)
		{
			if (other == null)
			{
				return false;
			}
			if (this == other)
			{
				return true;
			}
			if (ColorType == other.ColorType)
			{
				return object.Equals(ActualColor, other.ActualColor);
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (obj.GetType() != GetType())
			{
				return false;
			}
			return Equals((SerializableColorData)obj);
		}

		public override int GetHashCode()
		{
			return (17 * 23 + ColorType.GetHashCode()) * 23 + (ActualColor?.GetHashCode() ?? 0);
		}
	}
	internal class MenuButtons
	{
		public Button ContinueButton { get; set; }

		public Button LoadGameButton { get; set; }
	}
}

HonestMainMenu.Mono.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using HarmonyLib;
using HonestMainMenu;
using HonestMainMenu.Models;
using HonestMainMenu.Patches;
using HonestMainMenu.Services;
using MelonLoader;
using MelonLoader.Utils;
using ScheduleOne.AvatarFramework;
using ScheduleOne.AvatarFramework.Customization;
using ScheduleOne.Clothing;
using ScheduleOne.DevUtilities;
using ScheduleOne.Networking;
using ScheduleOne.Persistence;
using ScheduleOne.UI.Input;
using ScheduleOne.UI.MainMenu;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(true)]
[assembly: Guid("F2F8CCDD-DA07-47DF-9247-39B991BE39E3")]
[assembly: MelonInfo(typeof(Main), "Honest Main Menu", "1.1.0", "Roach_ (Adrian Nicolae)", "https://github.com/RoachxD/ScheduleOne.HonestMainMenu/releases/latest")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonColor(255, 97, 100, 62)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Roach_")]
[assembly: AssemblyConfiguration("Release_Mono")]
[assembly: AssemblyCopyright("Copyright © 2025 Roach_ (Adrian Nicolae)")]
[assembly: AssemblyDescription("A MelonLoader mod for Schedule I that adds a true continue button to the main menu.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("HonestMainMenu.Mono")]
[assembly: AssemblyTitle("HonestMainMenu.Mono")]
[assembly: NeutralResourcesLanguage("en-GB")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace HonestMainMenu
{
	public class Main : MelonMod
	{
		public override void OnInitializeMelon()
		{
			string text = "Mono";
			Melon<Main>.Logger.Msg("Honest Main Menu (" + text + ") initializing..");
			try
			{
				((MelonBase)this).HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly());
				IEnumerable<string> values = from p in ((MelonBase)this).HarmonyInstance.GetPatchedMethods()
					select p.DeclaringType.FullName + "." + p.Name;
				string text2 = string.Join(", ", values);
				Melon<Main>.Logger.Msg("Honest Main Menu initialized successfully!");
				Melon<Main>.Logger.Msg("Harmony patches successfully applied: " + text2 + ".");
			}
			catch (Exception ex)
			{
				Melon<Main>.Logger.Error("Failed to apply Harmony patches: " + ex.Message);
				Melon<Main>.Logger.Error((object)ex);
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (!sceneName.Equals("Menu", StringComparison.OrdinalIgnoreCase))
			{
				HandleNonMenuScene(sceneName);
				return;
			}
			MainMenuRigLoadStuffPatch.ResetLoadedRigs();
			HandleMenuScene();
		}

		private static void HandleNonMenuScene(string sceneName)
		{
			Melon<Main>.Logger.Msg("Scene '" + sceneName + "' loaded outside the main menu. Stopping menu reactivity and snapshotting live clothing colors.");
			MenuReactivity.Stop();
			MainMenuRigLoadStuffPatch.ResetLoadedRigs();
			ClothingUtility instance = Singleton<ClothingUtility>.Instance;
			if (instance?.ColorDataList != null)
			{
				ClothingDataService.ExtractAndSaveColorData(instance.ColorDataList);
				Melon<Main>.Logger.Msg($"Captured {instance.ColorDataList.Count} clothing colors before leaving the menu scene.");
			}
			else
			{
				Melon<Main>.Logger.Warning("[Main.OnSceneWasLoaded] ClothingUtility or its ColorDataList is null, skipping color data extraction.");
			}
		}

		private static void HandleMenuScene()
		{
			Melon<Main>.Logger.Msg("Main menu scene ('Menu') loaded. Attempting UI modifications..");
			GameObject val = GameObject.Find("MainMenu");
			if ((Object)(object)val == (Object)null)
			{
				Melon<Main>.Logger.Error("Could not find main menu root object 'MainMenu'. Aborting UI modifications.");
				return;
			}
			Transform transform = val.transform;
			BackButtonPromptSetup.Apply(transform);
			MenuButtons menuButtons = MenuSetup.Build(transform);
			if (menuButtons != null)
			{
				MelonCoroutines.Start(MenuReactivity.Run(menuButtons));
				ContinueScreenSetup.Apply(transform);
				Melon<Main>.Logger.Msg("Honest Main Menu UI modifications applied successfully.");
			}
		}
	}
	public static class UIConstants
	{
		public const string MenuSceneName = "Menu";

		public const string MainMenuObjectName = "MainMenu";

		public const string MenuButtonsParentPath = "Home/Bank";

		public const string ContinueObjectNameAndLabel = "Continue";

		public const string LoadGameObjectName = "LoadGame";

		public const string InputPromptObjectName = "InputPrompt (Back)";

		public const string LoadGameLabel = "Load Game";

		public const string RmbPromptBindingKey = "rightButton";

		public const string TitleObjectName = "Title";
	}
	public static class UIHelper
	{
		public static void SetText(this GameObject gameObject, string text)
		{
			if (!((Object)(object)gameObject == (Object)null))
			{
				TextMeshProUGUI componentInChildren = gameObject.GetComponentInChildren<TextMeshProUGUI>(true);
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					((TMP_Text)componentInChildren).text = text;
				}
			}
		}

		public static bool TryFindChild(Transform parent, string childPath, out Transform child, string failureMessage, bool logWarning = false)
		{
			child = ((parent != null) ? parent.Find(childPath) : null);
			if ((Object)(object)child != (Object)null)
			{
				return true;
			}
			if (logWarning)
			{
				Melon<Main>.Logger.Warning(failureMessage);
			}
			else
			{
				Melon<Main>.Logger.Error(failureMessage);
			}
			return false;
		}
	}
}
namespace HonestMainMenu.Services
{
	internal static class BackButtonPromptSetup
	{
		public static void Apply(Transform menuRoot)
		{
			if (TryGetInputPrompt(menuRoot, out var promptComponent, out var ownerObject) && RemoveActionsMatchingBinding(promptComponent, "rightButton"))
			{
				RefreshPrompt(promptComponent, ownerObject);
			}
		}

		private static bool TryGetInputPrompt(Transform mainMenuRoot, out InputPrompt promptComponent, out GameObject ownerObject)
		{
			promptComponent = null;
			Transform obj = mainMenuRoot.Find("InputPrompt (Back)");
			ownerObject = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)ownerObject == (Object)null)
			{
				Melon<Main>.Logger.Warning("Could not find InputPrompt owner GameObject at 'InputPrompt (Back)'.");
				return false;
			}
			promptComponent = ownerObject.GetComponent<InputPrompt>();
			if ((Object)(object)promptComponent == (Object)null)
			{
				Melon<Main>.Logger.Warning("Could not find 'ScheduleOne.UI.Input.InputPrompt' component on 'InputPrompt (Back)'. Make sure the type name is correct.");
				return false;
			}
			return true;
		}

		private static bool RemoveActionsMatchingBinding(InputPrompt promptComponent, string bindingKeyToRemove)
		{
			return promptComponent.Actions.RemoveAll((InputActionReference actionRef) => ShouldRemoveAction(actionRef, bindingKeyToRemove)) > 0;
		}

		private static bool ShouldRemoveAction(InputActionReference actionRef, string bindingKeyToRemove)
		{
			if (((actionRef != null) ? actionRef.action : null) == null)
			{
				return false;
			}
			string text = default(string);
			string value = default(string);
			InputActionRebindingExtensions.GetBindingDisplayString(actionRef.action, 0, ref text, ref value, (DisplayStringOptions)0);
			return bindingKeyToRemove.Equals(value, StringComparison.OrdinalIgnoreCase);
		}

		private static void RefreshPrompt(InputPrompt promptComponent, GameObject promptOwnerObject)
		{
			if (promptOwnerObject.activeInHierarchy)
			{
				promptOwnerObject.SetActive(false);
				promptOwnerObject.SetActive(true);
			}
		}
	}
	internal interface IClothingApplicator
	{
		IEnumerator Apply(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings);
	}
	internal static class ClothingApplicatorFactory
	{
		internal static IClothingApplicator Create()
		{
			return new MonoClothingApplicator();
		}
	}
	internal abstract class ClothingApplicatorBase : IClothingApplicator
	{
		protected static readonly Encoding Utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

		protected static readonly DataContractJsonSerializerSettings SerializerSettings = new DataContractJsonSerializerSettings
		{
			UseSimpleDictionaryFormat = true
		};

		protected static readonly DataContractJsonSerializer ClothingFileSerializer = new DataContractJsonSerializer(typeof(SerializableClothingFile), SerializerSettings);

		protected static readonly DataContractJsonSerializer ClothingItemSerializer = new DataContractJsonSerializer(typeof(SerializableClothingSaveData), SerializerSettings);

		public abstract IEnumerator Apply(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings);

		protected static SerializableClothingFile LoadClothingFile(string playerSavePath)
		{
			string text = Path.Combine(playerSavePath, "Clothing.json");
			if (!File.Exists(text))
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] Clothing file not found at " + text + ". Skipping.");
				return null;
			}
			try
			{
				using FileStream fileStream = File.OpenRead(text);
				return ((XmlObjectSerializer)ClothingFileSerializer).ReadObject((Stream)fileStream) as SerializableClothingFile;
			}
			catch (Exception arg)
			{
				Melon<Main>.Logger.Error($"[ClothingApplicator] Failed to read clothing file at {text}: {arg}");
				return null;
			}
		}

		protected static SerializableClothingSaveData DeserializeClothingItem(string json, string sourcePath)
		{
			if (string.IsNullOrWhiteSpace(json))
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] Empty clothing item JSON found in '" + sourcePath + "', skipping.");
				return null;
			}
			try
			{
				using MemoryStream memoryStream = new MemoryStream(Utf8.GetBytes(json));
				return ((XmlObjectSerializer)ClothingItemSerializer).ReadObject((Stream)memoryStream) as SerializableClothingSaveData;
			}
			catch (Exception arg)
			{
				Melon<Main>.Logger.Error($"[ClothingApplicator] Failed to deserialize clothing item ({sourcePath}): {arg}");
				return null;
			}
		}
	}
	internal sealed class MonoClothingApplicator : ClothingApplicatorBase
	{
		public override IEnumerator Apply(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings)
		{
			SerializableClothingFile serializableClothingFile = ClothingApplicatorBase.LoadClothingFile(playerSavePath);
			if (serializableClothingFile?.Items == null || serializableClothingFile.Items.Count == 0)
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] Clothing file at " + playerSavePath + " was empty or missing.");
				yield break;
			}
			AvatarSettings val = Object.Instantiate<AvatarSettings>(basicSettings.GetAvatarSettings());
			val.BodyLayerSettings.Clear();
			val.AccessorySettings.Clear();
			int num = 0;
			foreach (string item in serializableClothingFile.Items)
			{
				if (TryApplyItem(val, item, playerSavePath))
				{
					num++;
				}
			}
			avatar.LoadAvatarSettings(val);
			if (num > 0)
			{
				Melon<Main>.Logger.Msg($"[ClothingApplicator] Applied {num} clothing items to the main menu Avatar.");
			}
			else
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] No valid clothing items were applied to the main menu Avatar.");
			}
		}

		private static bool TryApplyItem(AvatarSettings avatarSettings, string itemJson, string sourcePath)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_008c: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			SerializableClothingSaveData serializableClothingSaveData = ClothingApplicatorBase.DeserializeClothingItem(itemJson, sourcePath);
			if (serializableClothingSaveData == null)
			{
				return false;
			}
			if (!string.Equals(serializableClothingSaveData.DataType, "ClothingData", StringComparison.OrdinalIgnoreCase) || !serializableClothingSaveData.TryGetValidColor(out var clothingColor))
			{
				return false;
			}
			if (!ClothingDefinitionResolver.TryResolve(serializableClothingSaveData, out var definition, out var _))
			{
				Melon<Main>.Logger.Warning("[ClothingApplicator] Clothing item not found in registry: " + serializableClothingSaveData.Id + " (source: " + sourcePath + ")");
				return false;
			}
			Color actualColor = ClothingColorExtensions.GetActualColor(clothingColor);
			if ((int)definition.ApplicationType == 0)
			{
				avatarSettings.BodyLayerSettings.Add(new LayerSetting
				{
					layerPath = definition.ClothingAssetPath,
					layerTint = actualColor
				});
			}
			else
			{
				avatarSettings.AccessorySettings.Add(new AccessorySetting
				{
					path = definition.ClothingAssetPath,
					color = actualColor
				});
			}
			return true;
		}
	}
	public static class ClothingDataService
	{
		public static IEnumerator ApplyClothingCoroutine(Avatar avatar, string playerSavePath, BasicAvatarSettings basicSettings)
		{
			if ((Object)(object)avatar == (Object)null || (Object)(object)basicSettings == (Object)null || string.IsNullOrEmpty(playerSavePath))
			{
				Melon<Main>.Logger.Warning("[ClothingDataService] Missing data needed for clothing application.");
				yield break;
			}
			ClothingUtilitySeeder.EnsureWithColors(ColorDataRepository.Load());
			IClothingApplicator clothingApplicator = ClothingApplicatorFactory.Create();
			yield return clothingApplicator.Apply(avatar, playerSavePath, basicSettings);
		}

		public static void ExtractAndSaveColorData(List<ColorData> liveDataList)
		{
			ColorDataRepository.SaveLiveColors(liveDataList);
		}

		public static List<SerializableColorData> LoadColorData()
		{
			return ColorDataRepository.Load();
		}
	}
	internal static class ClothingDefinitionResolver
	{
		private sealed class MonoRegistryAdapter
		{
			private static MonoRegistryAdapter _cached;

			private readonly Dictionary<string, object> _registers;

			private readonly Dictionary<string, string> _aliases;

			private MonoRegistryAdapter(Dictionary<string, object> registers, Dictionary<string, string> aliases)
			{
				_registers = registers;
				_aliases = aliases;
			}

			internal static MonoRegistryAdapter GetOrCreate()
			{
				if (_cached != null)
				{
					return _cached;
				}
				Type type = Type.GetType("ScheduleOne.Registry, Assembly-CSharp");
				if (type == null)
				{
					return null;
				}
				object obj = (type.BaseType?.BaseType?.GetField("instance", BindingFlags.Static | BindingFlags.NonPublic))?.GetValue(null);
				if (obj == null)
				{
					return null;
				}
				Dictionary<string, object> registers = BuildRegisterSnapshot(obj, type);
				Dictionary<string, string> aliases = BuildAliasSnapshot(obj, type);
				_cached = new MonoRegistryAdapter(registers, aliases);
				return _cached;
			}

			private static Dictionary<string, object> BuildRegisterSnapshot(object registryInstance, Type registryType)
			{
				Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
				if (registryType.GetField("ItemDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(registryInstance) is IDictionary dictionary2)
				{
					foreach (DictionaryEntry item in dictionary2)
					{
						object value = item.Value;
						string fieldValue = GetFieldValue<string>(value, "ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (!string.IsNullOrEmpty(fieldValue) && !dictionary.ContainsKey(fieldValue))
						{
							dictionary[fieldValue] = value;
						}
					}
				}
				return dictionary;
			}

			private static Dictionary<string, string> BuildAliasSnapshot(object registryInstance, Type registryType)
			{
				if (!(registryType.GetField("itemIDAliases", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(registryInstance) is IDictionary dictionary))
				{
					return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				}
				Dictionary<string, string> dictionary2 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				foreach (DictionaryEntry item in dictionary)
				{
					if (item.Key is string key && item.Value is string value)
					{
						dictionary2[key] = value;
					}
				}
				return dictionary2;
			}

			internal ClothingDefinition TryGetDefinition(string id)
			{
				string id2 = ResolveAlias(id);
				object obj = FindRegister(id2);
				if (obj == null)
				{
					return null;
				}
				return GetFieldValue<ClothingDefinition>(obj, "Definition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}

			internal string ResolveAlias(string id)
			{
				if (string.IsNullOrEmpty(id))
				{
					return id;
				}
				if (!_aliases.TryGetValue(id, out var value))
				{
					return id;
				}
				return value;
			}

			internal object FindRegister(string id)
			{
				if (string.IsNullOrEmpty(id))
				{
					return null;
				}
				if (!_registers.TryGetValue(id, out var value))
				{
					return null;
				}
				return value;
			}

			internal static T GetFieldValue<T>(object instance, string fieldName, BindingFlags flags)
			{
				if (instance == null || string.IsNullOrEmpty(fieldName))
				{
					return default(T);
				}
				FieldInfo field = instance.GetType().GetField(fieldName, flags);
				if (field == null)
				{
					return default(T);
				}
				object value = field.GetValue(instance);
				if (value is T)
				{
					return (T)value;
				}
				return default(T);
			}
		}

		internal unsafe static bool TryResolve(SerializableClothingSaveData clothingData, out ClothingDefinition definition, out EClothingColor resolvedColor)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected I4, but got Unknown
			//IL_001c->IL001c: Incompatible stack types: Ref vs I4
			//IL_0017->IL001c: Incompatible stack types: I4 vs Ref
			//IL_0017->IL001c: Incompatible stack types: Ref vs I4
			definition = TryGetDefinitionFromMonoRegistry(clothingData.Id);
			ref EClothingColor reference = ref resolvedColor;
			ClothingDefinition obj = definition;
			int num;
			if (obj != null)
			{
				reference = ref *(EClothingColor*)obj.DefaultColor;
				num = (int)(ref reference);
			}
			else
			{
				num = 0;
				reference = ref *(EClothingColor*)num;
				num = (int)(ref reference);
			}
			*(int*)num = (int)System.Runtime.CompilerServices.Unsafe.AsPointer(ref reference);
			if ((Object)(object)definition != (Object)null)
			{
				if (clothingData.TryGetValidColor(out var clothingColor))
				{
					resolvedColor = (EClothingColor)(int)clothingColor;
				}
				return true;
			}
			return TryResolveFromMonoRegister(clothingData, out definition, out resolvedColor);
		}

		private static ClothingDefinition TryGetDefinitionFromMonoRegistry(string id)
		{
			try
			{
				return MonoRegistryAdapter.GetOrCreate()?.TryGetDefinition(id);
			}
			catch (Exception arg)
			{
				Melon<Main>.Logger.Warning($"[ClothingDefinitionResolver] Failed to resolve clothing definition via reflection: {arg}");
				return null;
			}
		}

		private unsafe static bool TryResolveFromMonoRegister(SerializableClothingSaveData clothingData, out ClothingDefinition definition, out EClothingColor resolvedColor)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_0012->IL0012: Incompatible stack types: Ref vs I4
			//IL_0011->IL0012: Incompatible stack types: I4 vs Ref
			//IL_0011->IL0012: Incompatible stack types: Ref vs I4
			definition = null;
			ref EClothingColor reference = ref resolvedColor;
			int num;
			if (clothingData.TryGetValidColor(out var clothingColor))
			{
				reference = ref *(EClothingColor*)clothingColor;
				num = (int)(ref reference);
			}
			else
			{
				num = 0;
				reference = ref *(EClothingColor*)num;
				num = (int)(ref reference);
			}
			*(int*)num = (int)System.Runtime.CompilerServices.Unsafe.AsPointer(ref reference);
			MonoRegistryAdapter orCreate = MonoRegistryAdapter.GetOrCreate();
			if (orCreate == null)
			{
				return false;
			}
			string id = orCreate.ResolveAlias(clothingData.Id);
			object obj = orCreate.FindRegister(id);
			if (obj == null)
			{
				return false;
			}
			ClothingDefinition fieldValue = MonoRegistryAdapter.GetFieldValue<ClothingDefinition>(obj, "Definition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if ((Object)(object)fieldValue != (Object)null)
			{
				definition = fieldValue;
				return true;
			}
			string text = NormalizeRegistryAssetPath(MonoRegistryAdapter.GetFieldValue<string>(obj, "AssetPath", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			definition = Resources.Load<ClothingDefinition>(text);
			if ((Object)(object)definition != (Object)null)
			{
				return true;
			}
			if (TryMapItemDefinition(text, out var avatarPath, out var applicationType) && ResourceExists(avatarPath))
			{
				definition = ScriptableObject.CreateInstance<ClothingDefinition>();
				definition.ClothingAssetPath = avatarPath;
				definition.ApplicationType = applicationType;
				definition.Colorable = true;
				return true;
			}
			return false;
		}

		private static string NormalizeRegistryAssetPath(string assetPath)
		{
			if (string.IsNullOrWhiteSpace(assetPath))
			{
				return null;
			}
			string text = assetPath.Replace("\\", "/");
			if (text.StartsWith("Assets/Resources/", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring("Assets/Resources/".Length);
			}
			if (text.EndsWith(".asset", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - ".asset".Length);
			}
			return text.Trim(new char[1] { '/' });
		}

		private static bool TryMapItemDefinition(string normalizedPath, out string avatarPath, out EClothingApplicationType applicationType)
		{
			avatarPath = null;
			applicationType = (EClothingApplicationType)2;
			if (string.IsNullOrWhiteSpace(normalizedPath))
			{
				return false;
			}
			string[] array = normalizedPath.Split(new char[1] { '/' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 3 || !array[0].Equals("Clothing", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			if (array.Length >= 4 && array[1].Equals("Accessories", StringComparison.OrdinalIgnoreCase))
			{
				string text = array[2];
				string text2 = array[3];
				avatarPath = "Avatar/Accessories/" + text + "/" + text2 + "/" + text2;
				applicationType = (EClothingApplicationType)2;
				return true;
			}
			string text3 = array[1];
			string text4 = array[2];
			if (IsAccessoryCategory(text3))
			{
				avatarPath = "Avatar/Accessories/" + text3 + "/" + text4 + "/" + text4;
				applicationType = (EClothingApplicationType)2;
				return true;
			}
			applicationType = (EClothingApplicationType)0;
			avatarPath = "Avatar/Layers/" + text3 + "/" + text4;
			return true;
		}

		private static bool IsAccessoryCategory(string category)
		{
			if (!category.Equals("Head", StringComparison.OrdinalIgnoreCase) && !category.Equals("Face", StringComparison.OrdinalIgnoreCase) && !category.Equals("Feet", StringComparison.OrdinalIgnoreCase) && !category.Equals("Hands", StringComparison.OrdinalIgnoreCase) && !category.Equals("Neck", StringComparison.OrdinalIgnoreCase) && !category.Equals("Back", StringComparison.OrdinalIgnoreCase))
			{
				return category.Equals("Accessory", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static bool ResourceExists(string resourcePath)
		{
			if (string.IsNullOrEmpty(resourcePath))
			{
				return false;
			}
			return Resources.Load<Object>(resourcePath) != (Object)null;
		}
	}
	internal static class ClothingUtilitySeeder
	{
		private static int? _lastHash;

		internal static ClothingUtility EnsureWithColors(IReadOnlyList<SerializableColorData> colors)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			ClothingUtility val = Singleton<ClothingUtility>.Instance;
			if ((Object)(object)val == (Object)null)
			{
				Melon<Main>.Logger.Msg("[ClothingUtilitySeeder] ClothingUtility instance not found, creating a new one.");
				val = new GameObject("@Clothing").AddComponent<ClothingUtility>();
			}
			Populate(val, colors);
			return val;
		}

		internal static void Populate(ClothingUtility clothingUtility, IReadOnlyList<SerializableColorData> colors)
		{
			if ((Object)(object)clothingUtility == (Object)null)
			{
				Melon<Main>.Logger.Error("[ClothingUtilitySeeder] Cannot populate colors because ClothingUtility is null.");
			}
			else if (colors == null || colors.Count == 0)
			{
				Melon<Main>.Logger.Error("[ClothingUtilitySeeder] No color data provided; ClothingUtility will remain unchanged.");
			}
			else if (!IsAlreadySeeded(clothingUtility, colors))
			{
				PopulateColorList(clothingUtility, colors);
				_lastHash = ComputeHash(colors);
			}
		}

		private static void PopulateColorList(ClothingUtility clothingUtility, IReadOnlyList<SerializableColorData> colors)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			//IL_005c: Expected O, but got Unknown
			if (clothingUtility.ColorDataList == null)
			{
				clothingUtility.ColorDataList = new List<ColorData>();
			}
			List<ColorData> colorDataList = clothingUtility.ColorDataList;
			colorDataList.Clear();
			foreach (SerializableColorData color in colors)
			{
				if (color != null)
				{
					Color actualColor = color.ToUnityColor();
					colorDataList.Add(new ColorData
					{
						ColorType = color.GetEnumColorType(),
						ActualColor = actualColor
					});
				}
			}
		}

		private static bool IsAlreadySeeded(ClothingUtility clothingUtility, IReadOnlyList<SerializableColorData> colors)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			if (clothingUtility?.ColorDataList == null || colors == null)
			{
				return false;
			}
			if (colors.Count == 0)
			{
				return false;
			}
			int num = ComputeHash(colors);
			if (_lastHash.HasValue && _lastHash.Value == num)
			{
				return true;
			}
			if (clothingUtility.ColorDataList.Count != colors.Count)
			{
				return false;
			}
			for (int i = 0; i < colors.Count; i++)
			{
				ColorData val = clothingUtility.ColorDataList[i];
				SerializableColorData serializableColorData = colors[i];
				if (val == null || serializableColorData == null)
				{
					return false;
				}
				if (val.ColorType != serializableColorData.GetEnumColorType())
				{
					return false;
				}
				if (val.ActualColor != serializableColorData.ToUnityColor())
				{
					return false;
				}
			}
			_lastHash = num;
			return true;
		}

		private static int ComputeHash(IReadOnlyList<SerializableColorData> colors)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			int num = 17;
			for (int i = 0; i < colors.Count; i++)
			{
				SerializableColorData serializableColorData = colors[i];
				num = num * 31 + (serializableColorData?.ColorType.GetHashCode() ?? 0);
				Color val = serializableColorData?.ToUnityColor() ?? Color.white;
				num = num * 31 + val.r.GetHashCode();
				num = num * 31 + val.g.GetHashCode();
				num = num * 31 + val.b.GetHashCode();
				num = num * 31 + val.a.GetHashCode();
			}
			return num;
		}
	}
	internal static class ColorDataRepository
	{
		private const string ResourceName = "HonestMainMenu.Resources.ColorData.json";

		private static readonly Encoding Utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

		private static readonly DataContractJsonSerializerSettings SerializerSettings = new DataContractJsonSerializerSettings
		{
			UseSimpleDictionaryFormat = true
		};

		private static readonly DataContractJsonSerializer ColorListSerializer = new DataContractJsonSerializer(typeof(List<SerializableColorData>), SerializerSettings);

		internal static string UserDataPath => Path.Combine(MelonEnvironment.MelonBaseDirectory, "Mods", "HonestMainMenu");

		internal static string ColorDataFilePath => Path.Combine(UserDataPath, "ColorData.json");

		internal static List<SerializableColorData> Load()
		{
			if (File.Exists(ColorDataFilePath))
			{
				try
				{
					using FileStream stream = File.OpenRead(ColorDataFilePath);
					return ReadColorList(stream, ColorDataFilePath);
				}
				catch (Exception arg)
				{
					Melon<Main>.Logger.Error($"[ColorDataRepository] Failed to read custom color data '{ColorDataFilePath}': {arg}");
				}
			}
			Melon<Main>.Logger.Msg("[ColorDataRepository] Custom color data not found or unreadable. Loading embedded defaults.");
			return LoadEmbeddedDefaults();
		}

		internal static void SaveLiveColors(List<ColorData> liveDataList)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (liveDataList == null)
			{
				Melon<Main>.Logger.Warning("[ColorDataRepository] No live color data provided; skipping save.");
				return;
			}
			try
			{
				List<SerializableColorData> list = new List<SerializableColorData>(liveDataList.Count);
				foreach (ColorData liveData in liveDataList)
				{
					if (liveData != null)
					{
						list.Add(new SerializableColorData(liveData.ColorType, liveData.ActualColor));
					}
				}
				List<SerializableColorData> second = LoadEmbeddedDefaults(cloneList: false);
				if (!list.SequenceEqual(second))
				{
					Melon<Main>.Logger.Warning("[ColorDataRepository] Live color data differs from embedded defaults. Consider updating Resources/ColorData.json.");
				}
				else
				{
					Melon<Main>.Logger.Msg("[ColorDataRepository] Live color data matches embedded defaults.");
				}
				EnsureUserDataDirectory();
				string contents = SerializeColors(list);
				File.WriteAllText(ColorDataFilePath, contents, Utf8);
				Melon<Main>.Logger.Msg($"[ColorDataRepository] Saved {list.Count} colors to '{ColorDataFilePath}'.");
			}
			catch (Exception arg)
			{
				Melon<Main>.Logger.Error($"[ColorDataRepository] Failed to save live color data: {arg}");
			}
		}

		internal static List<SerializableColorData> LoadEmbeddedDefaults(bool cloneList = true)
		{
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("HonestMainMenu.Resources.ColorData.json");
				if (stream == null)
				{
					Melon<Main>.Logger.Error("[ColorDataRepository] Embedded resource 'HonestMainMenu.Resources.ColorData.json' not found.");
					return new List<SerializableColorData>();
				}
				List<SerializableColorData> list = ReadColorList(stream, "HonestMainMenu.Resources.ColorData.json");
				return cloneList ? new List<SerializableColorData>(list) : list;
			}
			catch (Exception arg)
			{
				Melon<Main>.Logger.Error(string.Format("[ColorDataRepository] Failed to read embedded color data '{0}': {1}", "HonestMainMenu.Resources.ColorData.json", arg));
				return new List<SerializableColorData>();
			}
		}

		private static List<SerializableColorData> ReadColorList(Stream stream, string source)
		{
			try
			{
				return Normalize(((XmlObjectSerializer)ColorListSerializer).ReadObject(stream) as List<SerializableColorData>);
			}
			catch (Exception arg)
			{
				Melon<Main>.Logger.Error($"[ColorDataRepository] Failed to deserialize color data ({source}): {arg}");
				return new List<SerializableColorData>();
			}
		}

		private static List<SerializableColorData> Normalize(List<SerializableColorData> rawList)
		{
			return rawList?.Where((SerializableColorData entry) => entry != null && entry.ActualColor != null).ToList() ?? new List<SerializableColorData>();
		}

		private static string SerializeColors(IReadOnlyList<SerializableColorData> colors)
		{
			using MemoryStream memoryStream = new MemoryStream();
			((XmlObjectSerializer)ColorListSerializer).WriteObject((Stream)memoryStream, (object)colors);
			return Utf8.GetString(memoryStream.ToArray());
		}

		private static void EnsureUserDataDirectory()
		{
			if (!Directory.Exists(UserDataPath))
			{
				Directory.CreateDirectory(UserDataPath);
			}
		}
	}
	internal static class ContinueScreenSetup
	{
		public static void Apply(Transform mainMenuRoot)
		{
			if (UIHelper.TryFindChild(mainMenuRoot, "Continue", out var child, "Could not find 'MainMenu/Continue' screen object. Aborting screen configuration."))
			{
				((Object)((Component)child).gameObject).name = "LoadGame";
				if (UIHelper.TryFindChild(child, "Title", out var child2, "Could not find 'Title' child GameObject under '" + ((Object)child).name + "'. The screen title text will not be updated."))
				{
					((Component)child2).gameObject.SetText("Load Game");
				}
			}
		}
	}
	internal static class MenuReactivity
	{
		private static UnityAction _onSaveInfoLoaded;

		private static bool _continueActionHooked;

		private const string ContinueErrorTitle = "Error";

		private const string ContinueErrorMessage = "An error occurred while trying to continue the last played game. Please try loading it manually from the Load Game menu.";

		public static IEnumerator Run(MenuButtons menuButtons)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Singleton<LoadManager>.Instance != (Object)null));
			if (LoadManager.LastPlayedGame != null)
			{
				UpdateContinueButtonInteractableState(menuButtons);
			}
			else if (_onSaveInfoLoaded == null)
			{
				_onSaveInfoLoaded = (UnityAction)delegate
				{
					Melon<Main>.Logger.Msg("LoadManager.OnSaveInfoLoaded event triggered, updating buttons interactable states.");
					UpdateContinueButtonInteractableState(menuButtons);
					DetachSaveInfoListener();
				};
				Singleton<LoadManager>.Instance.onSaveInfoLoaded.AddListener(_onSaveInfoLoaded);
			}
		}

		public static void Stop()
		{
			DetachSaveInfoListener();
			_continueActionHooked = false;
		}

		private static void UpdateContinueButtonInteractableState(MenuButtons menuButtons)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (!_continueActionHooked)
			{
				((UnityEvent)menuButtons.ContinueButton.onClick).AddListener(new UnityAction(PerformNewContinueAction));
				_continueActionHooked = true;
			}
			((Selectable)menuButtons.ContinueButton).interactable = true;
			((Selectable)menuButtons.LoadGameButton).interactable = true;
		}

		private static void PerformNewContinueAction()
		{
			if (!Singleton<Lobby>.Instance.IsHost)
			{
				Singleton<MainMenuPopup>.Instance.Open("Cannot Continue", "You must be the host in order to be able to continue a game.", true);
				return;
			}
			try
			{
				Singleton<LoadManager>.Instance.StartGame(LoadManager.LastPlayedGame, false, true);
			}
			catch (MissingMethodException ex) when (ex.Message.Contains("StartGame") || (ex.StackTrace?.Contains("LoadManager.StartGame") ?? false))
			{
				try
				{
					Singleton<LoadManager>.Instance.StartGame(LoadManager.LastPlayedGame, false, true);
					Melon<Main>.Logger.Warning($"Detected missing method exception while trying to continue the last played game: {ex}. " + "This is likely due to an outdated game build. Please update to the latest version. Continuing with the older method signature.");
				}
				catch (Exception exception)
				{
					ShowContinueFailureDialog("Fallback StartGame call also failed after MissingMethodException", exception);
				}
			}
			catch (Exception exception2)
			{
				ShowContinueFailureDialog("An error occurred while trying to continue the last played game", exception2);
			}
		}

		private static void ShowContinueFailureDialog(string context, Exception exception)
		{
			Melon<Main>.Logger.Error($"{context}: {exception}");
			Singleton<MainMenuPopup>.Instance.Open("Error", "An error occurred while trying to continue the last played game. Please try loading it manually from the Load Game menu.", true);
		}

		private static void DetachSaveInfoListener()
		{
			if (_onSaveInfoLoaded != null && !((Object)(object)Singleton<LoadManager>.Instance == (Object)null))
			{
				Singleton<LoadManager>.Instance.onSaveInfoLoaded.RemoveListener(_onSaveInfoLoaded);
				_onSaveInfoLoaded = null;
			}
		}
	}
	internal static class MenuSetup
	{
		public static MenuButtons Build(Transform menuRoot)
		{
			if (!UIHelper.TryFindChild(menuRoot, "Home/Bank", out var child, "Could not find menu buttons parent object at 'MainMenu/Home/Bank', aborting UI modifications!"))
			{
				return null;
			}
			if (!UIHelper.TryFindChild(child, "Continue", out var child2, "Could not find the original 'Continue' button object, aborting UI modifications!"))
			{
				return null;
			}
			MenuButtons menuButtons = new MenuButtons
			{
				ContinueButton = CreateAndConfigureNewContinueButton(((Component)child2).gameObject),
				LoadGameButton = null
			};
			if ((Object)(object)menuButtons.ContinueButton == (Object)null)
			{
				Melon<Main>.Logger.Error("Failed to create and configure the new 'Continue' button, aborting UI modifications!");
				return null;
			}
			menuButtons.LoadGameButton = ConfigureLoadGameButton(((Component)child2).gameObject);
			if ((Object)(object)menuButtons.LoadGameButton == (Object)null)
			{
				Melon<Main>.Logger.Error("Failed to configure the 'LoadGame' button, aborting UI modifications!");
				return null;
			}
			((Selectable)menuButtons.ContinueButton).interactable = false;
			((Selectable)menuButtons.LoadGameButton).interactable = false;
			PositionButtonsAndOffsetSiblings(menuButtons);
			return menuButtons;
		}

		private static Button ConfigureLoadGameButton(GameObject buttonObject)
		{
			Button component = buttonObject.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			((Object)buttonObject).name = "LoadGame";
			buttonObject.SetText("Load Game");
			return component;
		}

		private static Button CreateAndConfigureNewContinueButton(GameObject buttonObject)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(buttonObject, buttonObject.transform.parent);
			((Object)val).name = "Continue";
			val.SetText("Continue");
			Button component = val.GetComponent<Button>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			component.onClick = new ButtonClickedEvent();
			return component;
		}

		private static void PositionButtonsAndOffsetSiblings(MenuButtons menuButtons)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0038: 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_005a: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetRects(menuButtons, out var loadGameRect, out var continueRect, out var parentTransform, out var originalIndex))
			{
				Object.Destroy((Object)(object)((Component)menuButtons.ContinueButton).gameObject);
				return;
			}
			Rect rect = continueRect.rect;
			float height = ((Rect)(ref rect)).height;
			Vector2 anchoredPosition = loadGameRect.anchoredPosition;
			PlaceButton(((Component)menuButtons.ContinueButton).gameObject, continueRect, anchoredPosition, originalIndex);
			PlaceButton(((Component)menuButtons.LoadGameButton).gameObject, loadGameRect, anchoredPosition + new Vector2(0f, 0f - height), originalIndex + 1);
			OffsetRemainingSiblings(parentTransform, originalIndex + 2, height);
			Melon<Main>.Logger.Msg("Positioned new 'Continue' at original spot, shifted 'LoadGame' (Load Game) below it, and offset subsequent buttons.");
		}

		private static bool TryGetRects(MenuButtons menuButtons, out RectTransform loadGameRect, out RectTransform continueRect, out Transform parentTransform, out int originalIndex)
		{
			loadGameRect = ((Component)menuButtons.LoadGameButton).gameObject.GetComponent<RectTransform>();
			continueRect = ((Component)menuButtons.ContinueButton).gameObject.GetComponent<RectTransform>();
			parentTransform = ((Component)menuButtons.LoadGameButton).gameObject.transform.parent;
			originalIndex = ((Component)menuButtons.LoadGameButton).gameObject.transform.GetSiblingIndex();
			if ((Object)(object)loadGameRect != (Object)null && (Object)(object)continueRect != (Object)null && (Object)(object)parentTransform != (Object)null)
			{
				return true;
			}
			Melon<Main>.Logger.Error("Could not get RectTransforms or parent for positioning. Destroying new button.");
			return false;
		}

		private static void PlaceButton(GameObject buttonObject, RectTransform rectTransform, Vector2 anchoredPosition, int siblingIndex)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchoredPosition = anchoredPosition;
			buttonObject.transform.SetSiblingIndex(siblingIndex);
		}

		private static void OffsetRemainingSiblings(Transform parentTransform, int startIndex, float offset)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = startIndex; i < parentTransform.childCount; i++)
			{
				RectTransform component = ((Component)parentTransform.GetChild(i)).GetComponent<RectTransform>();
				if (component != null)
				{
					component.anchoredPosition = new Vector2(component.anchoredPosition.x, component.anchoredPosition.y - offset);
				}
			}
		}
	}
}
namespace HonestMainMenu.Patches
{
	[HarmonyPatch(typeof(MainMenuRig), "LoadStuff")]
	public static class MainMenuRigLoadStuffPatch
	{
		private static readonly HashSet<int> LoadedRigs = new HashSet<int>();

		private static readonly object LoadedRigsLock = new object();

		public static bool Prefix(MainMenuRig __instance)
		{
			try
			{
				if (!TryBeginRigLoad(__instance))
				{
					return false;
				}
				bool flag = false;
				if (LoadManager.LastPlayedGame != null)
				{
					string text = Path.Combine(LoadManager.LastPlayedGame.SavePath, "Players", "Player_0");
					string path = Path.Combine(text, "Appearance.json");
					BasicAvatarSettings val = ScriptableObject.CreateInstance<BasicAvatarSettings>();
					if (File.Exists(path))
					{
						JsonUtility.FromJsonOverwrite(File.ReadAllText(path), (object)val);
						__instance.Avatar.LoadAvatarSettings(val.GetAvatarSettings());
						MelonCoroutines.Start(ClothingDataService.ApplyClothingCoroutine(__instance.Avatar, text, val));
						flag = true;
					}
					else
					{
						Melon<Main>.Logger.Warning("[MainMenuRigLoadStuffPatch] Appearance.json not found, skipping avatar appearance load.");
					}
					float num = LoadManager.LastPlayedGame.Networth;
					for (int i = 0; i < __instance.CashPiles.Length; i++)
					{
						float displayedAmount = Mathf.Clamp(num, 0f, 100000f);
						__instance.CashPiles[i].SetDisplayedAmount(displayedAmount);
						num -= 100000f;
						if (num <= 0f)
						{
							break;
						}
					}
					Melon<Main>.Logger.Msg("[MainMenuRigLoadStuffPatch] Completed loading Main Menu Rig and started Avatar appearance application..");
				}
				if (!flag)
				{
					((Component)__instance.Avatar).gameObject.SetActive(false);
				}
			}
			catch (Exception arg)
			{
				Melon<Main>.Logger.Error($"[MainMenuRigLoadStuffPatch] An error occurred in the Prefix: {arg}");
				return true;
			}
			return false;
		}

		private static bool TryBeginRigLoad(MainMenuRig rig)
		{
			if ((Object)(object)rig == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)rig).GetInstanceID();
			lock (LoadedRigsLock)
			{
				if (LoadedRigs.Contains(instanceID))
				{
					return false;
				}
				LoadedRigs.Add(instanceID);
				return true;
			}
		}

		public static void ResetLoadedRigs()
		{
			lock (LoadedRigsLock)
			{
				LoadedRigs.Clear();
			}
		}
	}
	[HarmonyPatch(typeof(SceneManager), "LoadScene", new Type[] { typeof(string) })]
	public static class SceneManagerLoadScenePatch
	{
		private static string _lastSceneName = string.Empty;

		private static bool Prefix(string sceneName)
		{
			if (!string.IsNullOrEmpty(_lastSceneName) && (_lastSceneName.Equals(sceneName, StringComparison.OrdinalIgnoreCase) || _lastSceneName.Equals("Assets/Scenes/" + sceneName + ".unity", StringComparison.OrdinalIgnoreCase)))
			{
				return false;
			}
			_lastSceneName = sceneName;
			return true;
		}
	}
}
namespace HonestMainMenu.Models
{
	[Serializable]
	[DataContract]
	public sealed class SerializableClothingFile
	{
		[DataMember(Name = "Items")]
		public List<string> Items { get; private set; } = new List<string>();


		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (Items == null)
			{
				List<string> list2 = (Items = new List<string>());
			}
		}
	}
	[Serializable]
	[DataContract]
	public sealed class SerializableClothingSaveData
	{
		private const string ClothingDataType = "ClothingData";

		private static readonly Type ColorEnumType = typeof(EClothingColor);

		private static readonly Array EnumValues = Enum.GetValues(ColorEnumType);

		private static readonly EClothingColor DefaultColor = (EClothingColor)((EnumValues.Length > 0) ? ((int)(EClothingColor)EnumValues.GetValue(0)) : 0);

		private static readonly HashSet<int> ValidColorValues = BuildValidColorSet();

		[DataMember(Name = "DataType")]
		public string DataType { get; set; } = "ClothingData";


		[DataMember(Name = "ID")]
		public string Id { get; set; }

		[DataMember(Name = "Color")]
		public int Color { get; set; }

		public bool IsValid
		{
			get
			{
				EClothingColor clothingColor;
				return TryGetValidColor(out clothingColor);
			}
		}

		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (DataType == null)
			{
				string text2 = (DataType = "ClothingData");
			}
		}

		public bool TryGetValidColor(out EClothingColor clothingColor)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected I4, but got Unknown
			if (!string.Equals(DataType, "ClothingData", StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(Id))
			{
				clothingColor = (EClothingColor)(int)DefaultColor;
				return false;
			}
			return TryGetColor(out clothingColor);
		}

		public bool TryGetColor(out EClothingColor clothingColor)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected I4, but got Unknown
			if (ValidColorValues.Contains(Color))
			{
				clothingColor = (EClothingColor)Color;
				return true;
			}
			clothingColor = (EClothingColor)(int)DefaultColor;
			return false;
		}

		private static HashSet<int> BuildValidColorSet()
		{
			HashSet<int> hashSet = new HashSet<int>();
			foreach (object enumValue in EnumValues)
			{
				hashSet.Add((int)enumValue);
			}
			return hashSet;
		}
	}
	[Serializable]
	[DataContract]
	public sealed class SerializableColor : IEquatable<SerializableColor>
	{
		private float _alpha = 1f;

		private bool _alphaExplicitlySet;

		[DataMember(Name = "r")]
		public float R { get; private set; }

		[DataMember(Name = "g")]
		public float G { get; private set; }

		[DataMember(Name = "b")]
		public float B { get; private set; }

		[DataMember(Name = "a")]
		public float A
		{
			get
			{
				return _alpha;
			}
			private set
			{
				_alpha = value;
				_alphaExplicitlySet = true;
			}
		}

		public SerializableColor()
		{
		}

		public SerializableColor(float r, float g, float b, float a = 1f)
		{
			R = r;
			G = g;
			B = b;
			A = a;
		}

		public SerializableColor(Color color)
		{
			//IL_0012: 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_002a: 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)
			R = color.r;
			G = color.g;
			B = color.b;
			A = color.a;
		}

		public Color ToUnityColor()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Color(R, G, B, A);
		}

		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (!_alphaExplicitlySet)
			{
				_alpha = 1f;
			}
		}

		public bool Equals(SerializableColor other)
		{
			if (other == null)
			{
				return false;
			}
			if (this == other)
			{
				return true;
			}
			if (R.Equals(other.R) && G.Equals(other.G) && B.Equals(other.B))
			{
				return A.Equals(other.A);
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (obj.GetType() != GetType())
			{
				return false;
			}
			return Equals((SerializableColor)obj);
		}

		public override int GetHashCode()
		{
			return (((17 * 23 + R.GetHashCode()) * 23 + G.GetHashCode()) * 23 + B.GetHashCode()) * 23 + A.GetHashCode();
		}
	}
	[Serializable]
	[DataContract]
	public sealed class SerializableColorData : IEquatable<SerializableColorData>
	{
		[NonSerialized]
		private Color? _cachedUnityColor;

		[DataMember(Name = "ColorType")]
		public int ColorType { get; private set; }

		[DataMember(Name = "ActualColor")]
		public SerializableColor ActualColor { get; private set; } = new SerializableColor();


		public SerializableColorData()
		{
		}

		public SerializableColorData(int colorType, SerializableColor actualColor)
		{
			ColorType = colorType;
			ActualColor = actualColor ?? new SerializableColor();
		}

		public SerializableColorData(int colorType, Color actualColor)
			: this(colorType, new SerializableColor(actualColor))
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)


		public SerializableColorData(EClothingColor colorType, Color actualColor)
			: this((int)colorType, actualColor)
		{
		}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected I4, but got Unknown


		[OnDeserialized]
		private void OnDeserialized(StreamingContext context)
		{
			if (ActualColor == null)
			{
				SerializableColor serializableColor2 = (ActualColor = new SerializableColor());
			}
			_cachedUnityColor = null;
		}

		public EClothingColor GetEnumColorType()
		{
			return (EClothingColor)ColorType;
		}

		public Color ToUnityColor()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!_cachedUnityColor.HasValue)
			{
				_cachedUnityColor = ActualColor?.ToUnityColor() ?? Color.white;
			}
			return _cachedUnityColor.Value;
		}

		public bool Equals(SerializableColorData other)
		{
			if (other == null)
			{
				return false;
			}
			if (this == other)
			{
				return true;
			}
			if (ColorType == other.ColorType)
			{
				return object.Equals(ActualColor, other.ActualColor);
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (obj.GetType() != GetType())
			{
				return false;
			}
			return Equals((SerializableColorData)obj);
		}

		public override int GetHashCode()
		{
			return (17 * 23 + ColorType.GetHashCode()) * 23 + (ActualColor?.GetHashCode() ?? 0);
		}
	}
	internal class MenuButtons
	{
		public Button ContinueButton { get; set; }

		public Button LoadGameButton { get; set; }
	}
}