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.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Configs;
using DiscoveryPins.Extensions;
using DiscoveryPins.Helpers;
using DiscoveryPins.Pins;
using HarmonyLib;
using Jotunn;
using Jotunn.Managers;
using Jotunn.Utils;
using Logging;
using Microsoft.CodeAnalysis;
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.6")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.6.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.6")]
[BepInDependency("com.jotunn.jotunn", "2.23.0")]
[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.6";
internal static DiscoveryPins Instance;
internal static ConfigFile ConfigFile;
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()
{
Instance = this;
ConfigFile = ((BaseUnityPlugin)this).Config;
Log.Init(((BaseUnityPlugin)this).Logger);
((BaseUnityPlugin)this).Config.Init("Searica.Valheim.DiscoveryPins");
SetUpConfigEntries();
UpdatePlugin(saveConfig: true, initialUpdate: true);
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.DiscoveryPins");
Game.isModded = true;
((BaseUnityPlugin)this).Config.SetupWatcher();
ConfigFileManager.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 = ((BaseUnityPlugin)this).Config.BindConfigInOrder("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.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), synced: false, sectionOrder: true, settingOrder: true, null, new ConfigurationManagerAttributes
{
ShowRangeAsPercent = false
});
AutoPinShortcutConfigs = new AutoPinShortcutConfig
{
Enabled = ((BaseUnityPlugin)this).Config.BindConfigInOrder("Auto Pin Shortcut", "Enabled", value: true, "Whether to allow using the auto pin shortcut."),
Range = ((BaseUnityPlugin)this).Config.BindConfigInOrder("Auto Pin Shortcut", "Range", 20f, "Maximum distance that auto pins can be generated.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 50f)),
Shortcut = ((BaseUnityPlugin)this).Config.BindConfigInOrder<KeyboardShortcut>("Auto Pin Shortcut", "Shortcut", new KeyboardShortcut((KeyCode)324, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Shortcut to trigger auto pin.", null, synced: false)
};
DeathPinConfigs = new DeathPinConfig
{
PinWhenInvIsEmpty = ((BaseUnityPlugin)this).Config.BindConfigInOrder("Auto Pin: Tombstone", "Generate with empty inventory", value: true, "Death pin will/won't be generated if your inventory was empty.", null, synced: false),
AutoRemoveEnabled = ((BaseUnityPlugin)this).Config.BindConfigInOrder("Auto Pin: Tombstone", "Remove on retrieval", value: true, "Death pin be removed automatically when tombstone is retrieved.", null, synced: false)
};
foreach (KeyValuePair<AutoPins.AutoPinCategory, PinType> defaultPinType in AutoPins.DefaultPinTypes)
{
string section = $"Auto Pin: {defaultPinType.Key}";
AutoPinConfigs.Add(defaultPinType.Key, new AutoPinConfig
{
Enabled = ((BaseUnityPlugin)this).Config.BindConfigInOrder(section, "Enabled", value: true, "Whether auto pinning is enabled.", null, synced: false),
Icon = ((BaseUnityPlugin)this).Config.BindConfigInOrder(section, "Icon", PinNames.PinTypeToName(defaultPinType.Value), "Which icon to create the pin with.", (AcceptableValueBase)(object)PlaceablePins.AllowedPlaceablePinNames, synced: false)
});
}
EnableColors = ((BaseUnityPlugin)this).Config.BindConfigInOrder("Pin Colors", "Enabled", value: true, "Whether to enable custom pin colors.", null, synced: false);
foreach (KeyValuePair<PinType, string> defaultPinColor in PinColors.DefaultPinColors)
{
PinColorConfigs.Add(defaultPinColor.Key, ((BaseUnityPlugin)this).Config.BindConfigInOrder("Pin Colors", PinNames.PinTypeToName(defaultPinColor.Key), defaultPinColor.Value, "Color to use for pins of this type.", null, synced: false));
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_00be: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: 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_012f: 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_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
MeshRenderer val = null;
Location val2 = null;
pointsToCheck = null;
MineRock5 val3 = default(MineRock5);
if (((Component)this).TryGetComponent<MineRock5>(ref val3) && Object.op_Implicit((Object)(object)val3.m_meshRenderer))
{
val = val3.m_meshRenderer;
}
else if (Object.op_Implicit((Object)(object)((Component)this).GetComponent<Destructible>()))
{
val = ((Component)this).GetComponentInChildren<MeshRenderer>();
}
else if (!((Component)this).gameObject.TryGetComponent<Location>(ref val2) && ((Component)this).gameObject.IsLocationProxy())
{
val2 = ((Component)this).gameObject.GetComponentInChildren<Location>();
}
Bounds bounds = default(Bounds);
if (Object.op_Implicit((Object)(object)val))
{
if (!((Renderer)val).isVisible)
{
return false;
}
bounds = ((Renderer)val).bounds;
}
else
{
if (!Object.op_Implicit((Object)(object)val2))
{
pointsToCheck = new List<Vector3>(1) { Position };
return true;
}
float num = val2.m_exteriorRadius * 2f;
((Bounds)(ref bounds))..ctor(((Component)val2).transform.position, new Vector3(num, num, num));
}
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);
pointsToCheck = 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++)
{
pointsToCheck.Add(((Bounds)(ref bounds)).min + new Vector3((float)i * spacing, (float)j * spacing2, (float)k * spacing3));
}
}
}
return true;
}
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)
Minimap.instance.AddPin(pos, type, name ?? "", true, false, 0L, "");
}
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();
}
}
}
[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 List<string> OreNames = new List<string>(6) { "Tin", "Copper", "Silver", "Obsidian", "Giant", "Tar" };
private static readonly HashSet<string> OrePrefabNames = new HashSet<string>();
internal static void TryAddAutoPinnerToOre(GameObject prefab)
{
if (IsOrePrefab(prefab, out var OreName) && !OrePrefabNames.Contains(((Object)prefab).name))
{
OrePrefabNames.Add(((Object)prefab).name);
AutoPinner.AddAutoPinner(prefab, OreName, AutoPins.AutoPinCategory.Ore);
}
}
private static bool IsOrePrefab(GameObject gameObject, out string OreName)
{
bool flag = false;
OreName = null;
foreach (string oreName in OreNames)
{
if (StringExtensions.Contains(((Object)gameObject).name, oreName, StringComparison.OrdinalIgnoreCase))
{
OreName = oreName;
flag = true;
break;
}
}
if (!flag)
{
return false;
}
if (Object.op_Implicit((Object)(object)gameObject.GetComponent<Destructible>()))
{
HoverText val = default(HoverText);
if (gameObject.TryGetComponent<HoverText>(ref val))
{
OreName = val.m_text;
}
return true;
}
MineRock5 val2 = default(MineRock5);
if (gameObject.TryGetComponent<MineRock5>(ref val2))
{
OreName = val2.m_name;
return true;
}
if (gameObject.IsTarPit())
{
return true;
}
return false;
}
internal static bool TryGetOreName(GameObject prefab, out string OreName)
{
HoverText val = default(HoverText);
foreach (string oreName in OreNames)
{
if (StringExtensions.Contains(((Object)prefab).name, oreName, StringComparison.OrdinalIgnoreCase))
{
if (prefab.TryGetComponent<HoverText>(ref val))
{
OreName = val.m_text;
return true;
}
OreName = oreName;
return true;
}
}
OreName = null;
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MineRock5), "RPC_Damage")]
public static void MineRock5_RPCDamage_Prefix(MineRock5 __instance)
{
AutoPinner autoPinner = default(AutoPinner);
if (((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner))
{
autoPinner.AddAutoPin();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MineRock5), "AllDestroyed")]
public static void AllDestroyed(MineRock5 __instance, bool __result)
{
AutoPinner autoPinner = default(AutoPinner);
if (__result && ((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner))
{
autoPinner.RemoveAutoPin();
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Destructible), "RPC_Damage")]
public static void Destructible_RPCDamage_Prefix(Destructible __instance)
{
AutoPinner autoPinner = default(AutoPinner);
if (((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner))
{
autoPinner.AddAutoPin();
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Destructible), "Destroy")]
public static void Destructible_Destroy_Prefix(Destructible __instance)
{
AutoPinner autoPinner = default(AutoPinner);
if (((Component)__instance).TryGetComponent<AutoPinner>(ref autoPinner) && (!Object.op_Implicit((Object)(object)__instance.m_spawnWhenDestroyed) || !Object.op_Implicit((Object)(object)__instance.m_spawnWhenDestroyed.GetComponent<MineRock5>()) || !TryGetOreName(__instance.m_spawnWhenDestroyed, out var _)))
{
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>();
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();
}
}
}
[HarmonyPatch]
internal static class ZoneSystemPatches
{
[HarmonyPrefix]
[HarmonyPriority(800)]
[HarmonyPatch(typeof(ZoneSystem), "Start")]
private static void ZoneSystem_Start_Prefix()
{
//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())
{
OrePins.TryAddAutoPinnerToOre(prefab);
PortalPins.TryAddAutoPinnerToPortal(prefab);
}
}
}
}
}
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
{
internal static class GameObjectExtensions
{
private static readonly Dictionary<string, bool> IsPrefabLocationProxyMap = new Dictionary<string, bool>();
private static readonly Dictionary<string, bool> IsPrefabTarPitMap = new Dictionary<string, bool>();
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;
}
}
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;
}
}
}
namespace Configs
{
public static class ConfigFileManager
{
internal static string ConfigFileName;
internal static string ConfigFileFullPath;
internal static DateTime lastRead = DateTime.MinValue;
private static readonly Dictionary<string, int> _sectionToSectionNumber = new Dictionary<string, int>();
private static readonly Dictionary<string, int> _sectionToSettingOrder = new Dictionary<string, int>();
private static readonly List<string> ConfigManagerGUIDs = new List<string> { "_shudnal.ConfigurationManager", "com.bepis.bepinex.configurationmanager" };
private static BaseUnityPlugin _configManager = null;
private const string WindowChangedEventName = "DisplayingWindowChanged";
private const string DisplayingWindowName = "DisplayingWindow";
private static PropertyInfo _dispWindowInfo = null;
private static BaseUnityPlugin ConfigManager
{
get
{
if ((Object)(object)_configManager == (Object)null)
{
foreach (string configManagerGUID in ConfigManagerGUIDs)
{
if (Chainloader.PluginInfos.TryGetValue(configManagerGUID, out var value) && Object.op_Implicit((Object)(object)value.Instance))
{
_configManager = value.Instance;
break;
}
}
}
return _configManager;
}
}
private static PropertyInfo DisplayWindowInfo
{
get
{
if ((object)_dispWindowInfo == null)
{
_dispWindowInfo = ((object)ConfigManager).GetType().GetProperty("DisplayingWindow");
}
return _dispWindowInfo;
}
}
internal static event Action OnConfigFileReloaded;
internal static event Action OnConfigWindowClosed;
private static string GetOrderedSectionName(string section)
{
if (!_sectionToSectionNumber.TryGetValue(section, out var value))
{
value = _sectionToSectionNumber.Count + 1;
_sectionToSectionNumber[section] = value;
}
return $"{value} - {section}";
}
private static int GetSettingOrder(string section)
{
if (!_sectionToSettingOrder.TryGetValue(section, out var value))
{
value = 0;
}
_sectionToSettingOrder[section] = value - 1;
return value;
}
private static void InvokeOnConfigFileReloaded()
{
Action onConfigFileReloaded = ConfigFileManager.OnConfigFileReloaded;
if (onConfigFileReloaded != null)
{
onConfigFileReloaded.SafeInvoke();
}
}
private static void InvokeOnConfigWindowClosed()
{
Action onConfigWindowClosed = ConfigFileManager.OnConfigWindowClosed;
if (onConfigWindowClosed != null)
{
onConfigWindowClosed.SafeInvoke();
}
}
public static void Init(this ConfigFile configFile, string GUID, bool saveOnConfigSet = false)
{
configFile.SaveOnConfigSet = saveOnConfigSet;
ConfigFileName = GUID + ".cfg";
ConfigFileFullPath = Path.Combine(Paths.ConfigPath, ConfigFileName);
}
public static bool DisableSaveOnConfigSet(this ConfigFile configFile)
{
bool saveOnConfigSet = configFile.SaveOnConfigSet;
configFile.SaveOnConfigSet = false;
return saveOnConfigSet;
}
public static ConfigEntry<T> BindConfigInOrder<T>(this ConfigFile configFile, string section, string name, T value, string description, AcceptableValueBase acceptVals = null, bool synced = true, bool sectionOrder = true, bool settingOrder = true, Action<ConfigEntryBase> drawer = null, ConfigurationManagerAttributes configAttributes = null)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
section = (sectionOrder ? GetOrderedSectionName(section) : section);
int value2 = (settingOrder ? GetSettingOrder(section) : 0);
if (configAttributes == null)
{
configAttributes = new ConfigurationManagerAttributes();
}
configAttributes.Order = value2;
return configFile.BindConfig(section, name, value, description, acceptVals, synced, drawer, configAttributes);
}
public static ConfigEntry<T> BindConfig<T>(this ConfigFile configFile, string section, string name, T value, string description, AcceptableValueBase acceptVals = null, bool synced = true, Action<ConfigEntryBase> drawer = null, ConfigurationManagerAttributes configAttributes = null)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
string extendedDescription = GetExtendedDescription(description, synced);
if (configAttributes == null)
{
configAttributes = new ConfigurationManagerAttributes();
}
configAttributes.IsAdminOnly = synced;
if (drawer != null)
{
configAttributes.CustomDrawer = drawer;
}
return configFile.Bind<T>(section, name, value, new ConfigDescription(extendedDescription, acceptVals, new object[1] { configAttributes }));
}
internal static string GetExtendedDescription(string description, bool synchronizedSetting)
{
return description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]");
}
internal static void SetupWatcher(this ConfigFile configFile)
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
fileSystemWatcher.Changed += configFile.ReloadConfigFile;
fileSystemWatcher.Created += configFile.ReloadConfigFile;
fileSystemWatcher.Renamed += configFile.ReloadConfigFile;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
}
internal static void ReloadConfigFile(this ConfigFile configFile, object sender, FileSystemEventArgs eventArgs)
{
if (!File.Exists(ConfigFileFullPath))
{
return;
}
try
{
DateTime lastWriteTime = File.GetLastWriteTime(eventArgs.FullPath);
if (lastRead != lastWriteTime)
{
Log.LogInfo("Reloading config file");
bool saveOnConfigSet = configFile.DisableSaveOnConfigSet();
configFile.Reload();
configFile.SaveOnConfigSet = saveOnConfigSet;
InvokeOnConfigFileReloaded();
lastRead = lastWriteTime;
}
}
catch
{
Log.LogError("There was an issue loading your " + ConfigFileName);
Log.LogError("Please check your config entries for spelling and format!");
}
}
internal static void CheckForConfigManager(this ConfigFile config)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Invalid comparison between Unknown and I4
if ((int)SystemInfo.graphicsDeviceType != 4 && !((Object)(object)ConfigManager == (Object)null))
{
Log.LogDebug("Configuration manager found, hooking DisplayingWindowChanged");
EventInfo @event = ((object)ConfigManager).GetType().GetEvent("DisplayingWindowChanged");
if (!(@event == null))
{
Action<object, object> action = OnConfigManagerDisplayingWindowChanged;
Delegate handler = Delegate.CreateDelegate(@event.EventHandlerType, action.Target, action.Method);
@event.AddEventHandler(ConfigManager, handler);
}
}
}
private static void OnConfigManagerDisplayingWindowChanged(object sender, object e)
{
if (!(DisplayWindowInfo == null) && !(bool)DisplayWindowInfo.GetValue(ConfigManager, null))
{
InvokeOnConfigWindowClosed();
}
}
private 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 arg)
{
Log.LogWarning("Exception thrown at event " + new StackFrame(1).GetMethod().Name + $" in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{arg}");
}
}
}
}
}