using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Portningsbolaget.Platforms;
using UnityEngine;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
[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 PeakScrollFix
{
[BepInPlugin("com.dsh.peakscrollfix", "PEAK Guidebook Scroll Fix", "1.1.0")]
public class PeakScrollFixPlugin : BaseUnityPlugin
{
internal static ConfigEntry<bool> EnableGuard;
internal static ConfigEntry<bool> Verbose;
private void Awake()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Expected O, but got Unknown
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Expected O, but got Unknown
EnableGuard = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableGuard", true, "Keep the game's AchievementManager singleton (and its guidebook page data) alive while playing. Recommended on.");
Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "VerboseLogging", false, "Log every page-validation fallback and every direct page recording.");
GameObject val = new GameObject("PeakScrollFix_Guard");
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<AchievementManagerGuard>();
Harmony val2 = new Harmony("com.dsh.peakscrollfix");
int num = 0;
MethodInfo methodInfo = AccessTools.Method(typeof(Guidebook), "GuidebookPageValid", (Type[])null, (Type[])null);
if (methodInfo != null)
{
val2.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Patches), "GuidebookPageValidPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
num++;
}
MethodInfo methodInfo2 = AccessTools.Method(typeof(AchievementManager), "TriggerSeenGuidebookPage", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
val2.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Patches), "TriggerSeenGuidebookPagePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
num++;
}
MethodInfo methodInfo3 = AccessTools.Method(typeof(GuidebookPageCollection), "TryPickPageToSpawn", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
val2.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "TryPickPageToSpawnPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
num++;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[PeakScrollFix] v1.1.0 loaded. Guard active, {num}/3 concrete patches applied (no generic patching).");
}
}
internal static class ScrollFixCore
{
private const string TotalPagesReadStat = "TotalPagesRead";
internal static void Log(string message)
{
if (PeakScrollFixPlugin.Verbose != null && PeakScrollFixPlugin.Verbose.Value)
{
Debug.Log((object)("[PeakScrollFix] " + message));
}
}
internal static bool TryReadSeenPages(out int seen)
{
seen = 0;
IPlatform platform = PlatformManager.Platform;
if (platform == null || !platform.Initialized)
{
return false;
}
return platform.GetStat("TotalPagesRead", ref seen);
}
internal static bool TryHeal(AchievementManager manager)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)manager == (Object)null || manager.guidebookData != null)
{
return (Object)(object)manager != (Object)null;
}
if (!TryReadSeenPages(out var seen))
{
return false;
}
manager.guidebookData = new GuidebookData();
manager.guidebookData.seenGuidebookPages = (GUIDEBOOKPAGEFLAGS)seen;
Log($"healed guidebookData from TotalPagesRead={seen}");
UnlockBookwormIfEarned(seen);
return true;
}
internal static void RecordPageDirectly(GUIDEBOOKPAGEFLAGS flag, string reason)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: 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_002b: Expected I4, but got Unknown
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
if ((int)flag == 0)
{
return;
}
IPlatform platform = PlatformManager.Platform;
if (platform != null && platform.Initialized)
{
int num = default(int);
if (!platform.GetStat("TotalPagesRead", ref num))
{
num = 0;
}
int num2 = num | flag;
if (num2 != num)
{
platform.SetStat("TotalPagesRead", num2);
platform.StoreStats();
}
UnlockBookwormIfEarned(num2);
Debug.Log((object)$"[PeakScrollFix] recorded page {flag} directly ({reason}); TotalPagesRead {num} -> {num2}");
}
}
private static void UnlockBookwormIfEarned(int seenFlags)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
if ((seenFlags & 0x80) == 0)
{
return;
}
IPlatform platform = PlatformManager.Platform;
if (platform == null || !platform.Initialized)
{
return;
}
try
{
platform.UnlockAchievement(((object)(ACHIEVEMENTTYPE)31/*cast due to .constrained prefix*/).ToString());
}
catch
{
}
}
internal static int CountFlags(int seenFlags)
{
int num = 0;
for (int num2 = 1; num2 <= 262144; num2 <<= 1)
{
if ((seenFlags & num2) != 0)
{
num++;
}
}
return num;
}
}
public class AchievementManagerGuard : MonoBehaviour
{
private static AchievementManager s_fallback;
private void Update()
{
if (PeakScrollFixPlugin.EnableGuard != null && !PeakScrollFixPlugin.EnableGuard.Value)
{
return;
}
AchievementManager instance = Singleton<AchievementManager>.Instance;
if ((Object)(object)instance != (Object)null)
{
if (instance.guidebookData == null)
{
ScrollFixCore.TryHeal(instance);
}
}
else if (Time.frameCount % 5 == 0 && !((Object)(object)GameHandler.Instance == (Object)null) && GameHandler.IsInGameplayScene)
{
Ensure();
}
}
private static void Ensure()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
if ((Object)(object)s_fallback != (Object)null)
{
ScrollFixCore.TryHeal(s_fallback);
return;
}
AchievementManager val = Object.FindAnyObjectByType<AchievementManager>();
if ((Object)(object)val != (Object)null)
{
ScrollFixCore.TryHeal(val);
s_fallback = val;
return;
}
GameObject val2 = new GameObject("PeakScrollFix_AchievementManager");
Object.DontDestroyOnLoad((Object)(object)val2);
AchievementManager val3 = val2.AddComponent<AchievementManager>();
if ((Object)(object)val3 == (Object)null)
{
Object.Destroy((Object)(object)val2);
AchievementManager val4 = Object.FindAnyObjectByType<AchievementManager>();
if ((Object)(object)val4 != (Object)null)
{
ScrollFixCore.TryHeal(val4);
s_fallback = val4;
}
}
else
{
ScrollFixCore.TryHeal(val3);
val3.InitRunBasedValues();
s_fallback = val3;
Debug.Log((object)"[PeakScrollFix] AchievementManager singleton was missing; created a persistent replacement so guidebook scrolls keep working.");
}
}
}
internal static class Patches
{
internal static bool GuidebookPageValidPrefix(Guidebook __instance, Vector3 position, ref bool __result)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
AchievementManager instance = Singleton<AchievementManager>.Instance;
if ((Object)(object)instance != (Object)null)
{
if (instance.guidebookData != null)
{
return true;
}
if (ScrollFixCore.TryHeal(instance))
{
return true;
}
}
__result = ValidateWithoutManager(__instance, position);
return false;
}
private static bool ValidateWithoutManager(Guidebook page, Vector3 position)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: 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_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)page == (Object)null || !page.isSinglePage)
{
return false;
}
if (!ScrollFixCore.TryReadSeenPages(out var seen))
{
return false;
}
GUIDEBOOKPAGEFLAGS val = (GUIDEBOOKPAGEFLAGS)seen;
if ((int)page.requiredSeenPagesToSpawn != 0)
{
foreach (GUIDEBOOKPAGEFLAGS value in Enum.GetValues(typeof(GUIDEBOOKPAGEFLAGS)))
{
if ((int)value != 0 && ((Enum)page.requiredSeenPagesToSpawn).HasFlag((Enum)(object)value) && !((Enum)val).HasFlag((Enum)(object)value))
{
return false;
}
}
}
if (page.requiredSeenPagesCountToSpawn > 0 && ScrollFixCore.CountFlags(seen) < page.requiredSeenPagesCountToSpawn)
{
return false;
}
if (page.minimumSegment > 0 && Object.op_Implicit((Object)(object)Singleton<MapHandler>.Instance) && Campfire.GetClosestCampfireNextSegment(position) < page.minimumSegment)
{
return false;
}
if (page.requireBiomeType && Campfire.GetClosestCampfireNextBiome(position) != page.requiredBiome)
{
return false;
}
if (page.minSpawnHeight > 0f && position.y < page.minSpawnHeight)
{
return false;
}
Debug.Log((object)$"[PeakScrollFix] Page{((Object)((Component)page).gameObject).name} validated without AchievementManager (seen={val}); scroll will still produce a page.");
return true;
}
internal static bool TriggerSeenGuidebookPagePrefix(AchievementManager __instance, GUIDEBOOKPAGEFLAGS flag)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null)
{
ScrollFixCore.RecordPageDirectly(flag, "no AchievementManager instance");
return false;
}
if (__instance.guidebookData == null && !ScrollFixCore.TryHeal(__instance))
{
ScrollFixCore.RecordPageDirectly(flag, "guidebookData unavailable");
return false;
}
return true;
}
internal static void TryPickPageToSpawnPostfix(bool __result, ref GameObject result)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (!__result || (Object)(object)result == (Object)null)
{
return;
}
AchievementManager instance = Singleton<AchievementManager>.Instance;
if (!((Object)(object)instance != (Object)null) || instance.guidebookData == null)
{
Guidebook component = result.GetComponent<Guidebook>();
if (!((Object)(object)component == (Object)null))
{
ScrollFixCore.RecordPageDirectly(component.pageFlag, "manager unavailable at pick time");
}
}
}
}
}