using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; 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 System.Text; using HarmonyLib; using Il2Cpp; using Il2CppFishNet; using Il2CppFishNet.Connection; using Il2CppFishNet.Object; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.Building.Doors; using Il2CppScheduleOne.Core.Items.Framework; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Dialogue; using Il2CppScheduleOne.Doors; using Il2CppScheduleOne.Economy; using Il2CppScheduleOne.Effects; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.EntityFramework; using Il2CppScheduleOne.Equipping; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.Growing; using Il2CppScheduleOne.Interaction; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Law; using Il2CppScheduleOne.Levelling; using Il2CppScheduleOne.Management; using Il2CppScheduleOne.Map; using Il2CppScheduleOne.Messaging; using Il2CppScheduleOne.Misc; using Il2CppScheduleOne.Money; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Behaviour; using Il2CppScheduleOne.NPCs.CharacterClasses; using Il2CppScheduleOne.ObjectScripts; using Il2CppScheduleOne.Packaging; using Il2CppScheduleOne.Persistence; using Il2CppScheduleOne.Persistence.Datas; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Police; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Product.Packaging; using Il2CppScheduleOne.Property; using Il2CppScheduleOne.Quests; using Il2CppScheduleOne.StationFramework; using Il2CppScheduleOne.Storage; using Il2CppScheduleOne.Tiles; using Il2CppScheduleOne.Trash; using Il2CppScheduleOne.UI; using Il2CppScheduleOne.UI.ATM; using Il2CppScheduleOne.UI.Handover; using Il2CppScheduleOne.UI.Items; using Il2CppScheduleOne.UI.Phone; using Il2CppScheduleOne.UI.Phone.ContactsApp; using Il2CppScheduleOne.UI.Phone.Delivery; using Il2CppScheduleOne.UI.Phone.Messages; using Il2CppScheduleOne.UI.Phone.ProductManagerApp; using Il2CppScheduleOne.UI.Shop; using Il2CppScheduleOne.UI.Stations; using Il2CppScheduleOne.UI.Stations.Drying_rack; using Il2CppScheduleOne.Variables; using Il2CppScheduleOne.Vehicles; using Il2CppScheduleOne.Vehicles.Modification; using Il2CppScheduleOne.Vision; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using Il2CppTMPro; using Lithium; using Lithium.Helper; using Lithium.Modules; using Lithium.Modules.Banking; using Lithium.Modules.BrickPress; using Lithium.Modules.ChemistryStation; using Lithium.Modules.Customers; using Lithium.Modules.Customers.Architecture; using Lithium.Modules.Customers.Behaviours; using Lithium.Modules.Customers.BonusPayments; using Lithium.Modules.Customers.Patches; using Lithium.Modules.Dealers; using Lithium.Modules.Dealers.Architecture; using Lithium.Modules.DryingRacks; using Lithium.Modules.EffectCombos; using Lithium.Modules.EffectCombos.BonusPayments; using Lithium.Modules.ElectricBill; using Lithium.Modules.Employees; using Lithium.Modules.Employees.ProductionOrders; using Lithium.Modules.EndOfDayFreeze; using Lithium.Modules.LabOven; using Lithium.Modules.MixingStations; using Lithium.Modules.PhoneApp; using Lithium.Modules.PlantGrowth; using Lithium.Modules.PlantGrowth.Behaviours; using Lithium.Modules.Police; using Lithium.Modules.Police.Contraband; using Lithium.Modules.Police.PoliceEntry; using Lithium.Modules.Police.PropertyContraband; using Lithium.Modules.Products; using Lithium.Modules.PropertyPrices; using Lithium.Modules.Rent; using Lithium.Modules.Repairs; using Lithium.Modules.Shops; using Lithium.Modules.StackSizes; using Lithium.Modules.Storyline; using Lithium.Modules.TrashGrabber; using Lithium.Modules.Vehicles; using Lithium.Modules.Warehouse; using Lithium.Modules.WateringCans; using Lithium.Modules.Weapons; using Lithium.Util; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using UnityEngine; using UnityEngine.AI; 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), "Lithium", "1.4.0", "DerTomDer & YukiSora", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: MelonOptionalDependencies(new string[] { "ModManager&PhoneApp" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Lithium")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e2be586eaee486cf2bafe4d9e662842f5c3fc404")] [assembly: AssemblyProduct("Lithium")] [assembly: AssemblyTitle("Lithium")] [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] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Lithium { public class Core : MelonMod { public static readonly List Modules = new List(27) { new ModPropertyPrices(), new ModPlants(), new ModDryingRacks(), new ModCustomers(), new ModStackSizes(), new ModLabOven(), new ModTrashGrabber(), new ModMixingStations(), new ModStoryline(), new ModShops(), new ModEmployees(), new ModChemistryStation(), new ModWateringCan(), new ModEffectCombos(), new ModVehicles(), new ModEndOfDayFreeze(), new ModProducts(), new ModBanking(), new ModElectricBill(), new ModRent(), new ModBrickPress(), new ModDealers(), new ModRepairs(), new ModWeapons(), new ModWarehouse(), new ModPolice(), new ModPhoneApp() }; private bool _isFirstStart = true; public static Instance Logger { get; set; } public static bool IsInMainScene { get; private set; } public static T Get() where T : ModuleBase { return Modules.OfType().FirstOrDefault(); } public override void OnInitializeMelon() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown Logger = ((MelonBase)this).LoggerInstance; LithiumConfig.Load(); foreach (ModuleBase module in Modules) { Log.Info("Loading " + module.GetType().Name); module.Load(); } Harmony val = new Harmony("com.lithium"); val.PatchAll(); LithiumModMenu.Initialize(); Log.Info("Lithium initialized"); } public override void OnSceneWasInitialized(int buildIndex, string sceneName) { if (sceneName == "Main") { foreach (ModuleBase module in Modules) { Log.Info("Loading " + module.GetType().Name); module.Apply(); } _isFirstStart = false; IsInMainScene = true; } else if (sceneName.Equals("Menu", StringComparison.OrdinalIgnoreCase) && !_isFirstStart) { _isFirstStart = true; IsInMainScene = false; } } public override void OnPreferencesSaved() { LithiumModMenu.OnPreferencesSaved(); } public static void ReloadConfiguration() { Log.Warning("[Lithium] Reloading all configuration..."); LithiumConfig.Load(); foreach (ModuleBase module in Modules) { try { module.Load(); } catch (Exception value) { Log.Error($"[Lithium] {module.GetType().Name}.Load() failed during reload: {value}"); } } if (IsInMainScene) { foreach (ModuleBase module2 in Modules) { try { module2.Apply(); } catch (Exception value2) { Log.Error($"[Lithium] {module2.GetType().Name}.Apply() failed during reload: {value2}"); } } } Log.Warning(IsInMainScene ? "[Lithium] Configuration reloaded and reapplied." : "[Lithium] Configuration reloaded (no save loaded — runtime reapply skipped)."); } public override void OnUpdate() { ((MelonBase)this).OnUpdate(); Get()?.DriveUpdate(); Get()?.DriveUpdate(); Get()?.DriveUpdate(); Get()?.DriveUpdate(); Get()?.DriveUpdate(); Get()?.DriveUpdate(); } } public class LithiumConfig { public bool Debug = false; public static LithiumConfig Instance { get; private set; } = new LithiumConfig(); private static string ConfigFolder => Path.Combine(MelonEnvironment.UserDataDirectory, "Lithium"); private static string FilePath => Path.Combine(ConfigFolder, "Lithium.json"); public static void Load() { try { if (File.Exists(FilePath)) { JsonConvert.PopulateObject(File.ReadAllText(FilePath), (object)Instance); } Save(); } catch (Exception ex) { MelonLogger.Warning("[Lithium] Failed to load Lithium.json: " + ex.Message); } } public static void Save() { try { Directory.CreateDirectory(ConfigFolder); File.WriteAllText(FilePath, JsonConvert.SerializeObject((object)Instance, (Formatting)1)); } catch (Exception ex) { MelonLogger.Warning("[Lithium] Failed to save Lithium.json: " + ex.Message); } } } public static class LithiumModMenu { private sealed class Tool { public readonly string Name; public readonly bool RequiresSave; public readonly Action Run; public Tool(string name, bool requiresSave, Action run) { Name = name; RequiresSave = requiresSave; Run = run; } } private const string GeneralId = "Lithium_General"; private static MelonPreferences_Category _generalCategory; private static MelonPreferences_Entry _debugEntry; private static readonly List Tools = new List(); private static readonly List RootedHandlers = new List(); public static void Initialize() { try { _generalCategory = MelonPreferences.CreateCategory("Lithium_General", "Lithium - General"); _debugEntry = _generalCategory.CreateEntry("Debug", LithiumConfig.Instance.Debug, "Debug logging", "Verbose Log.Info output to the MelonLoader console.", false, false, (ValueValidator)null, (string)null); _debugEntry.Value = LithiumConfig.Instance.Debug; _generalCategory.SaveToFile(false); BuildToolTable(); TryHookModManager(); Log.Info("[Lithium] Mod Manager menu initialized."); } catch (Exception value) { Log.Error($"[Lithium] Mod Manager menu init failed: {value}"); } } private static void BuildToolTable() { Tools.Clear(); Tools.Add(new Tool("Reload & reapply all configs", requiresSave: false, Core.ReloadConfiguration)); Tools.Add(new Tool("Dump rent / dead-drop info", requiresSave: true, RentDebug.Dump)); Tools.Add(new Tool("Dump buildables / appliances", requiresSave: true, BuildablesDebug.Dump)); Tools.Add(new Tool("Dump RV furniture", requiresSave: true, RVFurnitureDebug.Dump)); Tools.Add(new Tool("Dump customer order patterns", requiresSave: true, OrderPatternDebug.Dump)); Tools.Add(new Tool("Dump NPC roster", requiresSave: true, NpcRosterDebug.Dump)); Tools.Add(new Tool("Dump police contraband scan", requiresSave: true, PoliceContrabandDebug.Dump)); Tools.Add(new Tool("Expand Veeper storage", requiresSave: true, ExpandVeeperStorage)); Tools.Add(new Tool("Toggle rent lockout (test)", requiresSave: true, delegate { Core.Get()?.DebugToggleLockout(); })); } public static void OnPreferencesSaved() { if (_debugEntry != null && _debugEntry.Value != LithiumConfig.Instance.Debug) { LithiumConfig.Instance.Debug = _debugEntry.Value; LithiumConfig.Save(); Log.Warning("[Lithium] Debug logging " + (_debugEntry.Value ? "enabled" : "disabled") + " via Mod Manager."); } } private static void TryHookModManager() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("ModManagerPhoneApp.ModSettingsAppCreator"); if (type == null) { Log.Info("[Lithium] ModManager app not installed — tool buttons unavailable."); return; } MethodInfo methodInfo = AccessTools.Method(type, "PopulateModSettings", (Type[])null, (Type[])null); if (methodInfo == null) { Log.Warning("[Lithium] ModManager.PopulateModSettings not found — tool buttons unavailable."); return; } MethodInfo method = typeof(LithiumModMenu).GetMethod("InjectToolButtons", BindingFlags.Static | BindingFlags.NonPublic); new Harmony("com.lithium.modmenu").Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.Info("[Lithium] ModManager tool-button hook applied."); } catch (Exception ex) { Log.Warning("[Lithium] Could not hook the ModManager UI: " + ex.Message); } } private static void InjectToolButtons(object __instance, MelonBase __0) { //IL_017e: Unknown result type (might be due to invalid IL or missing references) try { object obj; if (__0 == null) { obj = null; } else { MelonInfoAttribute info = __0.Info; obj = ((info != null) ? info.Name : null); } if ((string?)obj != "Lithium") { return; } GameObject value = Traverse.Create(__instance).Field("modManagerAppInstance").GetValue(); if ((Object)(object)value == (Object)null) { return; } Transform val = value.transform.Find("RightPanel/ConfigPanel/Viewport/Content"); Transform val2 = value.transform.Find("RightPanel/SaveButton"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return; } RootedHandlers.Clear(); GameObject value2 = Traverse.Create(__instance).Field("categoryTemplate").GetValue(); if ((Object)(object)value2 != (Object)null) { GameObject val3 = Object.Instantiate(value2, val); ((Object)val3).name = "Lithium_ToolsHeader"; Transform val4 = val3.transform.Find("Title"); if ((Object)(object)val4 != (Object)null) { TMP_Text component = ((Component)val4).GetComponent(); if ((Object)(object)component != (Object)null) { component.SetText("Debug Tools (press to run)"); } } val3.SetActive(true); } foreach (Tool tool in Tools) { GameObject val5 = Object.Instantiate(((Component)val2).gameObject, val); ((Object)val5).name = "Lithium_Tool_" + tool.Name; val5.transform.localScale = Vector3.one; Button component2 = val5.GetComponent