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.Configuration;
using BepInEx.Logging;
using DiscoveryPins.Extensions;
using DiscoveryPins.Helpers;
using DiscoveryPins.Pins;
using HarmonyLib;
using Jotunn;
using Jotunn.Managers;
using Jotunn.Utils;
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.1.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
namespace DiscoveryPins
{
[BepInPlugin("Searica.Valheim.DiscoveryPins", "DiscoveryPins", "0.1.1")]
[BepInDependency("com.jotunn.jotunn", "2.22.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.1.1";
internal static DiscoveryPins Instance;
internal static ConfigFile ConfigFile;
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();
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.DiscoveryPins");
Game.isModded = true;
UpdatePlugin(saveConfig: true, initialUpdate: true);
((BaseUnityPlugin)this).Config.SetupWatcher();
ConfigFileExtensions.OnConfigFileReloaded += delegate
{
UpdatePlugin(saveConfig: false);
};
SynchronizationManager.OnConfigurationWindowClosed += delegate
{
UpdatePlugin();
};
SynchronizationManager.OnConfigurationSynchronized += delegate
{
UpdatePlugin();
};
}
internal void SetUpConfigEntries()
{
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
int num = 1;
AutoPinShortcutConfigs = new AutoPinShortcutConfig
{
Enabled = ((BaseUnityPlugin)this).Config.BindConfig("Auto Pin Shortcut", "Enabled", value: true, "Whether to allow using the auto pin shortcut.", null, synced: true, 0, num),
Range = ((BaseUnityPlugin)this).Config.BindConfig("Auto Pin Shortcut", "Range", 50f, "Maximum distance that auto pins can be generated.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), synced: true, 0, num),
Shortcut = ((BaseUnityPlugin)this).Config.BindConfig<KeyboardShortcut>("Auto Pin Shortcut", "Shortcut", new KeyboardShortcut((KeyCode)308, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Shortcut to trigger auto pin.", null, synced: false, 0, num)
};
num++;
DeathPinConfigs = new DeathPinConfig
{
PinWhenInvIsEmpty = ((BaseUnityPlugin)this).Config.BindConfig("Auto Pin: Tombstone", "Generate with empty inventory", value: true, "Death pin will/won't be generated if your inventory was empty.", null, synced: false, 0, num),
AutoRemoveEnabled = ((BaseUnityPlugin)this).Config.BindConfig("Auto Pin: Tombstone", "Remove on retrieval", value: true, "Death pin be removed automatically when tombstone is retrieved.", null, synced: false, 0, num)
};
foreach (KeyValuePair<AutoPins.AutoPinCategory, PinType> defaultPinType in AutoPins.DefaultPinTypes)
{
num++;
string section = $"{num} - Auto Pin: {defaultPinType.Key.ToString()}";
AutoPinConfigs.Add(defaultPinType.Key, new AutoPinConfig
{
Enabled = ((BaseUnityPlugin)this).Config.BindConfig(section, "Enabled", value: true, "Whether auto pinning is enabled.", null, synced: false, 0, num),
Icon = ((BaseUnityPlugin)this).Config.BindConfig(section, "Icon", PinNames.PinTypeToName(defaultPinType.Value), "Which icon to create the pin with.", (AcceptableValueBase)(object)PlaceablePins.AllowedPlaceablePinNames, synced: false, 0, num)
});
}
num++;
EnableColors = ((BaseUnityPlugin)this).Config.BindConfig("Pin Colors", "Enabled", value: true, "Whether to enable custom pin colors.", null, synced: false, 10, num);
foreach (KeyValuePair<PinType, string> defaultPinColor in PinColors.DefaultPinColors)
{
PinColorConfigs.Add(defaultPinColor.Key, ((BaseUnityPlugin)this).Config.BindConfig("Pin Colors", PinNames.PinTypeToName(defaultPinColor.Key), defaultPinColor.Value, "Color to use for pins of this type.", null, synced: false, 0, num));
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();
}
}
internal enum LogLevel
{
Low,
Medium,
High
}
internal static class Log
{
private static ManualLogSource logSource;
internal static ConfigEntry<LogLevel> Verbosity { get; set; }
internal static LogLevel VerbosityLevel => Verbosity.Value;
internal static bool IsVerbosityLow => Verbosity.Value >= LogLevel.Low;
internal static bool IsVerbosityMedium => Verbosity.Value >= LogLevel.Medium;
internal static bool IsVerbosityHigh => Verbosity.Value >= LogLevel.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, LogLevel level = LogLevel.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;
LogInfo(" - " + ((Object)((Component)val).gameObject).name);
components = ((Component)val).gameObject.GetComponents<Component>();
for (int i = 0; i < components.Length; i++)
{
LogComponent(components[i]);
}
}
}
internal static void LogComponent(Component compo)
{
LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---");
PropertyInfo[] properties = ((object)compo).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
foreach (PropertyInfo propertyInfo in properties)
{
LogInfo($" - {propertyInfo.Name} = {propertyInfo.GetValue(compo)}");
}
FieldInfo[] fields = ((object)compo).GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.GetProperty | BindingFlags.SetProperty);
foreach (FieldInfo fieldInfo in fields)
{
LogInfo($" - {fieldInfo.Name} = {fieldInfo.GetValue(compo)}");
}
}
}
}
namespace DiscoveryPins.Pins
{
internal class AutoPinner : MonoBehaviour
{
private const float FindPinPrecision = 1f;
private const float InvokeRepeatingTime = 0.1f;
public string PinName;
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 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_0050: 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_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: 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) && !(Utils.DistanceXZ(Position, ((Component)Player.m_localPlayer).transform.position) > DiscoveryPins.Instance.AutoPinShortcutConfigs.Range.Value))
{
float num = Mathf.Acos((float)Math.PI / 180f * (GameCamera.instance.m_fov / 2f));
Vector3 val = Vector3.Normalize(Position - ((Component)GameCamera.instance).transform.position);
Vector3 val2 = Vector3.Normalize(((Character)Player.m_localPlayer).m_lookDir);
float num2 = Vector3.Dot(val, val2);
if (!(num2 < 0f) && !(num2 < num))
{
AddAutoPin();
}
}
}
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_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
if (!IsAutoPinEnabled(out var autoPinConfig))
{
return false;
}
PinType type = PinNames.PinNameToType(autoPinConfig.Icon.Value);
if (FindPin(Position, type, PinName) != null)
{
return false;
}
Log.LogDebug("Adding Auto Pin with name: " + PinName + ", icon: " + autoPinConfig.Icon.Value + ", pinType: " + ((object)(PinType)(ref type)).ToString());
AddPin(Position, type, 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 = FindPin(pos, pinType, name);
if (val != null)
{
Minimap.instance.RemovePin(val);
return true;
}
return false;
}
public static PinData FindPin(Vector3 pos, PinType type = 8, string name = null)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: 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;
float num = float.MaxValue;
foreach (var (val2, num2) in list)
{
if (val == null || num2 < num)
{
val = val2;
num = num2;
}
}
if (num > 1f)
{
return null;
}
if (!string.IsNullOrEmpty(name) && val.m_name != name)
{
return null;
}
return val;
}
}
internal static class AutoPins
{
internal enum AutoPinCategory
{
Dungeon,
Location,
Ore
}
internal static Dictionary<AutoPinCategory, PinType> DefaultPinTypes = new Dictionary<AutoPinCategory, PinType>
{
{
AutoPinCategory.Dungeon,
(PinType)6
},
{
AutoPinCategory.Location,
(PinType)0
},
{
AutoPinCategory.Ore,
(PinType)2
}
};
}
[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,
"#d43d3d"
},
{
(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_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: 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) && 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 LocationPins
{
internal static List<Location> Locations = new List<Location>();
[HarmonyPostfix]
[HarmonyPatch(typeof(Location), "Awake")]
private static void Location_AwakePostfix(Location __instance)
{
DungeonGenerator generator;
if (__instance.TryGetInteriorEntrance(out var teleport, out var name))
{
AutoPinner.AddAutoPinner(((Component)teleport).gameObject, name, AutoPins.AutoPinCategory.Dungeon);
}
else if (__instance.TryGetOverworldDungeon(out generator, out name))
{
AutoPinner.AddAutoPinner(((Component)generator).gameObject, name, AutoPins.AutoPinCategory.Location);
}
}
[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 OrePins
{
private static readonly List<string> OreNames = new List<string> { "Tin", "Copper", "Silver" };
private static HashSet<string> OrePrefabNames = new HashSet<string>();
[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 (!Object.op_Implicit((Object)(object)prefab.transform.parent) && IsOrePrefab(prefab, out var OreName) && !OrePrefabNames.Contains(((Object)prefab).name))
{
OrePrefabNames.Add(((Object)prefab).name);
AutoPinner.AddAutoPinner(prefab, OreName, AutoPins.AutoPinCategory.Ore);
}
}
}
private static void AddAutoPinnerIfOre(GameObject gameObject)
{
if ((Object.op_Implicit((Object)(object)gameObject.GetComponent<Destructible>()) || Object.op_Implicit((Object)(object)gameObject.GetComponent<MineRock5>())) && TryGetOreName(gameObject, out var OreName))
{
AutoPinner.AddAutoPinner(gameObject, OreName, AutoPins.AutoPinCategory.Ore);
}
}
private static bool IsOrePrefab(GameObject gameObject, out string OreName)
{
if (Object.op_Implicit((Object)(object)gameObject.GetComponent<Destructible>()) || Object.op_Implicit((Object)(object)gameObject.GetComponent<MineRock5>()))
{
return TryGetOreName(gameObject, out OreName);
}
OreName = null;
return false;
}
internal static bool TryGetOreName(GameObject prefab, out string OreName)
{
foreach (string oreName in OreNames)
{
if (StringExtensions.Contains(((Object)prefab).name, oreName, StringComparison.OrdinalIgnoreCase))
{
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();
}
}
}
}
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
{
public static class ConfigFileExtensions
{
internal static string ConfigFileName;
internal static string ConfigFileFullPath;
internal static DateTime lastRead = DateTime.MinValue;
internal static event Action OnConfigFileReloaded;
private static void InvokeOnConfigFileReloaded()
{
ConfigFileExtensions.OnConfigFileReloaded?.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> BindConfig<T>(this ConfigFile configFile, string section, string name, T value, string description, AcceptableValueBase acceptVals = null, bool synced = true, int order = 0, int sectionOrder = 0, Action<ConfigEntryBase> drawer = null, ConfigurationManagerAttributes configAttributes = null)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
string orderedSectionName = GetOrderedSectionName(section, sectionOrder);
string extendedDescription = GetExtendedDescription(description, synced);
if (configAttributes == null)
{
configAttributes = new ConfigurationManagerAttributes();
}
configAttributes.IsAdminOnly = synced;
configAttributes.Order = order;
if (drawer != null)
{
configAttributes.CustomDrawer = drawer;
}
return configFile.Bind<T>(orderedSectionName, name, value, new ConfigDescription(extendedDescription, acceptVals, new object[1] { configAttributes }));
}
internal static string GetOrderedSectionName(string section, int sectionOrder)
{
if (sectionOrder > 0)
{
return $"{sectionOrder} - {section}";
}
return section;
}
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 class EventExtensions
{
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 LocationExtensions
{
internal static bool TryGetInteriorEntrance(this Location location, out Teleport teleport, out string name)
{
teleport = null;
name = string.Empty;
if (!location.m_hasInterior)
{
return false;
}
for (int i = 0; i < ((Component)location).transform.childCount; i++)
{
if (((Component)((Component)location).transform.GetChild(i)).TryGetComponent<Teleport>(ref teleport) && teleport != null)
{
if (!Utility.IsNullOrWhiteSpace(teleport.m_enterText))
{
name = teleport.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) || generator == null)
{
return false;
}
name = ((object)(Theme)(ref generator.m_themes)).ToString();
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 TypeExtensions
{
internal static List<T> GetAllPublicConstantValues<T>(this Type type)
{
return (from fi in type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)
where fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(T)
select fi into x
select (T)x.GetRawConstantValue()).ToList();
}
internal static List<T> GetAllPublicStaticValues<T>(this Type type)
{
return (from fi in type.GetFields(BindingFlags.Static | BindingFlags.Public)
where fi.FieldType == typeof(T)
select fi into x
select (T)x.GetValue(null)).ToList();
}
}
internal static class GenericExtensions
{
internal static T Ref<T>(this T o) where T : Object
{
if (!Object.op_Implicit((Object)(object)o))
{
return default(T);
}
return o;
}
}
internal static class IEnumerableExtensions
{
internal static void Dispose(this IEnumerable<IDisposable> collection)
{
foreach (IDisposable item in collection)
{
if (item != null)
{
try
{
item.Dispose();
}
catch (Exception)
{
Log.LogWarning("Could not dispose of item");
}
}
}
}
}
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;
}
}
}