using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("CollectableWaypoints")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CollectableWaypoints")] [assembly: AssemblyTitle("CollectableWaypoints")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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; } } } public static class BearWaypointPatches { private static readonly List bearPings = new List(); private static readonly string[] BearNameTokens = new string[8] { "Bear", "bear", "Teddy", "teddy", "Bruce", "bruce", "Bruiser", "bruiser" }; public static void Initialize() { try { SceneManager.sceneLoaded += OnSceneLoaded; } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error initializing BearWaypointPatches: " + ex.Message)); } } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { try { bearPings.Clear(); ApplyConfig(); } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error in OnSceneLoaded for bears: " + ex.Message)); } } public static void ApplyConfig() { try { if (!CollectableWaypointsPlugin.bearWaypoints.Value || LevelData.IsHub) { ClearAllPings(); } else { if ((Object)(object)Highlighter.Instance == (Object)null) { return; } GameObject[] array = (from go in Object.FindObjectsOfType() where (Object)(object)go != (Object)null && BearNameTokens.Any((string n) => ((Object)go).name.Contains(n)) select go).ToArray(); foreach (GameObject val in array) { if (!bearPings.Contains(val.transform)) { Highlighter.Instance.AddWaypointPing(val.transform); bearPings.Add(val.transform); } } } } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error applying bear waypoint config: " + ex.Message)); } } private static void ClearAllPings() { foreach (Transform bearPing in bearPings) { if ((Object)(object)bearPing != (Object)null) { Highlighter instance = Highlighter.Instance; if (instance != null) { instance.RemovePing(bearPing); } } } bearPings.Clear(); } } public static class DataLogWaypointPatches { private static Dictionary datalogPings = new Dictionary(); private static FieldInfo logIDField; public static void Initialize(Harmony harmony) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown try { SceneManager.sceneLoaded += OnSceneLoaded; logIDField = typeof(TextLogInteractable).GetField("logID", BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo method = typeof(PlayerData).GetMethod("OnDataLogOpened", BindingFlags.Instance | BindingFlags.Public); MethodInfo method2 = typeof(DataLogWaypointPatches).GetMethod("PlayerDataOnDataLogOpened_Postfix", BindingFlags.Static | BindingFlags.Public); if (method != null && method2 != null) { harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error initializing DataLogWaypointPatches: " + ex.Message)); } } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown try { Harmony val = new Harmony("sparroh.collectablewaypoints"); MethodInfo method = typeof(TextLogWindow).GetMethod("Setup", new Type[1] { typeof(string) }); MethodInfo method2 = typeof(ImageLogWindow).GetMethod("Setup", new Type[1] { typeof(string) }); MethodInfo method3 = typeof(DataLogWaypointPatches).GetMethod("TextLogWindowSetup_Postfix", BindingFlags.Static | BindingFlags.Public); MethodInfo method4 = typeof(DataLogWaypointPatches).GetMethod("ImageLogWindowSetup_Postfix", BindingFlags.Static | BindingFlags.Public); if (method != null && method2 != null && method3 != null && method4 != null) { val.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)method2, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } datalogPings.Clear(); ApplyConfig(); } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error in OnSceneLoaded: " + ex.Message)); } } public static void ApplyConfig() { try { if (!CollectableWaypointsPlugin.dataLogWaypoints.Value) { ClearAllPings(); } else { if (logIDField == null || (Object)(object)Highlighter.Instance == (Object)null) { return; } TextLogInteractable[] array = Object.FindObjectsOfType(); foreach (TextLogInteractable val in array) { if (!((Object)(object)val == (Object)null) && logIDField.GetValue(val) is string text && !datalogPings.ContainsKey(text) && PlayerData.Instance != null && PlayerData.Instance.discoveredDataLogs != null && !PlayerData.Instance.discoveredDataLogs.Contains(text)) { Highlighter.Instance.AddWaypointPing(((Component)val).transform); datalogPings[text] = ((Component)val).transform; } } } } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error applying data log waypoint config: " + ex.Message)); } } private static void ClearAllPings() { foreach (KeyValuePair datalogPing in datalogPings) { if ((Object)(object)datalogPing.Value != (Object)null) { Highlighter instance = Highlighter.Instance; if (instance != null) { instance.RemovePing(datalogPing.Value); } } } datalogPings.Clear(); } public static void TextLogWindowSetup_Postfix(string id) { try { if (CollectableWaypointsPlugin.dataLogWaypoints.Value && datalogPings.TryGetValue(id, out var value)) { Highlighter instance = Highlighter.Instance; if (instance != null) { instance.RemovePing(value); } datalogPings.Remove(id); } } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error in TextLogWindowSetup_Postfix: " + ex.Message)); } } public static void ImageLogWindowSetup_Postfix(string id) { try { if (CollectableWaypointsPlugin.dataLogWaypoints.Value && datalogPings.TryGetValue(id, out var value)) { Highlighter instance = Highlighter.Instance; if (instance != null) { instance.RemovePing(value); } datalogPings.Remove(id); } } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error in ImageLogWindowSetup_Postfix: " + ex.Message)); } } public static void PlayerDataOnDataLogOpened_Postfix(string id) { try { if (CollectableWaypointsPlugin.dataLogWaypoints.Value && datalogPings.TryGetValue(id, out var value)) { Highlighter instance = Highlighter.Instance; if (instance != null) { instance.RemovePing(value); } datalogPings.Remove(id); } } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error in PlayerDataOnDataLogOpened_Postfix: " + ex.Message)); } } } [BepInPlugin("sparroh.collectablewaypoints", "CollectableWaypoints", "1.0.1")] [MycoMod(/*Could not decode attribute arguments.*/)] public class CollectableWaypointsPlugin : BaseUnityPlugin { public const string PluginGUID = "sparroh.collectablewaypoints"; public const string PluginName = "CollectableWaypoints"; public const string PluginVersion = "1.0.1"; internal static ManualLogSource Logger; internal static ConfigEntry dataLogWaypoints; internal static ConfigEntry pumpkinWaypoints; internal static ConfigEntry bearWaypoints; private FileSystemWatcher _configWatcher; private volatile bool _configFileChanged; private float _reloadCooldown = -1f; private const float ReloadDebounceSeconds = 0.25f; internal static CollectableWaypointsPlugin Instance { get; set; } private void Awake() { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; dataLogWaypoints = ((BaseUnityPlugin)this).Config.Bind("General", "Data Log Waypoints", true, "If true, shows waypoints for undiscovered data logs."); pumpkinWaypoints = ((BaseUnityPlugin)this).Config.Bind("General", "Pumpkin Waypoints", true, "If true, shows waypoints for undiscovered pumpkins."); bearWaypoints = ((BaseUnityPlugin)this).Config.Bind("General", "Bear Waypoints", true, "If true, shows waypoints for undiscovered bears."); dataLogWaypoints.SettingChanged += delegate { DataLogWaypointPatches.ApplyConfig(); }; pumpkinWaypoints.SettingChanged += delegate { PumpkinWaypointPatches.ApplyConfig(); }; bearWaypoints.SettingChanged += delegate { BearWaypointPatches.ApplyConfig(); }; SetupConfigWatcher(); try { DataLogWaypointPatches.Initialize(new Harmony("sparroh.collectablewaypoints")); PumpkinWaypointPatches.Initialize(); BearWaypointPatches.Initialize(); } catch (Exception ex) { Logger.LogError((object)("Error applying patches: " + ex.Message)); } Logger.LogInfo((object)"CollectableWaypoints loaded successfully."); } private void Update() { if (_configFileChanged) { _configFileChanged = false; _reloadCooldown = 0.25f; } if (_reloadCooldown < 0f) { return; } _reloadCooldown -= Time.unscaledDeltaTime; if (_reloadCooldown > 0f) { return; } _reloadCooldown = -1f; try { ((BaseUnityPlugin)this).Config.Reload(); Logger.LogInfo((object)"Configuration reloaded from disk."); } catch (Exception ex) { Logger.LogError((object)("Failed to reload configuration: " + ex.Message)); } } private void OnDestroy() { if (_configWatcher != null) { _configWatcher.EnableRaisingEvents = false; _configWatcher.Changed -= OnConfigFileChanged; _configWatcher.Created -= OnConfigFileChanged; _configWatcher.Renamed -= OnConfigFileRenamed; _configWatcher.Dispose(); _configWatcher = null; } } private void SetupConfigWatcher() { try { string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; string directoryName = Path.GetDirectoryName(configFilePath); string fileName = Path.GetFileName(configFilePath); if (string.IsNullOrEmpty(directoryName) || string.IsNullOrEmpty(fileName)) { Logger.LogWarning((object)"Could not set up config file watcher: invalid config path."); return; } _configWatcher = new FileSystemWatcher(directoryName, fileName) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), IncludeSubdirectories = false }; _configWatcher.Changed += OnConfigFileChanged; _configWatcher.Created += OnConfigFileChanged; _configWatcher.Renamed += OnConfigFileRenamed; _configWatcher.EnableRaisingEvents = true; Logger.LogInfo((object)("Watching config file for changes: " + configFilePath)); } catch (Exception ex) { Logger.LogError((object)("Failed to set up config file watcher: " + ex.Message)); } } private void OnConfigFileChanged(object sender, FileSystemEventArgs e) { _configFileChanged = true; } private void OnConfigFileRenamed(object sender, RenamedEventArgs e) { _configFileChanged = true; } } public static class PumpkinWaypointPatches { private static readonly List pumpkinPings = new List(); public static void Initialize() { try { SceneManager.sceneLoaded += OnSceneLoaded; } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error initializing PumpkinWaypointPatches: " + ex.Message)); } } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { try { pumpkinPings.Clear(); ApplyConfig(); } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error in OnSceneLoaded for pumpkins: " + ex.Message)); } } public static void ApplyConfig() { try { if (!CollectableWaypointsPlugin.pumpkinWaypoints.Value || LevelData.IsHub) { ClearAllPings(); } else { if ((Object)(object)Highlighter.Instance == (Object)null) { return; } GameObject[] array = (from go in Object.FindObjectsOfType() where (Object)(object)go != (Object)null && ((Object)go).name.Contains("Pumpkin") select go).ToArray(); foreach (GameObject val in array) { if (!pumpkinPings.Contains(val.transform)) { Highlighter.Instance.AddWaypointPing(val.transform); pumpkinPings.Add(val.transform); } } } } catch (Exception ex) { CollectableWaypointsPlugin.Logger.LogError((object)("Error applying pumpkin waypoint config: " + ex.Message)); } } private static void ClearAllPings() { foreach (Transform pumpkinPing in pumpkinPings) { if ((Object)(object)pumpkinPing != (Object)null) { Highlighter instance = Highlighter.Instance; if (instance != null) { instance.RemovePing(pumpkinPing); } } } pumpkinPings.Clear(); } } namespace CollectableWaypoints { public static class MyPluginInfo { public const string PLUGIN_GUID = "CollectableWaypoints"; public const string PLUGIN_NAME = "CollectableWaypoints"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }