Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of NoMoreTrash v1.0.0
NoMoreTrash-IL2CPP.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Il2CppFishNet; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.PlayerScripts; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using NoMoreTrash; using NoMoreTrash.Helpers; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(global::NoMoreTrash.NoMoreTrash), "NoMoreTrash", "1.0.0", "me", null)] [assembly: MelonColor(1, 255, 0, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("NoMoreTrash-IL2CPP")] [assembly: AssemblyConfiguration("Debug IL2CPP")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("NoMoreTrash-IL2CPP")] [assembly: AssemblyTitle("NoMoreTrash-IL2CPP")] [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.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] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 NoMoreTrash { public static class BuildInfo { public const string Name = "NoMoreTrash"; public const string Description = "Automatically clears trash to keep your game clean"; public const string Author = "me"; public const string Version = "1.0.0"; } public class NoMoreTrash : MelonMod { [CompilerGenerated] private sealed class <InitializeSaveDetection>d__14 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public NoMoreTrash <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitializeSaveDetection>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; ModLogger.Debug("Waiting for player before initializing save detection", "InitializeSaveDetection", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 169); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if (!SaveEventEnabledEntry.Value) { ModLogger.Msg("Automatic trash cleanup disabled - manual cleanup only"); return false; } if (<>4__this.SubscribeToSleepEndEvent()) { ModLogger.Msg("Automatic trash cleanup enabled - clearing after sleep"); return false; } ModLogger.Msg("Automatic trash cleanup enabled - cleaning every 24 minutes"); ModLogger.Debug("Using coroutine-based save detection (fallback approach)", "InitializeSaveDetection", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 187); <>4__this._saveCoroutineRunning = true; MelonCoroutines.Start(<>4__this.SaveCoroutine()); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SaveCoroutine>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public NoMoreTrash <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SaveCoroutine>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; if (<>4__this._saveCoroutineRunning && SaveEventEnabledEntry.Value) { ModLogger.Debug("Save interval reached, executing command", "SaveCoroutine", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 207); <>4__this.ExecuteClearTrashCommand(); } break; } if (<>4__this._saveCoroutineRunning && SaveEventEnabledEntry.Value) { <>2__current = (object)new WaitForSeconds(1440f); <>1__state = 1; return true; } <>4__this._saveCoroutineRunning = false; ModLogger.Debug("Save coroutine stopped", "SaveCoroutine", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 213); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static NoMoreTrash Instance; private static MelonPreferences_Category ConfigCategory; private static MelonPreferences_Entry<KeyCode> HotkeyEntry; private static MelonPreferences_Entry<bool> SaveEventEnabledEntry; private static MelonPreferences_Entry<bool> HotkeyEnabledEntry; private static MelonPreferences_Entry<string> CommandEntry; private bool _saveCoroutineRunning = false; private bool _sleepEndEventSubscribed = false; public override void OnInitializeMelon() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) Instance = this; ModLogger.Initialize(((MelonBase)this).LoggerInstance); ModLogger.Msg("NoMoreTrash - Automatic trash cleanup initialized!"); InitializePreferences(); ModLogger.Msg($"Ready to keep things clean! Press [{HotkeyEntry.Value}] to manually clear trash."); } private void InitializePreferences() { ConfigCategory = MelonPreferences.CreateCategory("NoMoreTrash"); HotkeyEntry = ConfigCategory.CreateEntry<KeyCode>("Hotkey", (KeyCode)112, "Trash cleanup hotkey", "Press this key to manually clear all trash", false, false, (ValueValidator)null, (string)null); HotkeyEnabledEntry = ConfigCategory.CreateEntry<bool>("HotkeyEnabled", true, "Enable hotkey trash clearing", "Allow manual trash cleanup using the hotkey", false, false, (ValueValidator)null, (string)null); SaveEventEnabledEntry = ConfigCategory.CreateEntry<bool>("SaveEventEnabled", true, "Auto-clear trash on save", "Automatically clear trash whenever the game saves", false, false, (ValueValidator)null, (string)null); CommandEntry = ConfigCategory.CreateEntry<string>("Command", "cleartrash", "Cleanup command", "The console command used to clear trash", false, false, (ValueValidator)null, (string)null); MelonPreferences.Save(); } private void ExecuteClearTrashCommand() { try { string value = CommandEntry.Value; if (string.IsNullOrEmpty(value)) { ModLogger.Warning("Cleanup command not configured - trash remains"); return; } ModLogger.Debug("Executing console command: " + value, "ExecuteClearTrashCommand", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 110); Console.SubmitCommand(value); ModLogger.Msg("✓ Trash cleared successfully!"); } catch (Exception ex) { ModLogger.Error("Failed to clear trash: " + ex.Message); ModLogger.Debug("Stack trace: " + ex.StackTrace, "ExecuteClearTrashCommand", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 123); } } public override void OnUpdate() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (HotkeyEnabledEntry.Value && Input.GetKeyDown(HotkeyEntry.Value)) { ModLogger.Debug($"Hotkey {HotkeyEntry.Value} pressed", "OnUpdate", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 132); ExecuteClearTrashCommand(); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { ModLogger.Debug("Scene loaded: " + sceneName, "OnSceneWasLoaded", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 139); if (sceneName == "Main") { ModLogger.Debug("Main scene loaded, initializing save detection", "OnSceneWasLoaded", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 142); MelonCoroutines.Start(Utils.WaitForPlayer(InitializeSaveDetection())); } } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { if (_saveCoroutineRunning) { ModLogger.Debug("Scene unloaded: " + sceneName + ", stopping save coroutine", "OnSceneWasUnloaded", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 152); _saveCoroutineRunning = false; } if (_sleepEndEventSubscribed) { UnsubscribeFromSleepEndEvent(); } } [IteratorStateMachine(typeof(<InitializeSaveDetection>d__14))] private IEnumerator InitializeSaveDetection() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeSaveDetection>d__14(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<SaveCoroutine>d__15))] private IEnumerator SaveCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SaveCoroutine>d__15(0) { <>4__this = this }; } private void OnSaveEvent() { if (!SaveEventEnabledEntry.Value) { ModLogger.Debug("Save event detected but execution is disabled in preferences", "OnSaveEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 223); return; } ModLogger.Debug("Save event detected, executing command", "OnSaveEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 227); ExecuteClearTrashCommand(); } private bool SubscribeToSleepEndEvent() { try { TimeManager instance = NetworkSingleton<TimeManager>.Instance; instance.onSleepEnd += Action.op_Implicit((Action)OnSleepEndHandler); _sleepEndEventSubscribed = true; ModLogger.Debug("Subscribed to TimeManager.Instance.onSleepEnd", "SubscribeToSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 242); return true; } catch (Exception ex) { ModLogger.Debug("Failed to subscribe to onSleepEnd: " + ex.Message, "SubscribeToSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 247); return false; } } private void UnsubscribeFromSleepEndEvent() { try { TimeManager instance = NetworkSingleton<TimeManager>.Instance; instance.onSleepEnd -= Action.op_Implicit((Action)OnSleepEndHandler); _sleepEndEventSubscribed = false; ModLogger.Debug("Unsubscribed from TimeManager.Instance.onSleepEnd", "UnsubscribeFromSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 263); } catch (Exception ex) { ModLogger.Debug("Failed to unsubscribe from onSleepEnd: " + ex.Message, "UnsubscribeFromSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 267); } } private void OnSleepEndHandler() { ModLogger.Debug("Sleep end detected, triggering trash cleanup", "OnSleepEndHandler", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 274); OnSaveEvent(); } } } namespace NoMoreTrash.Helpers { public static class ModLogger { private static Instance _logger; public static bool IsInitialized => _logger != null; public static void Initialize(string modName) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown _logger = new Instance(modName); } public static void Initialize(Instance loggerInstance) { _logger = loggerInstance; } public static void Msg(string message) { Instance logger = _logger; if (logger != null) { logger.Msg(message); } } public static void Debug(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { } public static void Warning(string message) { Instance logger = _logger; if (logger != null) { logger.Warning(message); } } public static void Error(string message) { Instance logger = _logger; if (logger != null) { logger.Error(message); } } public static void Msg(ConsoleColor color, string message) { Instance logger = _logger; if (logger != null) { logger.Msg(color, message); } } } public static class Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } public static List<T> ToIl2CppList<T>(this IEnumerable<T> source) { List<T> val = new List<T>(); foreach (T item in source) { val.Add(item); } return val; } public static List<T> ConvertToList<T>(List<T> il2CppList) { List<T> list = new List<T>(); T[] collection = Il2CppArrayBase<T>.op_Implicit(il2CppList.ToArray()); list.AddRange(collection); return list; } public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { IEnumerable<T> result; if (list != null) { result = ((IEnumerable<T>)list._items).Take(list._size); } else { IEnumerable<T> enumerable = Array.Empty<T>(); result = enumerable; } return result; } } public static class Utils { [CompilerGenerated] private sealed class <WaitForNetwork>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetwork>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (!InstanceFinder.IsServer && !InstanceFinder.IsClient) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForNetworkSingleton>d__8<T> : IEnumerator<object>, IEnumerator, IDisposable where T : notnull, NetworkSingleton<T> { private int <>1__state; private object <>2__current; public IEnumerator coroutine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetworkSingleton>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0044; case 1: <>1__state = -1; goto IL_0044; case 2: { <>1__state = -1; return false; } IL_0044: if (!NetworkSingleton<T>.InstanceExists) { <>2__current = null; <>1__state = 1; return true; } <>2__current = coroutine; <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForNotNull>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object obj; public float timeout; public Action onTimeout; public Action onFinish; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNotNull>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (obj == null) { if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForPlayer>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayer>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Instance Logger = new Instance("NoMoreTrash-Utils"); public static T FindObjectByName<T>(string objectName) where T : Object { try { foreach (T item in Resources.FindObjectsOfTypeAll<T>()) { if (((Object)item).name != objectName) { continue; } ModLogger.Debug($"Found {typeof(T).Name} '{objectName}' directly in loaded objects", "FindObjectByName", "D:\\Schedule 1 Modding\\NoMoreTrash\\Helpers\\Utils.cs", 115); return item; } return default(T); } catch (Exception ex) { Logger.Error($"Error finding {typeof(T).Name} '{objectName}': {ex.Message}"); return default(T); } } public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component { List<T> list = new List<T>(); if ((Object)(object)obj == (Object)null) { return list; } T[] array = Il2CppArrayBase<T>.op_Implicit(obj.GetComponents<T>()); if (array.Length != 0) { list.AddRange(array); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject)); } return list; } public static bool Is<T>(object obj, out T result) where T : Object { Object val = (Object)((obj is Object) ? obj : null); if (val != null) { Type val2 = Il2CppType.Of<T>(); Type il2CppType = val.GetIl2CppType(); if (val2.IsAssignableFrom(il2CppType)) { result = ((Il2CppObjectBase)val).TryCast<T>(); return result != null; } } result = default(T); return false; } public static List<StorableItemDefinition> GetAllStorableItemDefinitions() { List<ItemRegister> list = Il2CppListExtensions.ConvertToList<ItemRegister>(Singleton<Registry>.Instance.ItemRegistry); List<StorableItemDefinition> list2 = new List<StorableItemDefinition>(); foreach (ItemRegister item in list) { if (Utils.Is<StorableItemDefinition>((object)item.Definition, out StorableItemDefinition result)) { list2.Add(result); } else { Logger.Warning("Definition " + ((object)item.Definition)?.GetType().FullName + " is not a StorableItemDefinition"); } } return list2.ToList(); } [IteratorStateMachine(typeof(<WaitForPlayer>d__5))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayer>d__5(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForNetwork>d__6))] public static IEnumerator WaitForNetwork(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetwork>d__6(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForNotNull>d__7))] public static IEnumerator WaitForNotNull(object? obj, float timeout = float.NaN, Action onTimeout = null, Action onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNotNull>d__7(0) { obj = obj, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } [IteratorStateMachine(typeof(<WaitForNetworkSingleton>d__8<>))] public static IEnumerator WaitForNetworkSingleton<T>(IEnumerator coroutine) where T : NetworkSingleton<T> { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetworkSingleton>d__8<T>(0) { coroutine = coroutine }; } } }
NoMoreTrash-Mono.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FishNet; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using NoMoreTrash; using NoMoreTrash.Helpers; using ScheduleOne; using ScheduleOne.DevUtilities; using ScheduleOne.GameTime; using ScheduleOne.PlayerScripts; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(global::NoMoreTrash.NoMoreTrash), "NoMoreTrash", "1.0.0", "SirTidez", null)] [assembly: MelonColor(1, 255, 0, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NoMoreTrash-Mono")] [assembly: AssemblyConfiguration("Debug Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("NoMoreTrash-Mono")] [assembly: AssemblyTitle("NoMoreTrash-Mono")] [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.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] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 NoMoreTrash { public static class BuildInfo { public const string Name = "NoMoreTrash"; public const string Description = "Automatically clears trash to keep your game clean"; public const string Author = "SirTidez"; public const string Version = "1.0.0"; } public class NoMoreTrash : MelonMod { [CompilerGenerated] private sealed class <InitializeSaveDetection>d__14 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public NoMoreTrash <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <InitializeSaveDetection>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; ModLogger.Debug("Waiting for player before initializing save detection", "InitializeSaveDetection", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 169); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if (!SaveEventEnabledEntry.Value) { ModLogger.Msg("Automatic trash cleanup disabled - manual cleanup only"); return false; } if (<>4__this.SubscribeToSleepEndEvent()) { ModLogger.Msg("Automatic trash cleanup enabled - clearing after sleep"); return false; } ModLogger.Msg("Automatic trash cleanup enabled - cleaning every 24 minutes"); ModLogger.Debug("Using coroutine-based save detection (fallback approach)", "InitializeSaveDetection", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 187); <>4__this._saveCoroutineRunning = true; MelonCoroutines.Start(<>4__this.SaveCoroutine()); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SaveCoroutine>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public NoMoreTrash <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SaveCoroutine>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; if (<>4__this._saveCoroutineRunning && SaveEventEnabledEntry.Value) { ModLogger.Debug("Save interval reached, executing command", "SaveCoroutine", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 207); <>4__this.ExecuteClearTrashCommand(); } break; } if (<>4__this._saveCoroutineRunning && SaveEventEnabledEntry.Value) { <>2__current = (object)new WaitForSeconds(1440f); <>1__state = 1; return true; } <>4__this._saveCoroutineRunning = false; ModLogger.Debug("Save coroutine stopped", "SaveCoroutine", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 213); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static NoMoreTrash Instance; private static MelonPreferences_Category ConfigCategory; private static MelonPreferences_Entry<KeyCode> HotkeyEntry; private static MelonPreferences_Entry<bool> SaveEventEnabledEntry; private static MelonPreferences_Entry<bool> HotkeyEnabledEntry; private static MelonPreferences_Entry<string> CommandEntry; private bool _saveCoroutineRunning = false; private bool _sleepEndEventSubscribed = false; public override void OnInitializeMelon() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) Instance = this; ModLogger.Initialize(((MelonBase)this).LoggerInstance); ModLogger.Msg("NoMoreTrash - Automatic trash cleanup initialized!"); InitializePreferences(); ModLogger.Msg($"Ready to keep things clean! Press [{HotkeyEntry.Value}] to manually clear trash."); } private void InitializePreferences() { ConfigCategory = MelonPreferences.CreateCategory("NoMoreTrash"); HotkeyEntry = ConfigCategory.CreateEntry<KeyCode>("Hotkey", (KeyCode)112, "Trash cleanup hotkey", "Press this key to manually clear all trash", false, false, (ValueValidator)null, (string)null); HotkeyEnabledEntry = ConfigCategory.CreateEntry<bool>("HotkeyEnabled", true, "Enable hotkey trash clearing", "Allow manual trash cleanup using the hotkey", false, false, (ValueValidator)null, (string)null); SaveEventEnabledEntry = ConfigCategory.CreateEntry<bool>("SaveEventEnabled", true, "Auto-clear trash on save", "Automatically clear trash whenever the game saves", false, false, (ValueValidator)null, (string)null); CommandEntry = ConfigCategory.CreateEntry<string>("Command", "cleartrash", "Cleanup command", "The console command used to clear trash", false, false, (ValueValidator)null, (string)null); MelonPreferences.Save(); } private void ExecuteClearTrashCommand() { try { string value = CommandEntry.Value; if (string.IsNullOrEmpty(value)) { ModLogger.Warning("Cleanup command not configured - trash remains"); return; } ModLogger.Debug("Executing console command: " + value, "ExecuteClearTrashCommand", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 110); Console.SubmitCommand(value); ModLogger.Msg("✓ Trash cleared successfully!"); } catch (Exception ex) { ModLogger.Error("Failed to clear trash: " + ex.Message); ModLogger.Debug("Stack trace: " + ex.StackTrace, "ExecuteClearTrashCommand", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 123); } } public override void OnUpdate() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (HotkeyEnabledEntry.Value && Input.GetKeyDown(HotkeyEntry.Value)) { ModLogger.Debug($"Hotkey {HotkeyEntry.Value} pressed", "OnUpdate", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 132); ExecuteClearTrashCommand(); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { ModLogger.Debug("Scene loaded: " + sceneName, "OnSceneWasLoaded", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 139); if (sceneName == "Main") { ModLogger.Debug("Main scene loaded, initializing save detection", "OnSceneWasLoaded", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 142); MelonCoroutines.Start(Utils.WaitForPlayer(InitializeSaveDetection())); } } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { if (_saveCoroutineRunning) { ModLogger.Debug("Scene unloaded: " + sceneName + ", stopping save coroutine", "OnSceneWasUnloaded", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 152); _saveCoroutineRunning = false; } if (_sleepEndEventSubscribed) { UnsubscribeFromSleepEndEvent(); } } [IteratorStateMachine(typeof(<InitializeSaveDetection>d__14))] private IEnumerator InitializeSaveDetection() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <InitializeSaveDetection>d__14(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<SaveCoroutine>d__15))] private IEnumerator SaveCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SaveCoroutine>d__15(0) { <>4__this = this }; } private void OnSaveEvent() { if (!SaveEventEnabledEntry.Value) { ModLogger.Debug("Save event detected but execution is disabled in preferences", "OnSaveEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 223); return; } ModLogger.Debug("Save event detected, executing command", "OnSaveEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 227); ExecuteClearTrashCommand(); } private bool SubscribeToSleepEndEvent() { try { TimeManager instance = NetworkSingleton<TimeManager>.Instance; instance.onSleepEnd = (Action)Delegate.Combine(instance.onSleepEnd, new Action(OnSleepEndHandler)); _sleepEndEventSubscribed = true; ModLogger.Debug("Subscribed to TimeManager.Instance.onSleepEnd", "SubscribeToSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 242); return true; } catch (Exception ex) { ModLogger.Debug("Failed to subscribe to onSleepEnd: " + ex.Message, "SubscribeToSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 247); return false; } } private void UnsubscribeFromSleepEndEvent() { try { TimeManager instance = NetworkSingleton<TimeManager>.Instance; instance.onSleepEnd = (Action)Delegate.Remove(instance.onSleepEnd, new Action(OnSleepEndHandler)); _sleepEndEventSubscribed = false; ModLogger.Debug("Unsubscribed from TimeManager.Instance.onSleepEnd", "UnsubscribeFromSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 263); } catch (Exception ex) { ModLogger.Debug("Failed to unsubscribe from onSleepEnd: " + ex.Message, "UnsubscribeFromSleepEndEvent", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 267); } } private void OnSleepEndHandler() { ModLogger.Debug("Sleep end detected, triggering trash cleanup", "OnSleepEndHandler", "D:\\Schedule 1 Modding\\NoMoreTrash\\MainMod.cs", 274); OnSaveEvent(); } } } namespace NoMoreTrash.Helpers { public static class ModLogger { private static Instance _logger; public static bool IsInitialized => _logger != null; public static void Initialize(string modName) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown _logger = new Instance(modName); } public static void Initialize(Instance loggerInstance) { _logger = loggerInstance; } public static void Msg(string message) { Instance logger = _logger; if (logger != null) { logger.Msg(message); } } public static void Debug(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { } public static void Warning(string message) { Instance logger = _logger; if (logger != null) { logger.Warning(message); } } public static void Error(string message) { Instance logger = _logger; if (logger != null) { logger.Error(message); } } public static void Msg(ConsoleColor color, string message) { Instance logger = _logger; if (logger != null) { logger.Msg(color, message); } } } public static class Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } } public static class Utils { [CompilerGenerated] private sealed class <WaitForNetwork>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetwork>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (!InstanceFinder.IsServer && !InstanceFinder.IsClient) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForNetworkSingleton>d__7<T> : IEnumerator<object>, IEnumerator, IDisposable where T : notnull, NetworkSingleton<T> { private int <>1__state; private object <>2__current; public IEnumerator coroutine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetworkSingleton>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0044; case 1: <>1__state = -1; goto IL_0044; case 2: { <>1__state = -1; return false; } IL_0044: if (!NetworkSingleton<T>.InstanceExists) { <>2__current = null; <>1__state = 1; return true; } <>2__current = coroutine; <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForNotNull>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object obj; public float timeout; public Action onTimeout; public Action onFinish; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNotNull>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (obj == null) { if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForPlayer>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayer>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Instance Logger = new Instance("NoMoreTrash-Utils"); public static T FindObjectByName<T>(string objectName) where T : Object { try { T[] array = Resources.FindObjectsOfTypeAll<T>(); foreach (T val in array) { if (!(((Object)val).name != objectName)) { ModLogger.Debug("Found " + typeof(T).Name + " '" + objectName + "' directly in loaded objects", "FindObjectByName", "D:\\Schedule 1 Modding\\NoMoreTrash\\Helpers\\Utils.cs", 115); return val; } } return default(T); } catch (Exception ex) { Logger.Error("Error finding " + typeof(T).Name + " '" + objectName + "': " + ex.Message); return default(T); } } public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component { List<T> list = new List<T>(); if ((Object)(object)obj == (Object)null) { return list; } T[] components = obj.GetComponents<T>(); if (components.Length != 0) { list.AddRange(components); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject)); } return list; } public static bool Is<T>(object obj, out T result) where T : class { if (obj is T val) { result = val; return true; } result = null; return false; } [IteratorStateMachine(typeof(<WaitForPlayer>d__4))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayer>d__4(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForNetwork>d__5))] public static IEnumerator WaitForNetwork(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetwork>d__5(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForNotNull>d__6))] public static IEnumerator WaitForNotNull(object? obj, float timeout = float.NaN, Action onTimeout = null, Action onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNotNull>d__6(0) { obj = obj, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } [IteratorStateMachine(typeof(<WaitForNetworkSingleton>d__7<>))] public static IEnumerator WaitForNetworkSingleton<T>(IEnumerator coroutine) where T : NetworkSingleton<T> { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetworkSingleton>d__7<T>(0) { coroutine = coroutine }; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }