Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of OTC046PhoneFix v1.0.4
Mods\OTC046PhoneFix.dll
Decompiled a day agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne.UI; using Il2CppScheduleOne.UI.Phone.ContactsApp; using Il2CppScheduleOne.UI.Relations; using MelonLoader; using Microsoft.CodeAnalysis; using OTC046PhoneFix; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(PhoneFixMod), "OTC046PhoneFix", "1.0.4", "hotfix", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonOptionalDependencies(new string[] { "OverTheCounter" })] [assembly: HarmonyDontPatchAll] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("OTC046PhoneFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.4.0")] [assembly: AssemblyInformationalVersion("1.0.4")] [assembly: AssemblyProduct("OTC046PhoneFix")] [assembly: AssemblyTitle("OTC046PhoneFix")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace OTC046PhoneFix { public class PhoneFixMod : MelonMod { private static bool _otcUnpatched; public override void OnInitializeMelon() { try { PatchContactsAppStart(); PatchContactsAppSetOpen(); ((MelonBase)this).LoggerInstance.Msg("OTC046PhoneFix v1.0.4 initialized — monitoring and patch hooks active."); } catch (Exception value) { ((MelonBase)this).LoggerInstance.Error($"Failed to initialize: {value}"); } } public override void OnLateInitializeMelon() { UnpatchBrokenOTCPrefix("OnLateInitializeMelon"); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { UnpatchBrokenOTCPrefix("OnSceneWasLoaded(" + sceneName + ")"); } public static void UnpatchBrokenOTCPrefix(string source) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) try { MethodInfo methodInfo = AccessTools.Method(typeof(ContactsApp), "SetOpen", (Type[])null, (Type[])null); if (methodInfo == null) { return; } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo); if (patchInfo == null) { return; } int num = 0; foreach (Patch prefix in patchInfo.Prefixes) { if (prefix.PatchMethod != null && prefix.PatchMethod.Name.Equals("SetOpen_EnsureExitListener", StringComparison.Ordinal)) { new Harmony("OTC046PhoneFix").Unpatch((MethodBase)methodInfo, prefix.PatchMethod); LogSafe($"[{source}] UNPATCHED obsolete OTC prefix: {prefix.PatchMethod.DeclaringType?.FullName}.{prefix.PatchMethod.Name} (owner={prefix.owner})"); num++; } } if (num > 0) { _otcUnpatched = true; LogPatchStatusAfterUnpatch(methodInfo, source); } else if (!_otcUnpatched) { LogSafe("[" + source + "] Re-checked SetOpen patches: SetOpen_EnsureExitListener prefix not present."); } } catch (Exception ex) { LogSafe("[" + source + "] UnpatchBrokenOTCPrefix error: " + ex.Message); } } private static void LogPatchStatusAfterUnpatch(MethodBase method, string source) { try { Patches patchInfo = Harmony.GetPatchInfo(method); if (patchInfo == null) { LogSafe($"[{source}] Patch status on {method.Name}: no patches registered."); return; } LogSafe($"[{source}] Verified patches on {method.DeclaringType?.Name}.{method.Name}:"); bool flag = false; foreach (Patch prefix in patchInfo.Prefixes) { LogSafe($" Prefix: owner={prefix.owner}, priority={prefix.priority}, method={prefix.PatchMethod.Name}"); if (prefix.PatchMethod.Name.Equals("SetOpen_EnsureExitListener", StringComparison.Ordinal)) { flag = true; } } foreach (Patch postfix in patchInfo.Postfixes) { LogSafe($" Postfix: owner={postfix.owner}, priority={postfix.priority}, method={postfix.PatchMethod.Name}"); } foreach (Patch finalizer in patchInfo.Finalizers) { LogSafe($" Finalizer: owner={finalizer.owner}, priority={finalizer.priority}, method={finalizer.PatchMethod.Name}"); } if (!flag) { LogSafe("[" + source + "] CONFIRMED: SetOpen_EnsureExitListener is ABSENT. Unrelated patches & OTC046PhoneFix patches REMAIN INTAC."); } else { LogSafe("[" + source + "] WARNING: SetOpen_EnsureExitListener is STILL PRESENT."); } } catch (Exception ex) { LogSafe("[" + source + "] LogPatchStatusAfterUnpatch error: " + ex.Message); } } private void PatchContactsAppStart() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //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) //IL_006b: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(ContactsApp), "Start", (Type[])null, (Type[])null); if (methodInfo == null) { ((MelonBase)this).LoggerInstance.Warning("ContactsApp.Start not found — Start patch skipped."); return; } HarmonyMethod val = new HarmonyMethod(typeof(PhoneFixMod), "Start_Prefix", (Type[])null) { priority = 0 }; HarmonyMethod val2 = new HarmonyMethod(typeof(PhoneFixMod), "Start_Finalizer", (Type[])null) { priority = 0 }; ((MelonBase)this).HarmonyInstance.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, val2, (HarmonyMethod)null); ((MelonBase)this).LoggerInstance.Msg("Patched ContactsApp.Start (Prefix & Finalizer, Priority.Last)"); LogPatchInfo(methodInfo); } private void PatchContactsAppSetOpen() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //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) //IL_006b: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(ContactsApp), "SetOpen", (Type[])null, (Type[])null); if (methodInfo == null) { ((MelonBase)this).LoggerInstance.Warning("ContactsApp.SetOpen not found — SetOpen patch skipped."); return; } HarmonyMethod val = new HarmonyMethod(typeof(PhoneFixMod), "SetOpen_Prefix", (Type[])null) { priority = 0 }; HarmonyMethod val2 = new HarmonyMethod(typeof(PhoneFixMod), "SetOpen_Finalizer", (Type[])null) { priority = 0 }; ((MelonBase)this).HarmonyInstance.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, val2, (HarmonyMethod)null); ((MelonBase)this).LoggerInstance.Msg("Patched ContactsApp.SetOpen (Prefix & Finalizer, Priority.Last)"); LogPatchInfo(methodInfo); } public static string GetAppState(ContactsApp instance) { if ((Object)(object)instance == (Object)null) { return "instance=null"; } bool value = false; bool value2 = false; bool value3 = false; bool value4 = true; int value5 = -1; int num = 0; try { value = ((App<ContactsApp>)(object)instance).isOpen; } catch { } try { value3 = (Object)(object)((Component)instance).gameObject != (Object)null && ((Component)instance).gameObject.activeSelf; } catch { } try { RectTransform appContainer = ((App<ContactsApp>)(object)instance).appContainer; value4 = (Object)(object)appContainer == (Object)null; if ((Object)(object)appContainer != (Object)null) { value2 = (Object)(object)((Component)appContainer).gameObject != (Object)null && ((Component)appContainer).gameObject.activeSelf; } } catch { } try { Il2CppArrayBase<RelationCircle> componentsInChildren = ((Component)instance).GetComponentsInChildren<RelationCircle>(true); if (componentsInChildren != null) { value5 = componentsInChildren.Length; foreach (RelationCircle item in componentsInChildren) { if ((Object)(object)item != (Object)null && (Object)(object)item.AssignedNPC == (Object)null) { num++; } } } } catch { } return $"isOpen={value}, containerNull={value4}, containerActive={value2}, appActive={value3}, circles={value5}, unassigned={num}"; } private static void Start_Prefix(ContactsApp __instance, ref bool __runOriginal) { try { LogSafe($"[Start_Prefix] ContactsApp.Start CALLED. runOriginal={__runOriginal}. State BEFORE: {GetAppState(__instance)}"); } catch { } } private static Exception Start_Finalizer(ContactsApp __instance, Exception __exception) { try { string appState = GetAppState(__instance); LogSafe("[Start_Finalizer] ContactsApp.Start FINISHED. Exception=" + (__exception?.GetType().Name ?? "none") + ". State AFTER: " + appState); if ((Object)(object)__instance != (Object)null && !((App<ContactsApp>)(object)__instance).isOpen && (Object)(object)((App<ContactsApp>)(object)__instance).appContainer != (Object)null && ((Component)((App<ContactsApp>)(object)__instance).appContainer).gameObject.activeSelf) { ((Component)((App<ContactsApp>)(object)__instance).appContainer).gameObject.SetActive(false); LogSafe("[Start_Finalizer] Post-Start cleanup: Deactivated appContainer because isOpen=false."); } } catch (Exception ex) { LogSafe("[Start_Finalizer] Error: " + ex.Message); } return __exception; } private static void SetOpen_Prefix(ContactsApp __instance, bool open, ref bool __runOriginal) { try { string appState = GetAppState(__instance); LogSafe($"[SetOpen_Prefix] SetOpen(open={open}) CALLED. runOriginal={__runOriginal}. State BEFORE: {appState}"); if (open) { LogSafe("CONTACTS ICON CLICK RECEIVED -> SetOpen(true) INVOKED"); } } catch (Exception ex) { LogSafe("[SetOpen_Prefix] Error: " + ex.Message); } } private static Exception SetOpen_Finalizer(ContactsApp __instance, bool open, Exception __exception) { try { string appState = GetAppState(__instance); LogSafe($"[SetOpen_Finalizer] SetOpen(open={open}) FINISHED. Exception={__exception?.GetType().Name ?? "none"}. State AFTER: {appState}"); if ((Object)(object)__instance != (Object)null) { if (!open) { if (!((App<ContactsApp>)(object)__instance).isOpen && (Object)(object)((App<ContactsApp>)(object)__instance).appContainer != (Object)null && ((Component)((App<ContactsApp>)(object)__instance).appContainer).gameObject.activeSelf) { ((Component)((App<ContactsApp>)(object)__instance).appContainer).gameObject.SetActive(false); LogSafe("[SetOpen_Finalizer] SetOpen(false): Forced appContainer.gameObject.SetActive(false) because isOpen=false but container was active."); } } else if ((Object)(object)((App<ContactsApp>)(object)__instance).appContainer != (Object)null && !((Component)((App<ContactsApp>)(object)__instance).appContainer).gameObject.activeSelf) { ((Component)((App<ContactsApp>)(object)__instance).appContainer).gameObject.SetActive(true); LogSafe("[SetOpen_Finalizer] SetOpen(true): ACTIVATED appContainer because SetOpen(true) requested opening."); } } } catch (Exception ex) { LogSafe("[SetOpen_Finalizer] Error: " + ex.Message); } return __exception; } private static void LogSafe(string message) { try { Melon<PhoneFixMod>.Logger.Msg("[OTC046PhoneFix] " + message); } catch { MelonLogger.Msg("[OTC046PhoneFix] " + message); } } private void LogPatchInfo(MethodBase method) { try { Patches patchInfo = Harmony.GetPatchInfo(method); if (patchInfo == null) { ((MelonBase)this).LoggerInstance.Msg(" Patch info for " + method.Name + ": (none)"); return; } ((MelonBase)this).LoggerInstance.Msg($" Registered patches on {method.DeclaringType?.Name}.{method.Name}:"); foreach (Patch prefix in patchInfo.Prefixes) { ((MelonBase)this).LoggerInstance.Msg($" Prefix: owner={prefix.owner}, priority={prefix.priority}, method={prefix.PatchMethod.Name}"); } foreach (Patch postfix in patchInfo.Postfixes) { ((MelonBase)this).LoggerInstance.Msg($" Postfix: owner={postfix.owner}, priority={postfix.priority}, method={postfix.PatchMethod.Name}"); } foreach (Patch transpiler in patchInfo.Transpilers) { ((MelonBase)this).LoggerInstance.Msg($" Transpiler: owner={transpiler.owner}, priority={transpiler.priority}, method={transpiler.PatchMethod.Name}"); } foreach (Patch finalizer in patchInfo.Finalizers) { ((MelonBase)this).LoggerInstance.Msg($" Finalizer: owner={finalizer.owner}, priority={finalizer.priority}, method={finalizer.PatchMethod.Name}"); } } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning(" Could not read patch info for " + method.Name + ": " + ex.Message); } } } }