Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of WhatCurfew v1.2.0
WhatCurfew_Il2cpp.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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.GameTime; using Il2CppScheduleOne.Law; using Il2CppScheduleOne.ObjectScripts; using Il2CppScheduleOne.Persistence; using Il2CppScheduleOne.UI; using Il2CppTMPro; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using WhatCurfew; using WhatCurfew.Features; using WhatCurfew.Patches; [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), "WhatCurfew", "1.2.0", "HazDS", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WhatCurfew_Il2cpp")] [assembly: AssemblyConfiguration("Il2cpp")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e00c68090d19a1081be3397485311771842c66a7")] [assembly: AssemblyProduct("WhatCurfew_Il2cpp")] [assembly: AssemblyTitle("WhatCurfew_Il2cpp")] [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 WhatCurfew { public class Core : MelonMod { private static Harmony _harmony; public override void OnInitializeMelon() { Config.Initialize(); DiscoController.Initialize(); MelonLogger.Msg("WhatCurfew v1.2.0 loaded!"); ApplyPatches(); } private void ApplyPatches() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown try { _harmony = new Harmony("com.whatcurfew.patches"); Type typeFromHandle = typeof(CurfewManager); PatchMethod(typeFromHandle, "MinPass", "MinPass_Prefix"); PatchMethod(typeFromHandle, "OnUncappedMinPass", "MinPass_Prefix"); PatchEnableRPC(typeFromHandle); PatchVMSBoard(); PatchHUD(); } catch (Exception ex) { MelonLogger.Error("Failed to apply patches: " + ex.Message); } } private void PatchMethod(Type targetType, string methodName, string prefixMethodName) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown MethodInfo method = targetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { MethodInfo method2 = typeof(CurfewPatches).GetMethod(prefixMethodName, BindingFlags.Static | BindingFlags.Public); if (!(method2 == null)) { _harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private void PatchEnableRPC(Type curfewManagerType) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown MethodInfo method = curfewManagerType.GetMethod("RpcLogic___Enable_328543758", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { MethodInfo method2 = typeof(CurfewPatches).GetMethod("Enable_Prefix", BindingFlags.Static | BindingFlags.Public); if (!(method2 == null)) { _harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private void PatchVMSBoard() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown Type typeFromHandle = typeof(VMSBoard); MethodInfo method = typeFromHandle.GetMethod("SetText", new Type[2] { typeof(string), typeof(Color) }); if (method != null) { MethodInfo method2 = typeof(CurfewPatches).GetMethod("VMSBoard_SetText_Prefix", BindingFlags.Static | BindingFlags.Public); if (method2 != null) { _harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } MethodInfo method3 = typeFromHandle.GetMethod("SetText", new Type[1] { typeof(string) }); if (method3 != null) { MethodInfo method4 = typeof(CurfewPatches).GetMethod("VMSBoard_SetText_StringOnly_Prefix", BindingFlags.Static | BindingFlags.Public); if (method4 != null) { _harmony.Patch((MethodBase)method3, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private void PatchHUD() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown Type typeFromHandle = typeof(HUD); MethodInfo method = typeFromHandle.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { MethodInfo method2 = typeof(HUDPatches).GetMethod("Update_Postfix", BindingFlags.Static | BindingFlags.Public); if (!(method2 == null)) { _harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (sceneName == "Menu") { DiscoController.Reset(); } } } public static class Config { private static MelonPreferences_Category _category; private static MelonPreferences_Entry<bool> _enabled; private static MelonPreferences_Entry<bool> _curfewCustomTime; private static MelonPreferences_Entry<string> _curfewStartTime; private static MelonPreferences_Entry<string> _curfewEndTime; private static MelonPreferences_Entry<string> _vmsBoardMessage; private static MelonPreferences_Entry<string> _vmsBoardColor; private static MelonPreferences_Entry<bool> _discoMode; private static MelonPreferences_Entry<float> _discoSpeed; public static readonly Dictionary<string, Color32> ColorOptions = new Dictionary<string, Color32> { { "Green", new Color32((byte)100, byte.MaxValue, (byte)100, byte.MaxValue) }, { "Yellow", new Color32(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue) }, { "Red", new Color32(byte.MaxValue, (byte)85, (byte)60, byte.MaxValue) }, { "Blue", new Color32((byte)100, (byte)150, byte.MaxValue, byte.MaxValue) }, { "Cyan", new Color32((byte)100, byte.MaxValue, byte.MaxValue, byte.MaxValue) }, { "Purple", new Color32((byte)200, (byte)100, byte.MaxValue, byte.MaxValue) }, { "Orange", new Color32(byte.MaxValue, (byte)165, (byte)50, byte.MaxValue) }, { "White", new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) } }; public static bool Enabled => _enabled?.Value ?? true; public static bool CurfewCustomTime => _curfewCustomTime?.Value ?? false; public static string CurfewStartTimeStr => _curfewStartTime?.Value ?? "21:00"; public static string CurfewEndTimeStr => _curfewEndTime?.Value ?? "5:00"; public static string VMSBoardMessage => _vmsBoardMessage?.Value ?? "NO CURFEW\nENJOY THE NIGHT"; public static string VMSBoardColorName => _vmsBoardColor?.Value ?? "Green"; public static bool DiscoMode => _discoMode?.Value ?? false; public static float DiscoSpeed => _discoSpeed?.Value ?? 0.5f; public static int CurfewStart => ParseTimeString(CurfewStartTimeStr, 2100); public static int CurfewEnd => ParseTimeString(CurfewEndTimeStr, 500); public static int HourBeforeCurfew => AddMinutes(CurfewStart, -60); public static int WarningTime => AddMinutes(CurfewStart, -30); public static int HardCurfewStart => AddMinutes(CurfewStart, 15); public static string CustomCurfewTonightText => "CURFEW TONIGHT\n" + FormatGameTimeTo12Hr(CurfewStart) + " - " + FormatGameTimeTo12Hr(CurfewEnd); public static string CustomCurfewActiveText => "CURFEW ACTIVE\nUNTIL " + FormatGameTimeTo12Hr(CurfewEnd); public static Color32 VMSBoardColor { get { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (ColorOptions.TryGetValue(VMSBoardColorName, out var value)) { return value; } return ColorOptions["Green"]; } } public static event Action<bool> OnDiscoModeChanged; public static int ParseTimeString(string time, int fallback) { if (string.IsNullOrEmpty(time)) { return fallback; } string[] array = time.Split(':'); if (array.Length != 2) { return fallback; } if (!int.TryParse(array[0], out var result) || !int.TryParse(array[1], out var result2)) { return fallback; } if (result < 0 || result > 23 || result2 < 0 || result2 > 59) { return fallback; } return result * 100 + result2; } public static int AddMinutes(int gameTime, int minutes) { int num = gameTime / 100; int num2 = gameTime % 100; int num3 = num * 60 + num2 + minutes; if (num3 < 0) { num3 += 1440; } num3 %= 1440; return num3 / 60 * 100 + num3 % 60; } public static string FormatGameTimeTo12Hr(int gameTime) { int num = gameTime / 100; int num2 = gameTime % 100; string text = ((num >= 12) ? "PM" : "AM"); if (num == 0) { num = 12; } else if (num > 12) { num -= 12; } if (num2 == 0) { return $"{num}{text}"; } return $"{num}:{num2:00}{text}"; } public static void Initialize() { _category = MelonPreferences.CreateCategory("WhatCurfew", "WhatCurfew Settings"); _enabled = _category.CreateEntry<bool>("Enabled", true, "Enable Mod", "Master switch for the mod. When disabled, vanilla curfew behavior is restored.", false, false, (ValueValidator)null, (string)null); _curfewCustomTime = _category.CreateEntry<bool>("CurfewCustomTime", false, "Custom Curfew Times", "When enabled, curfew uses configurable start/end times instead of being fully disabled.", false, false, (ValueValidator)null, (string)null); _curfewStartTime = _category.CreateEntry<string>("CurfewStartTime", "21:00", "Curfew Start Time", "When curfew begins in 24-hour format (e.g. 21:00 for 9PM, 23:30 for 11:30PM). Only used in Custom mode.", false, false, (ValueValidator)null, (string)null); _curfewEndTime = _category.CreateEntry<string>("CurfewEndTime", "5:00", "Curfew End Time", "When curfew ends in 24-hour format (e.g. 5:00 for 5AM, 3:30 for 3:30AM). Only used in Custom mode.", false, false, (ValueValidator)null, (string)null); _vmsBoardMessage = _category.CreateEntry<string>("VMSBoardMessage", "NO CURFEW\nENJOY THE NIGHT", "VMS Board Message", "Custom message for VMS boards in Disabled mode. Use \\n for new lines.", false, false, (ValueValidator)null, (string)null); _vmsBoardColor = _category.CreateEntry<string>("VMSBoardColor", "Green", "VMS Board Color", "Color of the VMS board text. Options: Green, Yellow, Red, Blue, Cyan, Purple, Orange, White", false, false, (ValueValidator)null, (string)null); _discoMode = _category.CreateEntry<bool>("DiscoMode", false, "Disco Mode", "When enabled, VMS board colors cycle through all available colors.", false, false, (ValueValidator)null, (string)null); _discoSpeed = _category.CreateEntry<float>("DiscoSpeed", 0.5f, "Disco Speed", "Seconds between color changes in disco mode (0.1 to 2.0).", false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<bool, bool>>)(object)_enabled.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool oldVal, bool newVal) { MelonLogger.Msg("Mod " + (newVal ? "enabled" : "disabled")); CurfewPatches.OnEnabledChanged(newVal); DiscoController.OnModEnabledChanged(newVal); }, 0, false); ((MelonEventBase<LemonAction<bool, bool>>)(object)_curfewCustomTime.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool oldVal, bool newVal) { MelonLogger.Msg("Custom curfew times " + (newVal ? "enabled" : "disabled")); if (Enabled) { CurfewPatches.OnCurfewModeChanged(newVal); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_curfewStartTime.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("Curfew start time changed to: " + newVal); if (Enabled && CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_curfewEndTime.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("Curfew end time changed to: " + newVal); if (Enabled && CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_vmsBoardMessage.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("VMS message changed to: " + newVal); if (Enabled && !CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_vmsBoardColor.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("VMS color changed to: " + newVal); if (Enabled && !DiscoMode && !CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<bool, bool>>)(object)_discoMode.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool oldVal, bool newVal) { Config.OnDiscoModeChanged?.Invoke(newVal); }, 0, false); ((MelonEventBase<LemonAction<float, float>>)(object)_discoSpeed.OnEntryValueChanged).Subscribe((LemonAction<float, float>)delegate(float oldVal, float newVal) { MelonLogger.Msg($"Disco speed changed to: {newVal}s"); }, 0, false); MelonLogger.Msg($"Configuration loaded. CustomCurfewTime: {CurfewCustomTime}, Enabled: {Enabled}"); } } } namespace WhatCurfew.Features { public static class DiscoController { [CompilerGenerated] private sealed class <DiscoLoop>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private Color32 <currentColor>5__1; private float <delay>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DiscoLoop>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (_isRunning) { <currentColor>5__1 = _colorList[_currentColorIndex]; CurfewPatches.RefreshAllBoardsWithColor(<currentColor>5__1); _currentColorIndex = (_currentColorIndex + 1) % _colorList.Count; <delay>5__2 = Mathf.Clamp(Config.DiscoSpeed, 0.1f, 2f); <>2__current = (object)new WaitForSeconds(<delay>5__2); <>1__state = 1; return true; } 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 _discoCoroutine; private static int _currentColorIndex; private static List<Color32> _colorList; private static bool _isRunning; public static void Initialize() { _colorList = new List<Color32>(Config.ColorOptions.Values); _currentColorIndex = 0; Config.OnDiscoModeChanged += OnDiscoModeChanged; if (Config.DiscoMode && Config.Enabled) { StartDisco(); } } private static void OnDiscoModeChanged(bool enabled) { if (enabled && Config.Enabled) { StartDisco(); return; } StopDisco(); if (Config.Enabled) { CurfewPatches.RefreshAllBoards(); } } public static void OnModEnabledChanged(bool enabled) { if (enabled && Config.DiscoMode) { StartDisco(); } else { StopDisco(); } } private static void StartDisco() { if (!_isRunning) { _isRunning = true; _discoCoroutine = MelonCoroutines.Start(DiscoLoop()); MelonLogger.Msg("Disco mode started!"); } } private static void StopDisco() { if (_isRunning) { _isRunning = false; _discoCoroutine = null; MelonLogger.Msg("Disco mode stopped."); } } [IteratorStateMachine(typeof(<DiscoLoop>d__9))] private static IEnumerator DiscoLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DiscoLoop>d__9(0); } public static void Reset() { _isRunning = false; _discoCoroutine = null; _currentColorIndex = 0; } } } namespace WhatCurfew.Patches { public static class CurfewPatches { private static readonly Dictionary<int, (VMSBoard board, string text, Color color)> _trackedBoards = new Dictionary<int, (VMSBoard, string, Color)>(); private static readonly string[] CurfewMessages = new string[3] { "CURFEW TONIGHT", "CURFEW ACTIVE", "CURFEW SOON" }; private static bool _reflectionInitialized; private static PropertyInfo _cmInstanceProp; private static PropertyInfo _cmIsEnabledProp; private static PropertyInfo _cmIsActiveProp; private static PropertyInfo _cmIsHardProp; private static PropertyInfo _tmInstanceProp; private static PropertyInfo _tmCurrentTimeProp; private static PropertyInfo _tmElapsedDaysProp; private static PropertyInfo _tmIsSleepProp; private static PropertyInfo _lmInstanceProp; private static PropertyInfo _lmTimeSinceLoadedProp; private static void InitReflectionCache() { if (!_reflectionInitialized) { _reflectionInitialized = true; Type typeFromHandle = typeof(CurfewManager); _cmInstanceProp = FindStaticProperty(typeFromHandle, "Instance"); _cmIsEnabledProp = typeFromHandle.GetProperty("IsEnabled"); _cmIsActiveProp = typeFromHandle.GetProperty("IsCurrentlyActive"); _cmIsHardProp = typeFromHandle.GetProperty("IsHardCurfewActive"); Type typeFromHandle2 = typeof(TimeManager); _tmInstanceProp = FindStaticProperty(typeFromHandle2, "Instance"); _tmCurrentTimeProp = typeFromHandle2.GetProperty("CurrentTime"); _tmElapsedDaysProp = typeFromHandle2.GetProperty("ElapsedDays"); _tmIsSleepProp = typeFromHandle2.GetProperty("IsSleepInProgress"); Type typeFromHandle3 = typeof(LoadManager); _lmInstanceProp = FindStaticProperty(typeFromHandle3, "Instance"); _lmTimeSinceLoadedProp = typeFromHandle3.GetProperty("TimeSinceGameLoaded"); } } private static PropertyInfo FindStaticProperty(Type type, string name) { Type type2 = type; while (type2 != null) { PropertyInfo property = type2.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public); if (property != null) { return property; } type2 = type2.BaseType; } return null; } private static CurfewManager GetCurfewManagerInstance() { InitReflectionCache(); object? obj = _cmInstanceProp?.GetValue(null); return (CurfewManager)((obj is CurfewManager) ? obj : null); } private static bool IsTimeInRange(int time, int min, int max) { if (max > min) { return time >= min && time <= max; } return time >= min || time <= max; } private static int GetMinSum(int gameTime) { return gameTime / 100 * 60 + gameTime % 100; } private static float GetTimeSinceLoaded() { try { object obj = _lmInstanceProp?.GetValue(null); if (obj != null && _lmTimeSinceLoadedProp != null) { return (float)_lmTimeSinceLoadedProp.GetValue(obj); } } catch { } return float.MaxValue; } private static void SetBoardsText(CurfewManager instance, string text) { if (instance.VMSBoards == null) { return; } foreach (VMSBoard item in (Il2CppArrayBase<VMSBoard>)(object)instance.VMSBoards) { if ((Object)(object)item != (Object)null && (Object)(object)item.Label != (Object)null) { ((TMP_Text)item.Label).text = text; } } } private static void SetBoardsTextAndColor(CurfewManager instance, string text, Color color) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (instance.VMSBoards == null) { return; } foreach (VMSBoard item in (Il2CppArrayBase<VMSBoard>)(object)instance.VMSBoards) { if ((Object)(object)item != (Object)null && (Object)(object)item.Label != (Object)null) { ((TMP_Text)item.Label).text = text; ((Graphic)item.Label).color = color; } } } public static void RefreshAllBoards() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) string text; Color32 vMSBoardColor = default(Color32); if (Config.CurfewCustomTime) { text = Config.CustomCurfewTonightText; ((Color32)(ref vMSBoardColor))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); } else { text = Config.VMSBoardMessage; vMSBoardColor = Config.VMSBoardColor; } RefreshAllBoardsWithTextAndColor(text, vMSBoardColor); } public static void RefreshAllBoardsWithColor(Color32 color) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) string text = (Config.CurfewCustomTime ? Config.CustomCurfewTonightText : Config.VMSBoardMessage); RefreshAllBoardsWithTextAndColor(text, color); } private static void RefreshAllBoardsWithTextAndColor(string text, Color32 color) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) CleanupDestroyedBoards(); foreach (KeyValuePair<int, (VMSBoard, string, Color)> trackedBoard in _trackedBoards) { VMSBoard item = trackedBoard.Value.Item1; if ((Object)(object)item != (Object)null && (Object)(object)item.Label != (Object)null) { ((TMP_Text)item.Label).text = text; ((Graphic)item.Label).color = Color32.op_Implicit(color); } } } public static void RestoreAllBoards() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) CleanupDestroyedBoards(); List<(VMSBoard, string, Color)> list = new List<(VMSBoard, string, Color)>(); foreach (KeyValuePair<int, (VMSBoard, string, Color)> trackedBoard in _trackedBoards) { list.Add(trackedBoard.Value); } foreach (var (val, text, color) in list) { if ((Object)(object)val != (Object)null && (Object)(object)val.Label != (Object)null) { ((TMP_Text)val.Label).text = text; ((Graphic)val.Label).color = color; } } } private static void CleanupDestroyedBoards() { List<int> list = new List<int>(); foreach (KeyValuePair<int, (VMSBoard, string, Color)> trackedBoard in _trackedBoards) { if ((Object)(object)trackedBoard.Value.Item1 == (Object)null) { list.Add(trackedBoard.Key); } } foreach (int item in list) { _trackedBoards.Remove(item); } } public static void OnEnabledChanged(bool enabled) { if (enabled) { RefreshAllBoards(); return; } RestoreAllBoards(); RestoreCurfewState(); } public static void OnCurfewModeChanged(bool customTime) { InitReflectionCache(); CurfewManager curfewManagerInstance = GetCurfewManagerInstance(); if ((Object)(object)curfewManagerInstance == (Object)null) { return; } if (customTime) { _cmIsEnabledProp?.SetValue(curfewManagerInstance, true); try { UnityEvent onCurfewEnabled = curfewManagerInstance.onCurfewEnabled; if (onCurfewEnabled != null) { onCurfewEnabled.Invoke(); } } catch { } } else { bool flag = _cmIsActiveProp != null && (bool)_cmIsActiveProp.GetValue(curfewManagerInstance); _cmIsEnabledProp?.SetValue(curfewManagerInstance, false); _cmIsActiveProp?.SetValue(curfewManagerInstance, false); _cmIsHardProp?.SetValue(curfewManagerInstance, false); if (flag) { try { UnityEvent onCurfewEnd = curfewManagerInstance.onCurfewEnd; if (onCurfewEnd != null) { onCurfewEnd.Invoke(); } } catch { } } } RefreshAllBoards(); } private static void RestoreCurfewState() { try { InitReflectionCache(); CurfewManager curfewManagerInstance = GetCurfewManagerInstance(); if ((Object)(object)curfewManagerInstance != (Object)null) { _cmIsEnabledProp?.SetValue(curfewManagerInstance, true); _cmIsActiveProp?.SetValue(curfewManagerInstance, false); _cmIsHardProp?.SetValue(curfewManagerInstance, false); } } catch { } } private static bool IsCurfewMessage(string text) { if (string.IsNullOrEmpty(text)) { return false; } string[] curfewMessages = CurfewMessages; foreach (string value in curfewMessages) { if (text.Contains(value)) { return true; } } return false; } public static bool MinPass_Prefix(CurfewManager __instance) { if (!Config.Enabled) { return true; } if (Config.CurfewCustomTime) { return HandleCustomCurfew(__instance); } try { InitReflectionCache(); _cmIsEnabledProp?.SetValue(__instance, false); _cmIsActiveProp?.SetValue(__instance, false); _cmIsHardProp?.SetValue(__instance, false); } catch { } return false; } private static bool HandleCustomCurfew(CurfewManager __instance) { //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) try { InitReflectionCache(); _cmIsEnabledProp?.SetValue(__instance, true); object obj = _tmInstanceProp?.GetValue(null); if (obj == null) { return false; } int num = (int)_tmCurrentTimeProp.GetValue(obj); int curfewStart = Config.CurfewStart; int curfewEnd = Config.CurfewEnd; int hourBeforeCurfew = Config.HourBeforeCurfew; int warningTime = Config.WarningTime; int hardCurfewStart = Config.HardCurfewStart; bool flag = (bool)(_cmIsActiveProp?.GetValue(__instance) ?? ((object)false)); bool flag2 = (bool)(_cmIsHardProp?.GetValue(__instance) ?? ((object)false)); if (IsTimeInRange(num, hourBeforeCurfew, curfewStart)) { int num2 = GetMinSum(curfewStart) - GetMinSum(num); if (num2 < 0) { num2 += 1440; } SetBoardsText(__instance, $"CURFEW SOON\n{num2} MINS"); } if (num == warningTime) { UnityEvent onCurfewWarning = __instance.onCurfewWarning; if (onCurfewWarning != null) { onCurfewWarning.Invoke(); } if ((int)(_tmElapsedDaysProp?.GetValue(obj) ?? ((object)1)) == 0) { UnityEvent onCurfewHint = __instance.onCurfewHint; if (onCurfewHint != null) { onCurfewHint.Invoke(); } } __instance.CurfewWarningSound.Play(); } if (!flag && IsTimeInRange(num, curfewStart, curfewEnd)) { _cmIsActiveProp?.SetValue(__instance, true); UnityEvent onCurfewStart = __instance.onCurfewStart; if (onCurfewStart != null) { onCurfewStart.Invoke(); } bool flag3 = (bool)(_tmIsSleepProp?.GetValue(obj) ?? ((object)false)); float timeSinceLoaded = GetTimeSinceLoaded(); if (!flag3 && timeSinceLoaded > 3f && !__instance.CurfewAlarmSound.isPlaying) { __instance.CurfewAlarmSound.Play(); } SetBoardsTextAndColor(__instance, Config.CustomCurfewActiveText, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)85, (byte)60, byte.MaxValue))); } if (!flag2 && IsTimeInRange(num, hardCurfewStart, curfewEnd)) { _cmIsHardProp?.SetValue(__instance, true); UnityEvent onCurfewHardStart = __instance.onCurfewHardStart; if (onCurfewHardStart != null) { onCurfewHardStart.Invoke(); } } if (flag && IsTimeInRange(num, curfewEnd, curfewStart)) { _cmIsActiveProp?.SetValue(__instance, false); _cmIsHardProp?.SetValue(__instance, false); UnityEvent onCurfewEnd = __instance.onCurfewEnd; if (onCurfewEnd != null) { onCurfewEnd.Invoke(); } SetBoardsText(__instance, Config.CustomCurfewTonightText); } } catch (Exception ex) { MelonLogger.Error("Custom curfew error: " + ex.Message); } return false; } public static bool Enable_Prefix(CurfewManager __instance) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if (!Config.Enabled) { return true; } try { string text; Color32 vMSBoardColor = default(Color32); if (Config.CurfewCustomTime) { text = Config.CustomCurfewTonightText; ((Color32)(ref vMSBoardColor))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); InitReflectionCache(); _cmIsEnabledProp?.SetValue(__instance, true); UnityEvent onCurfewEnabled = __instance.onCurfewEnabled; if (onCurfewEnabled != null) { onCurfewEnabled.Invoke(); } } else { text = Config.VMSBoardMessage; vMSBoardColor = Config.VMSBoardColor; } if (__instance.VMSBoards != null) { foreach (VMSBoard item in (Il2CppArrayBase<VMSBoard>)(object)__instance.VMSBoards) { if ((Object)(object)item != (Object)null) { ((Component)item).gameObject.SetActive(true); if ((Object)(object)item.Label != (Object)null) { ((TMP_Text)item.Label).text = text; ((Graphic)item.Label).color = Color32.op_Implicit(vMSBoardColor); } int instanceID = ((Object)item).GetInstanceID(); _trackedBoards[instanceID] = (item, "CURFEW TONIGHT\n9PM - 5AM", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue))); } } } } catch { } return false; } public static bool IsCurrentlyActive_Prefix(ref bool __result) { if (!Config.Enabled) { return true; } __result = false; return false; } public static bool IsHardCurfewActive_Prefix(ref bool __result) { if (!Config.Enabled) { return true; } __result = false; return false; } public static bool IsEnabled_Prefix(ref bool __result) { if (!Config.Enabled) { return true; } __result = false; return false; } public static void VMSBoard_SetText_Prefix(VMSBoard __instance, ref string text, ref Color col) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (!IsCurfewMessage(text)) { return; } int instanceID = ((Object)__instance).GetInstanceID(); _trackedBoards[instanceID] = (__instance, text, col); if (Config.Enabled) { if (Config.CurfewCustomTime) { text = Config.CustomCurfewTonightText; return; } text = Config.VMSBoardMessage; col = Color32.op_Implicit(Config.VMSBoardColor); } } public static bool VMSBoard_SetText_StringOnly_Prefix(VMSBoard __instance, ref string text) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (IsCurfewMessage(text)) { int instanceID = ((Object)__instance).GetInstanceID(); Color32 val = default(Color32); ((Color32)(ref val))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); _trackedBoards[instanceID] = (__instance, text, Color32.op_Implicit(val)); if (!Config.Enabled) { return true; } string text2; Color32 vMSBoardColor = default(Color32); if (Config.CurfewCustomTime) { text2 = Config.CustomCurfewTonightText; ((Color32)(ref vMSBoardColor))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); } else { text2 = Config.VMSBoardMessage; vMSBoardColor = Config.VMSBoardColor; } if ((Object)(object)__instance.Label != (Object)null) { ((TMP_Text)__instance.Label).text = text2; ((Graphic)__instance.Label).color = Color32.op_Implicit(vMSBoardColor); } return false; } return true; } } public static class HUDPatches { private static bool _reflectionInitialized; private static PropertyInfo _cmInstanceExistsProp; private static PropertyInfo _cmInstanceProp; private static PropertyInfo _cmIsActiveProp; private static PropertyInfo _cmIsEnabledProp; private static PropertyInfo _tmInstanceProp; private static PropertyInfo _tmCurrentTimeProp; private static void InitReflectionCache() { if (!_reflectionInitialized) { _reflectionInitialized = true; Type typeFromHandle = typeof(CurfewManager); _cmInstanceExistsProp = FindStaticProperty(typeFromHandle, "InstanceExists"); _cmInstanceProp = FindStaticProperty(typeFromHandle, "Instance"); _cmIsActiveProp = typeFromHandle.GetProperty("IsCurrentlyActive"); _cmIsEnabledProp = typeFromHandle.GetProperty("IsEnabled"); Type typeFromHandle2 = typeof(TimeManager); _tmInstanceProp = FindStaticProperty(typeFromHandle2, "Instance"); _tmCurrentTimeProp = typeFromHandle2.GetProperty("CurrentTime"); } } private static PropertyInfo FindStaticProperty(Type type, string name) { Type type2 = type; while (type2 != null) { PropertyInfo property = type2.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public); if (property != null) { return property; } type2 = type2.BaseType; } return null; } public static void Update_Postfix(HUD __instance) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) if (!Config.Enabled || !Config.CurfewCustomTime || (Object)(object)__instance.CurfewPrompt == (Object)null || !((Component)__instance.CurfewPrompt).gameObject.activeSelf) { return; } try { InitReflectionCache(); object obj = _cmInstanceProp?.GetValue(null); if (obj == null) { return; } bool flag = (bool)(_cmIsActiveProp?.GetValue(obj) ?? ((object)false)); bool flag2 = (bool)(_cmIsEnabledProp?.GetValue(obj) ?? ((object)false)); if (flag) { ((TMP_Text)__instance.CurfewPrompt).text = "Police curfew in effect until " + Config.FormatGameTimeTo12Hr(Config.CurfewEnd); } else { if (!flag2) { return; } object obj2 = _tmInstanceProp?.GetValue(null); if (obj2 != null) { int time = (int)_tmCurrentTimeProp.GetValue(obj2); if (IsTimeInRange(time, Config.WarningTime, Config.CurfewEnd)) { ((TMP_Text)__instance.CurfewPrompt).text = "Police curfew starting soon"; ((Graphic)__instance.CurfewPrompt).color = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)182, (byte)88, (byte)60)); ((Component)__instance.CurfewPrompt).gameObject.SetActive(true); } else { ((Component)__instance.CurfewPrompt).gameObject.SetActive(false); } } } } catch { } } private static bool IsTimeInRange(int time, int min, int max) { if (max > min) { return time >= min && time <= max; } return time >= min || time <= max; } } } namespace WhatCurfew.Utils { public static class Constants { public static class Game { public const string GAME_STUDIO = "TVGS"; public const string GAME_NAME = "Schedule I"; } public const string MOD_NAME = "WhatCurfew"; public const string MOD_VERSION = "1.2.0"; public const string MOD_AUTHOR = "HazDS"; public const string MOD_DESCRIPTION = "Disable or customize curfew times in Schedule I."; public const string PREFERENCES_CATEGORY = "WhatCurfew"; } }
WhatCurfew_Mono.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using ScheduleOne.GameTime; using ScheduleOne.Law; using ScheduleOne.ObjectScripts; using ScheduleOne.Persistence; using ScheduleOne.UI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using WhatCurfew; using WhatCurfew.Features; using WhatCurfew.Patches; [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), "WhatCurfew", "1.2.0", "HazDS", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WhatCurfew_Mono")] [assembly: AssemblyConfiguration("Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e00c68090d19a1081be3397485311771842c66a7")] [assembly: AssemblyProduct("WhatCurfew_Mono")] [assembly: AssemblyTitle("WhatCurfew_Mono")] [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 WhatCurfew { public class Core : MelonMod { private static Harmony _harmony; public override void OnInitializeMelon() { Config.Initialize(); DiscoController.Initialize(); MelonLogger.Msg("WhatCurfew v1.2.0 loaded!"); ApplyPatches(); } private void ApplyPatches() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown try { _harmony = new Harmony("com.whatcurfew.patches"); Type typeFromHandle = typeof(CurfewManager); PatchMethod(typeFromHandle, "MinPass", "MinPass_Prefix"); PatchMethod(typeFromHandle, "OnUncappedMinPass", "MinPass_Prefix"); PatchEnableRPC(typeFromHandle); PatchVMSBoard(); PatchHUD(); } catch (Exception ex) { MelonLogger.Error("Failed to apply patches: " + ex.Message); } } private void PatchMethod(Type targetType, string methodName, string prefixMethodName) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown MethodInfo method = targetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { MethodInfo method2 = typeof(CurfewPatches).GetMethod(prefixMethodName, BindingFlags.Static | BindingFlags.Public); if (!(method2 == null)) { _harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private void PatchEnableRPC(Type curfewManagerType) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown MethodInfo method = curfewManagerType.GetMethod("RpcLogic___Enable_328543758", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { MethodInfo method2 = typeof(CurfewPatches).GetMethod("Enable_Prefix", BindingFlags.Static | BindingFlags.Public); if (!(method2 == null)) { _harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private void PatchVMSBoard() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown Type typeFromHandle = typeof(VMSBoard); MethodInfo method = typeFromHandle.GetMethod("SetText", new Type[2] { typeof(string), typeof(Color) }); if (method != null) { MethodInfo method2 = typeof(CurfewPatches).GetMethod("VMSBoard_SetText_Prefix", BindingFlags.Static | BindingFlags.Public); if (method2 != null) { _harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } MethodInfo method3 = typeFromHandle.GetMethod("SetText", new Type[1] { typeof(string) }); if (method3 != null) { MethodInfo method4 = typeof(CurfewPatches).GetMethod("VMSBoard_SetText_StringOnly_Prefix", BindingFlags.Static | BindingFlags.Public); if (method4 != null) { _harmony.Patch((MethodBase)method3, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private void PatchHUD() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown Type typeFromHandle = typeof(HUD); MethodInfo method = typeFromHandle.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null)) { MethodInfo method2 = typeof(HUDPatches).GetMethod("Update_Postfix", BindingFlags.Static | BindingFlags.Public); if (!(method2 == null)) { _harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (sceneName == "Menu") { DiscoController.Reset(); } } } public static class Config { private static MelonPreferences_Category _category; private static MelonPreferences_Entry<bool> _enabled; private static MelonPreferences_Entry<bool> _curfewCustomTime; private static MelonPreferences_Entry<string> _curfewStartTime; private static MelonPreferences_Entry<string> _curfewEndTime; private static MelonPreferences_Entry<string> _vmsBoardMessage; private static MelonPreferences_Entry<string> _vmsBoardColor; private static MelonPreferences_Entry<bool> _discoMode; private static MelonPreferences_Entry<float> _discoSpeed; public static readonly Dictionary<string, Color32> ColorOptions = new Dictionary<string, Color32> { { "Green", new Color32((byte)100, byte.MaxValue, (byte)100, byte.MaxValue) }, { "Yellow", new Color32(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue) }, { "Red", new Color32(byte.MaxValue, (byte)85, (byte)60, byte.MaxValue) }, { "Blue", new Color32((byte)100, (byte)150, byte.MaxValue, byte.MaxValue) }, { "Cyan", new Color32((byte)100, byte.MaxValue, byte.MaxValue, byte.MaxValue) }, { "Purple", new Color32((byte)200, (byte)100, byte.MaxValue, byte.MaxValue) }, { "Orange", new Color32(byte.MaxValue, (byte)165, (byte)50, byte.MaxValue) }, { "White", new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) } }; public static bool Enabled => _enabled?.Value ?? true; public static bool CurfewCustomTime => _curfewCustomTime?.Value ?? false; public static string CurfewStartTimeStr => _curfewStartTime?.Value ?? "21:00"; public static string CurfewEndTimeStr => _curfewEndTime?.Value ?? "5:00"; public static string VMSBoardMessage => _vmsBoardMessage?.Value ?? "NO CURFEW\nENJOY THE NIGHT"; public static string VMSBoardColorName => _vmsBoardColor?.Value ?? "Green"; public static bool DiscoMode => _discoMode?.Value ?? false; public static float DiscoSpeed => _discoSpeed?.Value ?? 0.5f; public static int CurfewStart => ParseTimeString(CurfewStartTimeStr, 2100); public static int CurfewEnd => ParseTimeString(CurfewEndTimeStr, 500); public static int HourBeforeCurfew => AddMinutes(CurfewStart, -60); public static int WarningTime => AddMinutes(CurfewStart, -30); public static int HardCurfewStart => AddMinutes(CurfewStart, 15); public static string CustomCurfewTonightText => "CURFEW TONIGHT\n" + FormatGameTimeTo12Hr(CurfewStart) + " - " + FormatGameTimeTo12Hr(CurfewEnd); public static string CustomCurfewActiveText => "CURFEW ACTIVE\nUNTIL " + FormatGameTimeTo12Hr(CurfewEnd); public static Color32 VMSBoardColor { get { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (ColorOptions.TryGetValue(VMSBoardColorName, out var value)) { return value; } return ColorOptions["Green"]; } } public static event Action<bool> OnDiscoModeChanged; public static int ParseTimeString(string time, int fallback) { if (string.IsNullOrEmpty(time)) { return fallback; } string[] array = time.Split(':'); if (array.Length != 2) { return fallback; } if (!int.TryParse(array[0], out var result) || !int.TryParse(array[1], out var result2)) { return fallback; } if (result < 0 || result > 23 || result2 < 0 || result2 > 59) { return fallback; } return result * 100 + result2; } public static int AddMinutes(int gameTime, int minutes) { int num = gameTime / 100; int num2 = gameTime % 100; int num3 = num * 60 + num2 + minutes; if (num3 < 0) { num3 += 1440; } num3 %= 1440; return num3 / 60 * 100 + num3 % 60; } public static string FormatGameTimeTo12Hr(int gameTime) { int num = gameTime / 100; int num2 = gameTime % 100; string text = ((num >= 12) ? "PM" : "AM"); if (num == 0) { num = 12; } else if (num > 12) { num -= 12; } if (num2 == 0) { return $"{num}{text}"; } return $"{num}:{num2:00}{text}"; } public static void Initialize() { _category = MelonPreferences.CreateCategory("WhatCurfew", "WhatCurfew Settings"); _enabled = _category.CreateEntry<bool>("Enabled", true, "Enable Mod", "Master switch for the mod. When disabled, vanilla curfew behavior is restored.", false, false, (ValueValidator)null, (string)null); _curfewCustomTime = _category.CreateEntry<bool>("CurfewCustomTime", false, "Custom Curfew Times", "When enabled, curfew uses configurable start/end times instead of being fully disabled.", false, false, (ValueValidator)null, (string)null); _curfewStartTime = _category.CreateEntry<string>("CurfewStartTime", "21:00", "Curfew Start Time", "When curfew begins in 24-hour format (e.g. 21:00 for 9PM, 23:30 for 11:30PM). Only used in Custom mode.", false, false, (ValueValidator)null, (string)null); _curfewEndTime = _category.CreateEntry<string>("CurfewEndTime", "5:00", "Curfew End Time", "When curfew ends in 24-hour format (e.g. 5:00 for 5AM, 3:30 for 3:30AM). Only used in Custom mode.", false, false, (ValueValidator)null, (string)null); _vmsBoardMessage = _category.CreateEntry<string>("VMSBoardMessage", "NO CURFEW\nENJOY THE NIGHT", "VMS Board Message", "Custom message for VMS boards in Disabled mode. Use \\n for new lines.", false, false, (ValueValidator)null, (string)null); _vmsBoardColor = _category.CreateEntry<string>("VMSBoardColor", "Green", "VMS Board Color", "Color of the VMS board text. Options: Green, Yellow, Red, Blue, Cyan, Purple, Orange, White", false, false, (ValueValidator)null, (string)null); _discoMode = _category.CreateEntry<bool>("DiscoMode", false, "Disco Mode", "When enabled, VMS board colors cycle through all available colors.", false, false, (ValueValidator)null, (string)null); _discoSpeed = _category.CreateEntry<float>("DiscoSpeed", 0.5f, "Disco Speed", "Seconds between color changes in disco mode (0.1 to 2.0).", false, false, (ValueValidator)null, (string)null); ((MelonEventBase<LemonAction<bool, bool>>)(object)_enabled.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool oldVal, bool newVal) { MelonLogger.Msg("Mod " + (newVal ? "enabled" : "disabled")); CurfewPatches.OnEnabledChanged(newVal); DiscoController.OnModEnabledChanged(newVal); }, 0, false); ((MelonEventBase<LemonAction<bool, bool>>)(object)_curfewCustomTime.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool oldVal, bool newVal) { MelonLogger.Msg("Custom curfew times " + (newVal ? "enabled" : "disabled")); if (Enabled) { CurfewPatches.OnCurfewModeChanged(newVal); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_curfewStartTime.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("Curfew start time changed to: " + newVal); if (Enabled && CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_curfewEndTime.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("Curfew end time changed to: " + newVal); if (Enabled && CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_vmsBoardMessage.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("VMS message changed to: " + newVal); if (Enabled && !CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<string, string>>)(object)_vmsBoardColor.OnEntryValueChanged).Subscribe((LemonAction<string, string>)delegate(string oldVal, string newVal) { MelonLogger.Msg("VMS color changed to: " + newVal); if (Enabled && !DiscoMode && !CurfewCustomTime) { CurfewPatches.RefreshAllBoards(); } }, 0, false); ((MelonEventBase<LemonAction<bool, bool>>)(object)_discoMode.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate(bool oldVal, bool newVal) { Config.OnDiscoModeChanged?.Invoke(newVal); }, 0, false); ((MelonEventBase<LemonAction<float, float>>)(object)_discoSpeed.OnEntryValueChanged).Subscribe((LemonAction<float, float>)delegate(float oldVal, float newVal) { MelonLogger.Msg($"Disco speed changed to: {newVal}s"); }, 0, false); MelonLogger.Msg($"Configuration loaded. CustomCurfewTime: {CurfewCustomTime}, Enabled: {Enabled}"); } } } namespace WhatCurfew.Features { public static class DiscoController { [CompilerGenerated] private sealed class <DiscoLoop>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private Color32 <currentColor>5__1; private float <delay>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DiscoLoop>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (_isRunning) { <currentColor>5__1 = _colorList[_currentColorIndex]; CurfewPatches.RefreshAllBoardsWithColor(<currentColor>5__1); _currentColorIndex = (_currentColorIndex + 1) % _colorList.Count; <delay>5__2 = Mathf.Clamp(Config.DiscoSpeed, 0.1f, 2f); <>2__current = (object)new WaitForSeconds(<delay>5__2); <>1__state = 1; return true; } 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 _discoCoroutine; private static int _currentColorIndex; private static List<Color32> _colorList; private static bool _isRunning; public static void Initialize() { _colorList = new List<Color32>(Config.ColorOptions.Values); _currentColorIndex = 0; Config.OnDiscoModeChanged += OnDiscoModeChanged; if (Config.DiscoMode && Config.Enabled) { StartDisco(); } } private static void OnDiscoModeChanged(bool enabled) { if (enabled && Config.Enabled) { StartDisco(); return; } StopDisco(); if (Config.Enabled) { CurfewPatches.RefreshAllBoards(); } } public static void OnModEnabledChanged(bool enabled) { if (enabled && Config.DiscoMode) { StartDisco(); } else { StopDisco(); } } private static void StartDisco() { if (!_isRunning) { _isRunning = true; _discoCoroutine = MelonCoroutines.Start(DiscoLoop()); MelonLogger.Msg("Disco mode started!"); } } private static void StopDisco() { if (_isRunning) { _isRunning = false; _discoCoroutine = null; MelonLogger.Msg("Disco mode stopped."); } } [IteratorStateMachine(typeof(<DiscoLoop>d__9))] private static IEnumerator DiscoLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DiscoLoop>d__9(0); } public static void Reset() { _isRunning = false; _discoCoroutine = null; _currentColorIndex = 0; } } } namespace WhatCurfew.Patches { public static class CurfewPatches { private static readonly Dictionary<int, (VMSBoard board, string text, Color color)> _trackedBoards = new Dictionary<int, (VMSBoard, string, Color)>(); private static readonly string[] CurfewMessages = new string[3] { "CURFEW TONIGHT", "CURFEW ACTIVE", "CURFEW SOON" }; private static bool _reflectionInitialized; private static PropertyInfo _cmInstanceProp; private static PropertyInfo _cmIsEnabledProp; private static PropertyInfo _cmIsActiveProp; private static PropertyInfo _cmIsHardProp; private static PropertyInfo _tmInstanceProp; private static PropertyInfo _tmCurrentTimeProp; private static PropertyInfo _tmElapsedDaysProp; private static PropertyInfo _tmIsSleepProp; private static PropertyInfo _lmInstanceProp; private static PropertyInfo _lmTimeSinceLoadedProp; private static void InitReflectionCache() { if (!_reflectionInitialized) { _reflectionInitialized = true; Type typeFromHandle = typeof(CurfewManager); _cmInstanceProp = FindStaticProperty(typeFromHandle, "Instance"); _cmIsEnabledProp = typeFromHandle.GetProperty("IsEnabled"); _cmIsActiveProp = typeFromHandle.GetProperty("IsCurrentlyActive"); _cmIsHardProp = typeFromHandle.GetProperty("IsHardCurfewActive"); Type typeFromHandle2 = typeof(TimeManager); _tmInstanceProp = FindStaticProperty(typeFromHandle2, "Instance"); _tmCurrentTimeProp = typeFromHandle2.GetProperty("CurrentTime"); _tmElapsedDaysProp = typeFromHandle2.GetProperty("ElapsedDays"); _tmIsSleepProp = typeFromHandle2.GetProperty("IsSleepInProgress"); Type typeFromHandle3 = typeof(LoadManager); _lmInstanceProp = FindStaticProperty(typeFromHandle3, "Instance"); _lmTimeSinceLoadedProp = typeFromHandle3.GetProperty("TimeSinceGameLoaded"); } } private static PropertyInfo FindStaticProperty(Type type, string name) { Type type2 = type; while (type2 != null) { PropertyInfo property = type2.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public); if (property != null) { return property; } type2 = type2.BaseType; } return null; } private static CurfewManager GetCurfewManagerInstance() { InitReflectionCache(); object? obj = _cmInstanceProp?.GetValue(null); return (CurfewManager)((obj is CurfewManager) ? obj : null); } private static bool IsTimeInRange(int time, int min, int max) { if (max > min) { return time >= min && time <= max; } return time >= min || time <= max; } private static int GetMinSum(int gameTime) { return gameTime / 100 * 60 + gameTime % 100; } private static float GetTimeSinceLoaded() { try { object obj = _lmInstanceProp?.GetValue(null); if (obj != null && _lmTimeSinceLoadedProp != null) { return (float)_lmTimeSinceLoadedProp.GetValue(obj); } } catch { } return float.MaxValue; } private static void SetBoardsText(CurfewManager instance, string text) { if (instance.VMSBoards == null) { return; } VMSBoard[] vMSBoards = instance.VMSBoards; foreach (VMSBoard val in vMSBoards) { if ((Object)(object)val != (Object)null && (Object)(object)val.Label != (Object)null) { ((TMP_Text)val.Label).text = text; } } } private static void SetBoardsTextAndColor(CurfewManager instance, string text, Color color) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (instance.VMSBoards == null) { return; } VMSBoard[] vMSBoards = instance.VMSBoards; foreach (VMSBoard val in vMSBoards) { if ((Object)(object)val != (Object)null && (Object)(object)val.Label != (Object)null) { ((TMP_Text)val.Label).text = text; ((Graphic)val.Label).color = color; } } } public static void RefreshAllBoards() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) string text; Color32 vMSBoardColor = default(Color32); if (Config.CurfewCustomTime) { text = Config.CustomCurfewTonightText; ((Color32)(ref vMSBoardColor))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); } else { text = Config.VMSBoardMessage; vMSBoardColor = Config.VMSBoardColor; } RefreshAllBoardsWithTextAndColor(text, vMSBoardColor); } public static void RefreshAllBoardsWithColor(Color32 color) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) string text = (Config.CurfewCustomTime ? Config.CustomCurfewTonightText : Config.VMSBoardMessage); RefreshAllBoardsWithTextAndColor(text, color); } private static void RefreshAllBoardsWithTextAndColor(string text, Color32 color) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) CleanupDestroyedBoards(); foreach (KeyValuePair<int, (VMSBoard, string, Color)> trackedBoard in _trackedBoards) { VMSBoard item = trackedBoard.Value.Item1; if ((Object)(object)item != (Object)null && (Object)(object)item.Label != (Object)null) { ((TMP_Text)item.Label).text = text; ((Graphic)item.Label).color = Color32.op_Implicit(color); } } } public static void RestoreAllBoards() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) CleanupDestroyedBoards(); List<(VMSBoard, string, Color)> list = new List<(VMSBoard, string, Color)>(); foreach (KeyValuePair<int, (VMSBoard, string, Color)> trackedBoard in _trackedBoards) { list.Add(trackedBoard.Value); } foreach (var (val, text, color) in list) { if ((Object)(object)val != (Object)null && (Object)(object)val.Label != (Object)null) { ((TMP_Text)val.Label).text = text; ((Graphic)val.Label).color = color; } } } private static void CleanupDestroyedBoards() { List<int> list = new List<int>(); foreach (KeyValuePair<int, (VMSBoard, string, Color)> trackedBoard in _trackedBoards) { if ((Object)(object)trackedBoard.Value.Item1 == (Object)null) { list.Add(trackedBoard.Key); } } foreach (int item in list) { _trackedBoards.Remove(item); } } public static void OnEnabledChanged(bool enabled) { if (enabled) { RefreshAllBoards(); return; } RestoreAllBoards(); RestoreCurfewState(); } public static void OnCurfewModeChanged(bool customTime) { InitReflectionCache(); CurfewManager curfewManagerInstance = GetCurfewManagerInstance(); if ((Object)(object)curfewManagerInstance == (Object)null) { return; } if (customTime) { _cmIsEnabledProp?.SetValue(curfewManagerInstance, true); try { UnityEvent onCurfewEnabled = curfewManagerInstance.onCurfewEnabled; if (onCurfewEnabled != null) { onCurfewEnabled.Invoke(); } } catch { } } else { bool flag = _cmIsActiveProp != null && (bool)_cmIsActiveProp.GetValue(curfewManagerInstance); _cmIsEnabledProp?.SetValue(curfewManagerInstance, false); _cmIsActiveProp?.SetValue(curfewManagerInstance, false); _cmIsHardProp?.SetValue(curfewManagerInstance, false); if (flag) { try { UnityEvent onCurfewEnd = curfewManagerInstance.onCurfewEnd; if (onCurfewEnd != null) { onCurfewEnd.Invoke(); } } catch { } } } RefreshAllBoards(); } private static void RestoreCurfewState() { try { InitReflectionCache(); CurfewManager curfewManagerInstance = GetCurfewManagerInstance(); if ((Object)(object)curfewManagerInstance != (Object)null) { _cmIsEnabledProp?.SetValue(curfewManagerInstance, true); _cmIsActiveProp?.SetValue(curfewManagerInstance, false); _cmIsHardProp?.SetValue(curfewManagerInstance, false); } } catch { } } private static bool IsCurfewMessage(string text) { if (string.IsNullOrEmpty(text)) { return false; } string[] curfewMessages = CurfewMessages; foreach (string value in curfewMessages) { if (text.Contains(value)) { return true; } } return false; } public static bool MinPass_Prefix(CurfewManager __instance) { if (!Config.Enabled) { return true; } if (Config.CurfewCustomTime) { return HandleCustomCurfew(__instance); } try { InitReflectionCache(); _cmIsEnabledProp?.SetValue(__instance, false); _cmIsActiveProp?.SetValue(__instance, false); _cmIsHardProp?.SetValue(__instance, false); } catch { } return false; } private static bool HandleCustomCurfew(CurfewManager __instance) { //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) try { InitReflectionCache(); _cmIsEnabledProp?.SetValue(__instance, true); object obj = _tmInstanceProp?.GetValue(null); if (obj == null) { return false; } int num = (int)_tmCurrentTimeProp.GetValue(obj); int curfewStart = Config.CurfewStart; int curfewEnd = Config.CurfewEnd; int hourBeforeCurfew = Config.HourBeforeCurfew; int warningTime = Config.WarningTime; int hardCurfewStart = Config.HardCurfewStart; bool flag = (bool)(_cmIsActiveProp?.GetValue(__instance) ?? ((object)false)); bool flag2 = (bool)(_cmIsHardProp?.GetValue(__instance) ?? ((object)false)); if (IsTimeInRange(num, hourBeforeCurfew, curfewStart)) { int num2 = GetMinSum(curfewStart) - GetMinSum(num); if (num2 < 0) { num2 += 1440; } SetBoardsText(__instance, $"CURFEW SOON\n{num2} MINS"); } if (num == warningTime) { UnityEvent onCurfewWarning = __instance.onCurfewWarning; if (onCurfewWarning != null) { onCurfewWarning.Invoke(); } if ((int)(_tmElapsedDaysProp?.GetValue(obj) ?? ((object)1)) == 0) { UnityEvent onCurfewHint = __instance.onCurfewHint; if (onCurfewHint != null) { onCurfewHint.Invoke(); } } __instance.CurfewWarningSound.Play(); } if (!flag && IsTimeInRange(num, curfewStart, curfewEnd)) { _cmIsActiveProp?.SetValue(__instance, true); UnityEvent onCurfewStart = __instance.onCurfewStart; if (onCurfewStart != null) { onCurfewStart.Invoke(); } bool flag3 = (bool)(_tmIsSleepProp?.GetValue(obj) ?? ((object)false)); float timeSinceLoaded = GetTimeSinceLoaded(); if (!flag3 && timeSinceLoaded > 3f && !__instance.CurfewAlarmSound.isPlaying) { __instance.CurfewAlarmSound.Play(); } SetBoardsTextAndColor(__instance, Config.CustomCurfewActiveText, Color32.op_Implicit(new Color32(byte.MaxValue, (byte)85, (byte)60, byte.MaxValue))); } if (!flag2 && IsTimeInRange(num, hardCurfewStart, curfewEnd)) { _cmIsHardProp?.SetValue(__instance, true); UnityEvent onCurfewHardStart = __instance.onCurfewHardStart; if (onCurfewHardStart != null) { onCurfewHardStart.Invoke(); } } if (flag && IsTimeInRange(num, curfewEnd, curfewStart)) { _cmIsActiveProp?.SetValue(__instance, false); _cmIsHardProp?.SetValue(__instance, false); UnityEvent onCurfewEnd = __instance.onCurfewEnd; if (onCurfewEnd != null) { onCurfewEnd.Invoke(); } SetBoardsText(__instance, Config.CustomCurfewTonightText); } } catch (Exception ex) { MelonLogger.Error("Custom curfew error: " + ex.Message); } return false; } public static bool Enable_Prefix(CurfewManager __instance) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) if (!Config.Enabled) { return true; } try { string text; Color32 vMSBoardColor = default(Color32); if (Config.CurfewCustomTime) { text = Config.CustomCurfewTonightText; ((Color32)(ref vMSBoardColor))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); InitReflectionCache(); _cmIsEnabledProp?.SetValue(__instance, true); UnityEvent onCurfewEnabled = __instance.onCurfewEnabled; if (onCurfewEnabled != null) { onCurfewEnabled.Invoke(); } } else { text = Config.VMSBoardMessage; vMSBoardColor = Config.VMSBoardColor; } if (__instance.VMSBoards != null) { VMSBoard[] vMSBoards = __instance.VMSBoards; foreach (VMSBoard val in vMSBoards) { if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(true); if ((Object)(object)val.Label != (Object)null) { ((TMP_Text)val.Label).text = text; ((Graphic)val.Label).color = Color32.op_Implicit(vMSBoardColor); } int instanceID = ((Object)val).GetInstanceID(); _trackedBoards[instanceID] = (val, "CURFEW TONIGHT\n9PM - 5AM", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue))); } } } } catch { } return false; } public static bool IsCurrentlyActive_Prefix(ref bool __result) { if (!Config.Enabled) { return true; } __result = false; return false; } public static bool IsHardCurfewActive_Prefix(ref bool __result) { if (!Config.Enabled) { return true; } __result = false; return false; } public static bool IsEnabled_Prefix(ref bool __result) { if (!Config.Enabled) { return true; } __result = false; return false; } public static void VMSBoard_SetText_Prefix(VMSBoard __instance, ref string text, ref Color col) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (!IsCurfewMessage(text)) { return; } int instanceID = ((Object)__instance).GetInstanceID(); _trackedBoards[instanceID] = (__instance, text, col); if (Config.Enabled) { if (Config.CurfewCustomTime) { text = Config.CustomCurfewTonightText; return; } text = Config.VMSBoardMessage; col = Color32.op_Implicit(Config.VMSBoardColor); } } public static bool VMSBoard_SetText_StringOnly_Prefix(VMSBoard __instance, ref string text) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (IsCurfewMessage(text)) { int instanceID = ((Object)__instance).GetInstanceID(); Color32 val = default(Color32); ((Color32)(ref val))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); _trackedBoards[instanceID] = (__instance, text, Color32.op_Implicit(val)); if (!Config.Enabled) { return true; } string text2; Color32 vMSBoardColor = default(Color32); if (Config.CurfewCustomTime) { text2 = Config.CustomCurfewTonightText; ((Color32)(ref vMSBoardColor))..ctor(byte.MaxValue, (byte)215, (byte)50, byte.MaxValue); } else { text2 = Config.VMSBoardMessage; vMSBoardColor = Config.VMSBoardColor; } if ((Object)(object)__instance.Label != (Object)null) { ((TMP_Text)__instance.Label).text = text2; ((Graphic)__instance.Label).color = Color32.op_Implicit(vMSBoardColor); } return false; } return true; } } public static class HUDPatches { private static bool _reflectionInitialized; private static PropertyInfo _cmInstanceExistsProp; private static PropertyInfo _cmInstanceProp; private static PropertyInfo _cmIsActiveProp; private static PropertyInfo _cmIsEnabledProp; private static PropertyInfo _tmInstanceProp; private static PropertyInfo _tmCurrentTimeProp; private static void InitReflectionCache() { if (!_reflectionInitialized) { _reflectionInitialized = true; Type typeFromHandle = typeof(CurfewManager); _cmInstanceExistsProp = FindStaticProperty(typeFromHandle, "InstanceExists"); _cmInstanceProp = FindStaticProperty(typeFromHandle, "Instance"); _cmIsActiveProp = typeFromHandle.GetProperty("IsCurrentlyActive"); _cmIsEnabledProp = typeFromHandle.GetProperty("IsEnabled"); Type typeFromHandle2 = typeof(TimeManager); _tmInstanceProp = FindStaticProperty(typeFromHandle2, "Instance"); _tmCurrentTimeProp = typeFromHandle2.GetProperty("CurrentTime"); } } private static PropertyInfo FindStaticProperty(Type type, string name) { Type type2 = type; while (type2 != null) { PropertyInfo property = type2.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public); if (property != null) { return property; } type2 = type2.BaseType; } return null; } public static void Update_Postfix(HUD __instance) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) if (!Config.Enabled || !Config.CurfewCustomTime || (Object)(object)__instance.CurfewPrompt == (Object)null || !((Component)__instance.CurfewPrompt).gameObject.activeSelf) { return; } try { InitReflectionCache(); object obj = _cmInstanceProp?.GetValue(null); if (obj == null) { return; } bool flag = (bool)(_cmIsActiveProp?.GetValue(obj) ?? ((object)false)); bool flag2 = (bool)(_cmIsEnabledProp?.GetValue(obj) ?? ((object)false)); if (flag) { ((TMP_Text)__instance.CurfewPrompt).text = "Police curfew in effect until " + Config.FormatGameTimeTo12Hr(Config.CurfewEnd); } else { if (!flag2) { return; } object obj2 = _tmInstanceProp?.GetValue(null); if (obj2 != null) { int time = (int)_tmCurrentTimeProp.GetValue(obj2); if (IsTimeInRange(time, Config.WarningTime, Config.CurfewEnd)) { ((TMP_Text)__instance.CurfewPrompt).text = "Police curfew starting soon"; ((Graphic)__instance.CurfewPrompt).color = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)182, (byte)88, (byte)60)); ((Component)__instance.CurfewPrompt).gameObject.SetActive(true); } else { ((Component)__instance.CurfewPrompt).gameObject.SetActive(false); } } } } catch { } } private static bool IsTimeInRange(int time, int min, int max) { if (max > min) { return time >= min && time <= max; } return time >= min || time <= max; } } } namespace WhatCurfew.Utils { public static class Constants { public static class Game { public const string GAME_STUDIO = "TVGS"; public const string GAME_NAME = "Schedule I"; } public const string MOD_NAME = "WhatCurfew"; public const string MOD_VERSION = "1.2.0"; public const string MOD_AUTHOR = "HazDS"; public const string MOD_DESCRIPTION = "Disable or customize curfew times in Schedule I."; public const string PREFERENCES_CATEGORY = "WhatCurfew"; } }