using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SeasonalityFix")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SeasonalityFix")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("50a8abcb-8785-4f05-ba56-a165eadf8d97")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("h4nz0.seasonalityfix", "Seasonality Fix", "1.0.0")] public class SeasonalityFix : BaseUnityPlugin { [HarmonyPatch] private static class Seasonality_SetNextSeason_DebugPatch { private static MethodBase TargetMethod() { return Type.GetType("Seasonality.SeasonalTimer, Seasonality")?.GetMethod("SetNextSeason", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } private static void Prefix() { if (DiagnosticLoggingEnabled && LogSource != null) { ManualLogSource logSource = LogSource; if (logSource != null) { logSource.LogWarning((object)"[SeasonFix DEBUG] Seasonality.SetNextSeason() meghívva."); } ManualLogSource logSource2 = LogSource; if (logSource2 != null) { logSource2.LogWarning((object)("[SeasonFix DEBUG] STACK:\n" + new StackTrace(fNeedFileInfo: true))); } } } private static void Postfix() { if (DiagnosticLoggingEnabled && LogSource != null) { ManualLogSource logSource = LogSource; if (logSource != null) { logSource.LogWarning((object)"[SeasonFix DEBUG] Seasonality.SetNextSeason() lefutott."); } } } } [HarmonyPatch] private static class Seasonality_ScheduleNextSeason_DebugPatch { private static MethodBase TargetMethod() { return Type.GetType("Seasonality.SeasonalTimer, Seasonality")?.GetMethod("ScheduleNextSeason", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } private static void Prefix() { if (DiagnosticLoggingEnabled && LogSource != null) { ManualLogSource logSource = LogSource; if (logSource != null) { logSource.LogWarning((object)"[SeasonFix DEBUG] Seasonality.ScheduleNextSeason() meghívva."); } ManualLogSource logSource2 = LogSource; if (logSource2 != null) { logSource2.LogWarning((object)("[SeasonFix DEBUG] STACK:\n" + new StackTrace(fNeedFileInfo: true))); } } } } [HarmonyPatch] private static class Seasonality_ChangeSeason_DebugPatch { private static MethodBase TargetMethod() { return Type.GetType("Seasonality.SeasonalTimer, Seasonality")?.GetMethod("ChangeSeason", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } private static void Prefix() { if (DiagnosticLoggingEnabled && LogSource != null) { ManualLogSource logSource = LogSource; if (logSource != null) { logSource.LogWarning((object)"[SeasonFix DEBUG] Seasonality.ChangeSeason() meghívva."); } ManualLogSource logSource2 = LogSource; if (logSource2 != null) { logSource2.LogWarning((object)("[SeasonFix DEBUG] STACK:\n" + new StackTrace(fNeedFileInfo: true))); } } } private static void Postfix() { if (DiagnosticLoggingEnabled && LogSource != null) { ManualLogSource logSource = LogSource; if (logSource != null) { logSource.LogWarning((object)"[SeasonFix DEBUG] Seasonality.ChangeSeason() lefutott."); } } } } private const string ModGuid = "h4nz0.seasonalityfix"; private const string ModName = "Seasonality Fix"; private const string ModVersion = "1.0.0"; private ConfigEntry _enabled; private ConfigEntry _checkInterval; private ConfigEntry _clearSleepOverrideWhenDue; private ConfigEntry _verbose; private ConfigEntry _diagnosticLogging; private Harmony _harmony; internal static ManualLogSource LogSource; internal static bool DiagnosticLoggingEnabled; private float _nextCheck; private float _lastForcedFixTime = -9999f; private Type _seasonalTimerType; private FieldInfo _instanceField; private FieldInfo _sleepOverrideField; private FieldInfo _lastSeasonChangeField; private MethodInfo _getSeasonLengthMethod; private MethodInfo _getTimeDifferenceMethod; private MethodInfo _scheduleNextSeasonMethod; private MethodInfo _broadcastLastSeasonChangeMethod; private MethodInfo _setNextSeasonMethod; private void Awake() { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown _enabled = ((BaseUnityPlugin)this).Config.Bind("Általános", "Engedélyezve", true, "Bekapcsolja az évszak beragadás javítását."); _checkInterval = ((BaseUnityPlugin)this).Config.Bind("Általános", "Ellenőrzési idő (másodperc)", 60f, "Milyen gyakran ellenőrizze a mod az évszak állapotát."); _clearSleepOverrideWhenDue = ((BaseUnityPlugin)this).Config.Bind("Javítás", "Sleep override törlése", true, "Ha az évszak lejárt, törölje a sleep override állapotot, ha be van ragadva."); _verbose = ((BaseUnityPlugin)this).Config.Bind("Debug", "Részletes naplózás", false, "Részletes debug logok kiírása a konzolba."); _diagnosticLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "Brutál diagnosztikai naplózás", false, "Bekapcsolja a Harmony patch alapú részletes Seasonality diagnosztikát és stack trace logokat. Csak hibakereséshez ajánlott."); DiagnosticLoggingEnabled = _diagnosticLogging.Value; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Seasonality Fix 1.0.0 betöltve."); LogSource = ((BaseUnityPlugin)this).Logger; if (_diagnosticLogging.Value) { _harmony = new Harmony("h4nz0.seasonalityfix"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogWarning((object)"[SeasonFix DEBUG] Brutál diagnosztikai logolás bekapcsolva."); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[SeasonFix] Brutál diagnosztikai logolás kikapcsolva."); } } private void Update() { if (!_enabled.Value || Time.time < _nextCheck) { return; } _nextCheck = Time.time + Mathf.Max(60f, _checkInterval.Value); try { WatchdogTick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[SeasonFix] Watchdog hiba: " + ex)); } } private void WatchdogTick() { if (Time.timeSinceLevelLoad < 180f || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } if (ZNet.instance.GetNrOfPlayers() <= 0) { Log("Nincs játékos a szerveren, ellenőrzés kihagyva."); return; } if (!ResolveSeasonality()) { Log("Seasonality még nem található."); return; } object obj = _instanceField?.GetValue(null); if (obj == null) { Log("SeasonalTimer.instance null."); return; } double num = InvokeDouble(_getSeasonLengthMethod); double num2 = InvokeDouble(_getTimeDifferenceMethod); Log($"SeasonLength={num}, TimeDifference={num2}"); if (num <= 0.0) { Log("Az évszak hossza 0 vagy kisebb, ellenőrzés kihagyva."); return; } MonoBehaviour val = (MonoBehaviour)((obj is MonoBehaviour) ? obj : null); if ((Object)(object)val == (Object)null) { Log("A SeasonalTimer nem MonoBehaviour."); return; } DiagnosticLog($"Tick | seasonLength={num} | diff={num2} | " + $"players={(((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetNrOfPlayers() : (-1))} | " + $"time={Time.time:0.00} | levelTime={Time.timeSinceLevelLoad:0.00} | " + $"lastFix={_lastForcedFixTime:0.00}"); if (num2 > 0.0) { return; } double num3 = Math.Max(30.0, num * 0.25); DiagnosticLog("FIX TRIGGER STACK:\n" + new StackTrace(fNeedFileInfo: true)); if ((double)(Time.time - _lastForcedFixTime) < num3) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"[SeasonFix] A javítás kihagyva, mert nemrég már történt kényszerített váltás. Cooldown: {num3:0} mp."); return; } _lastForcedFixTime = Time.time; ((BaseUnityPlugin)this).Logger.LogWarning((object)"[SeasonFix] Beragadt évszak detektálva. Évszakváltás + időzítő újraindítás indul."); if (_clearSleepOverrideWhenDue.Value && _sleepOverrideField != null) { _sleepOverrideField.SetValue(null, false); Log("Sleep override állapot törölve."); } val.CancelInvoke("ChangeSeason"); _setNextSeasonMethod.Invoke(null, null); _broadcastLastSeasonChangeMethod?.Invoke(null, null); _scheduleNextSeasonMethod.Invoke(obj, null); ((BaseUnityPlugin)this).Logger.LogWarning((object)"[SeasonFix] Évszakváltás kész, régi ChangeSeason invoke törölve, új időzítő beállítva."); } private bool ResolveSeasonality() { if (_seasonalTimerType != null) { return true; } _seasonalTimerType = Type.GetType("Seasonality.SeasonalTimer, Seasonality"); if (_seasonalTimerType == null) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { _seasonalTimerType = assembly.GetType("Seasonality.SeasonalTimer"); if (_seasonalTimerType != null) { break; } } } if (_seasonalTimerType == null) { return false; } BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; BindingFlags bindingAttr2 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; _instanceField = _seasonalTimerType.GetField("instance", bindingAttr); _sleepOverrideField = _seasonalTimerType.GetField("m_sleepOverride", bindingAttr); _lastSeasonChangeField = _seasonalTimerType.GetField("lastSeasonChange", bindingAttr); _getSeasonLengthMethod = _seasonalTimerType.GetMethod("GetSeasonLength", bindingAttr); _getTimeDifferenceMethod = _seasonalTimerType.GetMethod("GetTimeDifference", bindingAttr); _scheduleNextSeasonMethod = _seasonalTimerType.GetMethod("ScheduleNextSeason", bindingAttr2); _broadcastLastSeasonChangeMethod = _seasonalTimerType.GetMethod("BroadcastLastSeasonChange", bindingAttr); _setNextSeasonMethod = _seasonalTimerType.GetMethod("SetNextSeason", bindingAttr); bool flag = _instanceField != null && _sleepOverrideField != null && _lastSeasonChangeField != null && _getSeasonLengthMethod != null && _getTimeDifferenceMethod != null && _setNextSeasonMethod != null && _scheduleNextSeasonMethod != null; if (flag) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[SeasonFix] Seasonality reflection sikeresen betöltve."); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"[SeasonFix] Nem sikerült a szükséges Seasonality elemeket elérni."); } return flag; } private double InvokeDouble(MethodInfo method) { if (method == null) { return -1.0; } object obj = method.Invoke(null, null); if (obj == null) { return -1.0; } return Convert.ToDouble(obj); } private void Log(string msg) { if (_verbose.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[SeasonFix] " + msg)); } } private void DiagnosticLog(string msg) { if (_diagnosticLogging.Value) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[SeasonFix DEBUG] " + msg)); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } }