Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Vanilla Fix v1.0.6
sch1bugfix.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using HarmonyLib; using MelonLoader; using Microsoft.CodeAnalysis; using SCH1BugFix; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: MelonInfo(typeof(SCH1BugFixMod), "SCH1BugFix", "1.0.6", "Virtunerd", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: AssemblyVersion("0.0.0.0")] [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 SCH1BugFix { public class SCH1BugFixMod : MelonMod { private const string AuthorName = "Virtunerd"; private static readonly Type[] PatchTypes = new Type[11] { typeof(NpcOnDestroyPatch), typeof(EmployeeOnDestroyPatch), typeof(CustomerOnDestroyPatch), typeof(DealerOnDestroyPatch), typeof(WheelOnWeatherChangePatch), typeof(EnvironmentManagerUpdateWeatherEntitiesPatch), typeof(ConfigurationServiceNetworkerOnDestroyPatch), typeof(ContractUpdateTimingPatch), typeof(RectTransformLerpLocalScalePatch), typeof(NpcMovementFaceDirectionProcessMoveNextPatch), typeof(SetupCoroutineInvokeMoveNextPatch) }; private static readonly Dictionary<string, DateTime> LastSuppressedLogUtcByLocation = new Dictionary<string, DateTime>(StringComparer.Ordinal); private static readonly object SuppressedLogLock = new object(); private static Harmony harmony; public override void OnInitializeMelon() { try { harmony = ((MelonBase)this).HarmonyInstance; int value = ApplyPatchesSafely(); MelonLogger.Msg($"[SCH1BugFix] sch1bugfix v{((MelonBase)this).Info.Version} by {"Virtunerd"} initialized. Applied {value}/{PatchTypes.Length} patch classes."); } catch (Exception value2) { MelonLogger.Error($"[SCH1BugFix] Critical init failure: {value2}"); } } internal static Exception SuppressKnownNullRef(Exception exception, string location) { if (exception == null) { return null; } try { if (exception is NullReferenceException) { LogSuppressedOncePerWindow(location, "known game-side NRE"); return null; } string text = exception.GetType().FullName ?? string.Empty; if (text.IndexOf("Il2CppException", StringComparison.OrdinalIgnoreCase) >= 0) { string text2 = exception.Message ?? string.Empty; if (text2.IndexOf("NullReferenceException", StringComparison.OrdinalIgnoreCase) >= 0) { LogSuppressedOncePerWindow(location, "wrapped game-side NRE"); return null; } } } catch { } return exception; } internal static Exception SuppressKnownGameCoroutineExitError(Exception exception) { if (exception == null) { return null; } try { string text = exception.ToString(); if (text.IndexOf("NullReferenceException", StringComparison.OrdinalIgnoreCase) < 0) { return exception; } if (text.IndexOf("FaceDirection_Process", StringComparison.OrdinalIgnoreCase) >= 0) { LogSuppressedOncePerWindow("NPCMovement.FaceDirection_Process.MoveNext", "wrapped game-side NRE (SetupCoroutine fallback)"); return null; } if (text.IndexOf("StartConversate", StringComparison.OrdinalIgnoreCase) >= 0) { LogSuppressedOncePerWindow("NPCEvent_Conversate.StartConversate.MoveNext", "wrapped game-side NRE (SetupCoroutine fallback)"); return null; } if (text.IndexOf("SetSeat", StringComparison.OrdinalIgnoreCase) >= 0) { LogSuppressedOncePerWindow("AvatarAnimation.SetSeat.Lerp.MoveNext", "wrapped game-side NRE (SetupCoroutine fallback)"); return null; } if (text.IndexOf("ScheduleOne.", StringComparison.OrdinalIgnoreCase) >= 0) { LogSuppressedOncePerWindow("ScheduleOne (coroutine)", "wrapped game-side NRE (SetupCoroutine fallback)"); return null; } } catch { } return exception; } private static int ApplyPatchesSafely() { int num = 0; if (harmony == null) { MelonLogger.Error("[SCH1BugFix] Harmony instance not available. No patches were applied."); return num; } for (int i = 0; i < PatchTypes.Length; i++) { Type type = PatchTypes[i]; try { harmony.CreateClassProcessor(type).Patch(); num++; } catch (Exception ex) { MelonLogger.Warning("[SCH1BugFix] Skipping patch " + type.Name + ": " + ex.Message); } } return num; } private static void LogSuppressedOncePerWindow(string location, string reason) { try { DateTime utcNow = DateTime.UtcNow; bool flag = false; lock (SuppressedLogLock) { if (!LastSuppressedLogUtcByLocation.TryGetValue(location, out var value) || (utcNow - value).TotalSeconds >= 5.0) { LastSuppressedLogUtcByLocation[location] = utcNow; flag = true; } } if (flag) { MelonLogger.Warning($"[SCH1BugFix] Suppressed {reason} in {location}."); } } catch { } } internal static MethodBase ResolveMethod(string[] typeNames, string methodName, int parameterCount) { try { for (int i = 0; i < typeNames.Length; i++) { Type type = AccessTools.TypeByName(typeNames[i]); if (!(type == null)) { MethodBase methodBase = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == methodName && m.GetParameters().Length == parameterCount); if (methodBase != null) { return methodBase; } } } } catch (Exception ex) { MelonLogger.Warning("[SCH1BugFix] ResolveMethod error for " + methodName + ": " + ex.Message); } MelonLogger.Warning($"[SCH1BugFix] Target not found: {string.Join(" | ", typeNames)}::{methodName}/{parameterCount}"); return null; } } [HarmonyPatch] internal static class NpcOnDestroyPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.NPCs.NPC", "Il2CppScheduleOne.NPCs.NPC" }, "OnDestroy", 0); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "NPC.OnDestroy"); } } [HarmonyPatch] internal static class EmployeeOnDestroyPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.Employees.Employee", "Il2CppScheduleOne.Employees.Employee" }, "OnDestroy", 0); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "Employee.OnDestroy"); } } [HarmonyPatch] internal static class CustomerOnDestroyPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.Economy.Customer", "Il2CppScheduleOne.Economy.Customer" }, "OnDestroy", 0); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "Customer.OnDestroy"); } } [HarmonyPatch] internal static class DealerOnDestroyPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.Economy.Dealer", "Il2CppScheduleOne.Economy.Dealer" }, "OnDestroy", 0); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "Dealer.OnDestroy"); } } [HarmonyPatch] internal static class WheelOnWeatherChangePatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.Vehicles.Wheel", "Il2CppScheduleOne.Vehicles.Wheel" }, "OnWeatherChange", 1); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "Wheel.OnWeatherChange"); } } [HarmonyPatch] internal static class EnvironmentManagerUpdateWeatherEntitiesPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.Weather.EnvironmentManager", "Il2CppScheduleOne.Weather.EnvironmentManager" }, "UpdateWeatherEntities", 0); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "EnvironmentManager.UpdateWeatherEntities"); } } [HarmonyPatch] internal static class ConfigurationServiceNetworkerOnDestroyPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.Configuration.ConfigurationServiceNetworker", "Il2CppScheduleOne.Configuration.ConfigurationServiceNetworker" }, "OnDestroy", 0); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "ConfigurationServiceNetworker.OnDestroy"); } } [HarmonyPatch] internal static class ContractUpdateTimingPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.Quests.Contract", "Il2CppScheduleOne.Quests.Contract" }, "UpdateTiming", 0); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "Contract.UpdateTiming"); } } [HarmonyPatch] internal static class RectTransformLerpLocalScalePatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = SCH1BugFixMod.ResolveMethod(new string[2] { "ScheduleOne.UI.RectTransformLerp", "Il2CppScheduleOne.UI.RectTransformLerp" }, "LerpLocalScale", 2); return cachedTarget != null; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "RectTransformLerp.LerpLocalScale"); } } [HarmonyPatch] internal static class NpcMovementFaceDirectionProcessMoveNextPatch { private static MethodBase cachedTarget; private static bool Prepare() { cachedTarget = FindTarget(); if (cachedTarget == null) { MelonLogger.Warning("[SCH1BugFix] NPCMovement FaceDirection iterator target not found. Skipping this optional patch."); return false; } return true; } private static MethodBase TargetMethod() { return cachedTarget; } private static MethodBase FindTarget() { string[] array = new string[2] { "ScheduleOne.NPCs.NPCMovement", "Il2CppScheduleOne.NPCs.NPCMovement" }; try { for (int i = 0; i < array.Length; i++) { Type type = AccessTools.TypeByName(array[i]); if (type == null) { continue; } Type[] array2; try { array2 = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic); } catch (ReflectionTypeLoadException ex) { array2 = ex.Types; } if (array2 == null) { continue; } foreach (Type type2 in array2) { if (!(type2 == null) && type2.Name.StartsWith("<FaceDirection_Process>d__", StringComparison.Ordinal)) { MethodInfo method = type2.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { return method; } } } } } catch (Exception ex2) { MelonLogger.Warning("[SCH1BugFix] FindTarget error: " + ex2.Message); } return null; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownNullRef(__exception, "NPCMovement.FaceDirection_Process.MoveNext"); } } [HarmonyPatch] internal static class SetupCoroutineInvokeMoveNextPatch { private static MethodBase cachedTarget; private static bool Prepare() { try { cachedTarget = AccessTools.Method("UnityEngine.SetupCoroutine:InvokeMoveNext", (Type[])null, (Type[])null); } catch (Exception ex) { MelonLogger.Warning("[SCH1BugFix] SetupCoroutine target resolution error: " + ex.Message); } if (cachedTarget == null) { MelonLogger.Warning("[SCH1BugFix] SetupCoroutine.InvokeMoveNext not found. Skipping fallback patch."); return false; } return true; } private static MethodBase TargetMethod() { return cachedTarget; } [HarmonyFinalizer] [HarmonyWrapSafe] [HarmonyPriority(0)] private static Exception Finalizer(Exception __exception) { return SCH1BugFixMod.SuppressKnownGameCoroutineExitError(__exception); } } }