Decompiled source of ModEnforcementAgency v0.1.0

Plugins/ModEnforcementAgency.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppScheduleOne.UI.Shop;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.IO;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using ModEnforcementAgency;
using ModEnforcementAgency.MainMenu;
using ModEnforcementAgency.Managers;
using ModEnforcementAgency.Managers.Items;
using ModEnforcementAgency.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "ModEnforcementAgency", "0.1.0", "Moddy", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: HarmonyDontPatchAll]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ModEnforcementAgency")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6a79a3fbc4ab207727597e48f70871538fb4bb79")]
[assembly: AssemblyProduct("ModEnforcementAgency")]
[assembly: AssemblyTitle("ModEnforcementAgency")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ModEnforcementAgency
{
	public class Core : MelonPlugin
	{
		public static Core Instance;

		public const string VERSION = "0.1.0";

		private bool settingsTabAdded = false;

		private bool versionDisplayConfigured = false;

		public Instance logger;

		internal static ModManager ModManager => ModManager.Instance;

		public Il2CppAssetBundle MEAContent { get; private set; }

		public override void OnApplicationStarted()
		{
			ModManager.RegisterMods(MelonBase.RegisteredMelons);
			PrefManager.Instance.Initialize();
			PrefManager.Instance.RegisterAllMods();
			CustomItemManager.Initialize();
			MEAContent = AssetUtils.LoadAssetBundleFromResources("meacontent", ((MelonBase)this).MelonAssembly.Assembly);
		}

		public override void OnPreInitialization()
		{
		}

		public override void OnInitializeMelon()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			Instance = this;
			logger = ((MelonBase)this).LoggerInstance;
			((MelonBase)this).LoggerInstance.Msg("MEA v0.1.0 Initialized.");
			ClassInjector.RegisterTypeInIl2Cpp<VersionDisplayComponent>();
			Harmony harmony = new Harmony("com.moddy.ModEnforcementAgency");
			ApplyPatches(harmony);
		}

		private void ApplyPatches(Harmony harmony)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			MethodInfo method = typeof(SettingsScreen).GetMethod("Start", BindingFlags.Instance | BindingFlags.Public);
			MethodInfo method2 = typeof(Core).GetMethod("SettingsScreen_Start_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
			if (method != null && method2 != null)
			{
				harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("Successfully patched SettingsScreen.Start");
			}
			else
			{
				((MelonBase)this).LoggerInstance.Error("Failed to patch SettingsScreen.Start");
			}
			MethodInfo method3 = typeof(MainMenuRig).GetMethod("LoadStuff", BindingFlags.Instance | BindingFlags.Public);
			MethodInfo method4 = typeof(Core).GetMethod("MainMenuScreen_Open_Postfix", BindingFlags.Static | BindingFlags.NonPublic);
			if (method3 != null && method4 != null)
			{
				harmony.Patch((MethodBase)method3, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("Successfully patched MainMenuScreen.Open");
			}
			else
			{
				((MelonBase)this).LoggerInstance.Error("Failed to patch MainMenuScreen.Open");
			}
		}

		[HarmonyPatch(typeof(SettingsScreen), "Start")]
		private static void SettingsScreen_Start_Postfix(SettingsScreen __instance)
		{
			if (Instance != null && !Instance.settingsTabAdded)
			{
				((MelonBase)Instance).LoggerInstance.Msg("Adding mod settings tab to settings screen");
				MelonCoroutines.Start(ModSettingsMenu.AddModCategory(__instance));
				Instance.settingsTabAdded = true;
			}
		}

		[HarmonyPatch(typeof(MainMenuRig), "LoadStuff")]
		private static void MainMenuScreen_Open_Postfix(MainMenuScreen __instance)
		{
			if (Instance != null && !Instance.versionDisplayConfigured)
			{
				MelonCoroutines.Start(FontUtils.LoadFonts());
				MelonCoroutines.Start(VersionDisplayComponent.AddVersionDisplayWithDelay());
				Instance.versionDisplayConfigured = true;
				((MelonBase)Instance).LoggerInstance.Msg("Version display configured successfully");
			}
		}
	}
}
namespace ModEnforcementAgency.Utils
{
	internal class FontUtils
	{
		public static Font italicFont;

		public static Font normalFont;

		public static Font boldFont;

		public static IEnumerator LoadFonts()
		{
			yield return null;
			Font[] fonts = Il2CppArrayBase<Font>.op_Implicit(Resources.FindObjectsOfTypeAll<Font>());
			List<Font> fontList = new List<Font>(fonts);
			if (fontList.Count == 0)
			{
				((MelonBase)Core.Instance).LoggerInstance.Warning("No fonts found in the scene.");
			}
			else if (fontList.Count > 0)
			{
				italicFont = fontList[0];
				normalFont = ((fontList.Count > 1) ? fontList[1] : italicFont);
				boldFont = ((fontList.Count > 2) ? fontList[2] : italicFont);
				((MelonBase)Core.Instance).LoggerInstance.Msg($"Fonts loaded: Italic: {((Object)italicFont).name}, Normal: {((Object)normalFont).name}, Bold: {((Object)boldFont).name}");
			}
		}
	}
	public static class AssetUtils
	{
		public static Il2CppAssetBundle LoadAssetBundleFromResources(string bundleName, Assembly resourceAssembly)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			if (resourceAssembly == null)
			{
				throw new ArgumentNullException("Parameter resourceAssembly can not be null.");
			}
			string text = null;
			try
			{
				text = resourceAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(bundleName));
			}
			catch (Exception)
			{
			}
			if (text == null)
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("AssetBundle " + bundleName + " not found in assembly manifest");
				return null;
			}
			Il2CppAssetBundle result;
			using (Stream stream = resourceAssembly.GetManifestResourceStream(text))
			{
				if (stream == null)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("Failed to load AssetBundle " + bundleName + " from stream.");
					return null;
				}
				Stream val = (Stream)new MemoryStream();
				byte[] array = new byte[4096];
				int num;
				while ((num = stream.Read(array, 0, array.Length)) > 0)
				{
					val.Write(Il2CppStructArray<byte>.op_Implicit(array), 0, num);
				}
				val.Position = 0L;
				result = Il2CppAssetBundleManager.LoadFromStream(val);
			}
			return result;
		}

		public static Il2CppAssetBundle LoadAssetBundleFromAbsolutePath(string absolutePath)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			if (string.IsNullOrEmpty(absolutePath))
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Absolute path cannot be null or empty.");
				return null;
			}
			if (!File.Exists(absolutePath))
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("AssetBundle file not found at path: " + absolutePath);
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(absolutePath);
				MemoryStream val = new MemoryStream(Il2CppStructArray<byte>.op_Implicit(array));
				Il2CppAssetBundle val2 = Il2CppAssetBundleManager.LoadFromStream((Stream)(object)val);
				if (val2 == null)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("Failed to load AssetBundle from path: " + absolutePath);
					return null;
				}
				return val2;
			}
			catch (Exception ex)
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Exception loading AssetBundle from path " + absolutePath + ": " + ex.Message);
				return null;
			}
		}

		public static Il2CppAssetBundle LoadAssetBundleFromRelativePath(string relativePath, Assembly assembly)
		{
			if (assembly == null)
			{
				throw new ArgumentNullException("Parameter assembly cannot be null.");
			}
			if (string.IsNullOrEmpty(relativePath))
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Relative path cannot be null or empty.");
				return null;
			}
			try
			{
				string directoryName = Path.GetDirectoryName(assembly.Location);
				string absolutePath = Path.Combine(directoryName, relativePath);
				return LoadAssetBundleFromAbsolutePath(absolutePath);
			}
			catch (Exception ex)
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Exception resolving relative path: " + ex.Message);
				return null;
			}
		}
	}
}
namespace ModEnforcementAgency.MainMenu
{
	internal class ModSettingsMenu
	{
		public static GameObject templateMod;

		public static IEnumerator AddModCategory(SettingsScreen settingsScreen)
		{
			yield return null;
			try
			{
				if ((Object)(object)settingsScreen == (Object)null)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("SettingsScreen is null");
					yield break;
				}
				Il2CppReferenceArray<SettingsCategory> categories = settingsScreen.Categories;
				if (categories == null || ((Il2CppArrayBase<SettingsCategory>)(object)categories).Length == 0)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("Categories array is null or empty");
					yield break;
				}
				SettingsCategory modCategory = new SettingsCategory();
				Button firstButton = ((Il2CppArrayBase<SettingsCategory>)(object)categories)[1].Button;
				if ((Object)(object)firstButton == (Object)null)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("First category button is null");
					yield break;
				}
				GameObject buttonParentObj = ((Component)((Component)firstButton).gameObject.transform.parent).gameObject;
				GameObject buttonObj = Object.Instantiate<GameObject>(((Component)firstButton).gameObject, buttonParentObj.transform);
				((Object)buttonObj).name = "ModSettingsButton";
				Button button = buttonObj.GetComponent<Button>();
				TextMeshProUGUI buttonText = buttonObj.GetComponentInChildren<TextMeshProUGUI>();
				if ((Object)(object)buttonText != (Object)null)
				{
					((TMP_Text)buttonText).text = "Mods";
				}
				GameObject firstPanel = ((Il2CppArrayBase<SettingsCategory>)(object)categories)[0].Panel;
				if ((Object)(object)firstPanel == (Object)null)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("First category panel is null");
					yield break;
				}
				GameObject panelParentObj = ((Component)firstPanel.transform.parent).gameObject;
				GameObject uiPrefab = Object.Instantiate<GameObject>(Core.Instance.MEAContent.LoadAsset<GameObject>("UI_InstalledMods"));
				uiPrefab.transform.SetParent(panelParentObj.transform, false);
				((Object)uiPrefab).name = "ModSettingsPanel";
				Transform contentTransform = uiPrefab.transform.Find("Scroll View/Viewport/Content");
				if ((Object)(object)contentTransform == (Object)null)
				{
					((MelonBase)Core.Instance).LoggerInstance.Error("Content transform not found in UI_InstalledMods prefab");
					yield break;
				}
				templateMod = ((Component)((Component)contentTransform).transform.Find("TemplateMod")).gameObject;
				templateMod.SetActive(false);
				int modCount = 0;
				foreach (MelonBase mod in MelonBase.RegisteredMelons)
				{
					if (mod == null)
					{
						((MelonBase)Core.Instance).LoggerInstance.Warning("Encountered a null mod during mod settings UI creation");
						continue;
					}
					new ModInfoDisplay(mod, ((Component)contentTransform).gameObject);
					modCount++;
				}
				modCategory.Button = button;
				modCategory.Panel = uiPrefab;
				uiPrefab.SetActive(false);
				Il2CppReferenceArray<SettingsCategory> newCategories = new Il2CppReferenceArray<SettingsCategory>((long)(((Il2CppArrayBase<SettingsCategory>)(object)categories).Length + 1));
				for (int i = 0; i < ((Il2CppArrayBase<SettingsCategory>)(object)categories).Length; i++)
				{
					((Il2CppArrayBase<SettingsCategory>)(object)newCategories)[i] = ((Il2CppArrayBase<SettingsCategory>)(object)categories)[i];
				}
				((Il2CppArrayBase<SettingsCategory>)(object)newCategories)[((Il2CppArrayBase<SettingsCategory>)(object)categories).Length] = modCategory;
				settingsScreen.Categories = newCategories;
				int categoryIndex = ((Il2CppArrayBase<SettingsCategory>)(object)categories).Length;
				((UnityEvent)button.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
				{
					settingsScreen.ShowCategory(categoryIndex);
				}));
				((MelonBase)Core.Instance).LoggerInstance.Msg("Added mod settings tab");
			}
			catch (Exception ex)
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Error adding mod settings tab: " + ex.Message + "\n" + ex.StackTrace);
			}
		}
	}
	internal class ModInfoDisplay
	{
		private MelonBase mod;

		private GameObject modInfoContainer;

		public float PreferredHeight { get; private set; } = 70f;


		public ModInfoDisplay(MelonBase mod, GameObject parent)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Expected O, but got Unknown
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			this.mod = mod;
			modInfoContainer = Object.Instantiate<GameObject>(ModSettingsMenu.templateMod, parent.transform);
			modInfoContainer.SetActive(true);
			((Object)modInfoContainer).name = "ModInfo_" + mod.Info.Name;
			GameObject val = new GameObject("ContentLayout");
			val.transform.SetParent(modInfoContainer.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.sizeDelta = Vector2.zero;
			val2.offsetMin = new Vector2(10f, 10f);
			val2.offsetMax = new Vector2(-10f, -10f);
			GameObject val3 = new GameObject("ModName");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = new Vector2(0f, 1f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(0f, 1f);
			val4.sizeDelta = new Vector2(0f, 25f);
			val4.anchoredPosition = Vector2.zero;
			Text val5 = val3.AddComponent<Text>();
			val5.text = mod.Info.Name;
			val5.fontSize = 16;
			val5.fontStyle = (FontStyle)1;
			val5.alignment = (TextAnchor)3;
			((Graphic)val5).color = new Color(0.9f, 0.9f, 0.9f, 1f);
			val5.font = FontUtils.boldFont;
			GameObject val6 = new GameObject("ModVersion");
			val6.transform.SetParent(val.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = new Vector2(0f, 1f);
			val7.anchorMax = new Vector2(1f, 1f);
			val7.pivot = new Vector2(0f, 1f);
			val7.sizeDelta = new Vector2(0f, 18f);
			val7.anchoredPosition = new Vector2(0f, -25f);
			Text val8 = val6.AddComponent<Text>();
			val8.text = "Version: " + mod.Info.Version;
			val8.fontSize = 14;
			val8.alignment = (TextAnchor)3;
			((Graphic)val8).color = new Color(0.8f, 0.8f, 0.8f, 1f);
			val8.font = FontUtils.normalFont;
			val8.resizeTextForBestFit = true;
			GameObject val9 = new GameObject("ModAuthor");
			val9.transform.SetParent(val.transform, false);
			RectTransform val10 = val9.AddComponent<RectTransform>();
			val10.anchorMin = new Vector2(0f, 1f);
			val10.anchorMax = new Vector2(1f, 1f);
			val10.pivot = new Vector2(0f, 1f);
			val10.sizeDelta = new Vector2(0f, 18f);
			val10.anchoredPosition = new Vector2(0f, -43f);
			Text val11 = val9.AddComponent<Text>();
			val11.text = "Author: " + mod.Info.Author;
			val11.fontSize = 14;
			val11.alignment = (TextAnchor)3;
			((Graphic)val11).color = new Color(0.8f, 0.8f, 0.8f, 1f);
			val11.font = FontUtils.normalFont;
			val11.resizeTextForBestFit = true;
			GameObject val12 = new GameObject("ModAssembly");
			val12.transform.SetParent(val.transform, false);
			RectTransform val13 = val12.AddComponent<RectTransform>();
			val13.anchorMin = new Vector2(0f, 1f);
			val13.anchorMax = new Vector2(1f, 1f);
			val13.pivot = new Vector2(0f, 1f);
			val13.sizeDelta = new Vector2(0f, 18f);
			val13.anchoredPosition = new Vector2(0f, -61f);
			Text val14 = val12.AddComponent<Text>();
			string fileName = Path.GetFileName(mod.MelonAssembly.Location);
			val14.text = "Assembly: " + fileName;
			val14.fontSize = 12;
			val14.alignment = (TextAnchor)3;
			((Graphic)val14).color = new Color(0.7f, 0.7f, 0.7f, 1f);
			val14.font = FontUtils.normalFont;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class VersionDisplayComponent : MonoBehaviour
	{
		private static GameObject versionDisplay;

		private GameObject textObj;

		private Text versionText;

		public VersionDisplayComponent(IntPtr ptr)
			: base(ptr)
		{
		}

		public void SetVersion(string version)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				textObj = new GameObject("VersionText");
				textObj.transform.SetParent(((Component)this).transform, false);
				RectTransform val = ((Component)this).gameObject.AddComponent<RectTransform>();
				val.anchorMin = new Vector2(0f, 0f);
				val.anchorMax = new Vector2(0f, 0f);
				val.pivot = new Vector2(0f, 0f);
				val.anchoredPosition = new Vector2(10f, 10f);
				val.sizeDelta = new Vector2(200f, 30f);
				RectTransform val2 = textObj.AddComponent<RectTransform>();
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
				Image val3 = ((Component)this).gameObject.AddComponent<Image>();
				((Graphic)val3).color = new Color(0f, 0f, 0f, 0.5f);
				versionText = textObj.AddComponent<Text>();
				versionText.text = "MEA v" + version;
				versionText.fontSize = 14;
				((Graphic)versionText).color = Color.white;
				versionText.alignment = (TextAnchor)4;
				versionText.font = FontUtils.normalFont;
				((MelonBase)Core.Instance).LoggerInstance.Msg("Version display configured successfully");
			}
			catch (Exception ex)
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Error setting up version display: " + ex.Message);
			}
		}

		public static IEnumerator AddVersionDisplayWithDelay()
		{
			for (int i = 0; i < 5; i++)
			{
				yield return null;
			}
			try
			{
				Canvas canvas = Object.FindObjectOfType<Canvas>();
				if ((Object)(object)canvas != (Object)null && (Object)(object)versionDisplay == (Object)null)
				{
					versionDisplay = new GameObject("MEAVersionDisplay");
					versionDisplay.transform.SetParent(((Component)canvas).transform, false);
					VersionDisplayComponent versionComponent = versionDisplay.AddComponent<VersionDisplayComponent>();
					versionComponent.SetVersion("0.1.0");
					((MelonBase)Core.Instance).LoggerInstance.Msg("Added version display component");
				}
			}
			catch (Exception ex)
			{
				((MelonBase)Core.Instance).LoggerInstance.Error("Error adding version display: " + ex.Message + "\n" + ex.StackTrace);
			}
		}
	}
}
namespace ModEnforcementAgency.Managers
{
	internal class PrefManager
	{
		private static PrefManager _instance;

		private MelonPreferences_Category modConfigCategory;

		private MelonPreferences_Category userSettingsCategory;

		private MelonPreferences_Entry<bool> enabledModsAutoSave;

		private MelonPreferences_Entry<string> lastLoadedProfile;

		private Dictionary<string, MelonPreferences_Entry<bool>> modEnabledStateEntries;

		private const string MOD_PROFILES_DIR = "UserData/ModProfiles";

		private const string CURRENT_PROFILE_FILENAME = "CurrentProfile.cfg";

		public static PrefManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new PrefManager();
				}
				return _instance;
			}
		}

		public void Initialize()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			if (!Directory.Exists("UserData/ModProfiles"))
			{
				Directory.CreateDirectory("UserData/ModProfiles");
			}
			modConfigCategory = MelonPreferences.CreateCategory("MEA_ModConfiguration");
			userSettingsCategory = MelonPreferences.CreateCategory("MEA_UserSettings");
			modConfigCategory.SetFilePath(Path.Combine("UserData/ModProfiles", "CurrentProfile.cfg"));
			enabledModsAutoSave = userSettingsCategory.CreateEntry<bool>("EnabledModsAutoSave", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			lastLoadedProfile = userSettingsCategory.CreateEntry<string>("LastLoadedProfile", "Default", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			modEnabledStateEntries = new Dictionary<string, MelonPreferences_Entry<bool>>();
			((MelonEventBase<LemonAction>)(object)MelonEvents.OnApplicationQuit).Subscribe(new LemonAction(SaveAllPreferences), 0, false);
		}

		public void SaveAllPreferences()
		{
			MelonPreferences.Save();
			modConfigCategory.SaveToFile(true);
		}

		public void RegisterMod(MelonBase mod)
		{
			if (mod != null)
			{
				string modIdentifier = GetModIdentifier(mod);
				if (!modEnabledStateEntries.ContainsKey(modIdentifier))
				{
					MelonPreferences_Entry<bool> value = modConfigCategory.CreateEntry<bool>(modIdentifier, true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
					modEnabledStateEntries.Add(modIdentifier, value);
				}
			}
		}

		public void RegisterAllMods()
		{
			List<MelonBase> loadedMods = ModManager.Instance.LoadedMods;
			if (loadedMods == null)
			{
				return;
			}
			foreach (MelonBase item in loadedMods)
			{
				RegisterMod(item);
			}
		}

		public bool IsModEnabled(MelonBase mod)
		{
			if (mod == null)
			{
				return false;
			}
			string modIdentifier = GetModIdentifier(mod);
			if (modEnabledStateEntries.TryGetValue(modIdentifier, out var value))
			{
				return value.Value;
			}
			RegisterMod(mod);
			return true;
		}

		public void SetModEnabled(MelonBase mod, bool enabled)
		{
			if (mod != null)
			{
				string modIdentifier = GetModIdentifier(mod);
				if (modEnabledStateEntries.TryGetValue(modIdentifier, out var value))
				{
					value.Value = enabled;
				}
				else
				{
					RegisterMod(mod);
					modEnabledStateEntries[modIdentifier].Value = enabled;
				}
				if (enabledModsAutoSave.Value)
				{
					modConfigCategory.SaveToFile(true);
				}
			}
		}

		public void CreateProfile(string profileName)
		{
			if (!string.IsNullOrWhiteSpace(profileName))
			{
				modConfigCategory.SaveToFile(true);
				string text = Path.Combine("UserData/ModProfiles", profileName + ".cfg");
				modConfigCategory.SetFilePath(text, false);
				modConfigCategory.SaveToFile(true);
				lastLoadedProfile.Value = profileName;
				userSettingsCategory.SaveToFile(true);
			}
		}

		public void LoadProfile(string profileName)
		{
			if (!string.IsNullOrWhiteSpace(profileName))
			{
				string text = Path.Combine("UserData/ModProfiles", profileName + ".cfg");
				if (!File.Exists(text))
				{
					MelonLogger.Warning("Profile '" + profileName + "' does not exist. Creating new profile.");
					CreateProfile(profileName);
					return;
				}
				modConfigCategory.SetFilePath(text);
				RefreshModEnabledStateEntries();
				lastLoadedProfile.Value = profileName;
				userSettingsCategory.SaveToFile(true);
			}
		}

		public List<string> GetAvailableProfiles()
		{
			List<string> list = new List<string>();
			if (Directory.Exists("UserData/ModProfiles"))
			{
				string[] files = Directory.GetFiles("UserData/ModProfiles", "*.cfg");
				foreach (string path in files)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					list.Add(fileNameWithoutExtension);
				}
			}
			return list;
		}

		private string GetModIdentifier(MelonBase mod)
		{
			return mod.Info.Name + "_" + mod.MelonAssembly.Assembly.GetName().Name;
		}

		private void RefreshModEnabledStateEntries()
		{
			modEnabledStateEntries.Clear();
			foreach (MelonPreferences_Entry entry in modConfigCategory.Entries)
			{
				if (entry is MelonPreferences_Entry<bool> value)
				{
					modEnabledStateEntries.Add(entry.Identifier, value);
				}
			}
			RegisterAllMods();
		}

		private PrefManager()
		{
			modEnabledStateEntries = new Dictionary<string, MelonPreferences_Entry<bool>>();
		}
	}
	internal class ModManager
	{
		private static ModManager _instance;

		public static ModManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new ModManager();
				}
				return _instance;
			}
		}

		public List<MelonBase> LoadedMods { get; private set; }

		internal void RegisterMods(ReadOnlyCollection<MelonBase> loadedAssemblies)
		{
			if (LoadedMods == null)
			{
				LoadedMods = new List<MelonBase>();
			}
			LoadedMods.Clear();
			foreach (MelonBase loadedAssembly in loadedAssemblies)
			{
				if (loadedAssembly != null)
				{
					LoadedMods.Add(loadedAssembly);
				}
				else
				{
					((MelonBase)Core.Instance).LoggerInstance.Warning("Encountered a null mod during registration");
				}
			}
		}

		private ModManager()
		{
			LoadedMods = new List<MelonBase>();
		}
	}
}
namespace ModEnforcementAgency.Managers.Items
{
	public static class CustomItemManager
	{
		public enum EShopType
		{
			GasStation,
			HardwareStore,
			HardwareStoreNorth,
			GasStationCentral,
			WeedSupplier,
			MethSupplier,
			CokeSupplier,
			DarkMarket
		}

		private struct ShopPathMapping
		{
			public EShopType ShopType;

			public string Path;

			public ShopPathMapping(EShopType shopType, string path)
			{
				ShopType = shopType;
				Path = path;
			}
		}

		private class ShopItemMapping
		{
			public string ItemId { get; set; }

			public bool OverridePrice { get; set; }

			public float Price { get; set; }
		}

		private static readonly Dictionary<string, ItemDefinition> CustomItems = new Dictionary<string, ItemDefinition>();

		private static readonly Dictionary<string, StorableItemDefinition> CustomStorableItems = new Dictionary<string, StorableItemDefinition>();

		private static readonly Instance Logger = new Instance("MEA.CustomItemAPI");

		private static bool registryInitialized = false;

		private static readonly Dictionary<EShopType, ShopInterface> CachedShops = new Dictionary<EShopType, ShopInterface>();

		private static readonly ShopPathMapping[] KnownShopPaths = new ShopPathMapping[8]
		{
			new ShopPathMapping(EShopType.GasStation, "UI/GasStationInterface"),
			new ShopPathMapping(EShopType.HardwareStore, "UI/HardwareStoreInterface"),
			new ShopPathMapping(EShopType.HardwareStoreNorth, "UI/HardwareStoreInterface (North Store)"),
			new ShopPathMapping(EShopType.GasStationCentral, "UI/GasStationInterface_Central"),
			new ShopPathMapping(EShopType.WeedSupplier, "UI/Supplier Stores/WeedSupplierInterface"),
			new ShopPathMapping(EShopType.MethSupplier, "UI/Supplier Stores/MethSupplierInterface"),
			new ShopPathMapping(EShopType.CokeSupplier, "UI/Supplier Stores/CokeSupplierInterface"),
			new ShopPathMapping(EShopType.DarkMarket, "UI/DarkMarketInterface")
		};

		private static Dictionary<EShopType, List<ShopItemMapping>> shopItemMappings = new Dictionary<EShopType, List<ShopItemMapping>>();

		public static void Initialize()
		{
			((MelonEventBase<LemonAction<int, string>>)(object)MelonEvents.OnSceneWasLoaded).Subscribe((LemonAction<int, string>)delegate(int buildIndex, string sceneName)
			{
				if (sceneName == "Main" && !registryInitialized)
				{
					RegisterCachedItems();
					CacheShopsAndAddItems();
				}
			}, 0, false);
			Logger.Msg("Custom Item API initialized");
		}

		public static ItemDefinition RegisterItem(ItemDefinition itemDef)
		{
			StorableItemDefinition val = (StorableItemDefinition)(object)((itemDef is StorableItemDefinition) ? itemDef : null);
			if (val != null)
			{
				CustomStorableItems[itemDef.ID] = val;
				Logger.Msg("Stored " + itemDef.ID + " as StorableItemDefinition type: " + ((object)val).GetType().Name);
			}
			if (CustomItems.ContainsKey(itemDef.ID))
			{
				Logger.Warning("Item with ID " + itemDef.ID + " already exists! Returning existing item.");
				return CustomItems[itemDef.ID];
			}
			CustomItems.Add(itemDef.ID, itemDef);
			Logger.Msg("Custom item registered: " + itemDef.ID);
			if (registryInitialized && (Object)(object)Singleton<Registry>.Instance != (Object)null)
			{
				try
				{
					Singleton<Registry>.Instance.AddToRegistry(itemDef);
					Logger.Msg("Added " + itemDef.ID + " to game registry immediately");
				}
				catch (Exception ex)
				{
					Logger.Error("Failed to add item " + itemDef.ID + " to registry: " + ex.Message);
				}
			}
			return itemDef;
		}

		public static StorableItemDefinition GetStorableItem(string itemId)
		{
			if (CustomStorableItems.TryGetValue(itemId, out var value))
			{
				return value;
			}
			ItemDefinition item = Registry.GetItem(itemId);
			StorableItemDefinition val = (StorableItemDefinition)(object)((item is StorableItemDefinition) ? item : null);
			if (val != null)
			{
				return val;
			}
			return null;
		}

		public static void AddItemToShop(EShopType shopType, string itemId, float overridePrice = -1f)
		{
			if (!shopItemMappings.ContainsKey(shopType))
			{
				shopItemMappings[shopType] = new List<ShopItemMapping>();
			}
			shopItemMappings[shopType].Add(new ShopItemMapping
			{
				ItemId = itemId,
				OverridePrice = (overridePrice > 0f),
				Price = overridePrice
			});
			Logger.Msg($"Queued item {itemId} to be added to shop {shopType}");
			if (registryInitialized && CachedShops.TryGetValue(shopType, out var value))
			{
				AddItemToShopInternal(value, itemId, overridePrice > 0f, overridePrice);
				if (value.IsOpen)
				{
					value.RefreshShownItems();
				}
			}
		}

		public static Sprite LoadSpriteFromAssetBundle(string bundleName, string assetName, Assembly resourceAssembly)
		{
			try
			{
				Il2CppAssetBundle val = AssetUtils.LoadAssetBundleFromResources(bundleName, resourceAssembly);
				if (val == null)
				{
					return null;
				}
				return val.LoadAsset<Sprite>(assetName);
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to load sprite from asset bundle: " + ex.Message);
				return null;
			}
		}

		public static void RefreshShop(EShopType shopType)
		{
			if (CachedShops.TryGetValue(shopType, out var value))
			{
				value.RefreshShownItems();
				Logger.Msg($"Refreshed shop {shopType}");
			}
			else
			{
				Logger.Warning($"Cannot refresh shop {shopType}: Shop not found in cache");
			}
		}

		private static void CacheShopsAndAddItems()
		{
			try
			{
				CachedShops.Clear();
				ShopPathMapping[] knownShopPaths = KnownShopPaths;
				for (int i = 0; i < knownShopPaths.Length; i++)
				{
					ShopPathMapping shopPathMapping = knownShopPaths[i];
					GameObject val = GameObject.Find(shopPathMapping.Path);
					if ((Object)(object)val != (Object)null)
					{
						ShopInterface component = val.GetComponent<ShopInterface>();
						if ((Object)(object)component != (Object)null)
						{
							CachedShops[shopPathMapping.ShopType] = component;
							Logger.Msg($"Cached shop: {shopPathMapping.ShopType} from path {shopPathMapping.Path}");
						}
						else
						{
							Logger.Warning("Shop GameObject found at " + shopPathMapping.Path + " but doesn't have ShopInterface component");
						}
					}
					else
					{
						Logger.Warning("Shop GameObject not found at path: " + shopPathMapping.Path);
					}
				}
				foreach (KeyValuePair<EShopType, List<ShopItemMapping>> shopItemMapping in shopItemMappings)
				{
					EShopType key = shopItemMapping.Key;
					List<ShopItemMapping> value = shopItemMapping.Value;
					if (CachedShops.TryGetValue(key, out var value2))
					{
						foreach (ShopItemMapping item in value)
						{
							AddItemToShopInternal(value2, item.ItemId, item.OverridePrice, item.Price);
						}
						value2.RefreshShownItems();
						Logger.Msg($"Added {value.Count} items to shop: {key}");
					}
					else
					{
						Logger.Warning($"Failed to add items to shop {key}: Shop not found in cache");
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Error in CacheShopsAndAddItems: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		private static void AddItemToShopInternal(ShopInterface shop, string itemId, bool overridePrice, float price)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			try
			{
				StorableItemDefinition storableItem = GetStorableItem(itemId);
				if ((Object)(object)storableItem == (Object)null)
				{
					Logger.Warning($"Cannot add item {itemId} to shop {shop.ShopName}: Item not found or not a StorableItemDefinition");
					return;
				}
				Enumerator<ShopListing> enumerator = shop.Listings.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ShopListing current = enumerator.Current;
					if (((ItemDefinition)current.Item).ID == itemId)
					{
						Logger.Msg("Item " + itemId + " already in shop " + shop.ShopName);
						return;
					}
				}
				ShopListing val = new ShopListing();
				val.Item = storableItem;
				if (overridePrice)
				{
					val.OverridePrice = true;
					val.OverriddenPrice = price;
				}
				shop.Listings.Add(val);
				shop.CreateListingUI(val);
				Logger.Msg("Added item " + itemId + " to shop " + shop.ShopName);
			}
			catch (Exception ex)
			{
				Logger.Error($"Error adding {itemId} to shop {shop.ShopName}: {ex.Message}");
			}
		}

		private static void RegisterCachedItems()
		{
			Registry instance = Singleton<Registry>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Logger.Error("Registry instance not found! Items will not be registered.");
				return;
			}
			foreach (ItemDefinition value in CustomItems.Values)
			{
				try
				{
					instance.AddToRegistry(value);
					Logger.Msg("Added " + value.ID + " to game registry");
				}
				catch (Exception ex)
				{
					Logger.Error("Failed to register item " + value.ID + ": " + ex.Message);
				}
			}
			registryInitialized = true;
		}
	}
}