Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of TimeNeverStops IL2Cpp v1.4.0
TimeNeverStops_IL2Cpp.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; 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.InteropTypes.Arrays; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.UI; using Il2CppSystem; using Il2CppSystem.IO; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Time_Never_Stops; 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(Core), "Time Never Stops", "1.4.0", "DropDaDeuce", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("TimeNeverStops_IL2Cpp")] [assembly: AssemblyConfiguration("IL2CPP")] [assembly: AssemblyFileVersion("1.4.0.0")] [assembly: AssemblyInformationalVersion("1.4.0+8c929b51717e3ec8e52ac762fc8a2a1ff6130e2c")] [assembly: AssemblyProduct("TimeNeverStops_IL2Cpp")] [assembly: AssemblyTitle("TimeNeverStops_IL2Cpp")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.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 Time_Never_Stops { internal static class TNSLog { private static bool DebugEnabled => Core.cfgDebugLogging?.Value ?? false; public static void Msg(string message) { MelonLogger.Msg(message); } public static void Msg(string format, params object[] args) { MelonLogger.Msg(string.Format(format, args)); } public static void Debug(string message) { if (DebugEnabled) { MelonLogger.Msg("[Debug] " + message); } } public static void Debug(string format, params object[] args) { if (DebugEnabled) { MelonLogger.Msg("[Debug] " + string.Format(format, args)); } } public static void Warning(string message) { MelonLogger.Warning(message); } public static void Warning(string format, params object[] args) { MelonLogger.Warning(string.Format(format, args)); } public static void Error(string message) { MelonLogger.Error(message); } public static void Error(string format, params object[] args) { MelonLogger.Error(string.Format(format, args)); } } public class Core : MelonMod { [CompilerGenerated] private sealed class <SetDaySpeedLoop>d__22 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private WaitForSecondsRealtime <tick>5__1; private TimeManager <tm>5__2; private float <last>5__3; private float <desired>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SetDaySpeedLoop>d__22(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <tick>5__1 = null; <tm>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown bool flag; switch (<>1__state) { default: return false; case 0: <>1__state = -1; <tick>5__1 = new WaitForSecondsRealtime(1f); goto IL_0170; case 1: <>1__state = -1; goto IL_005d; case 2: { <>1__state = -1; goto IL_014f; } IL_0170: flag = true; goto IL_005d; IL_005d: if ((Object)(object)NetworkSingleton<TimeManager>.Instance == (Object)null) { <>2__current = null; <>1__state = 1; return true; } <tm>5__2 = NetworkSingleton<TimeManager>.Instance; <last>5__3 = <>4__this.<SetDaySpeedLoop>g__ReadPrefAndNormalize|22_0(); ApplyDaySpeed(<last>5__3); goto IL_014f; IL_014f: if ((Object)(object)NetworkSingleton<TimeManager>.Instance == (Object)(object)<tm>5__2) { if (<>4__this._cfgFileChanged) { <>4__this._cfgFileChanged = false; <>4__this.cfgCategory.LoadFromFile(false); } <desired>5__4 = <>4__this.<SetDaySpeedLoop>g__ReadPrefAndNormalize|22_0(); if (<SetDaySpeedLoop>g__Differs|22_1(<desired>5__4, <last>5__3) || <SetDaySpeedLoop>g__Differs|22_1(<desired>5__4, <tm>5__2.TimeProgressionMultiplier)) { <last>5__3 = <desired>5__4; ApplyDaySpeed(<last>5__3); } <>2__current = <tick>5__1; <>1__state = 2; return true; } <tm>5__2 = null; goto IL_0170; } } 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 <SleepStateWatcher>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Core <>4__this; private bool <last>5__1; private TimeManager <lastTm>5__2; private TimeManager <tm>5__3; private bool <cur>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SleepStateWatcher>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <lastTm>5__2 = null; <tm>5__3 = null; <>1__state = -2; } private bool MoveNext() { bool flag; switch (<>1__state) { default: return false; case 0: <>1__state = -1; <last>5__1 = false; <lastTm>5__2 = null; goto IL_013d; case 1: <>1__state = -1; break; case 2: { <>1__state = -1; <tm>5__3 = null; goto IL_013d; } IL_013d: flag = true; break; } if ((Object)(object)NetworkSingleton<TimeManager>.Instance == (Object)null) { <lastTm>5__2 = null; <last>5__1 = false; <>2__current = null; <>1__state = 1; return true; } <tm>5__3 = NetworkSingleton<TimeManager>.Instance; if ((Object)(object)<tm>5__3 != (Object)(object)<lastTm>5__2) { <lastTm>5__2 = <tm>5__3; <last>5__1 = <tm>5__3.SleepInProgress; } <cur>5__4 = <tm>5__3.SleepInProgress; if (<cur>5__4 && !<last>5__1) { <>4__this.OnSleepStart(); } else if (!<cur>5__4 & <last>5__1) { <>4__this.OnSleepEnd(); } <last>5__1 = <cur>5__4; <>2__current = null; <>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(); } } private MelonPreferences_Category cfgCategory; private MelonPreferences_Entry<string> cfgDaySpeedStr; public static MelonPreferences_Entry<bool> cfgEnableSummaryAwake; private MelonPreferences_Entry<float> cfgLegacyDaySpeed; public static MelonPreferences_Entry<bool> cfgMultiplierOnly; public static MelonPreferences_Entry<bool> cfgDebugLogging; private bool _updatingPref; private bool _lastEnableSummaryAwake; private const float DefaultSpeed = 1f; private const float MinSpeed = 0.1f; private const float MaxSpeed = 100f; private FileSystemWatcher _cfgWatcher; private volatile bool _cfgFileChanged; public override void OnInitializeMelon() { MelonPreferences_Category val = MelonPreferences.CreateCategory("TimeNeverStops"); cfgLegacyDaySpeed = val.GetEntry<float>("DaySpeedMultiplier") ?? val.CreateEntry<float>("DaySpeedMultiplier", 1f, "Day Speed Multiplier", "Sets the in-game time speed multiplier. 1.0 = normal speed, 0.5 = half speed, 2.0 = double speed.Minimum 0.1, Maximum 3.0. Default = 1.0 (Vanilla Game Speed)", false, false, (ValueValidator)null, (string)null); val.DeleteEntry("DaySpeedMultiplier"); if (cfgLegacyDaySpeed.Value != 1f) { TNSLog.Warning($"Legacy DaySpeedMultiplier found with value {cfgLegacyDaySpeed.Value}. Migrating to new config system."); } string text = Math.Clamp(cfgLegacyDaySpeed.Value, 0.1f, 100f).ToString("R", CultureInfo.InvariantCulture); string text2 = Path.Combine(MelonEnvironment.UserDataDirectory, "DropDaDeuce-TimeNeverStops"); string text3 = Path.Combine(text2, "TimeNeverStops.cfg"); Directory.CreateDirectory(text2); cfgCategory = val; val = null; cfgCategory.SetFilePath(text3, File.Exists(text3), true); cfgMultiplierOnly = cfgCategory.GetEntry<bool>("TimeMultiplierOnlyMode") ?? cfgCategory.CreateEntry<bool>("TimeMultiplierOnlyMode", false, "Multiplier Only Mode", "If true the mod ONLY changes the day speed multiplier.\nDisables:\n- 4AM freeze bypass\n- Daily summary while awake\n- Sleep prompt hiding.\nChange at runtime is applied but a restart is safest.", false, false, (ValueValidator)null, (string)null); cfgDaySpeedStr = cfgCategory.GetEntry<string>("DaySpeedMultiplier") ?? cfgCategory.CreateEntry<string>("DaySpeedMultiplier", text, "Day Speed Multiplier", "String parsed to float by the mod.\n1.0 = normal, 0.5 = half, 2.0 = double.\nMin 0.1, Max 100.0, Default 1.0.", false, false, (ValueValidator)null, (string)null); cfgEnableSummaryAwake = cfgCategory.GetEntry<bool>("EnableDailySummaryAwake") ?? cfgCategory.CreateEntry<bool>("EnableDailySummaryAwake", true, "Enable Daily Summary While Awake", "If enabled, the daily summary will be shown while awake (unless Multiplier Only Mode is ON).", false, false, (ValueValidator)null, (string)null); cfgDebugLogging = cfgCategory.GetEntry<bool>("EnableDebugLogging") ?? cfgCategory.CreateEntry<bool>("EnableDebugLogging", false, "Enable Debug Logging", "If true, prints additional debug messages from the mod to help diagnose issues.", false, false, (ValueValidator)null, (string)null); if (!cfgMultiplierOnly.Value) { _lastEnableSummaryAwake = cfgEnableSummaryAwake.Value; MelonCoroutines.Start(SleepStateWatcher()); } else { TNSLog.Msg("TimeMultiplierOnlyMode enabled: all non-multiplier features disabled."); } float num = Sanitize(ParseFloatOrDefault(cfgDaySpeedStr.Value, 1f)); if (!IsStringValidAndInRange(cfgDaySpeedStr.Value)) { cfgDaySpeedStr.Value = num.ToString(CultureInfo.InvariantCulture); } _updatingPref = true; cfgCategory.SaveToFile(true); _updatingPref = false; ((MelonEventBase<LemonAction<string, string>>)(object)cfgDaySpeedStr.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string _, string newV) { if (!_updatingPref) { float v = ParseFloatOrDefault(newV, 1f); float newSpeed = Sanitize(v); if (!IsStringValidAndInRange(newV)) { _updatingPref = true; cfgDaySpeedStr.Value = newSpeed.ToString(CultureInfo.InvariantCulture); cfgCategory.SaveToFile(false); _updatingPref = false; } ApplyDaySpeed(newSpeed); } }, 0, false); ((MelonEventBase<LemonAction<bool, bool>>)(object)cfgEnableSummaryAwake.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool _, bool newVal) { if (!_updatingPref) { _lastEnableSummaryAwake = newVal; TNSLog.Msg("EnableDailySummaryAwake: " + (newVal ? "ON" : "OFF")); _updatingPref = true; cfgCategory.SaveToFile(false); _updatingPref = false; } }, 0, false); ((MelonEventBase<LemonAction<bool, bool>>)(object)cfgDebugLogging.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool _, bool newVal) { if (!_updatingPref) { cfgDebugLogging.Value = newVal; TNSLog.Msg("DebugLogging: " + (newVal ? "Enabled" : "Disabled")); _updatingPref = true; cfgCategory.SaveToFile(false); _updatingPref = false; } }, 0, false); try { _cfgWatcher = new FileSystemWatcher(text2, Path.GetFileName(text3)) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), IncludeSubdirectories = false, EnableRaisingEvents = true }; FileSystemEventHandler value = delegate { _cfgFileChanged = true; }; RenamedEventHandler value2 = delegate { _cfgFileChanged = true; }; _cfgWatcher.Changed += value; _cfgWatcher.Created += value; _cfgWatcher.Renamed += value2; } catch (Exception ex) { TNSLog.Warning("Config watcher init failed: " + ex.Message + ". Falling back to in-process updates only."); } MelonCoroutines.Start(SetDaySpeedLoop()); } public override void OnDeinitializeMelon() { try { _cfgWatcher?.Dispose(); } catch { } _cfgWatcher = null; } [IteratorStateMachine(typeof(<SleepStateWatcher>d__15))] private IEnumerator SleepStateWatcher() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SleepStateWatcher>d__15(0) { <>4__this = this }; } private void OnSleepStart() { Patch_Tick_XPMenu.SuppressDuringSleep(on: true); TNSLog.Debug("Sleep start"); } private void OnSleepEnd() { Patch_SleepCanvas_SleepStart.StopRoutine(); Patch_Tick_XPMenu.SuppressDuringSleep(on: false); Patch_Tick_XPMenu.MarkHandledForToday(); Patch_Tick_XPMenu.EnsureHUDReset(); TNSLog.Debug("Sleep end -> PaidForToday reset path should run on employees"); } private static bool TryParseFloatInvariant(string s, out float value) { return float.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out value); } private static float ParseFloatOrDefault(string s, float fallback) { float value; return (TryParseFloatInvariant(s, out value) && float.IsFinite(value)) ? value : fallback; } private static float Sanitize(float v) { return Math.Clamp(float.IsFinite(v) ? v : 1f, 0.1f, 100f); } private static bool IsStringValidAndInRange(string s) { float value; return TryParseFloatInvariant(s, out value) && float.IsFinite(value) && value >= 0.1f && value <= 100f; } [IteratorStateMachine(typeof(<SetDaySpeedLoop>d__22))] private IEnumerator SetDaySpeedLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SetDaySpeedLoop>d__22(0) { <>4__this = this }; } private static void ApplyDaySpeed(float newSpeed) { TimeManager instance = NetworkSingleton<TimeManager>.Instance; if (!((Object)(object)instance == (Object)null)) { float num = Sanitize(newSpeed); if (Mathf.Abs(instance.TimeProgressionMultiplier - num) > 0.0001f) { instance.TimeProgressionMultiplier = num; TNSLog.Msg($"Day speed set to {num:0.########}x"); } } } [CompilerGenerated] private float <SetDaySpeedLoop>g__ReadPrefAndNormalize|22_0() { float num = ParseFloatOrDefault(cfgDaySpeedStr.Value, 1f); float result = Sanitize(float.IsFinite(num) ? num : 1f); string text = result.ToString(CultureInfo.InvariantCulture); if (cfgDaySpeedStr.Value != text) { _updatingPref = true; cfgDaySpeedStr.Value = text; cfgCategory.SaveToFile(false); _updatingPref = false; } return result; } [CompilerGenerated] internal static bool <SetDaySpeedLoop>g__Differs|22_1(float a, float b, float eps = 0.0001f) { return Mathf.Abs(a - b) > eps; } } public static class PatchLogger { public static void LogPatchLoad(string patchName) { TNSLog.Msg("[Harmony] " + patchName + " loaded."); } } [HarmonyPatch(typeof(TimeManager), "Tick")] [HarmonyPriority(600)] public static class Patch_Tick_XPMenu { private static bool firedToday; private static int lastHHmm; private static int lastHH; private static bool suppressForSleep; public static bool startupSkip; static Patch_Tick_XPMenu() { lastHH = -1; startupSkip = true; PatchLogger.LogPatchLoad("Patch_Tick_XPMenu"); startupSkip = true; } public static void SuppressDuringSleep(bool on) { suppressForSleep = on; } public static void MarkHandledForToday() { firedToday = true; lastHHmm = 700; } [HarmonyPrefix] public static bool Prefix(TimeManager __instance) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Invalid comparison between Unknown and I4 MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if (cfgMultiplierOnly != null && cfgMultiplierOnly.Value) { return true; } if (__instance.CurrentTime != 400 && (!__instance.IsCurrentTimeWithinRange(400, 600) || GameManager.IS_TUTORIAL)) { return true; } if ((Object)(object)Player.Local == (Object)null) { TNSLog.Warning("Local player does not exist. Waiting for player spawn."); return false; } TMAccess.SetTimeOnCurrentMinute(__instance, 0f); TMAccess.TryStartStaggeredMinPass(__instance, 1f / (__instance.TimeProgressionMultiplier * Time.timeScale)); if (__instance.CurrentTime == 2359) { TMAccess.SetElapsedDays(__instance, __instance.ElapsedDays + 1); TMAccess.SetCurrentTime(__instance, 0); TMAccess.SetDailyMinTotal(__instance, 0); Action onDayPass = __instance.onDayPass; if (onDayPass != null) { onDayPass.Invoke(); } Action onHourPass = __instance.onHourPass; if (onHourPass != null) { onHourPass.Invoke(); } if ((int)__instance.CurrentDay == 0) { Action onWeekPass = __instance.onWeekPass; if (onWeekPass != null) { onWeekPass.Invoke(); } } } else if (__instance.CurrentTime % 100 >= 59) { TMAccess.SetCurrentTime(__instance, __instance.CurrentTime + 41); Action onHourPass2 = __instance.onHourPass; if (onHourPass2 != null) { onHourPass2.Invoke(); } } else { TMAccess.SetCurrentTime(__instance, __instance.CurrentTime + 1); } TMAccess.SetDailyMinTotal(__instance, TimeManager.GetMinSumFrom24HourTime(__instance.CurrentTime)); __instance.HasChanged = true; if (__instance.ElapsedDays == 0 && __instance.CurrentTime == 2000 && __instance.onFirstNight != null) { __instance.onFirstNight.Invoke(); } return false; } [HarmonyPostfix] public static void Postfix(TimeManager __instance) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if (cfgMultiplierOnly != null && cfgMultiplierOnly.Value) { return; } if (lastHH != __instance.CurrentTime / 100) { TNSLog.Debug($"Current Time: {__instance.CurrentTime} Current Day: {__instance.CurrentDay} Days Elapsed: {__instance.ElapsedDays}"); } lastHH = __instance.CurrentTime / 100; if (__instance.SleepInProgress || suppressForSleep) { return; } DailySummary instance = NetworkSingleton<DailySummary>.Instance; if ((Object)(object)instance != (Object)null && instance.IsOpen) { return; } if (startupSkip) { startupSkip = false; lastHHmm = __instance.CurrentTime; firedToday = true; return; } int currentTime = __instance.CurrentTime; if (lastHHmm > currentTime) { firedToday = false; } if (!firedToday && __instance.CurrentTime > 658 && __instance.ElapsedDays > 0) { firedToday = true; TNSLog.Debug("Forcing Sleep in code."); NetworkSingleton<TimeManager>.Instance.ForceSleep(); } lastHHmm = currentTime; } public static void EnsureHUDReset() { Player.Local.CurrentBed = null; Player.Local.SetReadyToSleep(false); PlayerSingleton<PlayerCamera>.Instance.SetCanLook(true); PlayerSingleton<PlayerCamera>.Instance.StopTransformOverride(0f, true, false); PlayerSingleton<PlayerCamera>.Instance.LockMouse(); PlayerSingleton<PlayerInventory>.Instance.SetInventoryEnabled(true); Singleton<InputPromptsCanvas>.Instance.UnloadModule(); PlayerSingleton<PlayerMovement>.Instance.canMove = true; ((Component)Singleton<SleepCanvas>.Instance.MenuContainer).gameObject.SetActive(false); } } [HarmonyPatch(typeof(HUD), "Update")] [HarmonyPriority(200)] public static class Patch_HUD_HideSleepPrompt { private static void Postfix(HUD __instance) { MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if ((cfgMultiplierOnly == null || !cfgMultiplierOnly.Value) && (Object)(object)((__instance != null) ? __instance.SleepPrompt : null) != (Object)null) { ((Component)__instance.SleepPrompt).gameObject.SetActive(false); } } } [HarmonyPatch(typeof(RankUpCanvas), "StartEvent")] public static class Patch_RankUpCanvas_StartEvent { static Patch_RankUpCanvas_StartEvent() { PatchLogger.LogPatchLoad("Patch_RankUpCanvas_StartEvent"); } [HarmonyPrefix] public static bool PostFix(RankUpCanvas __instance) { MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if (cfgMultiplierOnly != null && !cfgMultiplierOnly.Value) { MelonPreferences_Entry<bool> cfgEnableSummaryAwake = Core.cfgEnableSummaryAwake; if (cfgEnableSummaryAwake != null && !cfgEnableSummaryAwake.Value) { TNSLog.Debug("Rank Up Canvas Skipping"); ((Behaviour)__instance.Canvas).enabled = false; __instance.EndEvent(); return false; } } TNSLog.Debug("Rank Up Canvas Running"); return true; } } [HarmonyPatch(typeof(RegionUnlockedCanvas), "StartEvent")] public static class Patch_RegionUnlockedCanvas_StartEvent { static Patch_RegionUnlockedCanvas_StartEvent() { PatchLogger.LogPatchLoad("Patch_RegionUnlockedCanvas_StartEvent"); } [HarmonyPrefix] public static bool PostFix(RegionUnlockedCanvas __instance) { MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if (cfgMultiplierOnly != null && !cfgMultiplierOnly.Value) { MelonPreferences_Entry<bool> cfgEnableSummaryAwake = Core.cfgEnableSummaryAwake; if (cfgEnableSummaryAwake != null && !cfgEnableSummaryAwake.Value) { TNSLog.Debug("Region Unlocked Canvas Skipping"); __instance.EndEvent(); return false; } } TNSLog.Debug("Region Unlocked Canvas Running"); return true; } } [HarmonyPatch(typeof(DailySummary))] public static class DailySummaryPatch { [HarmonyPrefix] [HarmonyPatch("Open")] public static bool OpenPrefix(DailySummary __instance) { MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if (cfgMultiplierOnly != null && !cfgMultiplierOnly.Value) { MelonPreferences_Entry<bool> cfgEnableSummaryAwake = Core.cfgEnableSummaryAwake; if (cfgEnableSummaryAwake != null && !cfgEnableSummaryAwake.Value) { TNSLog.Debug("Daily Summary Open Skipping"); return false; } } TNSLog.Debug("Daily Summary Open Running"); return true; } [HarmonyPrefix] [HarmonyPatch("Close")] public static bool ClosePrefix(DailySummary __instance) { MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if (cfgMultiplierOnly != null && !cfgMultiplierOnly.Value) { MelonPreferences_Entry<bool> cfgEnableSummaryAwake = Core.cfgEnableSummaryAwake; if (cfgEnableSummaryAwake != null && !cfgEnableSummaryAwake.Value) { TNSLog.Debug("Daily Summary Close Skipping"); return false; } } TNSLog.Debug("Daily Summary Close Running"); return true; } } [HarmonyPatch(typeof(SleepCanvas), "SleepStart")] public static class Patch_SleepCanvas_SleepStart { [CompilerGenerated] private sealed class <MakeThingsWorkRoutine>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SleepCanvas __instance; private int <i>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <MakeThingsWorkRoutine>d__3(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; <i>5__1 = 0; break; case 1: <>1__state = -1; <i>5__1++; break; } if (<i>5__1 < 3) { MakeThingsWork(__instance); <>2__current = null; <>1__state = 1; return true; } _routine = null; 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 object _routine; [HarmonyPrefix] public static void Prefix(SleepCanvas __instance) { MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if (cfgMultiplierOnly == null || !cfgMultiplierOnly.Value) { if (_routine != null) { MelonCoroutines.Stop(_routine); } TNSLog.Debug("Running SleepStart Prefix."); _routine = MelonCoroutines.Start(MakeThingsWorkRoutine(__instance)); } } public static void StopRoutine() { MelonPreferences_Entry<bool> cfgMultiplierOnly = Core.cfgMultiplierOnly; if ((cfgMultiplierOnly == null || !cfgMultiplierOnly.Value) && _routine != null) { MelonCoroutines.Stop(_routine); _routine = null; } } [IteratorStateMachine(typeof(<MakeThingsWorkRoutine>d__3))] private static IEnumerator MakeThingsWorkRoutine(SleepCanvas __instance) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <MakeThingsWorkRoutine>d__3(0) { __instance = __instance }; } private static void MakeThingsWork(SleepCanvas __instance) { try { PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance; if (!((Object)(object)instance == (Object)null)) { instance.SetCanLook(true); MelonPreferences_Entry<bool> cfgEnableSummaryAwake = Core.cfgEnableSummaryAwake; if (cfgEnableSummaryAwake != null && !cfgEnableSummaryAwake.Value) { instance.LockMouse(); } else { instance.FreeMouse(); } MelonPreferences_Entry<bool> cfgEnableSummaryAwake2 = Core.cfgEnableSummaryAwake; if (cfgEnableSummaryAwake2 != null && !cfgEnableSummaryAwake2.Value) { SCAccess.LerpBlackOverlay(__instance, 0f, 0.1f); } } } catch (Exception ex) { TNSLog.Warning("SleepStart look restore failed: " + ex.Message); } } } internal static class TMAccess { public static void SetCurrentTime(TimeManager tm, int v) { tm.CurrentTime = v; } public static void SetElapsedDays(TimeManager tm, int v) { tm.ElapsedDays = v; } public static void SetDailyMinTotal(TimeManager tm, int v) { tm.DailyMinTotal = v; } public static void SetTimeOnCurrentMinute(TimeManager tm, float v) { tm.TimeOnCurrentMinute = v; } public static void TryStartStaggeredMinPass(TimeManager tm, float arg) { ((MonoBehaviour)tm).StartCoroutine(tm.StaggeredMinPass(arg)); } } internal static class SCAccess { private static readonly MethodInfo _lerpBlackOverlay = AccessTools.Method(typeof(SleepCanvas), "LerpBlackOverlay", new Type[2] { typeof(float), typeof(float) }, (Type[])null); public static void LerpBlackOverlay(SleepCanvas inst, float transparency, float lerpTime) { if (_lerpBlackOverlay != null) { try { _lerpBlackOverlay.Invoke(inst, new object[2] { transparency, lerpTime }); } catch (Exception ex) { TNSLog.Warning("Invoke SleepCanvas.LerpBlackOverlay failed: " + ex.Message); } } } } [HarmonyPatch(typeof(TimeManager))] public static class Debug_TimeManager_SleepFlow { [HarmonyPostfix] [HarmonyPatch("ForceSleep")] private static void ForceSleep_Postfix(TimeManager __instance) { TNSLog.Debug("ForceSleep invoked. SleepInProgress=" + __instance.SleepInProgress); } [HarmonyPostfix] [HarmonyPatch("MarkHostSleepDone")] private static void MarkHostSleepDone_Postfix() { TNSLog.Debug("Host sleep done marked."); } } [HarmonyPatch(typeof(Employee))] public static class Debug_Employee_Pay { [HarmonyPrefix] [HarmonyPatch("SetIsPaid")] private static void SetIsPaid_Prefix(Employee __instance) { TNSLog.Debug($"Paying {((NPC)__instance).FirstName} {((NPC)__instance).LastName} DailyWage={__instance.DailyWage}"); } [HarmonyPrefix] [HarmonyPatch("RemoveDailyWage")] private static void RemoveDailyWage_Prefix(Employee __instance) { EmployeeHome home = __instance.GetHome(); float value = (((Object)(object)home != (Object)null) ? home.GetCashSum() : (-1f)); TNSLog.Debug($"Removing wage for {((NPC)__instance).FirstName} {((NPC)__instance).LastName}. HomeCashBefore={value}"); } [HarmonyPostfix] [HarmonyPatch("RemoveDailyWage")] private static void RemoveDailyWage_Postfix(Employee __instance) { EmployeeHome home = __instance.GetHome(); float value = (((Object)(object)home != (Object)null) ? home.GetCashSum() : (-1f)); TNSLog.Debug($"Wage removed. HomeCashAfter={value}"); } } internal static class BuildVersion { internal const string Value = "1.4.0"; } } namespace Time_Never_Stops.TemplateUtils { public static class AssetBundleUtils { private static Core mod = MelonAssembly.FindMelonInstance<Core>(); private static MelonAssembly melonAssembly = ((MelonBase)mod).MelonAssembly; public static Il2CppAssetBundle LoadAssetBundle(string bundleFileName) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown try { string text = typeof(Core).Namespace + ".Assets." + bundleFileName; Stream manifestResourceStream = melonAssembly.Assembly.GetManifestResourceStream(text ?? ""); if (manifestResourceStream == null) { ((MelonBase)mod).Unregister($"AssetBundle: '{text}' not found. \nOpen .csproj file and search for '{bundleFileName}'.\nIf it doesn't exist,\nCopy your asset to Assets/ folder then look for 'your.assetbundle' in .csproj file.", false); return null; } byte[] array; using (MemoryStream memoryStream = new MemoryStream()) { manifestResourceStream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Stream val = (Stream)new MemoryStream(Il2CppStructArray<byte>.op_Implicit(array)); return Il2CppAssetBundleManager.LoadFromStream(val); } catch (Exception value) { ((MelonBase)mod).Unregister($"Failed to load AssetBundle. Please report to dev: {value}", false); return null; } } public static Il2CppAssetBundle GetLoadedAssetBundle(string asset_name_flag) { Il2CppAssetBundle[] allLoadedAssetBundles = Il2CppAssetBundleManager.GetAllLoadedAssetBundles(); try { Il2CppAssetBundle[] array = allLoadedAssetBundles; foreach (Il2CppAssetBundle val in array) { if (val.Contains(asset_name_flag)) { return val; } } string text = ""; Il2CppAssetBundle[] array2 = allLoadedAssetBundles; foreach (Il2CppAssetBundle val2 in array2) { string[] array3 = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)val2.GetAllAssetNames()); string text2 = string.Join("\n\r -", array3); text = text + ((object)val2)?.ToString() + $"({array3.Length} assets):" + text2; } throw new Exception($"Asset '{asset_name_flag}' not found in {allLoadedAssetBundles.Length} bundle(s).\n{text}"); } catch (Exception value) { ((MelonBase)mod).Unregister($"Failed to get loaded AssetBundle. Please report to dev: \n{value}", false); return null; } } public static GameObject LoadAssetFromBundle(string asset_name) { Il2CppAssetBundle loadedAssetBundle = GetLoadedAssetBundle(asset_name); return loadedAssetBundle.LoadAsset<GameObject>(asset_name); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }