Decompiled source of Explorer v1.1.4
Explorer.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using Explorer.Functions; using Explorer.Patches; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using SkillManager; using Splatform; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("blacks7ar")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.4")] [assembly: AssemblyInformationalVersion("1.0.0+fd10bb74a3d9f67c27b67253529d021440e49f7e")] [assembly: AssemblyProduct("Explorer")] [assembly: AssemblyTitle("Explorer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.4.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 SkillManager { [PublicAPI] public class Skill { public static class LocalizationCache { private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>(); internal static void LocalizationPostfix(Localization __instance, string language) { Localization __instance2 = __instance; string key = Enumerable.FirstOrDefault<KeyValuePair<string, Localization>>(localizations, (KeyValuePair<string, Localization> l) => l.Value == __instance2).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance2); } } public static Localization ForLanguage(string? language = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out Localization value)) { return value; } value = new Localization(); if (language != null) { value.SetupLanguage(language); } return value; } } [PublicAPI] public class LocalizeKey { private static readonly List<LocalizeKey> keys = new List<LocalizeKey>(); public readonly string Key; public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>(); public LocalizeKey(string key) { Key = key.Replace("$", ""); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; Localization.instance.AddWord(Key, Localization.instance.Localize(alias)); } public LocalizeKey English(string key) { return addForLang("English", key); } public LocalizeKey Swedish(string key) { return addForLang("Swedish", key); } public LocalizeKey French(string key) { return addForLang("French", key); } public LocalizeKey Italian(string key) { return addForLang("Italian", key); } public LocalizeKey German(string key) { return addForLang("German", key); } public LocalizeKey Spanish(string key) { return addForLang("Spanish", key); } public LocalizeKey Russian(string key) { return addForLang("Russian", key); } public LocalizeKey Romanian(string key) { return addForLang("Romanian", key); } public LocalizeKey Bulgarian(string key) { return addForLang("Bulgarian", key); } public LocalizeKey Macedonian(string key) { return addForLang("Macedonian", key); } public LocalizeKey Finnish(string key) { return addForLang("Finnish", key); } public LocalizeKey Danish(string key) { return addForLang("Danish", key); } public LocalizeKey Norwegian(string key) { return addForLang("Norwegian", key); } public LocalizeKey Icelandic(string key) { return addForLang("Icelandic", key); } public LocalizeKey Turkish(string key) { return addForLang("Turkish", key); } public LocalizeKey Lithuanian(string key) { return addForLang("Lithuanian", key); } public LocalizeKey Czech(string key) { return addForLang("Czech", key); } public LocalizeKey Hungarian(string key) { return addForLang("Hungarian", key); } public LocalizeKey Slovak(string key) { return addForLang("Slovak", key); } public LocalizeKey Polish(string key) { return addForLang("Polish", key); } public LocalizeKey Dutch(string key) { return addForLang("Dutch", key); } public LocalizeKey Portuguese_European(string key) { return addForLang("Portuguese_European", key); } public LocalizeKey Portuguese_Brazilian(string key) { return addForLang("Portuguese_Brazilian", key); } public LocalizeKey Chinese(string key) { return addForLang("Chinese", key); } public LocalizeKey Japanese(string key) { return addForLang("Japanese", key); } public LocalizeKey Korean(string key) { return addForLang("Korean", key); } public LocalizeKey Hindi(string key) { return addForLang("Hindi", key); } public LocalizeKey Thai(string key) { return addForLang("Thai", key); } public LocalizeKey Abenaki(string key) { return addForLang("Abenaki", key); } public LocalizeKey Croatian(string key) { return addForLang("Croatian", key); } public LocalizeKey Georgian(string key) { return addForLang("Georgian", key); } public LocalizeKey Greek(string key) { return addForLang("Greek", key); } public LocalizeKey Serbian(string key) { return addForLang("Serbian", key); } public LocalizeKey Ukrainian(string key) { return addForLang("Ukrainian", key); } private LocalizeKey addForLang(string lang, string value) { Localizations[lang] = value; if (Localization.instance.GetSelectedLanguage() == lang) { Localization.instance.AddWord(Key, value); } else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key)) { Localization.instance.AddWord(Key, value); } return this; } [HarmonyPriority(300)] internal static void AddLocalizedKeys(Localization __instance, string language) { foreach (LocalizeKey key in keys) { string value2; if (key.Localizations.TryGetValue(language, out string value) || key.Localizations.TryGetValue("English", out value)) { __instance.AddWord(key.Key, value); } else if (key.Localizations.TryGetValue("alias", out value2)) { Localization.instance.AddWord(key.Key, Localization.instance.Localize(value2)); } } } } private class ConfigurationManagerAttributes { [UsedImplicitly] public string? Category; } [HarmonyPatch(typeof(Skills), "IsSkillValid")] private static class Patch_Skills_IsSkillValid { private static void Postfix(SkillType type, ref bool __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!__result && skills.ContainsKey(type)) { __result = true; } } } private static readonly Dictionary<SkillType, Skill> skills; internal static readonly Dictionary<string, Skill> skillByName; private readonly string skillName; private readonly string internalSkillName; private readonly SkillDef skillDef; public readonly LocalizeKey Name; public readonly LocalizeKey Description; private float skillEffectFactor = 1f; private int skillLoss = 5; public bool Configurable; private static bool InitializedTerminal; private static Localization? _english; private static BaseUnityPlugin? _plugin; private static bool hasConfigSync; private static object? _configSync; public float SkillGainFactor { get { return skillDef.m_increseStep; } set { skillDef.m_increseStep = value; this.SkillGainFactorChanged?.Invoke(value); } } public float SkillEffectFactor { get { return skillEffectFactor; } set { skillEffectFactor = value; this.SkillEffectFactorChanged?.Invoke(value); } } public int SkillLoss { get { return skillLoss; } set { skillLoss = value; this.SkillLossChanged?.Invoke(value); } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown object obj = _plugin; if (obj == null) { BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Enumerable.First(Assembly.GetExecutingAssembly().DefinedTypes, (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); _plugin = val; obj = (object)val; } return (BaseUnityPlugin)obj; } } private static object? configSync { get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } public event Action<float>? SkillGainFactorChanged; public event Action<float>? SkillEffectFactorChanged; public event Action<float>? SkillLossChanged; public Skill(string englishName, string icon) : this(englishName, loadSprite(icon, 64, 64)) { } public Skill(string englishName, Sprite icon) { //IL_0019: 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_003a: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0076: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown SkillType val = fromName(englishName); string text = new Regex("[^a-zA-Z]").Replace(englishName, "_"); skills[val] = this; skillByName[englishName] = this; skillDef = new SkillDef { m_description = "$skilldesc_" + text, m_icon = icon, m_increseStep = 1f, m_skill = val }; internalSkillName = text; skillName = englishName; Name = new LocalizeKey("skill_" + ((object)(SkillType)(ref val)).ToString()).English(englishName); Description = new LocalizeKey("skilldesc_" + text); } public static SkillType fromName(string englishName) { return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName)); } static Skill() { //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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_01ab: Expected O, but got Unknown //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_023c: Expected O, but got Unknown skills = new Dictionary<SkillType, Skill>(); skillByName = new Dictionary<string, Skill>(); InitializedTerminal = false; hasConfigSync = true; Harmony val = new Harmony("org.bepinex.helpers.skillmanager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); } private static void Patch_FejdStartup() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown foreach (Skill skill in skills.Values) { if (skill.Configurable) { string key = skill.Name.Key; string group = new Regex("['[\"\\]]").Replace(english.Localize(key), "").Trim(); string category = Localization.instance.Localize(key).Trim(); ConfigEntry<float> skillGain = config(group, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillGainFactor = skillGain.Value; skillGain.SettingChanged += delegate { skill.SkillGainFactor = skillGain.Value; }; ConfigEntry<float> skillEffect = config(group, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillEffectFactor = skillEffect.Value; skillEffect.SettingChanged += delegate { skill.SkillEffectFactor = skillEffect.Value; }; ConfigEntry<int> skillLoss = config(group, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.skillLoss = skillLoss.Value; skillLoss.SettingChanged += delegate { skill.skillLoss = skillLoss.Value; }; } } } private static void Patch_Skills_GetSkillDef(ref SkillDef? __result, List<SkillDef> ___m_skills, SkillType type) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (__result == null) { SkillDef val = GetSkillDef(type); if (val != null) { ___m_skills.Add(val); __result = val; } } } private static bool Patch_Skills_CheatRaiseskill(Skills __instance, string name, float value, Player ___m_player) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) foreach (SkillType key in skills.Keys) { SkillType current = key; Skill skill = skills[current]; if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase)) { Skill skill2 = __instance.GetSkill(current); skill2.m_level += value; skill2.m_level = Mathf.Clamp(skill2.m_level, 0f, 100f); ((Character)___m_player).Message((MessageType)1, "Skill increased " + Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref current)).ToString()) + ": " + (int)skill2.m_level, 0, skill2.m_info.m_icon); Console.instance.Print("Skill " + skill.internalSkillName + " = " + skill2.m_level); return false; } } return true; } private static bool Patch_Skills_CheatResetSkill(Skills __instance, string name) { //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) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) foreach (SkillType key in skills.Keys) { Skill skill = skills[key]; if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase)) { __instance.ResetSkill(key); Console.instance.Print("Skill " + skill.internalSkillName + " reset"); return false; } } return true; } private static void Patch_Skills_OnDeath_Prefix(Skills __instance, ref Dictionary<SkillType, Skill>? __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { __state = new Dictionary<SkillType, Skill>(); } foreach (KeyValuePair<SkillType, Skill> skill in skills) { if (__instance.m_skillData.TryGetValue(skill.Key, out var value)) { __state[skill.Key] = value; if (skill.Value.skillLoss > 0) { Skill obj = value; obj.m_level -= value.m_level * (float)skill.Value.SkillLoss / 100f; value.m_accumulator = 0f; } __instance.m_skillData.Remove(skill.Key); } } } private static void Patch_Skills_OnDeath_Finalizer(Skills __instance, ref Dictionary<SkillType, Skill>? __state) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { return; } foreach (KeyValuePair<SkillType, Skill> item in __state) { __instance.m_skillData[item.Key] = item.Value; } __state = null; } private static void Patch_Terminal_InitTerminal_Prefix() { InitializedTerminal = Terminal.m_terminalInitialized; } private static void Patch_Terminal_InitTerminal() { if (!InitializedTerminal) { AddSkill(Terminal.commands["raiseskill"]); AddSkill(Terminal.commands["resetskill"]); } static void AddSkill(ConsoleCommand command) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown ConsoleOptionsFetcher fetcher = command.m_tabOptionsFetcher; command.m_tabOptionsFetcher = (ConsoleOptionsFetcher)delegate { List<string> list = fetcher.Invoke(); list.AddRange(Enumerable.Select(skills.Values, (Skill skill) => skill.internalSkillName)); return list; }; } } private static SkillDef? GetSkillDef(SkillType skillType) { //IL_0005: 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) if (!skills.ContainsKey(skillType)) { return null; } return skills[skillType].skillDef; } private static byte[] ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream); return memoryStream.ToArray(); } private static Texture2D loadTexture(string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name)); return val; } public static Sprite loadSprite(string name, int width, int height) { //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) return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero); } private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description) { ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry<T> config<T>(string group, string name, T value, string description) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } } [PublicAPI] public static class SkillExtensions { public static float GetSkillFactor(this Character character, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return character.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static float GetSkillFactor(this Skills skills, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return skills.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static void RaiseSkill(this Character character, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) character.RaiseSkill(Skill.fromName(name), value); } public static void RaiseSkill(this Skills skill, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) skill.RaiseSkill(Skill.fromName(name), value); } public static void LowerSkill(this Character character, string name, float factor = 1f) { character.GetSkills().LowerSkill(name, factor); } public static void LowerSkill(this Skills skills, string name, float factor) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (factor > 0f && skills.m_skillData.TryGetValue(Skill.fromName(name), out var value)) { Skill obj = value; obj.m_level -= value.m_level * factor; value.m_accumulator = 0f; } } } } namespace Explorer { [BepInPlugin("blacks7ar.Explorer", "Explorer", "1.1.4")] public class Plugin : BaseUnityPlugin { private const string modGUID = "blacks7ar.Explorer"; public const string modName = "Explorer"; public const string modAuthor = "blacks7ar"; public const string modVersion = "1.1.4"; public const string modLink = "https://thunderstore.io/c/valheim/p/blacks7ar/Explorer/"; private static readonly Harmony _harmony = new Harmony("blacks7ar.Explorer"); private static readonly ConfigSync _configSync = new ConfigSync("blacks7ar.Explorer") { DisplayName = "Explorer", CurrentVersion = "1.1.4", MinimumRequiredVersion = "1.1.4" }; private static ConfigEntry<Toggle> _serverConfigLocked; private static ConfigEntry<float> _expGainFactor; private static ConfigEntry<int> _expLoss; public static ConfigEntry<Toggle> _displayExpGain; public static ConfigEntry<float> _detectionRadius; public static ConfigEntry<int> _increasePerLevel; public static ConfigEntry<float> _loreStoneExp; public static ConfigEntry<float> _locationExp; public static ConfigEntry<float> _newBiomeExp; public static ConfigEntry<int> _dungeonsLevel; public static ConfigEntry<string> _meadowsResourcesT1; public static ConfigEntry<int> _meadowsResourcesT1Level; public static ConfigEntry<string> _blackForestResourcesT2; public static ConfigEntry<int> _blackForestResourcesT2Level; public static ConfigEntry<string> _swampResourcesT3; public static ConfigEntry<int> _swampResourcesT3Level; public static ConfigEntry<string> _mountainResourcesT4; public static ConfigEntry<int> _mountainResourcesT4Level; public static ConfigEntry<string> _plainsResourcesT5; public static ConfigEntry<int> _plainsResourcesT5Level; public static ConfigEntry<string> _mistlandsResourcesT6; public static ConfigEntry<int> _mistlandsResourcesT6Level; public static ConfigEntry<string> _ashlandsResourcesT7; public static ConfigEntry<int> _ashlandsResourcesT7Level; public static ConfigEntry<Toggle> _iconsOnly; public static ConfigEntry<int> _maxPin; public static ConfigEntry<KeyboardShortcut> _hidePinKey; public static bool _hidePins; private static Skill _explorer; private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedConfig = true) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedConfig ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val); _configSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedConfig; return val2; } private ConfigEntry<T> config2<T>(string group, string name, T value, string desc, bool synchronizedConfig = true) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Explorer.Functions.ConfigurationManagerAttributes configurationManagerAttributes = new Explorer.Functions.ConfigurationManagerAttributes { CustomDrawer = TextBox }; return config(group, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes }), synchronizedConfig); } public void Awake() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected O, but got Unknown //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Expected O, but got Unknown //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Expected O, but got Unknown //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Expected O, but got Unknown //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Expected O, but got Unknown //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Expected O, but got Unknown //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_053a: Expected O, but got Unknown //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Expected O, but got Unknown //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Expected O, but got Unknown //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Expected O, but got Unknown ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; _explorer = new Skill("Explorer", "explorer.png"); _explorer.Description.English("Pins resources on the map while you explore and increases exploration radius."); _explorer.Configurable = false; _serverConfigLocked = config("1- ServerSync", "Lock Configuration", Toggle.On, new ConfigDescription("If On, the configuration is locked and can be changed by server admins only.", (AcceptableValueBase)null, Array.Empty<object>())); _configSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked); _detectionRadius = config("2- Exploration", "Detection Radius", 64f, new ConfigDescription("Detection radius for tracking down resources.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); _increasePerLevel = config("2- Exploration", "Radius Increase Per Level", 2, new ConfigDescription("Exploration radius increase per level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _loreStoneExp = config("2- Exploration", "Lore Stone Exp Gain", 3f, new ConfigDescription("Base exp factor gain when you interact to a runestone that gives lores about valheim.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _locationExp = config("2- Exploration", "Discovered Location Exp Gain", 2f, new ConfigDescription("Base exp factor gain when you discovered a new location.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); _newBiomeExp = config("2- Exploration", "New Biome Exp Gain", 10f, new ConfigDescription("Base exp factor gain when you discover a new biome.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 25f), Array.Empty<object>())); _iconsOnly = config("2- Exploration", "Icons Only", Toggle.Off, new ConfigDescription("If On, only icons will be visible on the world map.", (AcceptableValueBase)null, Array.Empty<object>())); _maxPin = config("2- Exploration", "Max Pin", 3, new ConfigDescription("Max number of pins of the same type to be displayed on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>())); _hidePinKey = config<KeyboardShortcut>("2- Exploration", "Hide Pin Hotkey", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new ConfigDescription("Quick hotkey to hide pins on the map", (AcceptableValueBase)null, Array.Empty<object>()), synchronizedConfig: false); _displayExpGain = config("3- Skills Exp", "Display Exp Gain", Toggle.On, new ConfigDescription("Enable/Disables exp gain notification.", (AcceptableValueBase)null, Array.Empty<object>())); _expGainFactor = config("3- Skills Exp", "Exp Gain Factor", 1f, new ConfigDescription("Exp gain factor for explorer skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), Array.Empty<object>())); _expGainFactor.SettingChanged += delegate { _explorer.SkillGainFactor = _expGainFactor.Value; }; _explorer.SkillGainFactor = _expGainFactor.Value; _expLoss = config("3- Skills Exp", "Exp Loss Amount", 0, new ConfigDescription("Skills exp loss on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); _expLoss.SettingChanged += delegate { _explorer.SkillLoss = _expLoss.Value; }; _explorer.SkillLoss = _expLoss.Value; _meadowsResourcesT1 = config2("4- Resources", "Tier1 Meadows", "Flint,Mushroom,Raspberry,Honey", "Prefab names of resources that you can gather in meadows biome.\nNOTE: You need to logout if you added additional resources while in-game."); _meadowsResourcesT1Level = config("4- Resources", "Tier1 Meadows Level", 10, new ConfigDescription("Required skill level needed to track down resources in meadows and pin them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _blackForestResourcesT2 = config2("4- Resources", "Tier2 BlackForest", "Blueberries,CarrotSeeds,Thistle,CopperOre,TinOre", "Prefab names of resources that you can gather in black forest biome.\nNOTE: You need to logout if you added additional resources while in-game."); _blackForestResourcesT2Level = config("4- Resources", "Tier2 BlackForest Level", 22, new ConfigDescription("Required skill level needed to track down resources in black forest and pin them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _swampResourcesT3 = config2("4- Resources", "Tier3 Swamp", "TurnipSeeds,Guck,Chitin", "Prefab names of resources that you can gather in swamp biome.\nNOTE: You need to logout if you added additional resources while in-game."); _swampResourcesT3Level = config("4- Resources", "Tier3 Swamp Level", 34, new ConfigDescription("Required skill level needed to track down resources in swamp and pin them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _mountainResourcesT4 = config2("4- Resources", "Tier4 Mountain", "DragonEgg,OnionSeeds,SilverOre", "Prefab names of resources that you can gather in mountain biome.\nNOTE: You need to logout if you added additional resources while in-game."); _mountainResourcesT4Level = config("4- Resources", "Tier4 Mountain Level", 46, new ConfigDescription("Required skill level needed to track down resources in mountain and pin them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _plainsResourcesT5 = config2("4- Resources", "Tier5 Plains", "Barley,Cloudberry,Flax,Tar", "Prefab names of resources that you can gather in plains biome.\nNOTE: You need to logout if you added additional resources while in-game."); _plainsResourcesT5Level = config("4- Resources", "Tier5 Plains Level", 58, new ConfigDescription("Required skill level needed to track down resources in plains and pin them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _mistlandsResourcesT6 = config2("4- Resources", "Tier6 Mistlands", "MushroomJotunPuffs,MushroomMagecap,Softtissue,BlackMarble,IronScrap,CopperScrap", "Prefab names of resources that you can gather in mistlands biome.\nNOTE: You need to logout if you added additional resources while in-game."); _mistlandsResourcesT6Level = config("4- Resources", "Tier6 Mistlands Level", 70, new ConfigDescription("Required skill level needed to track down resources in plains and pin them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _ashlandsResourcesT7 = config2("4- Resources", "Tier7 Ashlands", "Fiddleheadfern,MushroomSmokePuff,FlametalOreNew,ProustitePowder,SulfurStone", "Prefab names of resources that you can pick in ashlands biome.\nNOTE: You need to logout if you added additional resources while in-game."); _ashlandsResourcesT7Level = config("4- Resources", "Tier7 Ashlands Level", 82, new ConfigDescription("Required skill level needed to track down resources in ashlands and pin them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); _dungeonsLevel = config("5- Dungeons", "Dungeons Level", 28, new ConfigDescription("Required skill level needed to track down dungeons and caves and pins them on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new Explorer.Functions.ConfigurationManagerAttributes { ShowRangeAsPercent = false } })); Helper.GetDungeonSprites(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; ((BaseUnityPlugin)this).Config.Save(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); } public void Update() { //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) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } KeyboardShortcut value = _hidePinKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && ((Character)localPlayer).TakeInput() && !_hidePins) { _hidePins = true; ((Character)localPlayer).Message((MessageType)2, "Explorer pins are turned Off.", 0, (Sprite)null); return; } value = _hidePinKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && ((Character)localPlayer).TakeInput() && _hidePins) { ((Character)localPlayer).Message((MessageType)2, "Explorer pins are turned On.", 0, (Sprite)null); _hidePins = false; } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private static void TextBox(ConfigEntryBase entryBase) { entryBase.BoxedValue = GUILayout.TextArea((string)entryBase.BoxedValue, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true) }); } } } namespace Explorer.Patches { [HarmonyPatch(typeof(Destructible), "Awake")] public class DestructiblePatch { [HarmonyPostfix] private static void Awake_Postfix(Destructible __instance) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } DropOnDestroyed component = ((Component)__instance).GetComponent<DropOnDestroyed>(); MineRock5 val = null; if ((Object)(object)__instance.m_spawnWhenDestroyed != (Object)null) { val = __instance.m_spawnWhenDestroyed.GetComponent<MineRock5>(); } if ((((Object)(object)component == (Object)null || component.m_dropWhenDestroyed == null) && (Object)(object)val == (Object)null) || (Object)(object)((Component)__instance).GetComponent<Tracker>() != (Object)null) { return; } IEnumerable<DropData> enumerable = Enumerable.Empty<DropData>(); if (component?.m_dropWhenDestroyed?.m_drops != null) { enumerable = Enumerable.Concat(enumerable, component.m_dropWhenDestroyed.m_drops); } if (val?.m_dropItems?.m_drops != null) { enumerable = Enumerable.Concat(enumerable, val.m_dropItems.m_drops); } foreach (DropData item in enumerable) { if (!((Object)(object)item.m_item == (Object)null)) { ItemDrop component2 = item.m_item.GetComponent<ItemDrop>(); if (!((Object)(object)component2 == (Object)null)) { string name = ((Object)item.m_item).name; string localName = ((Localization.instance != null) ? Localization.instance.Localize(component2.m_itemData.m_shared.m_name) : component2.m_itemData.m_shared.m_name); AddTierTracker(__instance, name, localName); } } } } private static void AddTierTracker(Destructible destructible, string name, string localName) { AddTracker(destructible, name, localName, Helper._ResourceIconsT2, Helper.GetTier2PinIcons, Plugin._blackForestResourcesT2Level.Value); AddTracker(destructible, name, localName, Helper._ResourceIconsT3, Helper.GetTier3PinIcons, Plugin._swampResourcesT3Level.Value); AddTracker(destructible, name, localName, Helper._ResourceIconsT4, Helper.GetTier4PinIcons, Plugin._mountainResourcesT4Level.Value); AddTracker(destructible, name, localName, Helper._ResourceIconsT5, Helper.GetTier5PinIcons, Plugin._plainsResourcesT5Level.Value); AddTracker(destructible, name, localName, Helper._ResourceIconsT6, Helper.GetTier6PinIcons, Plugin._mistlandsResourcesT6Level.Value); AddTracker(destructible, name, localName, Helper._ResourceIconsT7, Helper.GetTier7PinIcons, Plugin._ashlandsResourcesT7Level.Value); } private static void AddTracker(Destructible destructible, string name, string localName, IDictionary<string, Sprite> iconDict, Action<string> fetchIcons, int level) { string localName2 = localName; fetchIcons(name); if (iconDict.TryGetValue(name, out Sprite value) && !((Object)(object)Enumerable.FirstOrDefault(((Component)destructible).GetComponents<Tracker>(), (Tracker t) => ((Object)t).name == localName2) != (Object)null)) { ((Component)destructible).gameObject.AddComponent<Tracker>().Create(localName2, Plugin._detectionRadius.Value, value, level); } } } [HarmonyPatch] public class DropOnDestroyedPatch { [HarmonyPostfix] [HarmonyPatch(typeof(DropOnDestroyed), "Awake")] private static void Awake_Postfix(DropOnDestroyed __instance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)__instance).name.Contains("Beehive")) { return; } foreach (DropData drop in __instance.m_dropWhenDestroyed.m_drops) { ItemDrop component = drop.m_item.GetComponent<ItemDrop>(); string name = ((Object)drop.m_item).name; string resourceName = Localization.instance.Localize(component.m_itemData.m_shared.m_name); Helper.GetTier1PinIcons(name); if (!Helper._ResourceIconsT1.TryGetValue(name, out Sprite value)) { break; } ((Component)__instance).gameObject.AddComponent<Tracker>().Create(resourceName, Plugin._detectionRadius.Value, value, Plugin._meadowsResourcesT1Level.Value); } } } [HarmonyPatch] public class LeviathanAwake { [HarmonyPostfix] [HarmonyPatch(typeof(Leviathan), "Awake")] private static void Awake_Postfix(Leviathan __instance) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_006b: 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) if ((Object)(object)__instance == (Object)null) { return; } MineRock component = ((Component)__instance).GetComponent<MineRock>(); if ((Object)(object)component == (Object)null) { return; } IEnumerable<DropData> enumerable = Enumerable.Empty<DropData>(); if (component?.m_dropItems?.m_drops != null) { enumerable = Enumerable.Concat(enumerable, component.m_dropItems.m_drops); } foreach (DropData item in enumerable) { if (!((Object)(object)item.m_item == (Object)null)) { ItemDrop component2 = item.m_item.GetComponent<ItemDrop>(); if (!((Object)(object)component2 == (Object)null)) { string name = ((Object)item.m_item).name; string localName = ((Localization.instance != null) ? Localization.instance.Localize(component2.m_itemData.m_shared.m_name) : component2.m_itemData.m_shared.m_name); AddTierTracker(__instance, name, localName); } } } } private static void AddTierTracker(Leviathan leviathan, string name, string localName) { AddTracker(leviathan, name, localName, Helper._ResourceIconsT3, Helper.GetTier3PinIcons, Plugin._swampResourcesT3Level.Value); AddTracker(leviathan, name, localName, Helper._ResourceIconsT7, Helper.GetTier7PinIcons, Plugin._swampResourcesT3Level.Value); } private static void AddTracker(Leviathan leviathan, string name, string localName, IDictionary<string, Sprite> iconDict, Action<string> fetchIcons, int level) { string localName2 = localName; fetchIcons(name); if (iconDict.TryGetValue(name, out Sprite value) && !((Object)(object)Enumerable.FirstOrDefault(((Component)leviathan).GetComponents<Tracker>(), (Tracker t) => ((Object)t).name == localName2) != (Object)null)) { ((Component)leviathan).gameObject.AddComponent<Tracker>().Create(localName2, Plugin._detectionRadius.Value, value, level); } } } [HarmonyPatch] public class LocationPatch { private static readonly IDictionary<string, string> _LocalizationDict = new Dictionary<string, string>(); [HarmonyPostfix] [HarmonyPatch(typeof(Location), "Awake")] private static void Awake_Postfix(Location __instance) { if (!Helper._DungeonList.Contains(((Object)((Component)__instance).gameObject).name.Replace("(Clone)", ""))) { return; } string text = ((Object)((Component)__instance).gameObject).name.Replace("(Clone)", ""); GetLocalizedName(); if (text == "SunkenCrypt4") { Sprite pinIcon = Skill.loadSprite("crypt.png", 64, 64); ((Component)__instance).gameObject.AddComponent<Tracker>().Create(Localized("SunkenCrypt4"), Plugin._detectionRadius.Value, pinIcon, Plugin._dungeonsLevel.Value); return; } Helper.GetDungeonPinIcons(text); if (Helper._DungeonPinIcons.TryGetValue(text, out Sprite value)) { ((Component)__instance).gameObject.AddComponent<Tracker>().Create(Localized(text), Plugin._detectionRadius.Value, value, Plugin._dungeonsLevel.Value); } } private static void GetLocalizedName() { _LocalizationDict.Clear(); foreach (string dungeon in Helper._DungeonList) { string text; switch (dungeon) { case "Crypt2": case "Crypt3": case "Crypt4": text = Localization.instance.Localize("$location_forestcrypt"); break; case "TrollCave02": text = Localization.instance.Localize("$location_forestcave"); break; case "SunkenCrypt4": text = Localization.instance.Localize("$location_sunkencrypt"); break; case "MountainCave02": text = Localization.instance.Localize("$location_mountaincave"); break; case "Mistlands_DvergrTownEntrance1": case "Mistlands_DvergrTownEntrance2": text = Localization.instance.Localize("$location_dvergrtown"); break; case "MorgenHole2": case "MorgenHole1": case "MorgenHole3": text = Localization.instance.Localize("$location_morgenhole"); break; default: text = ""; break; } string value = text; _LocalizationDict.Add(dungeon, value); } } private static string Localized(string name) { string result = ""; foreach (string key in _LocalizationDict.Keys) { if (!(name != key)) { result = _LocalizationDict[key]; } } return result; } } [HarmonyPatch] public class MinimapPatch { private static int velocity; [HarmonyPostfix] [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(int), typeof(int) })] private static void Explore_Postfix(ref bool __result) { if (__result) { velocity++; } } [HarmonyPostfix] [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(Vector3), typeof(float) })] private static void Explore_Postfix() { if (velocity > 0 && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)(object)Player.m_localPlayer).RaiseSkill("Explorer", 0.1f); } } [HarmonyPrefix] [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(Vector3), typeof(float) })] private static void Explore_Prefix(ref float radius) { velocity = 0; radius *= ((Character)(object)Player.m_localPlayer).GetSkillFactor("Explorer") * (float)Plugin._increasePerLevel.Value + 1f; } } [HarmonyPatch(typeof(ObjectDB), "UpdateRegisters")] public class ObjectDBPatch { public static readonly IDictionary<string, Sprite> _ResourceSpritesDictT1 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceSpritesDictT2 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceSpritesDictT3 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceSpritesDictT4 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceSpritesDictT5 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceSpritesDictT6 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceSpritesDictT7 = new Dictionary<string, Sprite>(); [HarmonyPostfix] private static void UpdateRegisters_Postfix(ObjectDB __instance) { GetResourceT1Sprites(__instance); GetResourceT2Sprites(__instance); GetResourceT3Sprites(__instance); GetResourceT4Sprites(__instance); GetResourceT5Sprites(__instance); GetResourceT6Sprites(__instance); GetResourceT7Sprites(__instance); } private static void GetResourceT1Sprites(ObjectDB objectDB) { _ResourceSpritesDictT1.Clear(); foreach (string item in new HashSet<string>(Plugin._meadowsResourcesT1.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))) { GameObject itemPrefab = objectDB.GetItemPrefab(StringExtensionMethods.GetStableHashCode(item)); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { _ResourceSpritesDictT1.Add(item, component.m_itemData.GetIcon()); } } } } private static void GetResourceT2Sprites(ObjectDB objectDB) { _ResourceSpritesDictT2.Clear(); foreach (string item in new HashSet<string>(Plugin._blackForestResourcesT2.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))) { GameObject itemPrefab = objectDB.GetItemPrefab(StringExtensionMethods.GetStableHashCode(item)); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { _ResourceSpritesDictT2.Add(item, component.m_itemData.GetIcon()); } } } } private static void GetResourceT3Sprites(ObjectDB objectDB) { _ResourceSpritesDictT3.Clear(); foreach (string item in new HashSet<string>(Plugin._swampResourcesT3.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))) { GameObject itemPrefab = objectDB.GetItemPrefab(StringExtensionMethods.GetStableHashCode(item)); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { _ResourceSpritesDictT3.Add(item, component.m_itemData.GetIcon()); } } } } private static void GetResourceT4Sprites(ObjectDB objectDB) { _ResourceSpritesDictT4.Clear(); foreach (string item in new HashSet<string>(Plugin._mountainResourcesT4.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))) { GameObject itemPrefab = objectDB.GetItemPrefab(StringExtensionMethods.GetStableHashCode(item)); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { _ResourceSpritesDictT4.Add(item, component.m_itemData.GetIcon()); } } } } private static void GetResourceT5Sprites(ObjectDB objectDB) { _ResourceSpritesDictT5.Clear(); foreach (string item in new HashSet<string>(Plugin._plainsResourcesT5.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))) { GameObject itemPrefab = objectDB.GetItemPrefab(StringExtensionMethods.GetStableHashCode(item)); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { _ResourceSpritesDictT5.Add(item, component.m_itemData.GetIcon()); } } } } private static void GetResourceT6Sprites(ObjectDB objectDB) { _ResourceSpritesDictT6.Clear(); foreach (string item in new HashSet<string>(Plugin._mistlandsResourcesT6.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))) { GameObject itemPrefab = objectDB.GetItemPrefab(StringExtensionMethods.GetStableHashCode(item)); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { _ResourceSpritesDictT6.Add(item, component.m_itemData.GetIcon()); } } } } private static void GetResourceT7Sprites(ObjectDB objectDB) { _ResourceSpritesDictT7.Clear(); foreach (string item in new HashSet<string>(Plugin._ashlandsResourcesT7.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries))) { GameObject itemPrefab = objectDB.GetItemPrefab(StringExtensionMethods.GetStableHashCode(item)); if (!((Object)(object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { _ResourceSpritesDictT7.Add(item, component.m_itemData.GetIcon()); } } } } } [HarmonyPatch] public class PickablePatch { [HarmonyPostfix] [HarmonyPatch(typeof(Pickable), "SetPicked")] private static void SetPicked_Postfix(Pickable __instance, ref bool picked) { if (!((Object)(object)__instance == (Object)null) && picked) { Tracker component = ((Component)__instance).gameObject.GetComponent<Tracker>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } } [HarmonyPostfix] [HarmonyPatch(typeof(Pickable), "Awake")] private static void Awake_Postfix(Pickable __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_itemPrefab == (Object)null)) { ItemDrop component = __instance.m_itemPrefab.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { string name = ((Object)__instance.m_itemPrefab).name; string localName = ((Localization.instance != null) ? Localization.instance.Localize(component.m_itemData.m_shared.m_name) : component.m_itemData.m_shared.m_name); AddTierTracker(__instance, name, localName); } } } private static void AddTierTracker(Pickable pickable, string name, string localName) { AddTracker(pickable, name, localName, Helper._ResourceIconsT1, Helper.GetTier1PinIcons, Plugin._meadowsResourcesT1Level.Value); AddTracker(pickable, name, localName, Helper._ResourceIconsT2, Helper.GetTier2PinIcons, Plugin._blackForestResourcesT2Level.Value); AddTracker(pickable, name, localName, Helper._ResourceIconsT3, Helper.GetTier3PinIcons, Plugin._swampResourcesT3Level.Value); AddTracker(pickable, name, localName, Helper._ResourceIconsT4, Helper.GetTier4PinIcons, Plugin._mountainResourcesT4Level.Value); AddTracker(pickable, name, localName, Helper._ResourceIconsT5, Helper.GetTier5PinIcons, Plugin._plainsResourcesT5Level.Value); AddTracker(pickable, name, localName, Helper._ResourceIconsT6, Helper.GetTier6PinIcons, Plugin._mistlandsResourcesT6Level.Value); AddTracker(pickable, name, localName, Helper._ResourceIconsT7, Helper.GetTier7PinIcons, Plugin._ashlandsResourcesT7Level.Value); } private static void AddTracker(Pickable pickable, string name, string localName, IDictionary<string, Sprite> iconDict, Action<string> fetchIcons, int level) { string localName2 = localName; fetchIcons(name); if (iconDict.TryGetValue(name, out Sprite value) && !((Object)(object)Enumerable.FirstOrDefault(((Component)pickable).GetComponents<Tracker>(), (Tracker t) => ((Object)t).name == localName2) != (Object)null)) { ((Component)pickable).gameObject.AddComponent<Tracker>().Create(localName2, Plugin._detectionRadius.Value, value, level); } } } [HarmonyPatch] public class PlayerPatch { [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Awake")] private static void Awake_Postfix(Player __instance) { Player __instance2 = __instance; ((Character)__instance2).m_nview.Register<int>("Explorer IncreaseSkill", (Action<long, int>)delegate(long _, int factor) { ((Character)(object)__instance2).RaiseSkill("Explorer", factor); }); } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Update")] private static void Update_Postfix(ref Player __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ((Character)__instance).m_nview.GetZDO().Set("Explorer Skill Factor", ((Character)__instance).GetSkillFactor(Skill.fromName("Explorer"))); } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "AddKnownText")] private static void AddKnownText_Postfix(Player __instance, ref string label) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && label.Length != 0 && label.StartsWith("$lore_") && !__instance.m_knownTexts.ContainsKey(label)) { ((Character)(object)__instance).RaiseSkill("Explorer", Plugin._loreStoneExp.Value); } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "AddKnownBiome")] private static void AddKnownBiome_Prefix(Player __instance, ref Biome biome) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !__instance.m_knownBiome.Contains(biome)) { ((Character)(object)__instance).RaiseSkill("Explorer", Plugin._newBiomeExp.Value); } } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "FixedUpdate")] private static void FixedUpdate_Postfix(Player __instance) { CheckKnownLocation(__instance); } private static void CheckKnownLocation(Player player) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)(object)Player.m_localPlayer || ((Character)player).InIntro() || ((Character)player).InCutscene() || (Object)(object)player == (Object)null) { return; } Location location = Location.GetLocation(((Component)player).transform.position, false); if ((Object)(object)location == (Object)null) { return; } string label = ((Object)((Component)location).gameObject).name.Replace("(Clone)", "") + "_BSE" + Helper.RandomNumber(); if (Location.IsInsideLocation(((Component)player).transform.position, 2f)) { Dictionary<string, string> customData = player.m_customData; Vector3 position = ((Component)location).transform.position; if (!customData.ContainsValue(((object)(Vector3)(ref position)).ToString())) { position = ((Component)location).transform.position; Helper.AddCustomData(player, label, ((object)(Vector3)(ref position)).ToString()); ((Character)(object)player).RaiseSkill("Explorer", Plugin._locationExp.Value); ((Character)player).Message((MessageType)2, "Discovered a new location!", 0, (Sprite)null); } } } } [HarmonyPatch] public class RuneStonePatch { [HarmonyPrefix] [HarmonyPatch(typeof(RuneStone), "Interact")] private static void Interact_Prefix(RuneStone __instance) { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { RandomRuneText randomText = __instance.GetRandomText(); string label = ((Object)((Component)__instance).gameObject).name + "_BSE" + Helper.RandomNumber(); if (randomText != null && !Player.m_localPlayer.m_customData.ContainsValue(randomText.m_text)) { Helper.AddCustomData(Player.m_localPlayer, label, randomText.m_text); ((Character)(object)Player.m_localPlayer).RaiseSkill("Explorer", Plugin._loreStoneExp.Value); } } } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] public class SkillsPatch { private static void Postfix(Skills __instance, SkillType skillType, float factor = 1f) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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) if (Plugin._displayExpGain.Value == Toggle.Off) { return; } ((Character)__instance.m_player).GetSkills().m_skillData.TryGetValue((SkillType)Mathf.Abs(StringExtensionMethods.GetStableHashCode("Explorer")), out var value); if ((SkillType?)skillType != value?.m_info.m_skill) { return; } try { if (value.m_level < 100f) { float value2 = value.m_accumulator / (value.GetNextLevelRequirement() / 100f); ((Character)__instance.m_player).Message((MessageType)1, $"Level {value.m_level.tFloat(0)} Explorer [{value.m_accumulator.tFloat(2)}/{value.GetNextLevelRequirement().tFloat(2)}] ({value2.tFloat(0)}%)", 0, value.m_info.m_icon); } } catch { } } } public class Tracker : MonoBehaviour { public string m_resourceName = ""; private float m_trackRange; private Sprite? m_pinIcon; private PinData? m_pinData; private int m_requiredLevel; private static readonly List<PinData> m_pinList = new List<PinData>(); private static readonly object m_pinLock = new object(); public void Create(string resourceName, float trackRange, Sprite pinIcon, int requiredLevel) { m_resourceName = resourceName; m_trackRange = trackRange; m_pinIcon = pinIcon; m_pinData = null; m_requiredLevel = requiredLevel; } private void Update() { //IL_002c: 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_004b: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) Player player = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)player)) { return; } Vector3 position = ((Component)this).transform.position; position.y = 0f; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(((Component)player).transform.position.x - position.x, ((Component)player).transform.position.z - position.z); float magnitude = ((Vector2)(ref val)).magnitude; float skillFactor = ((Character)(object)player).GetSkillFactor("Explorer"); bool flag = Plugin._iconsOnly.Value == Toggle.On; bool flag2 = magnitude < m_trackRange; lock (m_pinLock) { m_pinList.RemoveAll((PinData pin) => pin == null || Vector3.Distance(((Component)player).transform.position, pin.m_pos) > m_trackRange); while (m_pinList.Count > Plugin._maxPin.Value) { PinData val2 = Enumerable.FirstOrDefault(m_pinList); if (val2 != null) { Minimap.instance.RemovePin(val2); m_pinList.Remove(val2); continue; } break; } } if (m_pinData == null && flag2 && m_requiredLevel > 0 && skillFactor >= (float)m_requiredLevel / 100f && m_pinList.Count < Plugin._maxPin.Value) { lock (m_pinLock) { if (m_pinList.Count < Plugin._maxPin.Value) { m_pinData = HaveSimilarPin(position, (PinType)8, m_resourceName, save: false) ?? Minimap.instance.AddPin(position, (PinType)8, flag ? "" : m_resourceName, false, false, 0L, default(PlatformUserID)); if (m_pinData != null) { m_pinData.m_icon = m_pinIcon; m_pinData.m_worldSize = 0f; m_pinList.Add(m_pinData); } } } } else if (m_pinData != null && !flag2) { RemovePin(); } else if (m_pinData != null && (m_requiredLevel <= 0 || (float)m_requiredLevel / 100f > skillFactor)) { RemovePin(); } else if (m_pinData != null && Plugin._hidePins) { RemovePin(); } if (m_pinData != null) { m_pinData.m_pos = position; } } private void RemovePin() { if (m_pinData == null) { return; } try { lock (m_pinLock) { if (m_pinList.Contains(m_pinData)) { m_pinList.Remove(m_pinData); } } Minimap.instance.RemovePin(m_pinData); } catch { } finally { m_pinData = null; } } private static PinData? HaveSimilarPin(Vector3 pos, PinType type, string name, bool save) { //IL_000e: 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) //IL_001c: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) string name2 = name; Vector3 flatPos = new Vector3(pos.x, 0f, pos.z); return Enumerable.FirstOrDefault((IEnumerable<PinData>)Minimap.instance.m_pins, (Func<PinData, bool>)((PinData x) => x.m_name == name2 && x.m_type == type && x.m_save == save && CheckDistance(x.m_pos, flatPos, 20f))); } private static bool CheckDistance(Vector3 pinPos, Vector3 refPos, float distance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = pinPos.x - refPos.x; float num2 = pinPos.z - refPos.z; return num * num + num2 * num2 < distance * distance; } private void OnDestroy() { RemovePin(); } } } namespace Explorer.Functions { public class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ShowRangeAsPercent; [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string Category; [UsedImplicitly] public Action<ConfigEntryBase> CustomDrawer; } public static class Helper { public static readonly IDictionary<string, Sprite> _ResourceIconsT1 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceIconsT2 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceIconsT3 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceIconsT4 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceIconsT5 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceIconsT6 = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _ResourceIconsT7 = new Dictionary<string, Sprite>(); private static readonly IDictionary<string, Sprite> _DungeonSpritesDict = new Dictionary<string, Sprite>(); public static readonly IDictionary<string, Sprite> _DungeonPinIcons = new Dictionary<string, Sprite>(); public static HashSet<string> _DungeonList = new HashSet<string> { "Crypt2", "Crypt3", "Crypt4", "TrollCave02", "SunkenCrypt4", "MountainCave02", "Mistlands_DvergrTownEntrance1", "Mistlands_DvergrTownEntrance2", "MorgenHole1", "MorgenHole2", "MorgenHole3", "BOM_FlintMine01", "BOM_FlintMine02", "BOM_CopperMine01", "BOM_CopperMine02", "BOM_TinMine01", "BOM_TinMine02", "BOM_CoalMine01", "BOM_CoalMine02", "BOM_IronMine01", "BOM_IronMine02", "BOM_SilverMine01", "BOM_SilverMine02" }; public static float tFloat(this float value, int digits) { double num = Math.Pow(10.0, digits); return (float)(Math.Truncate(num * (double)value) / num); } public static void GetDungeonSprites() { _DungeonSpritesDict.Clear(); foreach (string dungeon in _DungeonList) { Sprite val; switch (dungeon) { case "Crypt2": case "Crypt3": case "Crypt4": val = Skill.loadSprite("burial.png", 64, 64); break; case "TrollCave02": val = Skill.loadSprite("troll_cave.png", 64, 64); break; case "MountainCave02": val = Skill.loadSprite("mountain_cave.png", 64, 64); break; case "Mistlands_DvergrTownEntrance1": val = Skill.loadSprite("mistland_dungeon.png", 64, 64); break; case "Mistlands_DvergrTownEntrance2": val = Skill.loadSprite("mistland_dungeon_rock.png", 64, 64); break; case "MorgenHole2": case "MorgenHole1": case "MorgenHole3": val = Skill.loadSprite("morgen_hole.png", 64, 64); break; case "BOM_CoalMine01": case "BOM_CoalMine02": case "BOM_IronMine01": case "BOM_IronMine02": case "BOM_FlintMine01": case "BOM_FlintMine02": case "BOM_CopperMine01": case "BOM_CopperMine02": case "BOM_SilverMine01": case "BOM_SilverMine02": case "BOM_TinMine01": case "BOM_TinMine02": val = Skill.loadSprite("oremine.png", 64, 64); break; default: val = null; break; } Sprite value = val; _DungeonSpritesDict.Add(dungeon, value); } } public static void GetDungeonPinIcons(string dungeon) { if (_DungeonPinIcons.ContainsKey(dungeon)) { return; } foreach (string key in _DungeonSpritesDict.Keys) { if (!(dungeon != key)) { _DungeonPinIcons.Add(dungeon, _DungeonSpritesDict[key]); } } } public static void GetTier1PinIcons(string resource) { if (_ResourceIconsT1.ContainsKey(resource)) { return; } foreach (string key in ObjectDBPatch._ResourceSpritesDictT1.Keys) { if (!(resource != key)) { _ResourceIconsT1.Add(resource, ObjectDBPatch._ResourceSpritesDictT1[key]); } } } public static void GetTier2PinIcons(string resource) { if (_ResourceIconsT2.ContainsKey(resource)) { return; } foreach (string key in ObjectDBPatch._ResourceSpritesDictT2.Keys) { if (!(resource != key)) { _ResourceIconsT2.Add(resource, ObjectDBPatch._ResourceSpritesDictT2[key]); } } } public static void GetTier3PinIcons(string resource) { if (_ResourceIconsT3.ContainsKey(resource)) { return; } foreach (string key in ObjectDBPatch._ResourceSpritesDictT3.Keys) { if (!(resource != key)) { _ResourceIconsT3.Add(resource, ObjectDBPatch._ResourceSpritesDictT3[key]); } } } public static void GetTier4PinIcons(string resource) { if (_ResourceIconsT4.ContainsKey(resource)) { return; } foreach (string key in ObjectDBPatch._ResourceSpritesDictT4.Keys) { if (!(resource != key)) { _ResourceIconsT4.Add(resource, ObjectDBPatch._ResourceSpritesDictT4[key]); } } } public static void GetTier5PinIcons(string resource) { if (_ResourceIconsT5.ContainsKey(resource)) { return; } foreach (string key in ObjectDBPatch._ResourceSpritesDictT5.Keys) { if (!(resource != key)) { _ResourceIconsT5.Add(resource, ObjectDBPatch._ResourceSpritesDictT5[key]); } } } public static void GetTier6PinIcons(string resource) { if (_ResourceIconsT6.ContainsKey(resource)) { return; } foreach (string key in ObjectDBPatch._ResourceSpritesDictT6.Keys) { if (!(resource != key)) { _ResourceIconsT6.Add(resource, ObjectDBPatch._ResourceSpritesDictT6[key]); } } } public static void GetTier7PinIcons(string resource) { if (_ResourceIconsT7.ContainsKey(resource)) { return; } foreach (string key in ObjectDBPatch._ResourceSpritesDictT7.Keys) { if (!(resource != key)) { _ResourceIconsT7.Add(resource, ObjectDBPatch._ResourceSpritesDictT7[key]); } } } public static void AddCustomData(Player player, string label, string text) { player.m_customData.TryAdd(label, text); } public static string RandomNumber() { int num = Random.Range(0, 9); int num2 = Random.Range(0, 9); int num3 = Random.Range(0, 9); int num4 = Random.Range(0, 9); int num5 = Random.Range(0, 9); return $"{num}{num2}{num3}{num4}{num5}"; } } public enum Toggle { On = 1, Off = 0 } } namespace ServerSync { [PublicAPI] internal abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] internal class SyncedConfigEntry<T> : OwnConfigEntryBase { public readonly ConfigEntry<T> SourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public SyncedConfigEntry(ConfigEntry<T> sourceConfig) { SourceConfig = sourceConfig; base..ctor(); } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } internal abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] internal class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } static void SendAdmin(List<ZNetPeer> peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = Enumerable.First(configSyncs); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List<string> CurrentList = new List<string>(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!Enumerable.SequenceEqual(adminList.GetList(), CurrentList)) { CurrentList = new List<string>(adminList.GetList()); List<ZNetPeer> adminPeer = Enumerable.ToList(Enumerable.Where(ZNet.instance.GetPeers(), delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); })); List<ZNetPeer> nonAdminPeer = Enumerable.ToList(Enumerable.Except(ZNet.instance.GetPeers(), adminPeer)); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync); } } } private class ParsedConfigs { public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>(); public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>(); } [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { private class BufferingSocket : ZPlayFabSocket, ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List<ZPackage> Package = new List<ZPackage>(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; ((ZPlayFabSocket)this)..ctor(); } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void VersionMatch() { if (finished) { Original.VersionMatch(); } else { versionMatchQueued = Package.Count; } } public void Send(ZPackage pkg) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown int pos = pkg.GetPos(); pkg.SetPos(0); int num = pkg.ReadInt(); if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished) { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pos); Package.Add(val); } else { pkg.SetPos(pos); Original.Send(pkg); } } } [HarmonyPriority(800)] [HarmonyPrefix] private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (!__instance.IsServer()) { return; } BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket); object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (val != null && (int)ZNet.m_onlineBackend > 0) { FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket"); object? value = fieldInfo.GetValue(val); ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null); if (val2 != null) { typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId); } fieldInfo.SetValue(val, bufferingSocket); } if (__state == null) { __state = new Dictionary<Assembly, BufferingSocket>(); } __state[Assembly.GetExecutingAssembly()] = bufferingSocket; } [HarmonyPostfix] private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc) { ZRpc rpc2 = rpc; ZNet __instance2 = __instance; Dictionary<Assembly, BufferingSocket> __state2 = __state; ZNetPeer peer; if (__instance2.IsServer()) { object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (peer == null) { SendBufferedData(); } else { ((MonoBehaviour)__instance2).StartCoroutine(sendAsync()); } } void SendBufferedData() { if (rpc2.GetSocket() is BufferingSocket bufferingSocket) { AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original); object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 }); ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null); if (val != null) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original); } } BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()]; bufferingSocket2.finished = true; for (int i = 0; i < bufferingSocket2.Package.Count; i++) { if (i == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } bufferingSocket2.Original.Send(bufferingSocket2.Package[i]); } if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } } IEnumerator sendAsync() { foreach (ConfigSync configSync in configSyncs) { List<PackageEntry> entries = new List<PackageEntry>(); if (configSync.CurrentVersion != null) { entries.Add(new PackageEntry { section = "Internal", key = "serverversion", type = typeof(string), value = configSync.CurrentVersion }); } MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); entries.Add(new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2] { adminList, rpc2.GetSocket().GetHostName() })) }); ZPackage package = ConfigsToPackage(Enumerable.Select(configSync.allConfigs, (OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false); yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package)); } SendBufferedData(); } } } private class PackageEntry { public string section = null; public string key = null; public Type type = null; public object? value; } [HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")] private static class PreventSavingServerInfo { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, ref string __result) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase)) { return true; } __result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType); return false; } } [HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")] private static class PreventConfigRereadChangingValues { [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, string value) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null) { return true; } try { ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType); } catch (Exception ex) { Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}"); } return false; } } private class InvalidDeserializationTypeException : Exception { public string expected = null; public string received = null; public string field = ""; } public static bool ProcessingServerUpdate; public readonly string Name; public string? DisplayName; public string? CurrentVersion; public string? MinimumRequiredVersion; public bool ModRequired = false; private bool? forceConfigLocking; private bool isSourceOfTruth = true; private static readonly HashSet<ConfigSync> configSyncs; private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>(); private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>(); private static bool isServer; private static bool lockExempt; private OwnConfigEntryBase? lockedConfig = null; private const byte PARTIAL_CONFIGS = 1; private const byte FRAGMENTED_CONFIG = 2; private const byte COMPRESSED_CONFIG = 4; private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>(); private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>(); private static long packageCounter; public bool IsLocked { get { bool? flag = forceConfigLocking; bool num; if (!flag.HasValue) { if (lockedConfig == null) { goto IL_0052; } num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0; } else { num = flag.GetValueOrDefault(); } if (!num) { goto IL_0052; } int result = ((!lockExempt) ? 1 : 0); goto IL_0053; IL_0053: return (byte)result != 0; IL_0052: result = 0; goto IL_0053; } set { forceConfigLocking = value; } } public bool IsAdmin => lockExempt || isSourceOfTruth; public bool IsSourceOfTruth { get { return isSourceOfTruth; } private set { if (value != isSourceOfTruth) { isSourceOfTruth = value; this.SourceOfTruthChanged?.Invoke(value); } } } public bool InitialSyncDone { get; private set; } = false; public event Action<bool>? SourceOfTruthChanged; private event Action? lockedConfigChanged; static ConfigSync() { ProcessingServerUpdate = false; configSyncs = new HashSet<ConfigSync>(); lockExempt = false; packageCounter = 0L; RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle); } public ConfigSync(string name) { Name = name; configSyncs.Add(this); new VersionCheck(this); } public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry) { ConfigEntry<T> configEntry2 = configEntry; OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2); SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>; if (syncedEntry == null) { syncedEntry = new SyncedConfigEntry<T>(configEntry2); AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, Enumerable.ToArray(Enumerable.Concat(Enumerable.Concat(new object[1] { new ConfigurationManagerAttributes() }, ((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()), new SyncedConfigEntry<T>[1] { syncedEntry }))); configEntry2.SettingChanged += delegate { if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig) { Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2); } }; allConfigs.Add(syncedEntry); } return syncedEntry; } public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible { if (lockedConfig != null) { throw new Exception("Cannot initialize locking ConfigEntry twice"); } lockedConfig = AddConfigEntry<T>(lockingConfig); lockingConfig.SettingChanged += delegate { this.lockedConfigChanged?.Invoke(); }; return (SyncedConfigEntry<T>)lockedConfig; } internal void AddCustomValue(CustomSyncedValueBase customValue) { CustomSyncedValueBase customValue2 = customValue; if (Enumerable.Contains(Enumerable.Concat(Enumerable.Select(allCustomValues, (CustomSyncedValueBase v) => v.Identifier), new string[1] { "serverversion" }), customValue2.Identifier)) { throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)"); } allCustomValues.Add(customValue2); allCustomValues = new HashSet<CustomSyncedValueBase>(Enumerable.OrderByDescending(allCustomValues, (CustomSyncedValueBase v) => v.Priority)); customValue2.ValueChanged += delegate { if (!ProcessingServerUpdate) { Broadcast(ZRoutedRpc.Everybody, customValue2); } }; } private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package) { lockedConfigChanged += serverLockedSettingChanged; IsSourceOfTruth = false; if (HandleConfigSyncRPC(0L, package, clientUpdate: false)) { InitialSyncDone = true; } } private void RPC_FromOtherClientConfigSync(long sender, ZPackage package) { HandleConfigSyncRPC(sender, package, clientUpdate: true); } private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown try { if (isServer && IsLocked) { ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc; object obj; if (currentRpc == null) { obj = null; } else { ISocket socket = currentRpc.GetSocket(); obj = ((s