Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Valheim Enchantment System v1.9.9
kg.ValheimEnchantmentSystem.dll
Decompiled a week 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.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Dynamic; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Net; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Xml.Serialization; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ItemDataManager; using JetBrains.Annotations; using Jewelcrafting; using LocalizationManager; using Microsoft.CodeAnalysis; using PieceManager; using ServerSync; using SkillManager; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; using fastJSON; using kg.ValheimEnchantmentSystem; using kg.ValheimEnchantmentSystem.Configs; using kg.ValheimEnchantmentSystem.Integrations; using kg.ValheimEnchantmentSystem.Items_Structures; using kg.ValheimEnchantmentSystem.Misc; using kg.ValheimEnchantmentSystem.Platform; using kg.ValheimEnchantmentSystem.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimEnchantmentSystem")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimEnchantmentSystem")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("02E7D016-77BE-40E0-9D13-8656CD0A4FD3")] [assembly: AssemblyFileVersion("1.9.8.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.9.8.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; } } } public static class AnimationSpeedManager { public delegate double Handler(Character character, double speed); private static readonly Harmony Harmony = new Harmony("kg.ValheimEnchantmentSystem.AnimationSpeedManager"); private static readonly MethodInfo TargetMethod = AccessTools.DeclaredMethod(typeof(CharacterAnimEvent), "CustomFixedUpdate", (Type[])null, (Type[])null); private static readonly Dictionary<int, List<Handler>> HandlersByPriority = new Dictionary<int, List<Handler>>(); private static Handler[][] _handlers = Array.Empty<Handler[]>(); private static bool _markerPatchInstalled; private static bool _wrapperInstalled; private static int _handlerIndex; private static bool _changed; [PublicAPI] public static void Add(Handler handler, int priority = 400) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown if (!_markerPatchInstalled) { Harmony.Patch((MethodBase)TargetMethod, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "MarkerPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null); _markerPatchInstalled = true; } if (!HandlersByPriority.TryGetValue(priority, out List<Handler> value)) { value = new List<Handler>(); HandlersByPriority.Add(priority, value); } if (!_wrapperInstalled) { Harmony.Patch((MethodBase)TargetMethod, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "Wrapper", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _wrapperInstalled = true; } value.Add(handler); _handlers = (from pair in HandlersByPriority orderby pair.Key select pair.Value.ToArray()).ToArray(); } private static void Wrapper(Character ___m_character, Animator ___m_animator) { Character ___m_character2 = ___m_character; double num = (double)___m_animator.speed * 10000000.0 % 100.0; if ((!(num > 10.0) || !(num < 30.0)) && !(___m_animator.speed <= 0.001f)) { double num2 = ___m_animator.speed; double num3 = _handlers[_handlerIndex++].Aggregate(num2, (double current, Handler handler) => handler(___m_character2, current)); if (Math.Abs(num3 - num2) > double.Epsilon) { ___m_animator.speed = (float)(num3 - num3 % 1E-05); _changed = true; } } } private static void MarkerPatch(Animator ___m_animator) { if (_changed) { float speed = ___m_animator.speed; double num = (double)speed * 10000000.0 % 100.0; if ((num < 10.0 || num > 30.0) ? true : false) { ___m_animator.speed += 1.9E-06f; } _changed = false; } _handlerIndex = 0; } } namespace PieceManager { [PublicAPI] public enum CraftingTable { None, [InternalName("piece_workbench")] Workbench, [InternalName("piece_cauldron")] Cauldron, [InternalName("forge")] Forge, [InternalName("piece_artisanstation")] ArtisanTable, [InternalName("piece_stonecutter")] StoneCutter, [InternalName("piece_magetable")] MageTable, [InternalName("blackforge")] BlackForge, [InternalName("piece_preptable")] FoodPreparationTable, [InternalName("piece_MeadCauldron")] MeadKetill, Custom } public class InternalName : Attribute { public readonly string internalName; public InternalName(string internalName) { this.internalName = internalName; } } [PublicAPI] public enum BuildPieceCategory { Misc = 0, Crafting = 1, BuildingWorkbench = 2, BuildingStonecutter = 3, Furniture = 4, All = 100, Custom = 99 } public struct Requirement { public string itemName; public int amount; public bool recover; } [PublicAPI] public class RequiredResourcesList { public readonly List<Requirement> Requirements = new List<Requirement>(); public void Add(string item, int amount, bool recover) { Requirements.Add(new Requirement { itemName = item, amount = amount, recover = recover }); } } public struct CraftingStationConfig { public CraftingTable Table; public string? custom; } [PublicAPI] public class CraftingStationList { public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>(); public void Set(CraftingTable table) { Stations.Add(new CraftingStationConfig { Table = table }); } public void Set(string customTable) { Stations.Add(new CraftingStationConfig { Table = CraftingTable.Custom, custom = customTable }); } } [PublicAPI] public class BuildingPieceCategory { public BuildPieceCategory Category; public string custom = ""; public void Set(BuildPieceCategory category) { Category = category; } public void Set(string customCategory) { Category = BuildPieceCategory.Custom; custom = customCategory; } } [PublicAPI] public class PieceTool { public readonly HashSet<string> Tools = new HashSet<string>(); public void Add(string tool) { Tools.Add(tool); } } [PublicAPI] public class BuildPiece { private sealed class PieceConfig { public ConfigEntry<string>? craft; } private static class SerializedRequirements { public static string Serialize(IEnumerable<Requirement> requirements) { return string.Join(",", requirements.Select((Requirement requirement) => $"{requirement.itemName}:{requirement.amount}:{requirement.recover}")); } public static Requirement[] ToPieceReqs(ObjectDB objectDb, IEnumerable<Requirement> requirements) { ObjectDB objectDb2 = objectDb; return (from requirement in requirements.Where((Requirement requirement) => !string.IsNullOrWhiteSpace(requirement.itemName)).Select((Func<Requirement, Requirement>)delegate(Requirement requirement) { //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown GameObject itemPrefab = objectDb2.GetItemPrefab(requirement.itemName); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null)) { return new Requirement { m_resItem = val, m_amount = requirement.amount, m_recover = requirement.recover }; } Debug.LogWarning((object)(Plugin.Info.Metadata.GUID + ": required build piece item '" + requirement.itemName + "' does not exist.")); return null; }) where requirement != null select requirement).ToArray(); } public static Requirement[] ToPieceReqs(ObjectDB objectDb, string serialized) { return ToPieceReqs(objectDb, serialized.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(delegate(string entry) { string[] array = entry.Split(new char[1] { ':' }); Requirement result = default(Requirement); result.itemName = array[0]; result.amount = ((array.Length <= 1 || !int.TryParse(array[1], out var result2)) ? 1 : result2); bool result3 = default(bool); result.recover = array.Length <= 2 || !bool.TryParse(array[2], out result3) || result3; return result; })); } } private static readonly Harmony Harmony; internal static readonly List<BuildPiece> registeredPieces; private static readonly Dictionary<BuildPiece, PieceConfig> pieceConfigs; private static bool configBindingsInitialized; [Description("Disables generation of configs for registered pieces.")] public static bool ConfigurationEnabled; public readonly GameObject Prefab; public readonly RequiredResourcesList RequiredItems = new RequiredResourcesList(); public readonly BuildingPieceCategory Category = new BuildingPieceCategory(); public readonly PieceTool Tool = new PieceTool(); public CraftingStationList Crafting = new CraftingStationList(); public ConfigEntryBase? RecipeIsActive; private static BaseUnityPlugin? _plugin; 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)Assembly.GetExecutingAssembly().DefinedTypes.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); _plugin = val; obj = (object)val; } return (BaseUnityPlugin)obj; } } static BuildPiece() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown Harmony = new Harmony("kg.ValheimEnchantmentSystem.ThinPieceManager"); registeredPieces = new List<BuildPiece>(); pieceConfigs = new Dictionary<BuildPiece, PieceConfig>(); ConfigurationEnabled = true; Harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(BuildPiece), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(BuildPiece), "Patch_ObjectDBInit", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(BuildPiece), "Patch_ObjectDBInit", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Harmony.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(BuildPiece), "Patch_ZNetSceneAwake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public BuildPiece(AssetBundle bundle, string prefabName) { Prefab = bundle.LoadAsset<GameObject>(prefabName) ?? throw new InvalidOperationException("Could not load piece prefab '" + prefabName + "' from asset bundle."); ((Object)Prefab).name = prefabName; ApplyStaticDefaults(this); registeredPieces.Add(this); } private static void Patch_FejdStartup() { EnsureConfigBindings(); } internal static void Patch_ObjectDBInit(ObjectDB __instance) { EnsureConfigBindings(); if ((Object)(object)__instance.GetItemPrefab("Hammer") == (Object)null) { return; } foreach (BuildPiece registeredPiece in registeredPieces) { ApplyRuntimeConfiguration(registeredPiece, __instance, ZNetScene.instance); } } internal static void Patch_ZNetSceneAwake(ZNetScene __instance) { foreach (BuildPiece registeredPiece in registeredPieces) { if (!__instance.m_prefabs.Contains(registeredPiece.Prefab)) { __instance.m_prefabs.Add(registeredPiece.Prefab); } int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)registeredPiece.Prefab).name); if (!__instance.m_namedPrefabs.ContainsKey(stableHashCode)) { __instance.m_namedPrefabs.Add(stableHashCode, registeredPiece.Prefab); } } } internal static void EnsureConfigBindings() { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown if (configBindingsInitialized) { return; } foreach (BuildPiece piece in registeredPieces) { ApplyStaticDefaults(piece); if (ConfigurationEnabled) { string token = piece.Prefab.GetComponent<Piece>()?.m_name ?? ((Object)piece.Prefab).name; string localizedDisplayName = GetLocalizedDisplayName(token, ((Object)piece.Prefab).name); string text = SharedLocalizationCache.LocalizeForConfig(token); string group = (string.IsNullOrWhiteSpace(text) ? localizedDisplayName : text); PieceConfig pieceConfig2 = (pieceConfigs[piece] = new PieceConfig()); PieceConfig pieceConfig3 = pieceConfig2; pieceConfig3.craft = Config(group, "Crafting Costs", SerializedRequirements.Serialize(piece.RequiredItems.Requirements), new ConfigDescription("Item costs to craft " + localizedDisplayName + ".", (AcceptableValueBase)null, Array.Empty<object>())); pieceConfig3.craft.SettingChanged += delegate { ReapplyRuntimeConfiguration(piece); }; } } configBindingsInitialized = true; } private static void ReapplyRuntimeConfiguration(BuildPiece piece) { if (!((Object)(object)ObjectDB.instance == (Object)null)) { ApplyRuntimeConfiguration(piece, ObjectDB.instance, ZNetScene.instance); } } private static void ApplyStaticDefaults(BuildPiece piece) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) Piece component = piece.Prefab.GetComponent<Piece>(); if (!((Object)(object)component == (Object)null)) { component.m_category = (PieceCategory)((piece.Category.Category == BuildPieceCategory.Custom) ? BuildPieceCategory.Crafting : piece.Category.Category); } } private static void ApplyRuntimeConfiguration(BuildPiece piece, ObjectDB objectDb, ZNetScene? scene) { Piece component = piece.Prefab.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { return; } if (pieceConfigs.TryGetValue(piece, out PieceConfig value)) { ConfigEntry<string> craft = value.craft; if (craft != null) { component.m_resources = SerializedRequirements.ToPieceReqs(objectDb, craft.Value); goto IL_005a; } } component.m_resources = SerializedRequirements.ToPieceReqs(objectDb, piece.RequiredItems.Requirements); goto IL_005a; IL_005a: ApplyCraftingStation(piece, component, scene); ApplyToolRegistration(piece, objectDb); ConfigEntryBase recipeIsActive = piece.RecipeIsActive; if (recipeIsActive != null) { component.m_enabled = Convert.ToInt32(recipeIsActive.BoxedValue) != 0; } } private static void ApplyCraftingStation(BuildPiece piece, Piece pieceComponent, ZNetScene? scene) { if (piece.Crafting.Stations.Count == 0 || (Object)(object)scene == (Object)null) { pieceComponent.m_craftingStation = null; return; } CraftingStationConfig craftingStationConfig = piece.Crafting.Stations.First(); switch (craftingStationConfig.Table) { case CraftingTable.None: pieceComponent.m_craftingStation = null; break; case CraftingTable.Custom: { GameObject prefab2 = scene.GetPrefab(craftingStationConfig.custom); pieceComponent.m_craftingStation = ((prefab2 != null) ? prefab2.GetComponent<CraftingStation>() : null); break; } default: { GameObject prefab = scene.GetPrefab(GetInternalName(craftingStationConfig.Table)); pieceComponent.m_craftingStation = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null); break; } } } private static void ApplyToolRegistration(BuildPiece piece, ObjectDB objectDb) { foreach (GameObject item in objectDb.m_items) { (item.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces)?.m_pieces.Remove(piece.Prefab); } IEnumerable<string> enumerable = piece.Tool.Tools.DefaultIfEmpty("Hammer"); foreach (string item2 in enumerable) { GameObject itemPrefab = objectDb.GetItemPrefab(item2); if (Object.op_Implicit((Object)(object)itemPrefab)) { PieceTable val = itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces; if ((Object)(object)val != (Object)null && !val.m_pieces.Contains(piece.Prefab)) { val.m_pieces.Add(piece.Prefab); } } } } private static string GetLocalizedDisplayName(string? token, string fallback) { if (string.IsNullOrWhiteSpace(token) || Localization.instance == null) { return fallback; } string text = Localization.instance.Localize(token).Trim(); if (!string.IsNullOrWhiteSpace(text) && !string.Equals(text, token, StringComparison.Ordinal)) { return text; } return fallback; } private static string GetInternalName(CraftingTable value) { return ((InternalName)typeof(CraftingTable).GetMember(value.ToString())[0].GetCustomAttributes(typeof(InternalName), inherit: false).First()).internalName; } private static ConfigEntry<T> Config<T>(string group, string name, T value, ConfigDescription description) { return ValheimEnchantmentSystem.config(group, name, value, description); } } } namespace SkillManager { [PublicAPI] public class Skill { private readonly struct SavedSkillState { public readonly float Level; public readonly float Accumulator; public SavedSkillState(float level, float accumulator) { Level = level; Accumulator = accumulator; } } public static class LocalizationCache { internal static void LocalizationPostfix(Localization __instance, string language) { SharedLocalizationCache.Track(__instance, language); } public static Localization ForLanguage(string? language = null) { return SharedLocalizationCache.ForLanguage(language); } public static string LocalizeForConfig(string token, string preferredLanguage = "English") { return SharedLocalizationCache.LocalizeForConfig(token, preferredLanguage); } } [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("$", ""); keys.Add(this); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; if (Localization.m_instance != null) { 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.m_instance != null) { 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)) { __instance.AddWord(key.Key, Localization.instance.Localize(value2)); } } } } private class ConfigurationManagerAttributes { [UsedImplicitly] public string? Category; } 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 configBindingsInitialized; private const string RequiredExperienceFormulaDescription = "Required EXP per level follows: ((current level + 1)^1.5) / 2 + 0.5."; private static bool InitializedTerminal; private static BaseUnityPlugin? _plugin; 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 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)Assembly.GetExecutingAssembly().DefinedTypes.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); _plugin = val; obj = (object)val; } return (BaseUnityPlugin)obj; } } 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_016a: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Expected O, but got Unknown //IL_02b0: Expected O, but got Unknown //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_0306: Expected O, but got Unknown skills = new Dictionary<SkillType, Skill>(); skillByName = new Dictionary<string, Skill>(); InitializedTerminal = false; 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(ZNet), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_ZNet_Awake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_Awake", (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), "Load", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_Load_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_Load_Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "IsSkillValid", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_IsSkillValid", (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(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 bool IsEnchantmentSkill(Skill skill) { return string.Equals(skill.internalSkillName, "kg_Enchantment", StringComparison.Ordinal); } private static string GetConfigGroup(Skill skill) { if (!IsEnchantmentSkill(skill)) { return skill.internalSkillName; } return "Enchantment"; } private static string GetConfigCategory(Skill skill, string localizedName) { if (!IsEnchantmentSkill(skill)) { return localizedName; } return "Enchantment"; } private static string GetSkillKeyDescription(string skillKey) { return "Skill key: " + skillKey + "."; } private static string GetLocalizedDisplayName(string token, string fallback) { if (Localization.instance == null) { return fallback; } string text = Localization.instance.Localize(token).Trim(); if (!string.IsNullOrWhiteSpace(text)) { return text; } return fallback; } private static void Patch_FejdStartup() { EnsureConfigBindings(); } private static void Patch_ZNet_Awake() { EnsureConfigBindings(); } private static void Patch_Skills_Awake(Skills __instance) { EnsureSkillDefinitions(__instance); } private static void EnsureSkillDefinitions(Skills? skillComponent) { if ((Object)(object)skillComponent == (Object)null) { return; } foreach (Skill customSkill in skills.Values) { if (!skillComponent.m_skills.Any((SkillDef skillDef) => skillDef?.m_skill == (SkillType?)customSkill.skillDef.m_skill)) { skillComponent.m_skills.Add(customSkill.skillDef); } } } private static Dictionary<SkillType, SavedSkillState>? CaptureCustomSkillStates(ZPackage? pkg) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0045: 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_007a: Unknown result type (might be due to invalid IL or missing references) if (pkg == null || skills.Count == 0) { return null; } try { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pkg.GetPos()); int num = val.ReadInt(); int num2 = val.ReadInt(); Dictionary<SkillType, SavedSkillState> dictionary = null; for (int i = 0; i < num2; i++) { SkillType key = (SkillType)val.ReadInt(); float level = val.ReadSingle(); float accumulator = ((num >= 2) ? val.ReadSingle() : 0f); if (skills.ContainsKey(key)) { if (dictionary == null) { dictionary = new Dictionary<SkillType, SavedSkillState>(); } dictionary[key] = new SavedSkillState(level, accumulator); } } return dictionary; } catch { return null; } } private static void RestoreCustomSkillStates(Skills? skillComponent, Dictionary<SkillType, SavedSkillState>? capturedStates) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)skillComponent == (Object)null || capturedStates == null || capturedStates.Count == 0) { return; } EnsureSkillDefinitions(skillComponent); foreach (KeyValuePair<SkillType, SavedSkillState> capturedState in capturedStates) { Skill skill = skillComponent.GetSkill(capturedState.Key); skill.m_level = capturedState.Value.Level; skill.m_accumulator = capturedState.Value.Accumulator; } } private static void Patch_Skills_Load_Prefix(Skills __instance, ZPackage pkg, out Dictionary<SkillType, SavedSkillState>? __state) { EnsureSkillDefinitions(__instance); __state = CaptureCustomSkillStates(pkg); } private static void Patch_Skills_Load_Postfix(Skills __instance, Dictionary<SkillType, SavedSkillState>? __state) { RestoreCustomSkillStates(__instance, __state); } private static void EnsureConfigBindings() { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown if (configBindingsInitialized) { return; } foreach (Skill skill in skills.Values) { if (!skill.Configurable) { continue; } string key = skill.Name.Key; string fallback = new Regex("['[\"\\]]").Replace(LocalizationCache.LocalizeForConfig(key), "").Trim(); string localizedDisplayName = GetLocalizedDisplayName(key, fallback); string configGroup = GetConfigGroup(skill); string configCategory = GetConfigCategory(skill, localizedDisplayName); ConfigEntry<float> skillGain = config(configGroup, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill. " + GetSkillKeyDescription(key) + " Required EXP per level follows: ((current level + 1)^1.5) / 2 + 0.5.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = configCategory } })); skill.SkillGainFactor = skillGain.Value; skillGain.SettingChanged += delegate { skill.SkillGainFactor = skillGain.Value; }; if (!IsEnchantmentSkill(skill)) { ConfigEntry<float> skillEffect = config(configGroup, "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 = configCategory } })); skill.SkillEffectFactor = skillEffect.Value; skillEffect.SettingChanged += delegate { skill.SkillEffectFactor = skillEffect.Value; }; } ConfigEntry<int> skillLoss = config(configGroup, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death. " + GetSkillKeyDescription(key) + " Required EXP per level follows: ((current level + 1)^1.5) / 2 + 0.5.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { Category = configCategory } })); skill.skillLoss = skillLoss.Value; skillLoss.SettingChanged += delegate { skill.skillLoss = skillLoss.Value; }; } configBindingsInitialized = true; } 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(skills.Values.Select((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; } Skill skill = skills[skillType]; return skill.skillDef; } private static void Patch_Skills_IsSkillValid(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 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_0008: Expected O, but got Unknown Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name)); return val; } private 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) { return ValheimEnchantmentSystem.config(group, name, value, description); } 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>())); } } public static class SkillManagerVersion { public const string Version = "1.7.0"; } [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 LocalizationManager { [PublicAPI] public static class SharedLocalizationCache { private static readonly Dictionary<string, WeakReference<Localization>> Localizations = new Dictionary<string, WeakReference<Localization>>(); private static readonly object CacheLock = new object(); public static void Track(Localization localization, string language) { Localization localization2 = localization; lock (CacheLock) { Localization target; string key = Localizations.FirstOrDefault<KeyValuePair<string, WeakReference<Localization>>>((KeyValuePair<string, WeakReference<Localization>> pair) => pair.Value.TryGetTarget(out target) && target == localization2).Key; if (key != null) { Localizations.Remove(key); } Localizations[language] = new WeakReference<Localization>(localization2); } } public static Localization ForLanguage(string? language = null) { bool flag = language != null; string text = language ?? PlayerPrefs.GetString("language", "English"); lock (CacheLock) { if (Localizations.TryGetValue(text, out WeakReference<Localization> value) && value.TryGetTarget(out var target)) { return target; } } if (Localization.m_instance != null) { Localization instance = Localization.instance; string selectedLanguage = instance.GetSelectedLanguage(); Track(instance, selectedLanguage); if (!flag || string.Equals(selectedLanguage, text, StringComparison.OrdinalIgnoreCase)) { return instance; } throw new InvalidOperationException("Requested localization '" + text + "' is not cached. Active language is '" + selectedLanguage + "'."); } throw new InvalidOperationException("No localization instance is available for language '" + text + "'."); } public static string LocalizeForConfig(string token, string preferredLanguage = "English") { if (string.IsNullOrWhiteSpace(token)) { return string.Empty; } string text = (token.StartsWith("$", StringComparison.Ordinal) ? token : ("$" + token)); string key = text.TrimStart(new char[1] { '$' }); if (Localizer.TryGetConfigText(preferredLanguage, key, out string text2)) { return text2; } try { string text3 = ForLanguage(preferredLanguage).Localize(text).Trim(); if (!string.IsNullOrWhiteSpace(text3) && !string.Equals(text3, text, StringComparison.Ordinal)) { return text3; } } catch { } string text4 = text.TrimStart(new char[1] { '$' }).Replace('_', ' ').Trim(); if (text4.Length != 0) { return text4; } return text; } } [PublicAPI] public class Localizer { private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> LoadedTexts; private static readonly object LoadedTextsLock; private static readonly ConditionalWeakTable<Localization, string> LocalizationLanguage; private static readonly List<WeakReference<Localization>> LocalizationObjects; private static readonly List<string> FileExtensions; private static BaseUnityPlugin? _plugin; private static readonly object ExternalLocalizationFilesLock; private static Dictionary<string, string>? _externalLocalizationFiles; private static BaseUnityPlugin plugin { get { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } public static event Action? OnLocalizationComplete; private static string? TryParseLanguageFromExternalFile(string filePath) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); string text = plugin.Info.Metadata.GUID + "."; if (!fileNameWithoutExtension.StartsWith(text, StringComparison.OrdinalIgnoreCase)) { return null; } string text2 = fileNameWithoutExtension.Substring(text.Length); if (!string.IsNullOrWhiteSpace(text2)) { return text2; } return null; } private static bool HasSupportedExtension(string filePath) { return FileExtensions.Contains<string>(Path.GetExtension(filePath), StringComparer.OrdinalIgnoreCase); } private static Dictionary<string, string> BuildExternalLocalizationFiles() { Dictionary<string, string> dictionary = new Dictionary<string, string>(); string directoryName = Path.GetDirectoryName(Paths.PluginPath); foreach (string item in Directory.GetFiles(directoryName, plugin.Info.Metadata.GUID + ".*", SearchOption.AllDirectories).Where(HasSupportedExtension)) { string text = TryParseLanguageFromExternalFile(item); if (text != null) { if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.GUID + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } } return dictionary; } private static Dictionary<string, string> GetExternalLocalizationFiles() { lock (ExternalLocalizationFilesLock) { if (_externalLocalizationFiles == null) { _externalLocalizationFiles = BuildExternalLocalizationFiles(); } return _externalLocalizationFiles; } } private static void UpdatePlaceholderText(Localization localization, string key) { if (!LocalizationLanguage.TryGetValue(localization, out string value) || !LoadedTexts.TryGetValue(value, out Dictionary<string, string> value2) || !value2.TryGetValue(key, out var value3)) { return; } if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value4)) { value3 = value4.Aggregate(value3, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, value3); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull { string key2 = key; string placeholder2 = placeholder; Func<T, string> convertConfigValue2 = convertConfigValue; ConfigEntry<T> config2 = config; if (convertConfigValue2 == null) { convertConfigValue2 = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key2)) { PlaceholderProcessors[key2] = new Dictionary<string, Func<string>>(); } config2.SettingChanged += delegate { UpdatePlaceholder(); }; if (Localization.instance != null && LoadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { if (Localization.instance != null) { PlaceholderProcessors[key2][placeholder2] = () => convertConfigValue2(config2.Value); UpdatePlaceholderText(Localization.instance, key2); } } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in LocalizationObjects) { if (localizationObject.TryGetTarget(out var target)) { string orCreateValue = LocalizationLanguage.GetOrCreateValue(target); if (!LoadedTexts.TryGetValue(orCreateValue, out Dictionary<string, string> value)) { value = new Dictionary<string, string>(); LoadedTexts[orCreateValue] = value; } if (!target.m_translations.ContainsKey(key)) { value[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { LocalizationObjects.Remove(item); } } public static bool TryGetConfigText(string language, string key, out string text) { text = string.Empty; if (string.IsNullOrWhiteSpace(language) || string.IsNullOrWhiteSpace(key)) { return false; } Dictionary<string, string> dictionary = EnsureConfigTextsLoaded(language); if (dictionary == null || !dictionary.TryGetValue(key, out var value) || string.IsNullOrWhiteSpace(value)) { return false; } text = value.Trim(); return text.Length > 0; } public static void Load() { _ = plugin; } public static void LoadLocalizationLater(Localization __instance) { LoadLocalization(Localization.instance, __instance.GetSelectedLanguage()); } public static void SafeCallLocalizeComplete() { Localizer.OnLocalizationComplete?.Invoke(); } private static void LoadLocalization(Localization __instance, string language) { if (!LocalizationLanguage.Remove(__instance)) { LocalizationObjects.Add(new WeakReference<Localization>(__instance)); } LocalizationLanguage.Add(__instance, language); SharedLocalizationCache.Track(__instance, language); Dictionary<string, string> externalLocalizationFiles = GetExternalLocalizationFiles(); byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary<string, string> dictionary = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array)); if (dictionary == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text = null; if (language != "English") { if (externalLocalizationFiles.TryGetValue(language, out var value)) { text = File.ReadAllText(value); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text = Encoding.UTF8.GetString(array2); } } } if (text == null && externalLocalizationFiles.TryGetValue("English", out var value2)) { text = File.ReadAllText(value2); } if (text != null) { foreach (KeyValuePair<string, string> item in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>()) { dictionary[item.Key] = item.Value; } } LoadedTexts[language] = dictionary; foreach (KeyValuePair<string, string> item2 in dictionary) { UpdatePlaceholderText(__instance, item2.Key); } } static Localizer() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); LoadedTexts = new Dictionary<string, Dictionary<string, string>>(); LoadedTextsLock = new object(); LocalizationLanguage = new ConditionalWeakTable<Localization, string>(); LocalizationObjects = new List<WeakReference<Localization>>(); FileExtensions = new List<string>(2) { ".json", ".yml" }; ExternalLocalizationFilesLock = new object(); Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { Assembly assembly = typeof(Localizer).Assembly; foreach (string fileExtension in FileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension, assembly); if (array != null) { return array; } } return null; } private static Dictionary<string, string>? EnsureConfigTextsLoaded(string language) { lock (LoadedTextsLock) { if (LoadedTexts.TryGetValue(language, out Dictionary<string, string> value)) { return value; } Dictionary<string, string> externalLocalizationFiles = GetExternalLocalizationFiles(); string text = null; if (externalLocalizationFiles.TryGetValue(language, out var value2)) { text = File.ReadAllText(value2); } else { byte[] array = LoadTranslationFromAssembly(language); if (array != null) { text = Encoding.UTF8.GetString(array); } } if (text == null) { return null; } Dictionary<string, string> dictionary = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text); if (dictionary == null) { return null; } LoadedTexts[language] = dictionary; return dictionary; } } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { string resourceFileName2 = resourceFileName; using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName2, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } public static class LocalizationManagerVersion { public const string Version = "1.4.2"; } } namespace ItemDataManager { [PublicAPI] public abstract class ItemData { internal static WeakReference<ItemInfo> constructingInfo = null; internal WeakReference<ItemInfo>? info; private static readonly FieldInfo parameterInfoClassImpl = AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl"); private static Dictionary<Type, Dictionary<string, FieldInfo>> serializedFields = new Dictionary<Type, Dictionary<string, FieldInfo>>(); public string CustomDataKey { get; internal set; } protected virtual bool AllowStackingIdenticalValues { get; set; } public string Value { get { if (!Item.m_customData.TryGetValue(CustomDataKey, out var value)) { return ""; } return value; } set { Item.m_customData[CustomDataKey] = value; } } public string Key { get; internal set; } public bool IsCloned => Info.isCloned.Contains(CustomDataKey); public bool IsAlive { get { ItemInfo target; return (info ?? constructingInfo).TryGetTarget(out target); } } public ItemData Item => Info.ItemData; public ItemInfo Info { get { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (!(info ?? constructingInfo).TryGetTarget(out ItemInfo target)) { return new ItemInfo(new ItemData()); } return target; } } public virtual void FirstLoad() { } public virtual void Load() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown Dictionary<string, FieldInfo> dictionary = fetchSerializedFields(); if (dictionary == null || dictionary.Count <= 0 || Value == "") { return; } List<object> list = new List<object>(); string[] array = Value.Split(new char[1] { '|' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); if (array2.Length == 2 && dictionary.TryGetValue(array2[0], out var value)) { ZPackage val = new ZPackage(array2[1]); ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); parameterInfoClassImpl.SetValue(parameterInfo, value.FieldType); list.Clear(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, val, ref list); if (list.Count > 0) { value.SetValue(this, list[0]); } } } } public virtual void Save() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown Dictionary<string, FieldInfo> dictionary = fetchSerializedFields(); if (dictionary == null || dictionary.Count <= 0) { return; } StringBuilder stringBuilder = new StringBuilder(); foreach (FieldInfo value in dictionary.Values) { ZPackage val = new ZPackage(); ZRpc.Serialize(new object[1] { value.GetValue(this) }, ref val); stringBuilder.Append(value.Name); stringBuilder.Append(':'); stringBuilder.Append(val.GetBase64()); stringBuilder.Append('|'); } int length = stringBuilder.Length - 1; stringBuilder.Length = length; Value = stringBuilder.ToString(); } public virtual void Unload() { } public virtual void Upgraded() { } public virtual string? TryStack(ItemData? data) { if (!AllowStackingIdenticalValues || !(data?.Value == Value)) { return null; } return Value; } private Dictionary<string, FieldInfo> fetchSerializedFields() { Type type = GetType(); if (serializedFields.TryGetValue(type, out Dictionary<string, FieldInfo> value)) { return value; } return serializedFields[type] = (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where f.GetCustomAttributes(typeof(SerializeField), inherit: true).Length != 0 select f).ToDictionary((FieldInfo f) => f.Name, (FieldInfo f) => f); } } public sealed class StringItemData : ItemData { } [PublicAPI] public class ItemInfo : IEnumerable<ItemData>, IEnumerable { [CompilerGenerated] private sealed class <>c__DisplayClass57_0 { public Label target; public CodeInstruction targetedInstr; internal bool <CheckStackableInFindFreeStackMethods>b__1(CodeInstruction i) { return i.labels.Contains(target); } internal bool <CheckStackableInFindFreeStackMethods>b__2(CodeInstruction i) { Label? label = default(Label?); if (CodeInstructionExtensions.Branches(i, ref label)) { return targetedInstr.labels.Contains(label.Value); } return false; } } [CompilerGenerated] private sealed class <CheckStackableInFindFreeStackMethods>d__57 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructionsEnumerable; public IEnumerable<CodeInstruction> <>3__instructionsEnumerable; private <>c__DisplayClass57_0 <>8__1; private CodeInstruction[] <instructions>5__2; private CodeInstruction <lastBranch>5__3; private CodeInstruction <loadingInstruction>5__4; private int <i>5__5; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckStackableInFindFreeStackMethods>d__57(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <instructions>5__2 = null; <lastBranch>5__3 = null; <loadingInstruction>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Expected O, but got Unknown //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Expected O, but got Unknown //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Expected O, but got Unknown int num; switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass57_0(); <instructions>5__2 = instructionsEnumerable.ToArray(); <>8__1.target = (Label)<instructions>5__2.First((CodeInstruction i) => i.opcode == OpCodes.Br || i.opcode == OpCodes.Br_S).operand; <>8__1.targetedInstr = <instructions>5__2.First((CodeInstruction i) => i.labels.Contains(<>8__1.target)); Label? label = default(Label?); <lastBranch>5__3 = <instructions>5__2.Reverse().First((CodeInstruction i) => CodeInstructionExtensions.Branches(i, ref label) && <>8__1.targetedInstr.labels.Contains(label.Value)); <loadingInstruction>5__4 = null; <i>5__5 = 0; break; } case 1: <>1__state = -1; if (<loadingInstruction>5__4 == null && <instructions>5__2[<i>5__5].opcode == OpCodes.Call && ((MethodInfo)<instructions>5__2[<i>5__5].operand).Name == "get_Current") { <loadingInstruction>5__4 = <instructions>5__2[<i>5__5 + 1].Clone(); <loadingInstruction>5__4.opcode = new Dictionary<OpCode, OpCode> { { OpCodes.Stloc_0, OpCodes.Ldloc_0 }, { OpCodes.Stloc_1, OpCodes.Ldloc_1 }, { OpCodes.Stloc_2, OpCodes.Ldloc_2 }, { OpCodes.Stloc_3, OpCodes.Ldloc_3 }, { OpCodes.Stloc_S, OpCodes.Ldloc_S } }[<loadingInstruction>5__4.opcode]; } if (<instructions>5__2[<i>5__5] == <lastBranch>5__3) { <>2__current = <loadingInstruction>5__4; <>1__state = 2; return true; } goto IL_02bc; case 2: <>1__state = -1; <>2__current = new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.DeclaredField(typeof(ItemInfo), "checkingForStackableItemData")); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "CheckItemDataIsStackableFindFree", (Type[])null, (Type[])null)); <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = new CodeInstruction(OpCodes.Brfalse, (object)<>8__1.target); <>1__state = 5; return true; case 5: { <>1__state = -1; goto IL_02bc; } IL_02bc: num = <i>5__5 + 1; <i>5__5 = num; break; } if (<i>5__5 < <instructions>5__2.Length) { <>2__current = <instructions>5__2[<i>5__5]; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <CheckStackableInFindFreeStackMethods>d__57 <CheckStackableInFindFreeStackMethods>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <CheckStackableInFindFreeStackMethods>d__ = this; } else { <CheckStackableInFindFreeStackMethods>d__ = new <CheckStackableInFindFreeStackMethods>d__57(0); } <CheckStackableInFindFreeStackMethods>d__.instructionsEnumerable = <>3__instructionsEnumerable; return <CheckStackableInFindFreeStackMethods>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <ImportCustomDataOnUpgrade>d__71 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructionList; public IEnumerable<CodeInstruction> <>3__instructionList; private List<CodeInstruction>.Enumerator <>7__wrap1; private CodeInstruction <instruction>5__3; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ImportCustomDataOnUpgrade>d__71(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 2u) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = default(List<CodeInstruction>.Enumerator); <instruction>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; List<CodeInstruction> list = instructionList.ToList(); <>7__wrap1 = list.GetEnumerator(); <>1__state = -3; break; } case 1: <>1__state = -3; if (<instruction>5__3.opcode == OpCodes.Stfld && CodeInstructionExtensions.OperandIs(<instruction>5__3, (MemberInfo)AccessTools.DeclaredField(typeof(ItemData), "m_dropPrefab"))) { <>2__current = new CodeInstruction(OpCodes.Ldarg_0, (object)null); <>1__state = 2; return true; } goto IL_0118; case 2: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ItemInfo), "CopyCustomDataFromUpgradedItem", (Type[])null, (Type[])null)); <>1__state = 3; return true; case 3: { <>1__state = -3; goto IL_0118; } IL_0118: <instruction>5__3 = null; break; } if (<>7__wrap1.MoveNext()) { <instruction>5__3 = <>7__wrap1.Current; <>2__current = <instruction>5__3; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = default(List<CodeInstruction>.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <ImportCustomDataOnUpgrade>d__71 <ImportCustomDataOnUpgrade>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <ImportCustomDataOnUpgrade>d__ = this; } else { <ImportCustomDataOnUpgrade>d__ = new <ImportCustomDataOnUpgrade>d__71(0); } <ImportCustomDataOnUpgrade>d__.instructionList = <>3__instructionList; return <ImportCustomDataOnUpgrade>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <TransferCustomItemDataOnUpgrade>d__68 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private MethodInfo <itemDeleter>5__2; private IEnumerator<CodeInstruction> <>7__wrap2; private CodeInstruction <instruction>5__4; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TransferCustomItemDataOnUpgrade>d__68(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 2u) { try { } finally { <>m__Finally1(); } } <itemDeleter>5__2 = null; <>7__wrap2 = null; <instruction>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <itemDeleter>5__2 = AccessTools.DeclaredMethod(typeof(Inventory), "RemoveItem", new Type[1] { typeof(ItemData) }, (Type[])null); <>7__wrap2 = instructions.GetEnumerator(); <>1__state = -3; goto IL_0136; case 1: <>1__state = -3; <>2__current = new CodeInstruction(OpCodes.Stsfld, (object)AccessTools.DeclaredField(typeof(ItemInfo), "currentlyUpgradingItem")); <>1__state = 2; return true; case 2: <>1__state = -3; goto IL_0110; case 3: { <>1__state = -3; <instruction>5__4 = null; goto IL_0136; } IL_0136: if (<>7__wrap2.MoveNext()) { <instruction>5__4 = <>7__wrap2.Current; if (<instruction>5__4.opcode == OpCodes.Callvirt && CodeInstructionExtensions.OperandIs(<instruction>5__4, (MemberInfo)<itemDeleter>5__2)) { <>2__current = new CodeInstruction(OpCodes.Dup, (object)null); <>1__state = 1; return true; } goto IL_0110; } <>m__Finally1(); <>7__wrap2 = null; return false; IL_0110: <>2__current = <instruction>5__4; <>1__state = 3; return true; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap2 != null) { <>7__wrap2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <TransferCustomItemDataOnUpgrade>d__68 <TransferCustomItemDataOnUpgrade>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <TransferCustomItemDataOnUpgrade>d__ = this; } else { <TransferCustomItemDataOnUpgrade>d__ = new <TransferCustomItemDataOnUpgrade>d__68(0); } <TransferCustomItemDataOnUpgrade>d__.instructions = <>3__instructions; return <TransferCustomItemDataOnUpgrade>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } public static HashSet<Type> ForceLoadTypes; internal static string? _modGuid; private static Dictionary<Type, HashSet<Type>> typeInheritorsCache; private static HashSet<string> knownTypes; private Dictionary<string, ItemData> data = new Dictionary<string, ItemData>(); private WeakReference<ItemInfo>? selfReference; internal HashSet<string> isCloned = new HashSet<string>(); private static ItemData? awakeningItem; private static Assembly primaryAssembly; private static Dictionary<Assembly, string> assemblyNameCache; private static Dictionary<Type, string> classKeyCache; private HashSet<string> fetchedClassKeys = new HashSet<string>(); private static MethodInfo removeMethod; private static ItemData? checkingForStackableItemData; private static Dictionary<string, string>? newValuesOnStackable; private static ItemData? currentlyUpgradingItem; internal static string modGuid => _modGuid ?? (_modGuid = ((Func<string>)delegate { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); return val.Info.Metadata.GUID; })()); public string Mod => modGuid; public ItemData ItemData { get; private set; } public string? this[string key] { get { return Get<StringItemData>(key)?.Value; } set { GetOrCreate<StringItemData>(key).Value = value ?? ""; } } internal static void addTypeToInheritorsCache(Type type, string typeKey) { Type type2 = type; if (!knownTypes.Contains(typeKey)) { knownTypes.Add(typeKey); Type type3 = type2; while ((object)type3 != null) { AddInterfaces(type3); type3 = type3.BaseType; } } void AddInterfaces(Type baseType) { if (!typeInheritorsCache.TryGetValue(baseType, out HashSet<Type> value)) { HashSet<Type> hashSet2 = (typeInheritorsCache[baseType] = new HashSet<Type>()); value = hashSet2; } value.Add(type2); Type[] interfaces = baseType.GetInterfaces(); foreach (Type baseType2 in interfaces) { AddInterfaces(baseType2); } } } private static string cachedAssemblyName(Assembly assembly) { if (assemblyNameCache.TryGetValue(assembly, out string value)) { return value; } return assemblyNameCache[assembly] = assembly.GetName().Name; } internal static string classKey(Type type, string key) { if (!classKeyCache.TryGetValue(type, out string value)) { value = type.FullName + ((type.Assembly != primaryAssembly) ? ("," + cachedAssemblyName(type.Assembly)) : ""); addTypeToInheritorsCache(type, value); } if (key == "") { return value; } return value + "#" + key; } internal static string dataKey(string key) { return modGuid + "#" + key; } internal ItemInfo(ItemData itemData) { ItemData = itemData; string text = dataKey(""); List<string> list = ItemData.m_customData.Keys.ToList(); foreach (string item in list) { if (!item.StartsWith(text)) { continue; } string text2 = item.Substring(text.Length); string[] array = text2.Split(new char[1] { '#' }, 2); if (!knownTypes.Contains(array[0])) { Type type = Type.GetType(array[0]); if ((object)type != null && typeof(ItemData).IsAssignableFrom(type)) { addTypeToInheritorsCache(type, array[0]); } } } } public T GetOrCreate<T>(string key = "") where T : ItemData, new() { return Add<T>(key) ?? Get<T>(key); } public T? Add<T>(string key = "") where T : ItemData, new() { string text = classKey(typeof(T), key); if (fetchedClassKeys.Contains(text) && data.ContainsKey(text)) { return null; } string text2 = dataKey(text); if (ItemData.m_customData.ContainsKey(text2) || (awakeningItem != ItemData && data.ContainsKey(text))) { return null; } ItemData.m_customData[text2] = ""; ItemDataManager.ItemData.constructingInfo = selfReference ?? (selfReference = new WeakReference<ItemInfo>(this)); T val = new T { info = selfReference, Key = key, CustomDataKey = text2 }; data[text] = val; val.Value = ""; val.FirstLoad(); return val; } public T? Get<T>(string key = "") where T : class { if (!typeInheritorsCache.TryGetValue(typeof(T), out HashSet<Type> value)) { if (!typeof(ItemData).IsAssignableFrom(typeof(T)) || typeof(T) == typeof(ItemData)) { throw new Exception("Trying to get value from ItemDataManager for class not inheriting from ItemData"); } return null; } foreach (Type item in value) { string text = classKey(item, key); if (data.TryGetValue(text, out ItemData value2)) { return (T)(object)value2; } if (!fetchedClassKeys.Contains(text) && awakeningItem != ItemData) { string text2 = dataKey(text); fetchedClassKeys.Add(text); if (ItemData.m_customData.ContainsKey(text2)) { return (T)(object)constructDataObj(text2, text); } } } return null; } public Dictionary<string, T> GetAll<T>() where T : ItemData { LoadAll(); return data.Values.Where((ItemData o) => o is T).ToDictionary((ItemData o) => o.Key, (ItemData o) => (T)o); } public bool Remove(string key = "") { return Remove<StringItemData>(key); } public bool Remove<T>(string key = "") where T : ItemData { string key2 = classKey(typeof(T), key); string key3 = dataKey(key2); if (ItemData.m_customData.Remove(key3)) { if (data.TryGetValue(key2, out ItemData value)) { value.Unload(); data.Remove(key2); } return true; } return false; } public bool Remove<T>(T itemData) where T : ItemData { if (typeof(T) == itemData.GetType()) { return Remove<T>(itemData.Key); } return (bool)removeMethod.MakeGenericMethod(itemData.GetType()).Invoke(this, new object[1] { itemData.Key }); } private ItemData? constructDataObj(string fullkey, string key) { string[] array = key.Split(new char[1] { '#' }, 2); Type type = Type.GetType(array[0]); if ((object)type == null || !typeof(ItemData).IsAssignableFrom(type)) { return null; } ItemDataManager.ItemData.constructingInfo = selfReference ?? (selfReference = new WeakReference<ItemInfo>(this)); ItemData itemData = (ItemData)Activator.CreateInstance(type); data[key] = itemData; itemData.info = selfReference; itemData.Key = ((array.Length > 1) ? array[1] : ""); itemData.CustomDataKey = fullkey; itemData.Load(); return itemData; } public void Save() { foreach (ItemData value in data.Values) { value.Save(); } } public void LoadAll() { if (awakeningItem == ItemData) { return; } string text = dataKey(""); List<string> list = ItemData.m_customData.Keys.ToList(); foreach (string item in list) { if (item.StartsWith(text)) { string key = item.Substring(text.Length); if (!data.ContainsKey(key)) { constructDataObj(item, key); } } } } public IEnumerator<ItemData> GetEnumerator() { LoadAll(); return data.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private static void SavePrefix(ItemData __instance) { SaveItem(__instance); } private static void SaveInventoryPrefix(Inventory __instance) { foreach (ItemData item in __instance.m_inventory) { SaveItem(item); } } private static void SaveItem(ItemData item) { if (ItemExtensions.itemInfo.TryGetValue(item, out ItemInfo value)) { value.Save(); } } public Dictionary<string, string>? IsStackableWithOtherInfo(ItemInfo? info) { LoadAll(); Dictionary<string, string> dictionary = new Dictionary<string, string>(); if (info != null) { info.LoadAll(); HashSet<string> hashSet = new HashSet<string>(info.data.Keys.Intersect(data.Keys)); foreach (string item in hashSet) { string text = data[item].TryStack(info.data[item]); if (text == null) { return null; } dictionary[item] = text; } foreach (KeyValuePair<string, ItemData> datum in info.data) { if (!dictionary.ContainsKey(datum.Key)) { string text2 = info.data[datum.Key].TryStack(null); if (text2 == null) { return null; } dictionary[datum.Key] = text2; } } } foreach (KeyValuePair<string, ItemData> datum2 in data) { if (!dictionary.ContainsKey(datum2.Key)) { string text3 = data[datum2.Key].TryStack(null); if (text3 == null) { return null; } dictionary[datum2.Key] = text3; } } return dictionary.ToDictionary((KeyValuePair<string, string> kv) => dataKey(kv.Key), (KeyValuePair<string, string> kv) => kv.Value); } private static void RegisterForceLoadedTypesAddItem(ItemData? __result) { awakeningItem = null; if (__result != null) { RegisterForceLoadedTypes(__result); } } private static void RegisterForceLoadedTypes(ItemData itemData) { foreach (Type forceLoadType in ForceLoadTypes) { string key = classKey(forceLoadType, ""); string text = dataKey(key); if (itemData.m_customData.ContainsKey(text)) { itemData.Data().constructDataObj(text, key); } } } private static void ItemDropAwake(ItemDrop __instance) { GameObject dropPrefab = __instance.m_itemData.m_dropPrefab; if (dropPrefab != null && ItemExtensions.itemInfo.TryGetValue(dropPrefab.GetComponent<ItemDrop>().m_itemData, out ItemInfo value)) { __instance.m_itemData.Data().isCloned = new HashSet<string>(value.data.Values.Select((ItemData i) => i.CustomDataKey)); } } private static void ItemDropAwakeDelayed(ItemDrop __instance) { if (!ZNetView.m_forceDisableInit) { RegisterForceLoadedTypes(__instance.m_itemData); } } private static void ItemDataClonePrefix(ItemData __instance, ItemData __result) { SaveItem(__instance); } private static void ItemDataClonePostfix(ItemData __instance, ItemData __result) { if (ItemExtensions.itemInfo.TryGetValue(__instance, out ItemInfo value)) { __result.Data().isCloned = new HashSet<string>(value.data.Values.Select((ItemData i) => i.CustomDataKey)); } } private static void ItemDataClonePostfixDelayed(ItemData __result) { RegisterForceLoadedTypes(__result); } private static void RegisterForceLoadedTypesOnPlayerLoaded(Player __instance) { foreach (Food food in __instance.m_foods) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(food.m_name); if (itemPrefab.GetComponent<ItemDrop>().m_itemData == food.m_item) { food.m_item = food.m_item.Clone(); food.m_item.m_dropPrefab = itemPrefab; } RegisterForceLoadedTypes(food.m_item); } } private static void SaveCheckingForStackableItemData(ItemData item) { checkingForStackableItemData = item; } private static void ResetCheckingForStackableItemData() { checkingForStackableItemData = null; } [IteratorStateMachine(typeof(<CheckStackableInFindFreeStackMethods>d__57))] private static IEnumerable<CodeInstruction> CheckStackableInFindFreeStackMethods(IEnumerable<CodeInstruction> instructionsEnumerable) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckStackableInFindFreeStackMethods>d__57(-2) { <>3__instructionsEnumerable = instructionsEnumerable }; } private static bool CheckItemDataIsStackableFindFree(ItemData item, ItemData? target) { if (target == null) { return true; } Dictionary<string, string> dictionary = IsStackable(item, target); if (dictionary != null) { newValuesOnStackable = dictionary; return true; } return false; } private static void ResetNewValuesOnStackable() { newValuesOnStackable = null; } private static void ApplyNewValuesOnStackable(ItemData? __result) { if (__result == null || newValuesOnStackable == null) { return; } foreach (KeyValuePair<string, string> item in newValuesOnStackable) { __result.m_customData[item.Key] = item.Value; } } private static Dictionary<string, string>? IsStackable(ItemData a, ItemData b) { ItemInfo itemInfo = a.Data(); if (itemInfo != null) { return itemInfo.IsStackableWithOtherInfo(b.Data()); } ItemInfo itemInfo2 = b.Data(); if (itemInfo2 != null) { return itemInfo2.IsStackableWithOtherInfo(null); } return new Dictionary<string, string>(); } private static bool CheckItemDataStackableAddItem(Inventory __instance, ItemData item, int x, int y, ref Dictionary<string, string>? __state, ref bool __result) { ItemData itemAt = __instance.GetItemAt(x, y); if (itemAt != null) { Dictionary<string, string> dictionary = IsStackable(item, itemAt); if (dictionary == null) { __result = false; return false; } __state = dictionary; } return true; } private static void ApplyCustomItemDataStackableAddItem(Inventory __instance, int x, int y, Dictionary<string, string>? __state, bool __result) { if (!__result || __state == null) { return; } foreach (KeyValuePair<string, string> item in __state) { __instance.GetItemAt(x, y).m_customData[item.Key] = item.Value; } } private static void ApplyCustomItemDataStackableAutoStack(ItemDrop item, Dictionary<string, string> customData) { item.m_itemData.m_customData = customData; } private static Dictionary<string, string>? IsStackableItemDrop(ItemDrop drop, ItemData item) { return IsStackable(drop.m_itemData, item); } private static IEnumerable<CodeInstruction> HandleAutostackableItems(IEnumerable<CodeInstruction> instructionList, ILGenerator ilg) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown List<CodeInstruction> list = instructionList.ToList(); FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ItemData), "m_stack"); FieldInfo fieldInfo2 = AccessTools.DeclaredField(typeof(ItemDrop), "m_itemData"); Label? label = default(Label?); for (int i = 0; i < list.Count; i++) { if (!CodeInstructionExtensions.StoresField(list[i], fieldInfo)) { continue; } for (int num = i; num > 0; num--)