Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DiscoveryPins v0.3.10
DiscoveryPins.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DiscoveryPins.Extensions; using DiscoveryPins.Helpers; using DiscoveryPins.Pins; using HarmonyLib; using Jotunn; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Logging; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("DiscoveryPins")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DiscoveryPins")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("08a6f7d7-cf93-4931-aecd-abf2ce6ed34c")] [assembly: AssemblyFileVersion("0.3.10")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.10.0")] [module: UnverifiableCode] [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 Logging { internal static class Log { internal enum InfoLevel { Low, Medium, High } private static ManualLogSource logSource; internal static ConfigEntry<InfoLevel> Verbosity { get; set; } internal static InfoLevel VerbosityLevel => Verbosity.Value; internal static bool IsVerbosityLow => Verbosity.Value >= InfoLevel.Low; internal static bool IsVerbosityMedium => Verbosity.Value >= InfoLevel.Medium; internal static bool IsVerbosityHigh => Verbosity.Value >= InfoLevel.High; internal static void Init(ManualLogSource logSource) { Log.logSource = logSource; } internal static void LogDebug(object data) { logSource.LogDebug(data); } internal static void LogError(object data) { logSource.LogError(data); } internal static void LogFatal(object data) { logSource.LogFatal(data); } internal static void LogMessage(object data) { logSource.LogMessage(data); } internal static void LogWarning(object data) { logSource.LogWarning(data); } internal static void LogInfo(object data, InfoLevel level = InfoLevel.Low) { if (Verbosity == null || VerbosityLevel >= level) { logSource.LogInfo(data); } } internal static void LogGameObject(GameObject prefab, bool includeChildren = false) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown LogInfo("***** " + ((Object)prefab).name + " *****"); Component[] components = prefab.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } if (!includeChildren) { return; } LogInfo("***** " + ((Object)prefab).name + " (children) *****"); foreach (Transform item in prefab.transform) { Transform val = item; if (Object.op_Implicit((Object)(object)val)) { LogInfo(" - " + ((Object)val).name); components = ((Component)val).GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } } } } internal static void LogComponent(Component compo) { if (!Object.op_Implicit((Object)(object)compo)) { return; } try { LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---"); } catch (Exception ex) { LogError(ex.ToString()); LogWarning("Could not get type name for component!"); return; } try { foreach (PropertyInfo declaredProperty in AccessTools.GetDeclaredProperties(((object)compo).GetType())) { try { LogInfo($" - {declaredProperty.Name} = {declaredProperty.GetValue(compo)}"); } catch (Exception ex2) { LogError(ex2.ToString()); LogWarning("Could not get property: " + declaredProperty.Name + " for component!"); } } } catch (Exception ex3) { LogError(ex3.ToString()); LogWarning("Could not get properties for component!"); } try { foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(((object)compo).GetType())) { try { LogInfo($" - {declaredField.Name} = {declaredField.GetValue(compo)}"); } catch (Exception ex4) { LogError(ex4.ToString()); LogWarning("Could not get field: " + declaredField.Name + " for component!"); } } } catch (Exception ex5) { LogError(ex5.ToString()); LogWarning("Could not get fields for component!"); } } } } namespace DiscoveryPins { [BepInPlugin("Searica.Valheim.DiscoveryPins", "DiscoveryPins", "0.3.10")] [BepInDependency("com.jotunn.jotunn", "2.24.2")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] internal sealed class DiscoveryPins : BaseUnityPlugin { internal class AutoPinShortcutConfig { internal ConfigEntry<bool> Enabled; internal ConfigEntry<float> Range; internal ConfigEntry<KeyboardShortcut> Shortcut; } internal class DeathPinConfig { internal ConfigEntry<bool> PinWhenInvIsEmpty; internal ConfigEntry<bool> AutoRemoveEnabled; } internal class AutoPinConfig { internal ConfigEntry<bool> Enabled; internal ConfigEntry<string> Icon; } public const string PluginName = "DiscoveryPins"; internal const string Author = "Searica"; public const string PluginGUID = "Searica.Valheim.DiscoveryPins"; public const string PluginVersion = "0.3.10"; internal static DiscoveryPins Instance; internal static ConfigFile ConfigFile; internal static ConfigFileWatcher ConfigFileWatcher; internal const string GlobalSection = "Global"; internal ConfigEntry<float> PinSpacing; internal const string AutoPinShortcutSection = "Auto Pin Shortcut"; internal AutoPinShortcutConfig AutoPinShortcutConfigs; internal const string DeathPinSection = "Auto Pin: Tombstone"; internal DeathPinConfig DeathPinConfigs; internal readonly Dictionary<AutoPins.AutoPinCategory, AutoPinConfig> AutoPinConfigs = new Dictionary<AutoPins.AutoPinCategory, AutoPinConfig>(); internal const string ColorSection = "Pin Colors"; internal ConfigEntry<bool> EnableColors; internal readonly Dictionary<PinType, ConfigEntry<string>> PinColorConfigs = new Dictionary<PinType, ConfigEntry<string>>(); internal static bool ColorConfigsChanged; internal static void OnColorConfigChanged(object obj, EventArgs args) { if (!ColorConfigsChanged) { ColorConfigsChanged = true; } } public void Awake() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown Instance = this; Log.Init(((BaseUnityPlugin)this).Logger); ConfigFile = ((BaseUnityPlugin)this).Config; ConfigFileWatcher = new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; SetUpConfigEntries(); UpdatePlugin(saveConfig: true, initialUpdate: true); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.DiscoveryPins"); Game.isModded = true; ConfigFileWatcher.OnConfigFileReloaded += delegate { UpdatePlugin(saveConfig: false); }; SynchronizationManager.OnConfigurationWindowClosed += delegate { UpdatePlugin(); }; SynchronizationManager.OnConfigurationSynchronized += delegate { UpdatePlugin(); }; } internal void SetUpConfigEntries() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) PinSpacing = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "Global", "Pin Spacing", 10f, "The minimum allowable distance between auto-pins. If a new auto-pin would be closer to an existing pin than the value of Pin Spacing, then no pin will be placed.", false, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), (Action<ConfigEntryBase>)null, new ConfigurationManagerAttributes { ShowRangeAsPercent = false }); AutoPinShortcutConfigs = new AutoPinShortcutConfig { Enabled = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "Auto Pin Shortcut", "Enabled", true, "Whether to allow using the auto pin shortcut.", true, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null), Range = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "Auto Pin Shortcut", "Range", 20f, "Maximum distance that auto pins can be generated.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 50f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null), Shortcut = ConfigFileExtensions.BindConfigInOrder<KeyboardShortcut>(((BaseUnityPlugin)this).Config, "Auto Pin Shortcut", "Shortcut", new KeyboardShortcut((KeyCode)324, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Shortcut to trigger auto pin.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null) }; DeathPinConfigs = new DeathPinConfig { PinWhenInvIsEmpty = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "Auto Pin: Tombstone", "Generate with empty inventory", true, "Death pin will/won't be generated if your inventory was empty.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null), AutoRemoveEnabled = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "Auto Pin: Tombstone", "Remove on retrieval", true, "Death pin be removed automatically when tombstone is retrieved.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null) }; foreach (KeyValuePair<AutoPins.AutoPinCategory, PinType> defaultPinType in AutoPins.DefaultPinTypes) { string text = $"Auto Pin: {defaultPinType.Key}"; AutoPinConfigs.Add(defaultPinType.Key, new AutoPinConfig { Enabled = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, text, "Enabled", true, "Whether auto pinning is enabled.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null), Icon = ConfigFileExtensions.BindConfigInOrder<string>(((BaseUnityPlugin)this).Config, text, "Icon", PinNames.PinTypeToName(defaultPinType.Value), "Which icon to create the pin with.", false, true, true, (AcceptableValueBase)(object)PlaceablePins.AllowedPlaceablePinNames, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null) }); } EnableColors = ConfigFileExtensions.BindConfigInOrder<bool>(((BaseUnityPlugin)this).Config, "Pin Colors", "Enabled", true, "Whether to enable custom pin colors.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); foreach (KeyValuePair<PinType, string> defaultPinColor in PinColors.DefaultPinColors) { PinColorConfigs.Add(defaultPinColor.Key, ConfigFileExtensions.BindConfigInOrder<string>(((BaseUnityPlugin)this).Config, "Pin Colors", PinNames.PinTypeToName(defaultPinColor.Key), defaultPinColor.Value, "Color to use for pins of this type.", false, true, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null)); PinColorConfigs[defaultPinColor.Key].SettingChanged += OnColorConfigChanged; } } private void UpdatePlugin(bool saveConfig = true, bool initialUpdate = false) { if (ColorConfigsChanged || initialUpdate) { PinColors.UpdatePinColorMap(); ColorConfigsChanged = false; } if (saveConfig) { ((BaseUnityPlugin)this).Config.Save(); } } public void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } } } namespace DiscoveryPins.Pins { internal class AutoPinner : MonoBehaviour { public const float CloseEnoughXZ = 5f; public const float CloseEnoughY = 5f; private const float FindPinPrecision = 1f; private const float InvokeRepeatingTime = 0.1f; public string PinName; private bool AutoPinNameChanged; public AutoPins.AutoPinCategory AutoPinCategory; private Vector3 LastPosition; public Vector3 Position { get { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)((Component)this).transform)) { LastPosition = ((Component)this).transform.position; } return LastPosition; } } internal static void AddAutoPinner(GameObject target, string pinName, AutoPins.AutoPinCategory pinCategory) { AutoPinner orAddComponent = ExposedGameObjectExtension.GetOrAddComponent<AutoPinner>(target); orAddComponent.PinName = pinName; orAddComponent.AutoPinCategory = pinCategory; } public void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) LastPosition = ((Component)this).transform.position; } public void Start() { ((MonoBehaviour)this).InvokeRepeating("CheckForAutoPinShortcut", 0.1f, 0.1f); } public void UpdatePinName(string pinName, bool markAsChanged = true) { AutoPinNameChanged = pinName != PinName; if (AutoPinNameChanged) { PinName = pinName; } AutoPinNameChanged = markAsChanged && AutoPinNameChanged; } public void CheckForAutoPinShortcut() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (!DiscoveryPins.Instance.AutoPinShortcutConfigs.Enabled.Value) { return; } KeyboardShortcut value = DiscoveryPins.Instance.AutoPinShortcutConfigs.Shortcut.Value; if (!((KeyboardShortcut)(ref value)).IsPressed() || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)GameCamera.instance)) { return; } float dotTolerance = Mathf.Acos((float)Math.PI / 180f * (GameCamera.instance.m_fov / 2f)); Vector3 position = ((Component)Player.m_localPlayer).transform.position; Vector3 lookDir = ((Character)Player.m_localPlayer).m_lookDir; if (!TryGetPointsToCheck(out var pointsToCheck)) { return; } foreach (Vector3 item in pointsToCheck) { if (IsPointVisibleOrCloseEnough(item, position, lookDir, dotTolerance)) { AddAutoPin(); break; } } } private bool TryGetPointsToCheck(out List<Vector3> pointsToCheck) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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_00cc: Unknown result type (might be due to invalid IL or missing references) pointsToCheck = null; MineRock5 val = default(MineRock5); if (((Component)this).TryGetComponent<MineRock5>(ref val) && Object.op_Implicit((Object)(object)val.m_meshRenderer)) { if (!((Renderer)val.m_meshRenderer).isVisible) { return false; } pointsToCheck = GetPointsFromBounds(((Renderer)val.m_meshRenderer).bounds); return true; } if (Object.op_Implicit((Object)(object)((Component)this).GetComponent<Destructible>())) { MeshRenderer componentInChildren = ((Component)this).GetComponentInChildren<MeshRenderer>(); if (!((Renderer)componentInChildren).isVisible) { return false; } pointsToCheck = GetPointsFromBounds(((Renderer)componentInChildren).bounds); return true; } MineRock val2 = default(MineRock); if (((Component)this).TryGetComponent<MineRock>(ref val2)) { Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(Position, Vector3.zero); if (val2.m_hitAreas == null || val2.m_hitAreas.Length < 1) { return false; } Collider[] hitAreas = val2.m_hitAreas; foreach (Collider val3 in hitAreas) { if (val3.enabled && ((Component)val3).gameObject.activeInHierarchy) { ((Bounds)(ref bounds)).Encapsulate(val3.bounds); } } pointsToCheck = GetPointsFromBounds(bounds); return true; } Location componentInChildren2 = default(Location); if (!((Component)this).gameObject.TryGetComponent<Location>(ref componentInChildren2) && ((Component)this).gameObject.IsLocationProxy()) { componentInChildren2 = ((Component)this).gameObject.GetComponentInChildren<Location>(); } if (Object.op_Implicit((Object)(object)componentInChildren2)) { float num = componentInChildren2.m_exteriorRadius * 2f; Bounds bounds2 = default(Bounds); ((Bounds)(ref bounds2))..ctor(((Component)componentInChildren2).transform.position, new Vector3(num, num, num)); pointsToCheck = GetPointsFromBounds(bounds2); return true; } pointsToCheck = new List<Vector3>(1) { Position }; return true; } private List<Vector3> GetPointsFromBounds(Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) GetPointSpacing(((Bounds)(ref bounds)).size.x, 5f, out var nPts, out var spacing); GetPointSpacing(((Bounds)(ref bounds)).size.y, 5f, out var nPts2, out var spacing2); GetPointSpacing(((Bounds)(ref bounds)).size.z, 5f, out var nPts3, out var spacing3); List<Vector3> list = new List<Vector3>(2) { Position, ((Bounds)(ref bounds)).center }; for (int i = 0; i < nPts; i++) { for (int j = 0; j < nPts2; j++) { for (int k = 0; k < nPts3; k++) { list.Add(((Bounds)(ref bounds)).min + new Vector3((float)i * spacing, (float)j * spacing2, (float)k * spacing3)); } } } return list; } private static void GetPointSpacing(float size, float targetSpacing, out int nPts, out float spacing) { nPts = Mathf.CeilToInt(size / targetSpacing); spacing = size / (float)nPts; nPts++; } private bool IsPointVisibleOrCloseEnough(Vector3 pos, Vector3 playerPosition, Vector3 lookDir, float dotTolerance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) float num = Utils.DistanceXZ(pos, playerPosition); if (num > DiscoveryPins.Instance.AutoPinShortcutConfigs.Range.Value) { return false; } bool flag = num <= 5f && Mathf.Abs(Position.y - playerPosition.y) <= 5f; lookDir = Vector3.Normalize(lookDir); float num2 = Vector3.Dot(Vector3.Normalize(pos - ((Component)GameCamera.instance).transform.position), lookDir); if ((num2 < 0f || num2 < dotTolerance) && !flag) { return false; } if (Object.op_Implicit((Object)(object)ZoneSystem.instance)) { float groundHeight = ZoneSystem.instance.GetGroundHeight(pos); if (pos.y < groundHeight - 1f) { return false; } } return true; } public bool TryGetAutoPinConfig(out DiscoveryPins.AutoPinConfig autoPinConfig) { if (DiscoveryPins.Instance.AutoPinConfigs.TryGetValue(AutoPinCategory, out autoPinConfig)) { return true; } return false; } public bool IsAutoPinEnabled(out DiscoveryPins.AutoPinConfig autoPinConfig) { if (TryGetAutoPinConfig(out autoPinConfig)) { return autoPinConfig.Enabled.Value; } return false; } public bool TryGetAutoPinIcon(out PinType icon) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown icon = (PinType)8; if (TryGetAutoPinConfig(out var autoPinConfig)) { icon = (PinType)(int)PinNames.PinNameToType(autoPinConfig.Icon.Value); return true; } return false; } public bool AddAutoPin() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!IsAutoPinEnabled(out var autoPinConfig)) { return false; } PinType val = PinNames.PinNameToType(autoPinConfig.Icon.Value); if (AutoPinNameChanged) { PinData val2 = FindExistingPin(Position, val); if (val2 != null) { Log.LogDebug($"Removing old pin with name {val2.m_NamePinData.PinNameText} because auto pin name changed."); Minimap.instance.RemovePin(val2); AutoPinNameChanged = false; AddPin(Position, val, PinName); return true; } } if (FindClosestPin(Position, out var closestDis, (PinType)8) != null && closestDis < DiscoveryPins.Instance.PinSpacing.Value) { return false; } if (FindExistingPin(Position, val, PinName) != null) { return false; } Log.LogDebug($"Adding Auto Pin with name: {PinName}, icon: {autoPinConfig.Icon.Value}, pinType: {val}"); AddPin(Position, val, PinName); return true; } private static void AddPin(Vector3 pos, PinType type, string name = null) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Minimap.instance.AddPin(pos, type, name ?? "", true, false, 0L, default(PlatformUserID)); } public bool RemoveAutoPin() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!TryGetAutoPinIcon(out var icon)) { return false; } return RemovePin(Position, icon, PinName); } public static bool RemovePin(Vector3 pos, PinType pinType = 8, string name = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) PinData val = FindExistingPin(pos, pinType, name); if (val != null) { Minimap.instance.RemovePin(val); return true; } return false; } public static PinData FindExistingPin(Vector3 pos, PinType type = 8, string name = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) float closestDis; PinData val = FindClosestPin(pos, out closestDis, type); if (closestDis > 1f) { return null; } if (!string.IsNullOrEmpty(name) && val.m_name != name) { return null; } return val; } public static PinData FindClosestPin(Vector3 pos, out float closestDis, PinType type = 8) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) List<(PinData, float)> list = new List<(PinData, float)>(); foreach (PinData pin in Minimap.instance.m_pins) { if ((int)type == 8 || pin.m_type == type) { list.Add((pin, Utils.DistanceXZ(pos, pin.m_pos))); } } PinData val = null; closestDis = float.MaxValue; foreach (var (val2, num) in list) { if (val == null || num < closestDis) { val = val2; closestDis = num; } } return val; } } internal static class AutoPins { internal enum AutoPinCategory { Dungeon, Location, Ore, Portal } internal static Dictionary<AutoPinCategory, PinType> DefaultPinTypes = new Dictionary<AutoPinCategory, PinType> { { AutoPinCategory.Dungeon, (PinType)6 }, { AutoPinCategory.Location, (PinType)0 }, { AutoPinCategory.Ore, (PinType)2 }, { AutoPinCategory.Portal, (PinType)3 } }; } [HarmonyPatch] internal static class PinColors { internal static Dictionary<PinType, Color> PinColorMap = new Dictionary<PinType, Color>(); private const string Red = "#d43d3d"; private const string Cyan = "#35b5cc"; private const string Orange = "#d6b340"; private const string LightDusk = "#737373"; private const string Brown = "#a86840"; private const string Purple = "#9c39ed"; private const string White = "#ffffff"; internal static readonly Dictionary<PinType, string> DefaultPinColors = new Dictionary<PinType, string> { { (PinType)4, "#d43d3d" }, { (PinType)5, "#35b5cc" }, { (PinType)0, "#d6b340" }, { (PinType)1, "#35b5cc" }, { (PinType)6, "#a86840" }, { (PinType)2, "#737373" }, { (PinType)3, "#d43d3d" }, { (PinType)7, "#ffffff" }, { (PinType)10, "#ffffff" }, { (PinType)9, "#9c39ed" }, { (PinType)11, "#ffffff" }, { (PinType)12, "#ffffff" }, { (PinType)13, "#ffffff" } }; [HarmonyPostfix] [HarmonyPatch(typeof(Minimap), "UpdatePins")] private static void MinimapUpdatePins_PostFix() { UpdatePinsColor(); } public static void UpdatePinColorMap() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (!DiscoveryPins.Instance.EnableColors.Value) { return; } PinColorMap.Clear(); foreach (KeyValuePair<PinType, ConfigEntry<string>> pinColorConfig in DiscoveryPins.Instance.PinColorConfigs) { PinColorMap[pinColorConfig.Key] = pinColorConfig.Value.Value.ToColor(); } } public static void UpdatePinsColor() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) if (!DiscoveryPins.Instance.EnableColors.Value) { return; } foreach (PinData pin in Minimap.instance.m_pins) { if (!((Object)(object)pin.m_iconElement == (Object)null) && !pin.m_shouldDelete && PinColorMap.TryGetValue(pin.m_type, out var value)) { Image iconElement = pin.m_iconElement; ((Graphic)iconElement).color = ((Graphic)iconElement).color * value; } } } } internal class PinNames { private static readonly Dictionary<PinType, string> PinTypeToNameMap = new Dictionary<PinType, string> { { (PinType)0, "Fireplace" }, { (PinType)1, "House" }, { (PinType)2, "Hammer" }, { (PinType)3, "Ball" }, { (PinType)6, "Cave" } }; private static Dictionary<string, PinType> _PinNameToTypeMap; private static Dictionary<string, PinType> PinNameToTypeMap { get { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (_PinNameToTypeMap == null) { _PinNameToTypeMap = new Dictionary<string, PinType>(); foreach (KeyValuePair<PinType, string> item in PinTypeToNameMap) { _PinNameToTypeMap.Add(item.Value, item.Key); } } return _PinNameToTypeMap; } } internal static string PinTypeToName(PinType pinType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (PinTypeToNameMap.TryGetValue(pinType, out var value)) { return value; } return ((object)(PinType)(ref pinType)).ToString(); } internal static PinType PinNameToType(string pinName) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (PinNameToTypeMap.TryGetValue(pinName, out var value)) { return value; } return EnumUtils.ParseEnum<PinType>(pinName); } } internal static class PlaceablePins { private static readonly List<PinType> PlaceablePinTypes = new List<PinType> { (PinType)0, (PinType)1, (PinType)2, (PinType)3, (PinType)6 }; private static List<string> _PlaceablePinNames; private static List<string> PlaceablePinNames => _PlaceablePinNames ?? (_PlaceablePinNames = PlaceablePinTypes.Select((PinType x) => PinNames.PinTypeToName(x)).ToList()); internal static AcceptableValueList<string> AllowedPlaceablePinNames => new AcceptableValueList<string>(PlaceablePinNames.ToArray()); } } namespace DiscoveryPins.Patches { [HarmonyPatch] internal static class DeathPins { public static bool InvIsEmpty; [HarmonyPrefix] [HarmonyPatch(typeof(Player), "OnDeath")] public static void PlayerOnDeath_Prefix(Player __instance) { InvIsEmpty = ((Humanoid)__instance).m_inventory.NrOfItems() < 1; } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "OnDeath")] public static void PlayerOnDeath_Postfix(Player __instance) { //IL_0024: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (InvIsEmpty && !DiscoveryPins.Instance.DeathPinConfigs.PinWhenInvIsEmpty.Value) { Vector3 position = ((Component)__instance).transform.position; Log.LogDebug("Negating pin at '" + ((Vector3)(ref position)).ToString("F0") + "' because inventory was empty\n"); AutoPinner.RemovePin(position, (PinType)4); PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); playerProfile.GetWorldData(ZNet.instance.GetWorldUID()).m_haveDeathPoint = false; playerProfile.GetWorldData(ZNet.instance.GetWorldUID()).m_deathPoint = Vector3.zero; } } [HarmonyPostfix] [HarmonyPatch(typeof(TombStone), "GiveBoost")] public static void TombStoneGiveBoost_Postfix(TombStone __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (DiscoveryPins.Instance.DeathPinConfigs.AutoRemoveEnabled.Value) { AutoPinner.RemovePin(((Component)__instance).transform.position, (PinType)4); } } } [HarmonyPatch] internal static class DungeonPins { [HarmonyPostfix] [HarmonyPatch(typeof(Location), "Awake")] private static void Location_AwakePostfix(Location __instance) { if (__instance.TryGetInteriorEntrance(out var teleport, out var name)) { AutoPinner.AddAutoPinner(((Component)teleport).gameObject, name, AutoPins.AutoPinCategory.Dungeon); } } [HarmonyPrefix] [HarmonyPatch(typeof(Teleport), "Interact")] private static void TeleportInteract_Prefix(Teleport __instance) { AutoPinner autoPinner = default(AutoPinner); if (((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.AddAutoPin(); } } } internal class FortressPins { } [HarmonyPatch] internal static class LocationPins { private static readonly HashSet<string> LocationNames = new HashSet<string>(); private static readonly Dictionary<string, string> OverworldLocationNamesMap = new Dictionary<string, string>(); [HarmonyPostfix] [HarmonyPatch(typeof(Location), "Awake")] private static void Location_AwakePostfix(Location __instance) { if (Object.op_Implicit((Object)(object)__instance)) { string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject); if (!OverworldLocationNamesMap.ContainsKey(prefabName) && __instance.TryGetOverworldDungeon(out var _, out var name)) { OverworldLocationNamesMap[prefabName] = name; } } } [HarmonyPostfix] [HarmonyPatch(typeof(LocationProxy), "SpawnLocation")] private static void AddAutoPinnerToSpawnedLocationProxy(LocationProxy __instance) { if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)__instance.m_instance)) { string prefabName = Utils.GetPrefabName(__instance.m_instance); if (OverworldLocationNamesMap.ContainsKey(prefabName)) { AutoPinner.AddAutoPinner(((Component)__instance).gameObject, OverworldLocationNamesMap[prefabName], AutoPins.AutoPinCategory.Location); } } } } [HarmonyPatch] internal static class OrePins { private static readonly HashSet<string> OreDropNames = new HashSet<string> { "BlackMarble", "Softtissue", "TinOre", "CopperOre", "SilverOre", "Obsidian", "FlametalOreNew" }; private static readonly List<string> OreNames = new List<string>(7) { "Tin", "Copper", "Silver", "Obsidian", "Giant", "LeviathanLava", "Meteorite" }; private static readonly HashSet<string> OrePrefabNames = new HashSet<string>(); [HarmonyPrefix] [HarmonyPatch(typeof(MineRock), "Start")] private static void AddOreAutoPinnerOnStartMineRock(MineRock __instance) { if (DropsOre(__instance) && TryGetOreName((Component)(object)__instance, out var OreName)) { AutoPinner.AddAutoPinner(((Component)__instance).gameObject, OreName, AutoPins.AutoPinCategory.Ore); } } [HarmonyPrefix] [HarmonyPatch(typeof(MineRock5), "Awake")] private static void AddOreAutoPinnerOnAwakeMineRock5(MineRock5 __instance) { if (DropsOre(__instance) && TryGetOreName((Component)(object)__instance, out var OreName)) { AutoPinner.AddAutoPinner(((Component)__instance).gameObject, OreName, AutoPins.AutoPinCategory.Ore); } } [HarmonyPrefix] [HarmonyPatch(typeof(Destructible), "Awake")] private static void AddOreAutoPinnerOnAwakeDestructible(Destructible __instance) { if (DropsOre(__instance) && TryGetOreName((Component)(object)__instance, out var OreName)) { AutoPinner.AddAutoPinner(((Component)__instance).gameObject, OreName, AutoPins.AutoPinCategory.Ore); } } private static bool DropsOre(Destructible destructible) { if (!Object.op_Implicit((Object)(object)destructible) || !Object.op_Implicit((Object)(object)destructible.m_spawnWhenDestroyed)) { return false; } if (IsOreDrop(destructible.m_spawnWhenDestroyed)) { return true; } MineRock5 mineRock = default(MineRock5); if (destructible.m_spawnWhenDestroyed.TryGetComponent<MineRock5>(ref mineRock)) { return DropsOre(mineRock); } MineRock mineRock2 = default(MineRock); if (destructible.m_spawnWhenDestroyed.TryGetComponent<MineRock>(ref mineRock2)) { return DropsOre(mineRock2); } return false; } private static bool DropsOre(MineRock5 mineRock5) { if (!Object.op_Implicit((Object)(object)mineRock5) || mineRock5.m_dropItems == null) { return false; } return DropTableContainsOreDrop(mineRock5.m_dropItems); } private static bool DropsOre(MineRock mineRock) { if (!Object.op_Implicit((Object)(object)mineRock) || mineRock.m_dropItems == null) { return false; } return DropTableContainsOreDrop(mineRock.m_dropItems); } private static bool DropTableContainsOreDrop(DropTable dropTable) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (dropTable.m_drops == null || dropTable.m_drops.Count < 1) { return false; } foreach (DropData drop in dropTable.m_drops) { if (IsOreDrop(drop.m_item)) { return true; } } return false; } private static bool IsOreDrop(GameObject gameObject) { string prefabName = gameObject.GetPrefabName(); return OreDropNames.Contains(prefabName); } internal static bool TryGetOreName(Component oreComponent, out string OreName) { if (oreComponent is Destructible) { HoverText val = default(HoverText); if (oreComponent.TryGetComponent<HoverText>(ref val)) { OreName = val.m_text; return true; } } else { MineRock5 val2 = (MineRock5)(object)((oreComponent is MineRock5) ? oreComponent : null); if (val2 != null) { OreName = val2.m_name; return true; } MineRock val3 = (MineRock)(object)((oreComponent is MineRock) ? oreComponent : null); if (val3 != null) { OreName = val3.m_name; return true; } } OreName = null; return false; } [HarmonyPrefix] [HarmonyPatch(typeof(MineRock5), "RPC_Damage")] private static void PinMineRock5OnDamage(MineRock5 __instance) { AutoPinner autoPinner = default(AutoPinner); if (((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.AddAutoPin(); } } [HarmonyPostfix] [HarmonyPatch(typeof(MineRock5), "AllDestroyed")] private static void RemoveMineRock5PinOnDestroy(MineRock5 __instance, bool __result) { AutoPinner autoPinner = default(AutoPinner); if (__result && ((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.RemoveAutoPin(); } } [HarmonyPrefix] [HarmonyPatch(typeof(MineRock), "RPC_Hit")] private static void PinMineRockOnHit(MineRock __instance) { AutoPinner autoPinner = default(AutoPinner); if (((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.AddAutoPin(); } } [HarmonyPostfix] [HarmonyPatch(typeof(MineRock), "AllDestroyed")] private static void RemoveMineRockPinOnDestroy(MineRock __instance, bool __result) { AutoPinner autoPinner = default(AutoPinner); if (__result && ((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.RemoveAutoPin(); } } [HarmonyPrefix] [HarmonyPatch(typeof(Destructible), "RPC_Damage")] private static void PinDestructibleOnDamage(Destructible __instance) { AutoPinner autoPinner = default(AutoPinner); if (((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.AddAutoPin(); } } [HarmonyPrefix] [HarmonyPatch(typeof(Destructible), "Destroy")] private static void RemoveDestructiblePineOnDestory(Destructible __instance) { AutoPinner autoPinner = default(AutoPinner); if (!((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { return; } if (Object.op_Implicit((Object)(object)__instance.m_spawnWhenDestroyed)) { GameObject spawnWhenDestroyed = __instance.m_spawnWhenDestroyed; MineRock5 mineRock = default(MineRock5); MineRock mineRock2 = default(MineRock); if ((spawnWhenDestroyed.TryGetComponent<MineRock5>(ref mineRock) && DropsOre(mineRock)) || (spawnWhenDestroyed.TryGetComponent<MineRock>(ref mineRock2) && DropsOre(mineRock2))) { return; } } autoPinner.RemoveAutoPin(); } } [HarmonyPatch] internal static class PlaceRemovePatches { [HarmonyPostfix] [HarmonyPatch(typeof(Piece), "OnPlaced")] public static void Piece_OnPlaced_Postfix(Piece __instance) { AutoPinner autoPinner = default(AutoPinner); if (Object.op_Implicit((Object)(object)__instance) && ((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.AddAutoPin(); } } [HarmonyPostfix] [HarmonyPatch(typeof(Piece), "DropResources")] public static void Piece_DropResources_Postfix(Piece __instance) { AutoPinner autoPinner = default(AutoPinner); if (Object.op_Implicit((Object)(object)__instance) && ((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.RemoveAutoPin(); } } } [HarmonyPatch] internal static class PortalPins { private const string DefaultPortalName = "Portal"; private static readonly HashSet<string> PortalPrefabNames = new HashSet<string>(); [HarmonyPrefix] [HarmonyPriority(800)] [HarmonyPatch(typeof(ZoneSystem), "Start")] private static void AddAutoPinnerToPortalPrefabs() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "main") { return; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if (prefab.IsTopLevelPrefab()) { TryAddAutoPinnerToPortal(prefab); } } } internal static void TryAddAutoPinnerToPortal(GameObject prefab) { if (IsPortal(prefab) && !PortalPrefabNames.Contains(((Object)prefab).name)) { PortalPrefabNames.Add(((Object)prefab).name); AutoPinner.AddAutoPinner(prefab, "Portal", AutoPins.AutoPinCategory.Portal); } } internal static bool IsPortal(GameObject prefab) { return Object.op_Implicit((Object)(object)prefab.GetComponent<TeleportWorld>()); } [HarmonyPostfix] [HarmonyPatch(typeof(TeleportWorld), "Awake")] internal static void TeleportWorld_Awake_Postfix(TeleportWorld __instance) { AutoPinner autoPinner = default(AutoPinner); if (Object.op_Implicit((Object)(object)__instance) && ((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.UpdatePinName(GetPortalAutoPinName(__instance), markAsChanged: false); } } [HarmonyPostfix] [HarmonyPatch(typeof(TeleportWorld), "RPC_SetTag")] internal static void TeleportWorld_RPC_SetTag_Postfix(TeleportWorld __instance) { AutoPinner autoPinner = default(AutoPinner); if (Object.op_Implicit((Object)(object)__instance) && ((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.UpdatePinName(GetPortalAutoPinName(__instance)); } } internal static string GetPortalAutoPinName(TeleportWorld teleportWorld) { string text = teleportWorld.GetText(); if (!string.IsNullOrWhiteSpace(text)) { return text; } return "Portal"; } [HarmonyPrefix] [HarmonyPatch(typeof(TeleportWorld), "Teleport")] internal static void TeleportWorld_Teleport_Prefix(TeleportWorld __instance) { TriggerAutoPinPortal(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(TeleportWorld), "GetHoverText")] internal static void TeleportWorld_GetHoverText_Prefix(TeleportWorld __instance) { TriggerAutoPinPortal(__instance); } private static void TriggerAutoPinPortal(TeleportWorld teleportWorld) { AutoPinner autoPinner = default(AutoPinner); if (Object.op_Implicit((Object)(object)teleportWorld) && ((Component)teleportWorld).TryGetComponent<AutoPinner>(ref autoPinner)) { autoPinner.AddAutoPin(); } } } } namespace DiscoveryPins.Helpers { internal static class EnumUtils { internal static IEnumerable<T> GetEnumValues<T>() { return Enum.GetValues(typeof(T)).Cast<T>(); } public static T ParseEnum<T>(string value) { return (T)Enum.Parse(typeof(T), value, ignoreCase: true); } } internal static class ReflectionUtils { public const BindingFlags AllBindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty; internal static MethodInfo GetMethod(Type type, string name, Type[] types) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == name && HasMatchingParameterTypes(0, types, methodInfo.GetParameters())) { return methodInfo; } } return null; } internal static MethodInfo GetGenericMethod(Type type, string name, int genericParameterCount, Type[] types) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty); foreach (MethodInfo methodInfo in methods) { if (methodInfo.IsGenericMethod && methodInfo.ContainsGenericParameters && methodInfo.Name == name && HasMatchingParameterTypes(genericParameterCount, types, methodInfo.GetParameters())) { return methodInfo; } } return null; } private static bool HasMatchingParameterTypes(int genericParameterCount, Type[] types, ParameterInfo[] parameters) { if (parameters.Length < genericParameterCount || parameters.Length != types.Length) { return false; } int num = 0; for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsGenericParameter) { num++; } else if (types[i] != parameters[i].ParameterType) { return false; } } if (num != genericParameterCount) { return false; } return true; } } } namespace DiscoveryPins.Extensions { [HarmonyPatch] internal static class GameObjectExtensions { private const string MineRock5Name = "___MineRock5"; private static readonly Dictionary<string, bool> IsPrefabLocationProxyMap = new Dictionary<string, bool>(); private static readonly Dictionary<string, bool> IsPrefabTarPitMap = new Dictionary<string, bool>(); internal static string GetPrefabName(this GameObject gameObject) { MineRock5Tracker mineRock5Tracker = default(MineRock5Tracker); if (((Object)gameObject).name.Contains("___MineRock5") && gameObject.TryGetComponent<MineRock5Tracker>(ref mineRock5Tracker)) { return mineRock5Tracker.m_prefabName; } return Utils.GetPrefabName(gameObject); } internal static bool IsTopLevelPrefab(this GameObject gameObject) { return !Object.op_Implicit((Object)(object)gameObject.transform.parent); } internal static bool IsTarPit(this GameObject gameObject) { string prefabName = Utils.GetPrefabName(gameObject); if (!IsPrefabTarPitMap.TryGetValue(prefabName, out var value)) { value = Object.op_Implicit((Object)(object)gameObject.transform.Find("TarLiquid")); IsPrefabTarPitMap[prefabName] = value; } return value; } internal static bool IsLocationProxy(this GameObject gameObject) { string prefabName = Utils.GetPrefabName(gameObject); if (!IsPrefabLocationProxyMap.TryGetValue(prefabName, out var value)) { value = Object.op_Implicit((Object)(object)gameObject.GetComponent<LocationProxy>()); IsPrefabTarPitMap[prefabName] = value; } return value; } } [HarmonyPatch] internal class MineRock5Tracker : MonoBehaviour { public string m_prefabName; [HarmonyPrefix] [HarmonyPatch(typeof(MineRock5), "Awake")] private static void MineRock5TrackOnAwake(MineRock5 __instance) { if (Object.op_Implicit((Object)(object)__instance)) { AddMineRock5Tracker(__instance); } } public static void AddMineRock5Tracker(MineRock5 mineRock5) { if (!Object.op_Implicit((Object)(object)((Component)mineRock5).GetComponent<MineRock5Tracker>())) { ((Component)mineRock5).gameObject.AddComponent<MineRock5Tracker>().m_prefabName = Utils.GetPrefabName(((Component)mineRock5).gameObject); } } } internal static class LocationExtensions { private const string EntranceName = "GateWay"; private const string ExteriorName = "exterior"; internal static bool TryGetInteriorEntrance(this Location location, out Teleport teleport, out string name) { teleport = null; name = string.Empty; if (!location.m_hasInterior) { return false; } if (TryGetTeleportEntrance(((Component)location).transform, out teleport, out name)) { return true; } Transform val = ((Component)location).transform.Find("exterior"); if (Object.op_Implicit((Object)(object)val) && TryGetTeleportEntrance(val, out teleport, out name)) { return true; } return false; } internal static bool TryGetTeleportEntrance(Transform parent, out Teleport entrance, out string name) { name = string.Empty; entrance = null; for (int i = 0; i < ((Component)parent).transform.childCount; i++) { if (((Component)((Component)parent).transform.GetChild(i)).TryGetComponent<Teleport>(ref entrance) && entrance != null) { if (!Utility.IsNullOrWhiteSpace(entrance.m_enterText)) { name = entrance.m_enterText; } return true; } } return false; } internal static bool TryGetOverworldDungeon(this Location location, out DungeonGenerator generator, out string name) { generator = null; name = string.Empty; if (location.m_hasInterior) { return false; } if (!location.TryGetDungeonGenerator(out generator) || !Object.op_Implicit((Object)(object)generator)) { return false; } name = ((object)(Theme)(ref generator.m_themes)).ToString().Replace("Goblin", "Fuling"); return true; } internal static bool TryGetDungeonGenerator(this Location location, out DungeonGenerator generator) { generator = null; if (Object.op_Implicit((Object)(object)location.m_generator)) { generator = location.m_generator; return true; } for (int i = 0; i < ((Component)location).transform.childCount; i++) { if (((Component)((Component)location).transform.GetChild(i)).TryGetComponent<DungeonGenerator>(ref generator) && generator != null) { return true; } } return false; } } internal static class SafeInvokEvents { public static void SafeInvoke(this Action events) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1>(this Action<TArg1> events, TArg1 arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1> action = (Action<TArg1>)invocationList[i]; try { action(arg1); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1, TArg2>(this Action<TArg1, TArg2> events, TArg1 arg1, TArg2 arg2) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1, TArg2> action = (Action<TArg1, TArg2>)invocationList[i]; try { action(arg1, arg2); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TEventArg>(this EventHandler<TEventArg> events, object sender, TEventArg arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { EventHandler<TEventArg> eventHandler = (EventHandler<TEventArg>)invocationList[i]; try { eventHandler(sender, arg1); } catch (Exception ex) { Log.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {eventHandler.Method.DeclaringType.Name}.{eventHandler.Method.Name}:\n{ex}"); } } } } internal static class StringExtensions { private static StringBuilder sb = new StringBuilder(9); public static Color ToColor(this string color) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) sb.Append(color); if (color.StartsWith("#", StringComparison.InvariantCulture)) { sb.Remove(0, 1); } if (sb.Length == 6) { sb.Append("FF"); } uint num = Convert.ToUInt32(sb.ToString(), 16); sb.Clear(); return new Color((float)((num & 0xFF000000u) >> 24) / 255f, (float)((num & 0xFF0000) >> 16) / 255f, (float)((num & 0xFF00) >> 8) / 255f, (float)(num & 0xFFu) / 255f); } public static bool Contains(this string orig, string value, StringComparison comparisonType) { return orig.IndexOf(value, comparisonType) > -1; } } }