using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; 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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using Groups; using HarmonyLib; using ItemManager; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using PieceManager; using ServerSync; using SkillManager; using TMPro; using UnityEngine; 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; [assembly: Guid("150BFDAF-FF35-4302-B7CC-BEDCE69118D5")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyProduct("PotionsPlus")] [assembly: AssemblyCompany("")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyDescription("https://valheim.thunderstore.io/package/OdinPlus/PotionPlus")] [assembly: AssemblyTitle("PotionsPlus")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyConfiguration("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: <9407dcec-b638-448b-adf5-8a2e40be51e7>RefSafetyRules(11)] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<1195e483-29da-41f7-8154-e81dc911ce3c>Embedded] internal sealed class <1195e483-29da-41f7-8154-e81dc911ce3c>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<1195e483-29da-41f7-8154-e81dc911ce3c>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [<1195e483-29da-41f7-8154-e81dc911ce3c>Embedded] [CompilerGenerated] internal sealed class <278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContextAttribute : Attribute { public readonly byte Flag; public <278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [<1195e483-29da-41f7-8154-e81dc911ce3c>Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class <9407dcec-b638-448b-adf5-8a2e40be51e7>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <9407dcec-b638-448b-adf5-8a2e40be51e7>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SkillManager { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] [PublicAPI] public class Skill { [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] public static class LocalizationCache { private static readonly Dictionary localizations = new Dictionary(); internal static void LocalizationPostfix(Localization __instance, string language) { string key = localizations.FirstOrDefault([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (KeyValuePair l) => l.Value == __instance).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance); } } public static Localization ForLanguage([<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] string language = null) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value)) { return value; } value = new Localization(); if (language != null) { value.SetupLanguage(language); } return value; } } [PublicAPI] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] public class LocalizeKey { private static readonly List keys = new List(); public readonly string Key; public readonly Dictionary Localizations = new Dictionary(); 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 var 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)); } } } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] private class ConfigurationManagerAttributes { [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] [UsedImplicitly] public string Category; } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] [HarmonyPatch(typeof(Skills), "IsSkillValid")] private static class Patch_Skills_IsSkillValid { private static void Postfix(SkillType type, ref bool __result) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!__result && skills.ContainsKey(type)) { __result = true; } } } private static readonly Dictionary skills; internal static readonly Dictionary 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 = false; private static bool InitializedTerminal; [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] private static Localization _english; [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] private static BaseUnityPlugin _plugin; private static bool hasConfigSync; [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] private static object _configSync; public float SkillGainFactor { get { return skillDef.m_increseStep; } set { skillDef.m_increseStep = value; this.SkillGainFactorChanged?.Invoke(value); } } public float SkillEffectFactor { get { return skillEffectFactor; } set { skillEffectFactor = value; this.SkillEffectFactorChanged?.Invoke(value); } } public int SkillLoss { get { return skillLoss; } set { skillLoss = value; this.SkillLossChanged?.Invoke(value); } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown object obj = _plugin; if (obj == null) { BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Assembly.GetExecutingAssembly().DefinedTypes.First([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); _plugin = val; obj = (object)val; } return (BaseUnityPlugin)obj; } } [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] private static object configSync { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(2)] get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] [method: <278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(2)] [field: <6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] public event Action SkillGainFactorChanged; [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] [method: <278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(2)] [field: <6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] public event Action SkillEffectFactorChanged; [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] [method: <278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(2)] [field: <6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] public event Action SkillLossChanged; public Skill(string englishName, string icon) : this(englishName, loadSprite(icon, 64, 64)) { } public unsafe Skill(string englishName, Sprite icon) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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*)(&val))/*cast due to .constrained prefix*/).ToString()).English(englishName); Description = new LocalizeKey("skilldesc_" + text); } public static SkillType fromName(string englishName) { return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName)); } static Skill() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01ad: Expected O, but got Unknown //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown //IL_023f: Expected O, but got Unknown skills = new Dictionary(); skillByName = new Dictionary(); InitializedTerminal = false; hasConfigSync = true; Harmony val = new Harmony("org.bepinex.helpers.skillmanager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); } private static void Patch_FejdStartup() { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Expected O, but got Unknown foreach (Skill skill in skills.Values) { if (skill.Configurable) { string key = skill.Name.Key; string text = new Regex("['[\"\\]]").Replace(english.Localize(key), "").Trim(); string category = Localization.instance.Localize(key).Trim(); ConfigEntry skillGain = config(text, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillGainFactor = skillGain.Value; skillGain.SettingChanged += [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (object _, EventArgs _) => { skill.SkillGainFactor = skillGain.Value; }; ConfigEntry skillEffect = config(text, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillEffectFactor = skillEffect.Value; skillEffect.SettingChanged += [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (object _, EventArgs _) => { skill.SkillEffectFactor = skillEffect.Value; }; ConfigEntry skillLoss = config(text, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.skillLoss = skillLoss.Value; skillLoss.SettingChanged += [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (object _, EventArgs _) => { skill.skillLoss = skillLoss.Value; }; } } } private static void Patch_Skills_GetSkillDef([<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] ref SkillDef __result, List ___m_skills, SkillType type) { //IL_0005: 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 unsafe static bool Patch_Skills_CheatRaiseskill(Skills __instance, string name, float value, Player ___m_player) { //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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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)) { Skill skill2 = __instance.GetSkill(key); 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*)(&key))/*cast due to .constrained prefix*/).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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) { 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, [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(new byte[] { 2, 1 })] ref Dictionary __state) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { __state = new Dictionary(); } foreach (KeyValuePair 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, [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(new byte[] { 2, 1 })] ref Dictionary __state) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { return; } foreach (KeyValuePair 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown ConsoleOptionsFetcher fetcher = command.m_tabOptionsFetcher; command.m_tabOptionsFetcher = (ConsoleOptionsFetcher)([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] () => { List list = fetcher.Invoke(); list.AddRange(skills.Values.Select([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (Skill skill) => skill.internalSkillName)); return list; }); } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(2)] private static SkillDef GetSkillDef(SkillType skillType) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!skills.ContainsKey(skillType)) { return null; } Skill skill = skills[skillType]; return skill.skillDef; } private static byte[] ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream); return memoryStream.ToArray(); } private static Texture2D loadTexture(string name) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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 config<[<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] T>(string group, string name, T value, ConfigDescription description) { ConfigEntry val = plugin.Config.Bind(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry config<[<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] 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())); } } public static class SkillManagerVersion { [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(1)] public const string Version = "1.7.0"; } [PublicAPI] [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] 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_0010: 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 PotionsPlus { public static class FlaskEffects { [HarmonyPatch(typeof(Character), "RPC_Damage")] private class ReduceDamageTaken { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] private static void Prefix(Character __instance, HitData hit) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { if (((Character)val).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Flask_of_Elements"))) { hit.m_damage.m_fire *= 1f - (float)PotionsPlus.flaskOfElementsFireDamageTakenReduction.Value / 100f; hit.m_damage.m_lightning *= 1f - (float)PotionsPlus.flaskOfElementsLightningDamageTakenReduction.Value / 100f; } if (((Character)val).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Flask_of_Fortification"))) { hit.m_damage.m_blunt *= 1f - (float)PotionsPlus.flaskOfFortificationBluntDamageTakenReduction.Value / 100f; hit.m_damage.m_slash *= 1f - (float)PotionsPlus.flaskOfFortificationSlashDamageTakenReduction.Value / 100f; hit.m_damage.m_pierce *= 1f - (float)PotionsPlus.flaskOfFortificationPierceDamageTakenReduction.Value / 100f; } } } } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] public class GroupPotion : SE_Stats { public static bool effectApplied; public DamageType damageType; public int range; public override void Setup(Character character) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) ((SE_Stats)this).Setup(character); if ((Object)(object)character != (Object)(object)Player.m_localPlayer || effectApplied || !API.IsLoaded()) { return; } try { List list = API.GroupPlayers(); if (list == null) { return; } foreach (PlayerReference groupPlayer in list.Where((PlayerReference p) => p != PlayerReference.fromPlayer(Player.m_localPlayer))) { Player val = Player.s_players?.FirstOrDefault((Func)([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (Player p) => (Object)(object)p != (Object)null && p.GetPlayerID() == groupPlayer.peerId)); if (!((Object)(object)val == (Object)null)) { Vector3 position = ((Component)val).transform.position; if ((range == 0 || Utils.DistanceXZ(((Component)character).transform.position, position) < (float)range) && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(groupPlayer.peerId, "PotionsPlus Potion Activated", new object[1] { ((Object)this).name }); } } } effectApplied = true; } catch (Exception ex) { Debug.LogError((object)("[PotionsPlus] Error in GroupPotion.Setup: " + ex.Message + "\n" + ex.StackTrace)); } } public override void ModifyAttack(SkillType skill, ref HitData hitData) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_006b: Invalid comparison between Unknown and I4 //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 if ((int)damageType == 0) { return; } float chop = hitData.m_damage.m_chop; float pickaxe = hitData.m_damage.m_pickaxe; float num = hitData.GetTotalDamage() - pickaxe - chop; hitData.m_damage = new DamageTypes { m_chop = chop, m_pickaxe = pickaxe }; DamageType val = damageType; DamageType val2 = val; if ((int)val2 <= 64) { if ((int)val2 != 32) { if ((int)val2 == 64) { hitData.m_damage.m_frost = num; } } else { hitData.m_damage.m_fire = num; } } else if ((int)val2 != 128) { if ((int)val2 != 256) { if ((int)val2 == 512) { hitData.m_damage.m_spirit = num; } } else { hitData.m_damage.m_poison = num; } } else { hitData.m_damage.m_lightning = num; } } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] [BepInPlugin("com.odinplus.potionsplus", "PotionsPlus", "4.3.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class PotionsPlus : BaseUnityPlugin { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] private enum Toggle { On = 1, Off = 0 } [HarmonyPatch(typeof(ObjectDB), "Awake")] [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] private static class RegisterAlchemySkill { private static void Postfix() { if (alchemy == null) { Sprite icon = potionAssets.LoadAsset("AlcSkill"); alchemy = new Skill("Alchemy", icon) { Configurable = false }; alchemy.Name.Alias("pp_potion_skill_name"); alchemy.Description.Alias("pp_potion_skill_description"); } } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] [HarmonyPatch(typeof(Character), "SetHealth")] public static class PatchCharacterSetHealth { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] private static bool Prefix(ref Character __instance, float health) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !(health > 0f)) { StatusEffect val = ((IEnumerable)((Character)Player.m_localPlayer).GetSEMan().GetStatusEffects()).FirstOrDefault((Func)((StatusEffect se) => se.m_category == "pp_philstone")); if (val != null) { ((Character)Player.m_localPlayer).GetSEMan().RemoveStatusEffect(val, false); Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); ItemData val2 = ((IEnumerable)inventory.GetAllItems()).FirstOrDefault((Func)((ItemData i) => i.m_equipped && (int)i.m_shared.m_itemType == 18 && i.m_shared.m_equipStatusEffect.m_category == "pp_philstone")); if (val2 != null) { inventory.RemoveOneItem(val2); ((StatusEffect)CheatDeathStatusEffect).m_ttl = 6f; ((Character)Player.m_localPlayer).GetSEMan().AddStatusEffect((StatusEffect)(object)CheatDeathStatusEffect, false, 0, 0f); __instance.Heal(__instance.GetMaxHealth(), true); return false; } return true; } } return true; } } [HarmonyPatch(typeof(ZNet), "Awake")] [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] private static class RegisterRPCPatch { private static void Postfix() { ZRoutedRpc.instance.Register("PotionsPlus Raise Alchemy", (Action)delegate(long _, float num) { ((Character)(object)Player.m_localPlayer).RaiseSkill("Alchemy", num); }); ZRoutedRpc.instance.Register("PotionsPlus Alchemy Level", (Action)delegate(long sender, int num) { SubmitAlchemyLevel.playerAlchemyLevels[sender] = num; }); ZRoutedRpc.instance.Register("PotionsPlus Alchemy Proc", (Action)delegate { ((Character)Player.m_localPlayer).GetSEMan().AddStatusEffect((StatusEffect)(object)AlchemySkillProcStatusEffect, false, 0, 0f); }); ZRoutedRpc.instance.Register("PotionsPlus Potion Activated", (Action)onGroupPotionActivated); } } [HarmonyPatch(typeof(Incinerator), "OnIncinerate")] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] private static class SubmitAlchemyLevel { public static readonly Dictionary playerAlchemyLevels = new Dictionary(); private static void Postfix(Incinerator __instance) { ZRoutedRpc.instance.InvokeRoutedRPC(__instance.m_nview.GetZDO().GetOwner(), "PotionsPlus Alchemy Level", new object[1] { Mathf.RoundToInt(((Character)(object)Player.m_localPlayer).GetSkillFactor("Alchemy") * 100f) }); } } [HarmonyPatch] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] private static class SaveCauldronUsingPlayer { public static long uid; private static void SetUid(Incinerator incinerator, long sender) { if (((Object)incinerator).name.StartsWith("opcauldron", StringComparison.Ordinal)) { uid = sender; } } private static MethodInfo TargetMethod() { return (from t in typeof(Incinerator).GetNestedTypes(BindingFlags.Instance | BindingFlags.NonPublic) where t.Name.Contains("Incinerate") select t).SelectMany([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (Type t) => from m in t.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) where m.Name == "MoveNext" select m).First(); } private static IEnumerable Transpiler(IEnumerable instructions) { Type Incinerate = TargetMethod().DeclaringType; MethodInfo invoke = AccessTools.DeclaredMethod(typeof(MonoBehaviour), "Invoke", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Call && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)invoke)) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.DeclaredField(Incinerate, "<>4__this")); yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.DeclaredField(Incinerate, "uid")); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(SaveCauldronUsingPlayer), "SetUid", (Type[])null, (Type[])null)); } if (instruction.opcode == OpCodes.Ret) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.DeclaredField(Incinerate, "<>4__this")); yield return new CodeInstruction(OpCodes.Ldc_I8, (object)0L); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(SaveCauldronUsingPlayer), "SetUid", (Type[])null, (Type[])null)); } yield return instruction; } } } [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] [HarmonyPatch(typeof(IncineratorConversion), "AttemptCraft")] private static class ApplyAlchemySkillOnCauldronUsage { private static void Prefix(List toAdd, out int __state) { __state = toAdd.Count; } private static void Postfix(List toAdd, int __state, ref int __result) { if (SaveCauldronUsingPlayer.uid == 0L || toAdd.Count == __state) { return; } for (int num = toAdd.Count - 1; num >= __state; num--) { SubmitAlchemyLevel.playerAlchemyLevels.TryGetValue(SaveCauldronUsingPlayer.uid, out var value); for (int num2 = DetermineExtraItems(value, SaveCauldronUsingPlayer.uid); num2 > 0; num2--) { toAdd.Add(toAdd[num]); __result++; } } if (alchemySkillEnabled.Value == Toggle.On) { ZRoutedRpc.instance.InvokeRoutedRPC(SaveCauldronUsingPlayer.uid, "PotionsPlus Raise Alchemy", new object[1] { (float)toAdd.Count }); } } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] private static class ApplyAlchemySkillOnAlchemyTableCrafting { private static void Prefix(out int __state) { __state = (int)Game.instance.GetPlayerProfile().m_playerStats[(PlayerStatType)13]; } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] private static void Postfix(InventoryGui __instance, Player player, int __state) { if ((int)Game.instance.GetPlayerProfile().m_playerStats[(PlayerStatType)13] <= __state) { return; } CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation(); if (currentCraftingStation != null && ((Object)currentCraftingStation).name.StartsWith("opalchemy") && __instance.m_craftUpgradeItem == null) { for (int num = DetermineExtraItems(Mathf.RoundToInt(((Character)(object)player).GetSkillFactor("Alchemy") * 100f), ZDOMan.instance.m_sessionID); num > 0; num--) { int num2 = ((__instance.m_craftUpgradeItem == null) ? 1 : (__instance.m_craftUpgradeItem.m_quality + 1)); ((Humanoid)player).GetInventory().AddItem(((Object)((Component)__instance.m_craftRecipe.m_item).gameObject).name, __instance.m_craftRecipe.m_amount, num2, __instance.m_craftVariant, player.GetPlayerID(), player.GetPlayerName(), false); } if (alchemySkillEnabled.Value == Toggle.On) { ((Character)(object)player).RaiseSkill("Alchemy"); } } } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] [HarmonyPatch(typeof(RandomSpeak), "Start")] private class PreventGhostFromTalking { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] private static bool Prefix(RandomSpeak __instance) { return ((Component)__instance).gameObject.layer != Piece.s_ghostLayer; } } [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] [HarmonyPatch(typeof(Attack), "Start")] private class BypassAmmoCheck { private static void Prefix(Attack __instance, ItemData weapon, ref string __state) { GameObject dropPrefab = weapon.m_dropPrefab; if (((dropPrefab != null) ? ((Object)dropPrefab).name : null) == "Odins_Dragon_Staff") { GameObject spawnOnTrigger = __instance.m_spawnOnTrigger; if (((spawnOnTrigger != null) ? ((Object)spawnOnTrigger).name : null) == "Staff_Smoke_Cloud") { __state = weapon.m_shared.m_ammoType; weapon.m_shared.m_ammoType = ""; } } } private static void Finalizer(ItemData weapon, ref string __state) { if (__state != null) { weapon.m_shared.m_ammoType = __state; } } } [HarmonyPatch(typeof(Attack), "UseAmmo")] [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] private class ReduceAmmoUsage { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] private static bool Prefix(Attack __instance, ref bool __result) { GameObject dropPrefab = __instance.m_weapon.m_dropPrefab; string text = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); string text2 = text; if (!(text2 == "Odins_Dragon_Staff")) { if (!(text2 == "Odins_Alchemy_Wand")) { goto IL_00f8; } } else { GameObject spawnOnTrigger = __instance.m_spawnOnTrigger; if (((spawnOnTrigger != null) ? ((Object)spawnOnTrigger).name : null) == "Staff_Smoke_Cloud") { __result = true; return false; } } ItemData helmetItem = __instance.m_character.m_helmetItem; object obj; if (helmetItem == null) { obj = null; } else { GameObject dropPrefab2 = helmetItem.m_dropPrefab; obj = ((dropPrefab2 != null) ? ((Object)dropPrefab2).name : null); } if ((string?)obj == "Odins_Wizard_Hat") { ItemData ammoItem = __instance.m_character.GetInventory().GetAmmoItem(__instance.m_weapon.m_shared.m_ammoType, (string)null); if (ammoItem == null) { return true; } if (Random.value < wizardHatConsumeChargeReduction.Value / 100f) { __instance.m_ammoItem = ammoItem; __result = true; return false; } } goto IL_00f8; IL_00f8: return true; } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] public class HealingAoe : MonoBehaviour { private float nextHealTime = 0f; [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(1)] private HashSet healedThisTick = new HashSet(); private float radius => hellbrothOfEternalLifeRadius.Value; private float healInterval => hellbrothOfEternalLifeTickInterval.Value; private void Start() { nextHealTime = Time.time; } private void Update() { if (Time.time >= nextHealTime) { healedThisTick.Clear(); HealNearbyCharacters(); nextHealTime = Time.time + healInterval; } } private void HealNearbyCharacters() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)this).transform.position; int mask = LayerMask.GetMask(new string[3] { "character", "character_noenv", "character_ghost" }); Collider[] array = Physics.OverlapSphere(position, radius, mask); int num = 0; Collider[] array2 = array; foreach (Collider val in array2) { Character val2 = ((Component)val).GetComponentInParent(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).GetComponent(); } if ((Object)(object)val2 == (Object)null || val2.IsDead()) { continue; } int instanceID = ((Object)val2).GetInstanceID(); if (healedThisTick.Contains(instanceID)) { continue; } healedThisTick.Add(instanceID); if (val2 is Player || val2.IsTamed()) { float maxHealth = val2.GetMaxHealth(); float num2 = maxHealth * hellbrothOfEternalLifeHealing.Value / 100f; val2.Heal(num2, true); num++; Player val3 = (Player)(object)((val2 is Player) ? val2 : null); if (val3 != null && Random.value < 0.3f) { ((Character)val3).Message((MessageType)2, $"+{Mathf.RoundToInt(num2)} HP", 0, (Sprite)null); } } } } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] public class SmokescreenOwner : MonoBehaviour, IProjectile { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public void Setup(Character owner, Vector3 velocity, float hitNoise, HitData hitData, ItemData item, ItemData ammo) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) ZDO zdo = ((Component)this).GetComponent().m_zdo; zdo.Set("PotionsPlus SmokeCloud Owner", owner.GetZDOID()); zdo.Set("PotionsPlus SmokeCloud HatBonus", ((Component)owner).GetComponent().m_currentHelmetItemHash == StringExtensionMethods.GetStableHashCode("Odins_Warlock_Hat")); } public void Start() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (((Component)this).GetComponent().m_zdo.GetBool("PotionsPlus SmokeCloud HatBonus", false)) { ParticleSystem[] componentsInChildren = ((Component)this).GetComponentsInChildren(); foreach (ParticleSystem val in componentsInChildren) { ShapeModule shape = val.shape; ((ShapeModule)(ref shape)).radius = ((ShapeModule)(ref shape)).radius + warlockHatSmokeScreenSizeIncrease.Value; } SphereCollider componentInChildren = ((Component)this).GetComponentInChildren(); componentInChildren.radius += warlockHatSmokeScreenSizeIncrease.Value; TimedDestruction component = ((Component)this).GetComponent(); ((MonoBehaviour)component).CancelInvoke("DestroyNow"); component.Trigger(smokeScreenTTL.Value + (float)warlockHatSmokeScreenDurationIncrease.Value); } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public string GetTooltipString(int itemQuality) { return ""; } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] [HarmonyPatch(typeof(Projectile), "FixedUpdate")] private class SmokescreenHitBarrier { private static int ProjectileBlocker(int mask) { return mask | (1 << LayerMask.NameToLayer("blocker")); } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] private static IEnumerable Transpiler(IEnumerable instructions) { FieldInfo maskField = AccessTools.DeclaredField(typeof(Projectile), "s_rayMaskSolids"); foreach (CodeInstruction instruction in instructions) { yield return instruction; if (instruction.opcode == OpCodes.Ldsfld && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)maskField)) { yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(SmokescreenHitBarrier), "ProjectileBlocker", (Type[])null, (Type[])null)); } } } } [HarmonyPatch(typeof(Projectile), "OnHit")] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] private class DestroyBlockedProjectile { private static bool Prefix(Projectile __instance, Collider collider, ref bool __state) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)collider) && ((Component)collider).gameObject.layer == LayerMask.NameToLayer("blocker")) { Transform parent = ((Component)collider).transform.parent; ZDO val = ((parent == null) ? null : ((Component)parent).GetComponent()?.m_zdo); if (val != null) { GameObject obj = ZNetScene.instance.FindInstance(val.GetZDOID("PotionsPlus SmokeCloud Owner")); Character val2 = ((obj != null) ? obj.GetComponent() : null); if (val2 != null && !__instance.IsValidTarget((IDestructible)(object)val2)) { return false; } __state = true; Random.InitState((int)((ZDOID)(ref __instance.m_nview.m_zdo.m_uid)).ID); State state = Random.state; bool result = Random.value < (float)(smokeScreenChanceToBlock.Value + (val.GetBool("PotionsPlus SmokeCloud HatBonus", false) ? warlockHatSmokeScreenBlockIncrease.Value : 0)) / 100f; Random.state = state; return result; } } return true; } [HarmonyPriority(200)] private static void Postfix(Projectile __instance, Collider collider, bool __state) { if (__state && __instance != null && __instance.m_didHit && __instance.m_stayAfterHitStatic) { ZNetScene.instance.Destroy(((Component)__instance).gameObject); } } } [HarmonyPatch(typeof(Projectile), "SpawnOnHit")] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] private class TransferDamageToAoeProjectile { private static IProjectile UpdateAoeProjectileDamage(IProjectile newProjectile, IProjectile spawning) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) string projectileName = ((Object)(Component)spawning).name; if (wandProjectiles.Any([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (string p) => projectileName.StartsWith(p, StringComparison.Ordinal))) { Aoe val = (Aoe)newProjectile; Projectile val2 = (Projectile)spawning; ((DamageTypes)(ref val.m_damage)).Add(val2.m_damage, 1); val.m_attackForce += val2.m_attackForce; val.m_backstabBonus += val2.m_backstabBonus; val.m_statusEffect += val2.m_statusEffect; } return newProjectile; } private static IEnumerable Transpiler(IEnumerable instructions) { MethodInfo projectile = AccessTools.DeclaredMethod(typeof(GameObject), "GetComponent", Array.Empty(), new Type[1] { typeof(IProjectile) }); foreach (CodeInstruction instruction in instructions) { yield return instruction; if (instruction.opcode == OpCodes.Callvirt && CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)projectile)) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(TransferDamageToAoeProjectile), "UpdateAoeProjectileDamage", (Type[])null, (Type[])null)); } } } } private const string ModName = "PotionsPlus"; private const string ModVersion = "4.3.1"; private const string ModGUID = "com.odinplus.potionsplus"; private static readonly ConfigSync configSync = new ConfigSync("PotionsPlus") { DisplayName = "PotionsPlus", CurrentVersion = "4.3.1", MinimumRequiredVersion = "4.3.1" }; private static AssetBundle potionAssets; public static readonly HashSet wandProjectiles = new HashSet(); private static ConfigEntry serverConfigLocked = null; public static ConfigEntry philosophersStoneXpGainFactor = null; private static ConfigEntry alchemySkillEnabled = null; private static ConfigEntry alchemySkillBonusWhenCraftingEnabled = null; public static ConfigEntry flaskOfElementsFireDamageTakenReduction = null; public static ConfigEntry flaskOfElementsLightningDamageTakenReduction = null; public static ConfigEntry flaskOfElementsTTL = null; public static ConfigEntry flaskOfFortificationBluntDamageTakenReduction = null; public static ConfigEntry flaskOfFortificationSlashDamageTakenReduction = null; public static ConfigEntry flaskOfFortificationPierceDamageTakenReduction = null; public static ConfigEntry flaskOfFortificationTTL = null; public static ConfigEntry flaskOfMagelightIntensity = null; public static ConfigEntry flaskOfMagelightColor = null; public static ConfigEntry flaskOfMagelightTTL = null; public static ConfigEntry flaskOfGodsHealing = null; public static ConfigEntry flaskOfGodsRegenMultiplier = null; public static ConfigEntry flaskOfGodsTTL = null; public static ConfigEntry flaskOfSecondWindJumpStaminaFactor = null; public static ConfigEntry flaskOfSecondWindRunStaminaFactor = null; public static ConfigEntry flaskOfSecondWindStaminaRegenMultiplier = null; public static ConfigEntry flaskOfSecondWindTTL = null; public static ConfigEntry grandHealingTidePotionHealthOverTime = null; public static ConfigEntry grandHealingTidePotionTickInterval = null; public static ConfigEntry grandHealingTidePotionTTL = null; public static ConfigEntry grandHealingTidePotionCooldown = null; public static ConfigEntry grandSpiritualHealingPotionHealthOverTime = null; public static ConfigEntry grandSpiritualHealingPotionCooldown = null; public static ConfigEntry grandStaminaElixirStaminaOverTime = null; public static ConfigEntry grandStaminaElixirTTL = null; public static ConfigEntry grandStaminaElixirCooldown = null; public static ConfigEntry grandStealthElixirNoiseReduction = null; public static ConfigEntry grandStealthElixirVisibilityReduction = null; public static ConfigEntry grandStealthElixirTTL = null; public static ConfigEntry mediumHealingTideFlaskHealthOverTime = null; public static ConfigEntry mediumHealingTideFlaskTickInterval = null; public static ConfigEntry mediumHealingTideFlaskTTL = null; public static ConfigEntry mediumHealingTideFlaskCooldown = null; public static ConfigEntry mediumSpiritualHealingFlaskHealthOverTime = null; public static ConfigEntry mediumSpiritualHealingFlaskCooldown = null; public static ConfigEntry mediumStaminaFlaskStaminaOverTime = null; public static ConfigEntry mediumStaminaFlaskCooldown = null; public static ConfigEntry lesserHealingTideVialHealthOverTime = null; public static ConfigEntry lesserHealingTideVialTickInterval = null; public static ConfigEntry lesserHealingTideVialTTL = null; public static ConfigEntry lesserHealingTideVialCooldown = null; public static ConfigEntry lesserSpiritualHealingVialHealthOverTime = null; public static ConfigEntry lesserSpiritualHealingVialCooldown = null; public static ConfigEntry lesserStaminaVialStaminaOverTime = null; public static ConfigEntry lesserStaminaVialCooldown = null; public static ConfigEntry hellbrothOfFlamesDamage = null; public static ConfigEntry hellbrothOfFrostDamage = null; public static ConfigEntry hellbrothOfThorsFuryDamage = null; public static ConfigEntry hellbrothOfEternalLifeHealing = null; public static ConfigEntry hellbrothOfEternalLifeTTL = null; public static ConfigEntry hellbrothOfEternalLifeRadius = null; public static ConfigEntry hellbrothOfEternalLifeTickInterval = null; public static ConfigEntry brewOfFaintGroupHealingHealthOverTime = null; public static ConfigEntry brewOfFaintGroupHealingCooldown = null; private static ConfigEntry brewOfFaintGroupHealingRange = null; public static ConfigEntry brewOfGroupHealingHealthOverTime = null; public static ConfigEntry brewOfGroupHealingCooldown = null; private static ConfigEntry brewOfGroupHealingRange = null; public static ConfigEntry brewOfGrandGroupHealingHealthOverTime = null; public static ConfigEntry brewOfGrandGroupHealingCooldown = null; private static ConfigEntry brewOfGrandGroupHealingRange = null; public static ConfigEntry brewOfFieryRevengeTTL = null; public static ConfigEntry brewOfFieryRevengeRange = null; public static ConfigEntry brewOfIcyTouchTTL = null; public static ConfigEntry brewOfIcyTouchRange = null; public static ConfigEntry brewOfCunningToxicityTTL = null; public static ConfigEntry brewOfCunningToxicityRange = null; public static ConfigEntry brewOfSpiritualDeathTTL = null; public static ConfigEntry brewOfSpiritualDeathRange = null; public static ConfigEntry brewOfThunderousWordsTTL = null; public static ConfigEntry brewOfThunderousWordsRange = null; private static ConfigEntry wizardHatConsumeChargeReduction = null; private static ConfigEntry warlockHatSmokeScreenSizeIncrease = null; private static ConfigEntry warlockHatSmokeScreenBlockIncrease = null; private static ConfigEntry warlockHatSmokeScreenDurationIncrease = null; public static ConfigEntry weaponOilDamageIncrease = null; public static ConfigEntry weaponOilTTL = null; private static ConfigEntry smokeScreenChanceToBlock = null; public static ConfigEntry smokeScreenTTL = null; private static Skill alchemy = null; private bool _placeholdersRegistered = false; private static SE_Stats CheatDeathStatusEffect = null; private static SE_Stats AlchemySkillProcStatusEffect = null; private ConfigEntry config<[<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry val = ((BaseUnityPlugin)this).Config.Bind(group, name, value, description); SyncedConfigEntry syncedConfigEntry = configSync.AddConfigEntry(val); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry config<[<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } public void Awake() { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Expected O, but got Unknown //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Expected O, but got Unknown //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Expected O, but got Unknown //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Expected O, but got Unknown //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Expected O, but got Unknown //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Expected O, but got Unknown //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Expected O, but got Unknown //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Expected O, but got Unknown //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Expected O, but got Unknown //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Expected O, but got Unknown //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Expected O, but got Unknown //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Expected O, but got Unknown //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Expected O, but got Unknown //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Expected O, but got Unknown //IL_0551: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Expected O, but got Unknown //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_0591: Expected O, but got Unknown //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Expected O, but got Unknown //IL_05e6: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Expected O, but got Unknown //IL_0615: Unknown result type (might be due to invalid IL or missing references) //IL_0620: Expected O, but got Unknown //IL_0644: Unknown result type (might be due to invalid IL or missing references) //IL_064f: Expected O, but got Unknown //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Expected O, but got Unknown //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06ac: Expected O, but got Unknown //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_06e5: Expected O, but got Unknown //IL_0713: Unknown result type (might be due to invalid IL or missing references) //IL_071e: Expected O, but got Unknown //IL_0748: Unknown result type (might be due to invalid IL or missing references) //IL_0753: Expected O, but got Unknown //IL_0773: Unknown result type (might be due to invalid IL or missing references) //IL_077e: Expected O, but got Unknown //IL_07a8: Unknown result type (might be due to invalid IL or missing references) //IL_07b3: Expected O, but got Unknown //IL_07d3: Unknown result type (might be due to invalid IL or missing references) //IL_07de: Expected O, but got Unknown //IL_0808: Unknown result type (might be due to invalid IL or missing references) //IL_0813: Expected O, but got Unknown //IL_0833: Unknown result type (might be due to invalid IL or missing references) //IL_083e: Expected O, but got Unknown //IL_086c: Unknown result type (might be due to invalid IL or missing references) //IL_0877: Expected O, but got Unknown //IL_08a5: Unknown result type (might be due to invalid IL or missing references) //IL_08b0: Expected O, but got Unknown //IL_08da: Unknown result type (might be due to invalid IL or missing references) //IL_08e5: Expected O, but got Unknown //IL_0905: Unknown result type (might be due to invalid IL or missing references) //IL_0910: Expected O, but got Unknown //IL_093a: Unknown result type (might be due to invalid IL or missing references) //IL_0945: Expected O, but got Unknown //IL_0965: Unknown result type (might be due to invalid IL or missing references) //IL_0970: Expected O, but got Unknown //IL_099a: Unknown result type (might be due to invalid IL or missing references) //IL_09a5: Expected O, but got Unknown //IL_09c5: Unknown result type (might be due to invalid IL or missing references) //IL_09d0: Expected O, but got Unknown //IL_09f0: Unknown result type (might be due to invalid IL or missing references) //IL_09fb: Expected O, but got Unknown //IL_0a1b: Unknown result type (might be due to invalid IL or missing references) //IL_0a26: Expected O, but got Unknown //IL_0a54: Unknown result type (might be due to invalid IL or missing references) //IL_0a5f: Expected O, but got Unknown //IL_0a8d: Unknown result type (might be due to invalid IL or missing references) //IL_0a98: Expected O, but got Unknown //IL_0ac6: Unknown result type (might be due to invalid IL or missing references) //IL_0ad1: Expected O, but got Unknown //IL_0aff: Unknown result type (might be due to invalid IL or missing references) //IL_0b0a: Expected O, but got Unknown //IL_0b2a: Unknown result type (might be due to invalid IL or missing references) //IL_0b35: Expected O, but got Unknown //IL_0b5f: Unknown result type (might be due to invalid IL or missing references) //IL_0b6a: Expected O, but got Unknown //IL_0b91: Unknown result type (might be due to invalid IL or missing references) //IL_0b9c: Expected O, but got Unknown //IL_0bbc: Unknown result type (might be due to invalid IL or missing references) //IL_0bc7: Expected O, but got Unknown //IL_0bf1: Unknown result type (might be due to invalid IL or missing references) //IL_0bfc: Expected O, but got Unknown //IL_0c23: Unknown result type (might be due to invalid IL or missing references) //IL_0c2e: Expected O, but got Unknown //IL_0c4e: Unknown result type (might be due to invalid IL or missing references) //IL_0c59: Expected O, but got Unknown //IL_0c83: Unknown result type (might be due to invalid IL or missing references) //IL_0c8e: Expected O, but got Unknown //IL_0cb5: Unknown result type (might be due to invalid IL or missing references) //IL_0cc0: Expected O, but got Unknown //IL_0cee: Unknown result type (might be due to invalid IL or missing references) //IL_0cf9: Expected O, but got Unknown //IL_0d20: Unknown result type (might be due to invalid IL or missing references) //IL_0d2b: Expected O, but got Unknown //IL_0d59: Unknown result type (might be due to invalid IL or missing references) //IL_0d64: Expected O, but got Unknown //IL_0d8b: Unknown result type (might be due to invalid IL or missing references) //IL_0d96: Expected O, but got Unknown //IL_0dc4: Unknown result type (might be due to invalid IL or missing references) //IL_0dcf: Expected O, but got Unknown //IL_0df6: Unknown result type (might be due to invalid IL or missing references) //IL_0e01: Expected O, but got Unknown //IL_0e2f: Unknown result type (might be due to invalid IL or missing references) //IL_0e3a: Expected O, but got Unknown //IL_0e61: Unknown result type (might be due to invalid IL or missing references) //IL_0e6c: Expected O, but got Unknown //IL_0e9a: Unknown result type (might be due to invalid IL or missing references) //IL_0ea5: Expected O, but got Unknown //IL_0ecc: Unknown result type (might be due to invalid IL or missing references) //IL_0ed7: Expected O, but got Unknown //IL_0f05: Unknown result type (might be due to invalid IL or missing references) //IL_0f10: Expected O, but got Unknown //IL_0f3e: Unknown result type (might be due to invalid IL or missing references) //IL_0f49: Expected O, but got Unknown //IL_0f6c: Unknown result type (might be due to invalid IL or missing references) //IL_0f77: Expected O, but got Unknown //IL_0f9b: Unknown result type (might be due to invalid IL or missing references) //IL_0fa6: Expected O, but got Unknown //IL_0fca: Unknown result type (might be due to invalid IL or missing references) //IL_0fd5: Expected O, but got Unknown //IL_1003: Unknown result type (might be due to invalid IL or missing references) //IL_100e: Expected O, but got Unknown //IL_1031: Unknown result type (might be due to invalid IL or missing references) //IL_103c: Expected O, but got Unknown //IL_106a: Unknown result type (might be due to invalid IL or missing references) //IL_1075: Expected O, but got Unknown //IL_10af: Unknown result type (might be due to invalid IL or missing references) //IL_10b5: Expected O, but got Unknown Localizer.Load(); potionAssets = PrefabManager.RegisterAssetBundle("potions"); AssetBundle val = potionAssets; serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, the configuration is locked and can be changed by server admins only."); configSync.AddLockingConfigEntry(serverConfigLocked); alchemySkillEnabled = config("1 - General", "Alchemy Skill", Toggle.On, "Enables the Alchemy skill."); alchemySkillBonusWhenCraftingEnabled = config("1 - General", "Alchemy Crafting Bonus", Toggle.On, "Enable Alchemy Bonus when crafting."); philosophersStoneXpGainFactor = config("2 - Philosophers Stone", "Philosophers Stone XP Gain Factor", 1.25f, new ConfigDescription("Factor for Alchemy XP gain, when a Philosophers Stone is equipped.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 3f), Array.Empty())); flaskOfElementsFireDamageTakenReduction = config("Flask of Elements", "Fire damage reduction", 66, new ConfigDescription("Fire damage reduction during Flask of Elements effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); flaskOfElementsLightningDamageTakenReduction = config("Flask of Elements", "Lightning damage reduction", 66, new ConfigDescription("Lightning damage reduction during Flask of Elements effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); flaskOfElementsTTL = config("Flask of Elements", "Effect Duration", 120, new ConfigDescription("Effect duration of the Flask of Elements in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); flaskOfFortificationBluntDamageTakenReduction = config("Flask of Fortification", "Blunt damage reduction", 66, new ConfigDescription("Blunt damage reduction during Flask of Fortification effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); flaskOfFortificationSlashDamageTakenReduction = config("Flask of Fortification", "Slash damage reduction", 66, new ConfigDescription("Slash damage reduction during Flask of Fortification effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); flaskOfFortificationPierceDamageTakenReduction = config("Flask of Fortification", "Pierce damage reduction", 66, new ConfigDescription("Pierce damage reduction during Flask of Fortification effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); flaskOfFortificationTTL = config("Flask of Fortification", "Effect Duration", 120, new ConfigDescription("Effect duration of the Flask of Fortification in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); flaskOfMagelightColor = config("Flask of Magelight", "Effect Color", new Color(0.75f, 0.75f, 1f), new ConfigDescription("Color of the Flask of Magelight effect.", (AcceptableValueBase)null, Array.Empty())); flaskOfMagelightIntensity = config("Flask of Magelight", "Effect Intensity", 3f, new ConfigDescription("Intensity of the Flask of Magelight effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 5f), Array.Empty())); flaskOfMagelightTTL = config("Flask of Magelight", "Effect Duration", 300, new ConfigDescription("Effect duration of the Flask of Magelight in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); flaskOfGodsHealing = config("Flask of the Gods", "Healing Effect", 250f, new ConfigDescription("Healing from the Flask of the Gods effect.", (AcceptableValueBase)null, Array.Empty())); flaskOfGodsRegenMultiplier = config("Flask of the Gods", "Health Regen Factor", 1.05f, new ConfigDescription("Health regen factor from the Flask of the Gods effect.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 5f), Array.Empty())); flaskOfGodsTTL = config("Flask of the Gods", "Effect Duration", 300, new ConfigDescription("Effect duration of the Flask of the Gods in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); flaskOfSecondWindJumpStaminaFactor = config("Flask of Second Wind", "Jump Stamina Usage Factor", 0.75f, new ConfigDescription("Jump stamina usage factor the Flask of Second Wind effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); flaskOfSecondWindRunStaminaFactor = config("Flask of Second Wind", "Run Stamina Usage Factor", 0.75f, new ConfigDescription("Run stamina usage factor from the Flask of Second Wind effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); flaskOfSecondWindStaminaRegenMultiplier = config("Flask of Second Wind", "Stamina Regen Factor", 1.05f, new ConfigDescription("Stamina regeneration factor from the Flask of Second Wind effect.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 5f), Array.Empty())); flaskOfSecondWindTTL = config("Flask of Second Wind", "Effect Duration", 120, new ConfigDescription("Effect duration of the Flask of Second Wind in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); grandHealingTidePotionHealthOverTime = config("Grand Healing Tide Potion", "Healing Effect", 95f, new ConfigDescription("Healing from the Grand Healing Tide Potion effect.", (AcceptableValueBase)null, Array.Empty())); grandHealingTidePotionTickInterval = config("Grand Healing Tide Potion", "Tick Interval", 1f, new ConfigDescription("Tick interval for the Grand Healing Tide Potion effect.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f), Array.Empty())); grandHealingTidePotionTTL = config("Grand Healing Tide Potion", "Effect Duration", 10f, new ConfigDescription("Effect duration of the Grand Healing Tide Potion in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); grandHealingTidePotionCooldown = config("Grand Healing Tide Potion", "Cooldown Duration", 240, new ConfigDescription("Cooldown of the Grand Healing Tide Potion in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 600), Array.Empty())); grandStaminaElixirStaminaOverTime = config("Grand Stamina Elixir", "Stamina Regeneration", 150f, new ConfigDescription("Stamina regeneration from the Grand Stamina Elixir effect.", (AcceptableValueBase)null, Array.Empty())); grandStaminaElixirTTL = config("Grand Stamina Elixir", "Effect Duration", 15f, new ConfigDescription("Effect duration of the Grand Stamina Elixir effect in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); grandStaminaElixirCooldown = config("Grand Stamina Elixir", "Cooldown Duration", 300, new ConfigDescription("Cooldown duration of the Grand Stamina Elixir in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); grandSpiritualHealingPotionHealthOverTime = config("Grand Spiritual Healing Potion", "Healing Effect", 100f, new ConfigDescription("Healing from the Grand Spiritual Healing Potion effect.", (AcceptableValueBase)null, Array.Empty())); grandSpiritualHealingPotionCooldown = config("Grand Spiritual Healing Potion", "Cooldown Duration", 240, new ConfigDescription("Cooldown of the Grand Spiritual Healing Potion in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 600), Array.Empty())); grandStealthElixirVisibilityReduction = config("Grand Stealth Elixir", "Visibility Reduction", 100, new ConfigDescription("Visibility reduction while sneaking during the Grand Stealth Elixir effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); grandStealthElixirNoiseReduction = config("Grand Stealth Elixir", "Noise Reduction", 100, new ConfigDescription("Noise reduction while sneaking during the Grand Stealth Elixir effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); grandStealthElixirTTL = config("Grand Stealth Elixir", "Effect Duration", 60, new ConfigDescription("Effect duration of the Grand Stealth Elixir effect in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); mediumHealingTideFlaskHealthOverTime = config("Medium Healing Tide Flask", "Healing Effect", 45f, new ConfigDescription("Healing from the Medium Healing Tide Flask effect.", (AcceptableValueBase)null, Array.Empty())); mediumHealingTideFlaskTickInterval = config("Medium Healing Tide Flask", "Tick Interval", 1f, new ConfigDescription("Tick interval for the Medium Healing Tide Flask effect.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f), Array.Empty())); mediumHealingTideFlaskTTL = config("Medium Healing Tide Flask", "Effect Duration", 10f, new ConfigDescription("Effect duration of the Medium Healing Tide Flask in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); mediumHealingTideFlaskCooldown = config("Medium Healing Tide Flask", "Cooldown Duration", 240, new ConfigDescription("Cooldown of the Medium Healing Tide Flask in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 600), Array.Empty())); mediumSpiritualHealingFlaskHealthOverTime = config("Medium Spiritual Healing Flask", "Healing Effect", 50f, new ConfigDescription("Healing from the Medium Spiritual Healing Flask effect.", (AcceptableValueBase)null, Array.Empty())); mediumSpiritualHealingFlaskCooldown = config("Medium Spiritual Healing Flask", "Cooldown Duration", 240, new ConfigDescription("Cooldown of the Medium Spiritual Healing Flask in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); mediumStaminaFlaskStaminaOverTime = config("Medium Stamina Flask", "Stamina Regeneration", 90f, new ConfigDescription("Stamina regeneration from the Medium Stamina Flask effect.", (AcceptableValueBase)null, Array.Empty())); mediumStaminaFlaskCooldown = config("Medium Stamina Flask", "Cooldown Duration", 240, new ConfigDescription("Cooldown duration of the Medium Stamina Flask in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); lesserHealingTideVialHealthOverTime = config("Lesser Healing Tide Vial", "Healing Effect", 25f, new ConfigDescription("Healing from the Lesser Healing Tide Vial effect.", (AcceptableValueBase)null, Array.Empty())); lesserHealingTideVialTickInterval = config("Lesser Healing Tide Vial", "Tick Interval", 1f, new ConfigDescription("Tick interval for the Lesser Healing Tide Vial effect.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f), Array.Empty())); lesserHealingTideVialTTL = config("Lesser Healing Tide Vial", "Effect Duration", 10f, new ConfigDescription("Effect duration of the Lesser Healing Tide Vial in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); lesserHealingTideVialCooldown = config("Lesser Healing Tide Vial", "Cooldown Duration", 240, new ConfigDescription("Cooldown duration of the Lesser Healing Tide Vial in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); lesserSpiritualHealingVialHealthOverTime = config("Lesser Spiritual Healing Vial", "Healing Effect", 25f, new ConfigDescription("Healing from the Lesser Spiritual Healing Vial effect.", (AcceptableValueBase)null, Array.Empty())); lesserSpiritualHealingVialCooldown = config("Lesser Spiritual Healing Vial", "Cooldown Duration", 240, new ConfigDescription("Cooldown duration of the Lesser Spiritual Healing Vial in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); lesserStaminaVialStaminaOverTime = config("Lesser Stamina Vial", "Stamina Regeneration", 45f, new ConfigDescription("Stamina regeneration from the Lesser Stamina Vial effect.", (AcceptableValueBase)null, Array.Empty())); lesserStaminaVialCooldown = config("Lesser Stamina Vial", "Cooldown Duration", 240, new ConfigDescription("Cooldown duration of the Lesser Stamina Vial in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); hellbrothOfFlamesDamage = config("Hellbroth of Flames", "Fire Damage", 20f, new ConfigDescription("Fire damage dealt per tick by the Hellbroth of Flames.", (AcceptableValueBase)null, Array.Empty())); hellbrothOfFrostDamage = config("Hellbroth of Frost", "Frost Damage", 50f, new ConfigDescription("Frost damage dealt per tick by the Hellbroth of Frost.", (AcceptableValueBase)null, Array.Empty())); hellbrothOfThorsFuryDamage = config("Hellbroth of Thors Fury", "Lightning Damage", 60f, new ConfigDescription("Lightning damage dealt per tick by the Hellbroth of Thors Fury.", (AcceptableValueBase)null, Array.Empty())); hellbrothOfEternalLifeHealing = config("Hellbroth of Eternal Life", "Healing", 20f, new ConfigDescription("Percentage of maximum health as healing per tick by the Hellbroth of Eternal Life.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 100f), Array.Empty())); hellbrothOfEternalLifeTTL = config("Hellbroth of Eternal Life", "Effect Duration", 5f, new ConfigDescription("Duration of the healing effect in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); hellbrothOfEternalLifeRadius = config("Hellbroth of Eternal Life", "Healing Radius", 5f, new ConfigDescription("Healing radius in meters.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 20f), Array.Empty())); hellbrothOfEternalLifeTickInterval = config("Hellbroth of Eternal Life", "Heal Interval", 1f, new ConfigDescription("Time between healing ticks in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 5f), Array.Empty())); brewOfFaintGroupHealingHealthOverTime = config("Brew of Faint Group Healing", "Healing Effect", 25f, new ConfigDescription("Healing from the Brew of Faint Group Healing effect.", (AcceptableValueBase)null, Array.Empty())); brewOfFaintGroupHealingCooldown = config("Brew of Faint Group Healing", "Cooldown Duration", 240, new ConfigDescription("Cooldown of the Brew of Faint Group Healing in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); brewOfFaintGroupHealingRange = config("Brew of Faint Group Healing", "Effect Range", 30, new ConfigDescription("Range of the Brew of Faint Group Healing effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); brewOfGroupHealingHealthOverTime = config("Brew of Group Healing", "Healing Effect", 50f, new ConfigDescription("Healing from the Brew of Group Healing effect.", (AcceptableValueBase)null, Array.Empty())); brewOfGroupHealingCooldown = config("Brew of Group Healing", "Cooldown Duration", 240, new ConfigDescription("Cooldown of the Brew of Group Healing in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); brewOfGroupHealingRange = config("Brew of Group Healing", "Effect Range", 30, new ConfigDescription("Range of the Brew of Group Healing effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); brewOfGrandGroupHealingHealthOverTime = config("Brew of Grand Group Healing", "Healing Effect", 125f, new ConfigDescription("Healing from the Brew of Grand Group Healing effect.", (AcceptableValueBase)null, Array.Empty())); brewOfGrandGroupHealingCooldown = config("Brew of Grand Group Healing", "Cooldown Duration", 240, new ConfigDescription("Cooldown of the Brew of Grand Group Healing in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5, 900), Array.Empty())); brewOfGrandGroupHealingRange = config("Brew of Grand Group Healing", "Effect Range", 30, new ConfigDescription("Range of the Brew of Grand Group Healing effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); brewOfFieryRevengeTTL = config("Brew of Fiery Revenge", "Effect Duration", 180f, new ConfigDescription("Effect duration for the Brew of Fiery Revenge in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 900f), Array.Empty())); brewOfFieryRevengeRange = config("Brew of Fiery Revenge", "Effect Range", 30, new ConfigDescription("Range of the Brew of Fiery Revenge effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); brewOfIcyTouchTTL = config("Brew of the Icy Touch", "Effect Duration", 180f, new ConfigDescription("Effect duration for the Brew of the Icy Touch in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 900f), Array.Empty())); brewOfIcyTouchRange = config("Brew of the Icy Touch", "Effect Range", 30, new ConfigDescription("Range of the Brew of the Icy Touch effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); brewOfCunningToxicityTTL = config("Brew of Cunning Toxicity", "Effect Duration", 180f, new ConfigDescription("Effect duration for the Brew of Cunning Toxicity in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 900f), Array.Empty())); brewOfCunningToxicityRange = config("Brew of Cunning Toxicity", "Effect Range", 30, new ConfigDescription("Range of the Brew of Cunning Toxicity effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); brewOfSpiritualDeathTTL = config("Brew of Spiritual Death", "Effect Duration", 180f, new ConfigDescription("Effect duration for the Brew of Spiritual Death in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 900f), Array.Empty())); brewOfSpiritualDeathRange = config("Brew of Spiritual Death", "Effect Range", 30, new ConfigDescription("Range of the Brew of Spiritual Death effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); brewOfThunderousWordsTTL = config("Brew of Thunderous Words", "Effect Duration", 180f, new ConfigDescription("Effect duration for the Brew of Thunderous Words in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 900f), Array.Empty())); brewOfThunderousWordsRange = config("Brew of Thunderous Words", "Effect Range", 30, new ConfigDescription("Range of the Brew of Thunderous Words effect.", (AcceptableValueBase)(object)new AcceptableValueRange(3, 200), Array.Empty())); wizardHatConsumeChargeReduction = config("Odins Wizard Hat", "Charge Consumption Reduction", 40f, new ConfigDescription("Chance to not consume a Hellbroth charge, when using the Alchemy Wand or Dragon Staff while wearing the Wizard hat.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); warlockHatSmokeScreenSizeIncrease = config("Odins Warlock Hat", "Smoke Screen Size Increase", 2f, new ConfigDescription("Radius increase for the smoke screen ability of the Dragon Staff while wearing the Warlock hat.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 5f), Array.Empty())); warlockHatSmokeScreenDurationIncrease = config("Odins Warlock Hat", "Smoke Screen Duration Increase", 2, new ConfigDescription("Duration increase for the smoke screen ability of the Dragon Staff while wearing the Warlock hat in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 15), Array.Empty())); warlockHatSmokeScreenBlockIncrease = config("Odins Warlock Hat", "Smoke Screen Block Chance Increase", 25, new ConfigDescription("Projectile block chance increase for the smoke screen ability of the Dragon Staff while wearing the Warlock hat.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); smokeScreenChanceToBlock = config("Odins Dragon Staff", "Block Chance", 50, new ConfigDescription("Chance to block projectiles for the smoke screen effect of Odins Dragon Staff.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); smokeScreenTTL = config("Odins Dragon Staff", "Effect Duration", 8f, new ConfigDescription("Effect duration for the smoke screen effect of Odins Dragon Staff in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); weaponOilDamageIncrease = config("Odins Weapon Oil", "Damage Increase", 5, new ConfigDescription("Damage increase for weapons from the Odins Weapon Oil effect.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); weaponOilTTL = config("Odins Weapon Oil", "Effect Duration", 30f, new ConfigDescription("Effect duration for Odins Weapon Oil in minutes.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 120f), Array.Empty())); BuildingPiecesSetup.initializeBuildingPieces(val); PotionsSetup.initializePotions(val); EquipmentSetup.initializeEquipment(val); GroupPotionSetup.initializeGroupPotions(val); HellbrothSetup.initializeHellbroth(val); PhilosophersSetup.initializePhilosophersStones(val); Assembly executingAssembly = Assembly.GetExecutingAssembly(); Harmony val2 = new Harmony("com.odinplus.potionsplus"); val2.PatchAll(executingAssembly); CheatDeathStatusEffect = val.LoadAsset("CheatDeath"); AlchemySkillProcStatusEffect = val.LoadAsset("AlcSkillProc"); PrefabManager.RegisterPrefab(val, "PP_sfx_rebirth"); PrefabManager.RegisterPrefab(val, "PP_sfx_stoneuse"); PrefabManager.RegisterPrefab(val, "PP_sfx_brewpotiondone"); PrefabManager.RegisterPrefab(val, "PP_sfx_potion_smash"); PrefabManager.RegisterPrefab(val, "PP_sfx_brewpotion"); PrefabManager.RegisterPrefab(val, "PP_vfx_potionhit"); PrefabManager.RegisterPrefab(val, "sfx_build_alchemy"); PrefabManager.RegisterPrefab(val, "VFX_RedPotionDrink"); PrefabManager.RegisterPrefab(val, "VFX_GreenPotionDrink"); PrefabManager.RegisterPrefab(val, "VFX_BluePotionDrink"); PrefabManager.RegisterPrefab(val, "VFX_PurplePotionDrink"); PrefabManager.RegisterPrefab(val, "VFX_StonePurple"); PrefabManager.RegisterPrefab(val, "VFX_StoneBlue"); PrefabManager.RegisterPrefab(val, "VFX_StoneGreen"); PrefabManager.RegisterPrefab(val, "potionaudio"); } private void Start() { Localizer.OnLocalizationComplete += RegisterPlaceholders; } private void RegisterPlaceholders() { if (!_placeholdersRegistered) { _placeholdersRegistered = true; Localizer.AddPlaceholder("pp_flask_elements_description", "duration", flaskOfElementsTTL, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (int ttl) => ((float)ttl / 60f).ToString("0.#")); Localizer.AddPlaceholder("pp_flask_secondwind_description", "duration", flaskOfSecondWindTTL, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (int ttl) => ((float)ttl / 60f).ToString("0.#")); Localizer.AddPlaceholder("pp_flask_fort_description", "duration", flaskOfFortificationTTL, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (int ttl) => ((float)ttl / 60f).ToString("0.#")); Localizer.AddPlaceholder("pp_flask_god_description", "power", flaskOfGodsHealing); Localizer.AddPlaceholder("pp_elixir_healing_description", "power", grandHealingTidePotionHealthOverTime); Localizer.AddPlaceholder("pp_elixir_healing_description", "duration", grandHealingTidePotionTTL); Localizer.AddPlaceholder("pp_elixir_spiritual_description", "power", grandSpiritualHealingPotionHealthOverTime); Localizer.AddPlaceholder("pp_elixir_stam_description", "power", grandStaminaElixirStaminaOverTime); Localizer.AddPlaceholder("pp_elixir_stam_description", "duration", grandStaminaElixirTTL); Localizer.AddPlaceholder("pp_elixir_stealth_description", "duration", grandStealthElixirTTL); Localizer.AddPlaceholder("pp_potion_healing_description", "power", mediumHealingTideFlaskHealthOverTime); Localizer.AddPlaceholder("pp_potion_healing_description", "duration", mediumHealingTideFlaskTTL); Localizer.AddPlaceholder("pp_potion_spiritual_description", "power", mediumSpiritualHealingFlaskHealthOverTime); Localizer.AddPlaceholder("pp_potion_stam_description", "power", mediumStaminaFlaskStaminaOverTime); Localizer.AddPlaceholder("pp_vial_healing_description", "power", lesserHealingTideVialHealthOverTime); Localizer.AddPlaceholder("pp_vial_healing_description", "duration", lesserHealingTideVialTTL); Localizer.AddPlaceholder("pp_vial_spiritual_description", "power", lesserSpiritualHealingVialHealthOverTime); Localizer.AddPlaceholder("pp_vial_stam_description", "power", lesserStaminaVialStaminaOverTime); Localizer.AddPlaceholder("pp_hellbroth_of_flames_description", "power", hellbrothOfFlamesDamage); Localizer.AddPlaceholder("pp_hellbroth_of_frost_description", "power", hellbrothOfFrostDamage); Localizer.AddPlaceholder("pp_hellbroth_of_thors_fury_description", "power", hellbrothOfThorsFuryDamage); Localizer.AddPlaceholder("pp_hellbroth_of_eternal_life_description", "power", hellbrothOfEternalLifeHealing); Localizer.AddPlaceholder("pp_hellbroth_of_eternal_life_description", "duration", hellbrothOfEternalLifeTTL); Localizer.AddPlaceholder("pp_hellbroth_of_eternal_life_description", "radius", hellbrothOfEternalLifeRadius); Localizer.AddPlaceholder("pp_lesser_group_healing_description", "power", brewOfFaintGroupHealingHealthOverTime); Localizer.AddPlaceholder("pp_lesser_group_healing_description", "range", brewOfFaintGroupHealingRange); Localizer.AddPlaceholder("pp_medium_group_healing_description", "power", brewOfGroupHealingHealthOverTime); Localizer.AddPlaceholder("pp_medium_group_healing_description", "range", brewOfGroupHealingRange); Localizer.AddPlaceholder("pp_grand_group_healing_description", "power", brewOfGrandGroupHealingHealthOverTime); Localizer.AddPlaceholder("pp_grand_group_healing_description", "range", brewOfGrandGroupHealingRange); Localizer.AddPlaceholder("pp_brew_of_toxicity_description", "range", brewOfCunningToxicityRange); Localizer.AddPlaceholder("pp_brew_of_fiery_revenge_description", "range", brewOfFieryRevengeRange); Localizer.AddPlaceholder("pp_brew_of_icy_touch_description", "range", brewOfIcyTouchRange); Localizer.AddPlaceholder("pp_brew_of_spiritual_death_description", "range", brewOfSpiritualDeathRange); Localizer.AddPlaceholder("pp_brew_of_thunderous_words_description", "range", brewOfThunderousWordsRange); Localizer.AddPlaceholder("pp_odins_wizard_hat_description", "power", wizardHatConsumeChargeReduction); Localizer.AddPlaceholder("pp_odins_weapon_oil_description", "power", weaponOilDamageIncrease); Localizer.AddPlaceholder("pp_odins_weapon_oil_description", "duration", weaponOilTTL); Localizer.AddPlaceholder("pp_weapon_oil_description", "power", weaponOilDamageIncrease); Localizer.AddPlaceholder("pp_odins_dragon_staff_description", "power", smokeScreenChanceToBlock); Localizer.AddPlaceholder("pp_odins_dragon_staff_description", "duration", smokeScreenTTL); Localizer.AddPlaceholder("pp_odins_warlock_hat_description", "power", warlockHatSmokeScreenBlockIncrease); Localizer.AddPlaceholder("pp_odins_warlock_hat_description", "radius", warlockHatSmokeScreenSizeIncrease); Localizer.AddPlaceholder("pp_odins_warlock_hat_description", "duration", warlockHatSmokeScreenDurationIncrease); } } public static string SanitizeText(string input) { return Regex.Replace(input, "[\\p{C}-[\\r\\n\\t]]+", ""); } private static void onGroupPotionActivated(long sender, string effect) { GroupPotion.effectApplied = true; ((Character)Player.m_localPlayer).GetSEMan().AddStatusEffect(ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(effect)), false, 0, 0f); GroupPotion.effectApplied = false; } private static int DetermineExtraItems(int skillLevel, long sender) { int num = 0; if (alchemySkillBonusWhenCraftingEnabled.Value == Toggle.On) { if (Random.Range(1, 100) < skillLevel) { num++; } if ((float)skillLevel > 25f && Random.Range(1, 400) < skillLevel) { num++; } } if (num > 0) { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "PotionsPlus Alchemy Proc", Array.Empty()); } return num; } } public static class BuildingPiecesSetup { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public static void initializeBuildingPieces(AssetBundle assets) { BuildPiece buildPiece = new BuildPiece(assets, "opalchemy"); buildPiece.RequiredItems.Add("Stone", 8, recover: true); buildPiece.Category.Set(BuildPieceCategory.Crafting); buildPiece = new BuildPiece(assets, "opcauldron"); buildPiece.RequiredItems.Add("Iron", 4, recover: true); buildPiece.Category.Set(BuildPieceCategory.Crafting); buildPiece = new BuildPiece(assets, "Odins_Alchemy_Book"); buildPiece.RequiredItems.Add("WitheredBone", 1, recover: true); buildPiece.RequiredItems.Add("SurtlingCore", 2, recover: true); buildPiece.RequiredItems.Add("Iron", 4, recover: true); buildPiece.Category.Set(BuildPieceCategory.Crafting); } } public static class EquipmentSetup { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public static void initializeEquipment(AssetBundle assets) { Item item = new Item(assets, "Odins_Alchemy_Wand"); item.Crafting.Add(ItemManager.CraftingTable.Forge, 2); item.RequiredItems.Add("FineWood", 8); item.RequiredItems.Add("Copper", 3); item.RequiredItems.Add("SurtlingCore", 1); item.RequiredUpgradeItems.Add("FineWood", 4); item.RequiredUpgradeItems.Add("Copper", 1); item = new Item(assets, "Odins_Wizard_Hat"); item.Crafting.Add(ItemManager.CraftingTable.Workbench, 5); item.MaximumRequiredStationLevel = 5; item.RequiredItems.Add("LinenThread", 20); item.RequiredItems.Add("SurtlingCore", 5); item.RequiredUpgradeItems.Add("LinenThread", 10); item.RequiredUpgradeItems.Add("SurtlingCore", 2); item = new Item(assets, "Odins_Warlock_Hat"); item.Crafting.Add(ItemManager.CraftingTable.Workbench, 5); item.MaximumRequiredStationLevel = 5; item.RequiredItems.Add("LinenThread", 20); item.RequiredItems.Add("SurtlingCore", 5); item.RequiredUpgradeItems.Add("LinenThread", 10); item.RequiredUpgradeItems.Add("SurtlingCore", 2); item = new Item(assets, "Odins_Dragon_Staff"); item.Crafting.Add(ItemManager.CraftingTable.Workbench, 3); item.MaximumRequiredStationLevel = 5; item.RequiredItems.Add("Odins_Alchemy_Wand", 1); item.RequiredItems.Add("ElderBark", 40); item.RequiredItems.Add("BlackMetal", 40); item.RequiredItems.Add("SurtlingCore", 1); item.RequiredUpgradeItems.Add("ElderBark", 20); item.RequiredUpgradeItems.Add("BlackMetal", 20); GameObject smokeScreen = PrefabManager.RegisterPrefab(assets, "Staff_Smoke_Cloud"); smokeScreen.AddComponent(); smokeScreen.GetComponent().m_timeout = PotionsPlus.smokeScreenTTL.Value; PotionsPlus.smokeScreenTTL.SettingChanged += delegate { smokeScreen.GetComponent().m_timeout = PotionsPlus.smokeScreenTTL.Value; }; } } public static class GroupPotionSetup { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public static void initializeGroupPotions(AssetBundle assets) { //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Unknown result type (might be due to invalid IL or missing references) //IL_05c7: Unknown result type (might be due to invalid IL or missing references) bool flag = API.IsLoaded(); if (!flag) { Debug.Log((object)"[PotionsPlus] Groups mod not detected - group potions will be created but may not work properly"); } Item item = new Item(assets, "Lesser_Group_Healing"); if (flag) { item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Honey", 1); item.RequiredItems.Add("Mushroom", 2); } Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfFaintGroupHealingCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.brewOfFaintGroupHealingHealthOverTime); ((SE_Stats)Utils.ConvertConsumeSEStats(item.Prefab)).m_healthOverTimeDuration = 1f; item = new Item(assets, "Medium_Group_Healing"); if (flag) { item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Honey", 2); item.RequiredItems.Add("Mushroom", 4); } Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfGroupHealingCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.brewOfGroupHealingHealthOverTime); ((SE_Stats)Utils.ConvertConsumeSEStats(item.Prefab)).m_healthOverTimeDuration = 1f; item = new Item(assets, "Grand_Group_Healing"); if (flag) { item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Honey", 4); item.RequiredItems.Add("Mushroom", 6); } Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfGrandGroupHealingCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.brewOfGrandGroupHealingHealthOverTime); ((SE_Stats)Utils.ConvertConsumeSEStats(item.Prefab)).m_healthOverTimeDuration = 1f; item = new Item(assets, "Brew_of_Cunning_Toxicity"); if (flag) { item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Ooze", 10); item.RequiredItems.Add("Bloodbag", 3); item.RequiredItems.Add("Dandelion", 4); } Utils.ConvertConsumeSEStats(item.Prefab).damageType = (DamageType)256; Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfCunningToxicityTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((GroupPotion)(object)effect).range = value; }, PotionsPlus.brewOfCunningToxicityRange); item = new Item(assets, "Brew_of_Fiery_Revenge"); if (flag) { item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Resin", 20); item.RequiredItems.Add("Torch", 3); item.RequiredItems.Add("SurtlingCore", 2); } Utils.ConvertConsumeSEStats(item.Prefab).damageType = (DamageType)32; Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfFieryRevengeTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((GroupPotion)(object)effect).range = value; }, PotionsPlus.brewOfFieryRevengeRange); item = new Item(assets, "Brew_of_Icy_Touch"); if (flag) { item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("FreezeGland", 4); item.RequiredItems.Add("Carrot", 5); item.RequiredItems.Add("Turnip", 5); } Utils.ConvertConsumeSEStats(item.Prefab).damageType = (DamageType)64; Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfIcyTouchTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((GroupPotion)(object)effect).range = value; }, PotionsPlus.brewOfIcyTouchRange); item = new Item(assets, "Brew_of_Spiritual_Death"); if (flag) { item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Chitin", 2); item.RequiredItems.Add("Entrails", 4); } Utils.ConvertConsumeSEStats(item.Prefab).damageType = (DamageType)512; Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfSpiritualDeathTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((GroupPotion)(object)effect).range = value; }, PotionsPlus.brewOfSpiritualDeathRange); item = new Item(assets, "Brew_of_Thunderous_Words"); if (flag) { item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Obsidian", 3); item.RequiredItems.Add("GreydwarfEye", 6); item.RequiredItems.Add("Cloudberry", 2); } Utils.ConvertConsumeSEStats(item.Prefab).damageType = (DamageType)128; Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.brewOfThunderousWordsTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((GroupPotion)(object)effect).range = value; }, PotionsPlus.brewOfThunderousWordsRange); } } public static class HellbrothSetup { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public static void initializeHellbroth(AssetBundle assets) { try { Item item = new Item(assets, "Hellbroth_of_Flames"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Resin", 8); item.RequiredItems.Add("Torch", 1); item.Configurable = Configurability.Recipe; GameObject val = PrefabManager.RegisterPrefab(assets, "Hellbroth_Explosion"); if ((Object)(object)val != (Object)null) { Aoe fireAoe = val.GetComponent(); if ((Object)(object)fireAoe != (Object)null) { fireAoe.m_damage.m_fire = PotionsPlus.hellbrothOfFlamesDamage.Value; PotionsPlus.hellbrothOfFlamesDamage.SettingChanged += delegate { fireAoe.m_damage.m_fire = PotionsPlus.hellbrothOfFlamesDamage.Value; }; } else { Debug.LogWarning((object)"[PotionsPlus] Hellbroth_Explosion prefab missing Aoe component"); } } else { Debug.LogError((object)"[PotionsPlus] Failed to register Hellbroth_Explosion prefab"); } PrefabManager.RegisterPrefab(assets, "Hellbroth_Projectile"); PrefabManager.RegisterPrefab(assets, "Hellbroth_Orb_Projectile"); PotionsPlus.wandProjectiles.Add("Hellbroth_Orb_Projectile"); Item item2 = new Item(assets, "Hellbroth_of_Flames_Charge"); item2.Crafting.Add("opcauldron", 1); item2.CraftAmount = 2; item2.RequiredItems.Add("Hellbroth_of_Flames", 3); item2.Configurable = Configurability.Recipe; item = new Item(assets, "Hellbroth_of_Frost"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("FreezeGland", 4); item.RequiredItems.Add("Chain", 1); item.Configurable = Configurability.Recipe; GameObject val2 = PrefabManager.RegisterPrefab(assets, "Hellbroth_Frost_Explosion"); if ((Object)(object)val2 != (Object)null) { Aoe frostAoe = val2.GetComponent(); if ((Object)(object)frostAoe != (Object)null) { frostAoe.m_damage.m_frost = PotionsPlus.hellbrothOfFrostDamage.Value; PotionsPlus.hellbrothOfFrostDamage.SettingChanged += delegate { frostAoe.m_damage.m_frost = PotionsPlus.hellbrothOfFrostDamage.Value; }; } else { Debug.LogWarning((object)"[PotionsPlus] Hellbroth_Frost_Explosion prefab missing Aoe component"); } } PrefabManager.RegisterPrefab(assets, "Hellbroth_Frost_Projectile"); PrefabManager.RegisterPrefab(assets, "Hellbroth_Frost_Orb_Projectile"); PotionsPlus.wandProjectiles.Add("Hellbroth_Frost_Orb_Projectile"); item2 = new Item(assets, "Hellbroth_of_Frost_Charge"); item2.Crafting.Add("opcauldron", 1); item2.CraftAmount = 2; item2.RequiredItems.Add("Hellbroth_of_Frost", 3); item2.Configurable = Configurability.Recipe; item = new Item(assets, "Hellbroth_of_Thors_Fury"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Tar", 6); item.RequiredItems.Add("Thunderstone", 1); item.Configurable = Configurability.Recipe; GameObject val3 = PrefabManager.RegisterPrefab(assets, "Hellbroth_Thors_Fury_Explosion"); if ((Object)(object)val3 != (Object)null) { Aoe lightningAoe = val3.GetComponent(); if ((Object)(object)lightningAoe != (Object)null) { lightningAoe.m_damage.m_lightning = PotionsPlus.hellbrothOfThorsFuryDamage.Value; PotionsPlus.hellbrothOfThorsFuryDamage.SettingChanged += delegate { lightningAoe.m_damage.m_lightning = PotionsPlus.hellbrothOfThorsFuryDamage.Value; }; } else { Debug.LogWarning((object)"[PotionsPlus] Hellbroth_Thors_Fury_Explosion prefab missing Aoe component"); } } PrefabManager.RegisterPrefab(assets, "Hellbroth_Thors_Fury_Projectile"); PrefabManager.RegisterPrefab(assets, "Hellbroth_Thors_Fury_Orb_Projectile"); PotionsPlus.wandProjectiles.Add("Hellbroth_Thors_Fury_Orb_Projectile"); item2 = new Item(assets, "Hellbroth_of_Thors_Fury_Charge"); item2.Crafting.Add("opcauldron", 1); item2.CraftAmount = 2; item2.RequiredItems.Add("Hellbroth_of_Thors_Fury", 3); item2.Configurable = Configurability.Recipe; item = new Item(assets, "Hellbroth_of_Eternal_Life"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Honey", 5); item.RequiredItems.Add("Dandelion", 3); item.Configurable = Configurability.Recipe; PrefabManager.RegisterPrefab(assets, "Hellbroth_Life_Projectile"); GameObject val4 = PrefabManager.RegisterPrefab(assets, "Hellbroth_Life_Explosion"); if ((Object)(object)val4 != (Object)null) { if ((Object)(object)val4.GetComponent() == (Object)null) { val4.AddComponent(); Debug.Log((object)"[PotionsPlus] Added HealingAoe component to Hellbroth_Life_Explosion"); } } else { Debug.LogError((object)"[PotionsPlus] Failed to register Hellbroth_Life_Explosion prefab"); } PrefabManager.RegisterPrefab(assets, "Hellbroth_Life_Orb_Projectile"); PotionsPlus.wandProjectiles.Add("Hellbroth_Life_Orb_Projectile"); item2 = new Item(assets, "Hellbroth_of_Eternal_Life_Charge"); item2.Crafting.Add("opcauldron", 1); item2.CraftAmount = 2; item2.RequiredItems.Add("Hellbroth_of_Eternal_Life", 3); item2.Configurable = Configurability.Recipe; } catch (Exception ex) { Debug.LogError((object)("[PotionsPlus] HellbrothSetup ERROR: " + ex.Message + "\n" + ex.StackTrace)); } } } public static class PhilosophersSetup { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public static void initializePhilosophersStones(AssetBundle assets) { Item item = new Item(assets, "PhilosopherStoneBlue"); item.Crafting.Add("opcauldron", 1); item.RequiredItems.Add("Flask_of_Elements", 5); AddStatusEffectModifier(item); item = new Item(assets, "PhilosopherStoneGreen"); item.Crafting.Add("opcauldron", 1); item.RequiredItems.Add("Flask_of_Fortification", 5); AddStatusEffectModifier(item); item = new Item(assets, "PhilosopherStoneRed"); item.Crafting.Add("opcauldron", 1); item.RequiredItems.Add("Flask_of_the_Gods", 5); AddStatusEffectModifier(item); item = new Item(assets, "PhilosopherStonePurple"); item.Crafting.Add("opcauldron", 1); item.RequiredItems.Add("Flask_of_Second_Wind", 5); AddStatusEffectModifier(item); AddStatusEffectModifier(new Item(assets, "PhilosopherStoneBlack")); [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] static void AddStatusEffectModifier(Item item2) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0037: 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) SE_Stats statusEffect = (SE_Stats)item2.Prefab.GetComponent().m_itemData.m_shared.m_equipStatusEffect; statusEffect.m_raiseSkill = Skill.fromName("Alchemy"); statusEffect.m_raiseSkillModifier = PotionsPlus.philosophersStoneXpGainFactor.Value; PotionsPlus.philosophersStoneXpGainFactor.SettingChanged += delegate { statusEffect.m_raiseSkillModifier = PotionsPlus.philosophersStoneXpGainFactor.Value; }; } } } public static class PotionsSetup { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public static void initializePotions(AssetBundle assets) { //IL_098a: Unknown result type (might be due to invalid IL or missing references) //IL_0a60: Unknown result type (might be due to invalid IL or missing references) //IL_0c13: Unknown result type (might be due to invalid IL or missing references) //IL_0cd6: Unknown result type (might be due to invalid IL or missing references) Item item = new Item(assets, "Flask_of_Elements"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Potion_Meadbase", 1); item.RequiredItems.Add("FreezeGland", 2); item.RequiredItems.Add("ElderBark", 4); item.RequiredItems.Add("Entrails", 8); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.flaskOfElementsTTL); item = new Item(assets, "Flask_of_Fortification"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Potion_Meadbase", 1); item.RequiredItems.Add("Obsidian", 2); item.RequiredItems.Add("Flint", 4); item.RequiredItems.Add("Stone", 8); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.flaskOfFortificationTTL); item = new Item(assets, "Flask_of_the_Gods"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Potion_Meadbase", 1); item.RequiredItems.Add("Thistle", 4); item.RequiredItems.Add("Flax", 4); item.RequiredItems.Add("Carrot", 2); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.flaskOfGodsTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.flaskOfGodsHealing); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthRegenMultiplier = value; }, PotionsPlus.flaskOfGodsRegenMultiplier); item = new Item(assets, "Flask_of_Magelight"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Potion_Meadbase", 1); item.RequiredItems.Add("BoneFragments", 4); item.RequiredItems.Add("FreezeGland", 4); item.RequiredItems.Add("GreydwarfEye", 8); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.flaskOfMagelightTTL); Light Magelight = PrefabManager.RegisterPrefab(assets, "Magelight").GetComponent(); SetLightIntensity(); PotionsPlus.flaskOfMagelightIntensity.SettingChanged += delegate { SetLightIntensity(); }; PotionsPlus.flaskOfMagelightColor.SettingChanged += delegate { SetLightIntensity(); }; item = new Item(assets, "Flask_of_Second_Wind"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Potion_Meadbase", 1); item.RequiredItems.Add("Ooze", 4); item.RequiredItems.Add("FreezeGland", 2); item.RequiredItems.Add("Feathers", 6); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.flaskOfSecondWindTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_jumpStaminaUseModifier = 1f - value; }, PotionsPlus.flaskOfSecondWindJumpStaminaFactor); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_runStaminaDrainModifier = 1f - value; }, PotionsPlus.flaskOfSecondWindRunStaminaFactor); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_staminaRegenMultiplier = value; }, PotionsPlus.flaskOfSecondWindStaminaRegenMultiplier); item = new Item(assets, "Grand_Healing_Tide_Potion"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Ooze", 2); item.RequiredItems.Add("Barley", 4); item.RequiredItems.Add("Needle", 2); item.RequiredItems.Add("Cloudberry", 6); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.grandHealingTidePotionCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.grandHealingTidePotionHealthOverTime); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTimeDuration = value; }, PotionsPlus.grandHealingTidePotionTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTimeInterval = value; }, PotionsPlus.grandHealingTidePotionTickInterval); item = new Item(assets, "Grand_Spiritual_Healing_Potion"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("Ooze", 4); item.RequiredItems.Add("Flax", 4); item.RequiredItems.Add("WolfFang", 2); item.RequiredItems.Add("Cloudberry", 6); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.grandSpiritualHealingPotionCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.grandSpiritualHealingPotionHealthOverTime); item = new Item(assets, "Grand_Stamina_Elixir"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("LoxMeat", 2); item.RequiredItems.Add("Carrot", 4); item.RequiredItems.Add("Turnip", 4); item.RequiredItems.Add("Cloudberry", 8); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.grandStaminaElixirCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_staminaOverTime = value; }, PotionsPlus.grandStaminaElixirStaminaOverTime); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_staminaOverTimeDuration = value; }, PotionsPlus.grandStaminaElixirTTL); item = new Item(assets, "Grand_Stealth_Elixir"); item.Crafting.Add("opalchemy", 2); item.RequiredItems.Add("FreezeGland", 2); item.RequiredItems.Add("Flax", 4); item.RequiredItems.Add("Feathers", 2); item.RequiredItems.Add("Carrot", 2); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.grandStealthElixirTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { effect.m_noiseModifier = (float)(-value) / 100f; }, PotionsPlus.grandStealthElixirNoiseReduction); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { effect.m_stealthModifier = (float)(-value) / 100f; }, PotionsPlus.grandStealthElixirVisibilityReduction); item = new Item(assets, "Medium_Healing_Tide_Flask"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Resin", 6); item.RequiredItems.Add("Blueberries", 4); item.RequiredItems.Add("Bloodbag", 2); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.mediumHealingTideFlaskCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.mediumHealingTideFlaskHealthOverTime); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTimeDuration = value; }, PotionsPlus.mediumHealingTideFlaskTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTimeInterval = value; }, PotionsPlus.mediumHealingTideFlaskTickInterval); item = new Item(assets, "Medium_Spiritual_Healing_Flask"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Ooze", 2); item.RequiredItems.Add("BoneFragments", 4); item.RequiredItems.Add("Bloodbag", 2); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.mediumSpiritualHealingFlaskCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.mediumSpiritualHealingFlaskHealthOverTime); ((SE_Stats)item.Prefab.GetComponent().m_itemData.m_shared.m_consumeStatusEffect).m_healthOverTimeDuration = 1f; item = new Item(assets, "Medium_Stamina_Flask"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Resin", 4); item.RequiredItems.Add("Blueberries", 4); item.RequiredItems.Add("Bloodbag", 2); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.mediumStaminaFlaskCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_staminaOverTime = value; }, PotionsPlus.mediumStaminaFlaskStaminaOverTime); ((SE_Stats)item.Prefab.GetComponent().m_itemData.m_shared.m_consumeStatusEffect).m_staminaOverTimeDuration = 1f; item = new Item(assets, "Lesser_Healing_Tide_Vial"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Honey", 2); item.RequiredItems.Add("Raspberry", 4); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.lesserHealingTideVialCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.lesserHealingTideVialHealthOverTime); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTimeDuration = value; }, PotionsPlus.lesserHealingTideVialTTL); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTimeInterval = value; }, PotionsPlus.lesserHealingTideVialTickInterval); item = new Item(assets, "Lesser_Spiritual_Healing_Vial"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Dandelion", 2); item.RequiredItems.Add("Raspberry", 4); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.lesserSpiritualHealingVialCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_healthOverTime = value; }, PotionsPlus.lesserSpiritualHealingVialHealthOverTime); ((SE_Stats)item.Prefab.GetComponent().m_itemData.m_shared.m_consumeStatusEffect).m_healthOverTimeDuration = 1f; item = new Item(assets, "Lesser_Stamina_Vial"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Honey", 2); item.RequiredItems.Add("Mushroom", 4); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, int value) => { ((StatusEffect)effect).m_ttl = value; }, PotionsPlus.lesserStaminaVialCooldown); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { effect.m_staminaOverTime = value; }, PotionsPlus.lesserStaminaVialStaminaOverTime); ((SE_Stats)item.Prefab.GetComponent().m_itemData.m_shared.m_consumeStatusEffect).m_staminaOverTimeDuration = 1f; item = new Item(assets, "Odins_Weapon_Oil"); item.Crafting.Add("opalchemy", 1); item.RequiredItems.Add("Tar", 8); item.RequiredItems.Add("Crystal", 1); Utils.SEValue(item, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] (SE_Stats effect, float value) => { ((StatusEffect)effect).m_ttl = value * 60f; }, PotionsPlus.weaponOilTTL); Utils.ConvertConsumeSEStats(item.Prefab); item = new Item(assets, "Potion_Meadbase"); item["Tide"].Crafting.Add("opcauldron", 1); item["Tide"].RequiredItems.Add("Grand_Healing_Tide_Potion", 1); item["Spiritual"].Crafting.Add("opcauldron", 1); item["Spiritual"].RequiredItems.Add("Grand_Spiritual_Healing_Potion", 1); item["Table"].Crafting.Add("opalchemy", 2); item["Table"].RequiredItems.Add("Honey", 2); item["Table"].RequiredItems.Add("YmirRemains", 4); void SetLightIntensity() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) Magelight.intensity = PotionsPlus.flaskOfMagelightIntensity.Value; Magelight.color = PotionsPlus.flaskOfMagelightColor.Value; } } } [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] [<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] public static class Utils { private static void ItemValue<[<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] T>(Item item, Action setter, ConfigEntry config) { string itemName = item.Prefab.GetComponent().m_itemData.m_shared.m_name; config.SettingChanged += [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (object _, EventArgs _) => { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { Inventory[] source = Player.s_players.Select([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (Player p) => ((Humanoid)p).GetInventory()).Concat(from c in Object.FindObjectsOfType() select c.GetInventory()).ToArray(); foreach (ItemData item2 in (from i in (from p in ObjectDB.instance.m_items select p.GetComponent() into c where Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent()) select c).Concat(ItemDrop.s_instances) select i.m_itemData).Concat(source.SelectMany([<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] (Inventory i) => i.GetAllItems()))) { if (itemName == item2.m_shared.m_name) { setter(item2.m_shared, config.Value); } } } set(); }; set(); void set() { setter(item.Prefab.GetComponent().m_itemData.m_shared, config.Value); } } public static void SEValue<[<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(2)] T>(Item potion, Action setter, ConfigEntry config) { ItemValue(potion, [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(0)] ([<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(1)] SharedData i, T c) => { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown setter((SE_Stats)i.m_consumeStatusEffect, c); }, config); } public static T ConvertConsumeSEStats<[<6e8bc1f7-ed74-405e-8cf6-e77cb9d255f7>Nullable(0)] T>(GameObject item) where T : StatusEffect { SharedData shared = item.GetComponent().m_itemData.m_shared; StatusEffect consumeStatusEffect = shared.m_consumeStatusEffect; T val = ScriptableObject.CreateInstance(); shared.m_consumeStatusEffect = (StatusEffect)(object)val; ((Object)(object)val).name = ((Object)consumeStatusEffect).name; FieldInfo[] fields = ((object)consumeStatusEffect).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val, fieldInfo.GetValue(consumeStatusEffect)); } return val; } } public class WeaponOil : SE_Stats { [<278e803c-873f-4fa5-9ebc-5b24f0c1bd96>NullableContext(1)] public override void ModifyAttack(SkillType skill, ref HitData hitData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)skill != 8) { Character character = ((StatusEffect)this).m_character; Player val = (Player)(object)((character is Player) ? character : null); if (val == null || ((Humanoid)val).GetCurrentWeapon() != ((Humanoid)val).m_unarmedWeapon.m_itemData) { ((DamageTypes)(ref hitData.m_damage)).Modify(1f + (float)PotionsPlus.weaponOilDamageIncrease.Value / 100f); } } } } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<033f7354-4422-4073-936b-92f82ce2b86b>Embedded] internal sealed class <033f7354-4422-4073-936b-92f82ce2b86b>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<033f7354-4422-4073-936b-92f82ce2b86b>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <1513dc90-670f-4f35-9177-defdddfcb8f6>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <1513dc90-670f-4f35-9177-defdddfcb8f6>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <1513dc90-670f-4f35-9177-defdddfcb8f6>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<033f7354-4422-4073-936b-92f82ce2b86b>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContextAttribute : Attribute { public readonly byte Flag; public <9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContextAttribute(byte P_0) { Flag = P_0; } } [<033f7354-4422-4073-936b-92f82ce2b86b>Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class <6735a782-beab-4ceb-8c97-7cd0766b45ce>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <6735a782-beab-4ceb-8c97-7cd0766b45ce>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ServerSync { [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] [PublicAPI] internal abstract class OwnConfigEntryBase { [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] public object LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] [PublicAPI] internal class SyncedConfigEntry<[<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] T>(ConfigEntry sourceConfig) : OwnConfigEntryBase() { public readonly ConfigEntry SourceConfig = sourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(2)] [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] internal abstract class CustomSyncedValueBase { public object LocalBaseValue; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(1)] public readonly string Identifier; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(1)] public readonly Type Type; private object boxedValue; protected bool localIsOwner; public readonly int Priority; public object BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action ValueChanged; [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] [PublicAPI] internal sealed class CustomSyncedValue<[<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] [PublicAPI] internal class ConfigSync { [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] public static ZRpc currentRpc; [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] internal static class RegisterRPCPatch { [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register(configSync2.Name + " ConfigSync", (Action)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges()); } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] static void SendAdmin(List peers, bool isAdmin) { ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1] { new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = isAdmin } }); ConfigSync configSync = configSyncs.First(); if (configSync != null) { ((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package)); } } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] static IEnumerator WatchAdminListChanges() { MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); List CurrentList = new List(adminList.GetList()); while (true) { yield return (object)new WaitForSeconds(30f); if (!adminList.GetList().SequenceEqual(CurrentList)) { CurrentList = new List(adminList.GetList()); List adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p) { string hostName = p.m_rpc.GetSocket().GetHostName(); return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })); }).ToList(); List nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList(); SendAdmin(nonAdminPeer, isAdmin: false); SendAdmin(adminPeer, isAdmin: true); } } } } } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class RegisterClientRPCPatch { [HarmonyPostfix] [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] private static void Postfix(ZNet __instance, ZNetPeer peer) { if (__instance.IsServer()) { return; } foreach (ConfigSync configSync in configSyncs) { peer.m_rpc.Register(configSync.Name + " ConfigSync", (Action)configSync.RPC_FromServerConfigSync); } } } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] private class ParsedConfigs { [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 1, 1, 2 })] public readonly Dictionary configValues = new Dictionary(); [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 1, 1, 2 })] public readonly Dictionary customValues = new Dictionary(); } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] [HarmonyPatch(typeof(ZNet), "Shutdown")] private class ResetConfigsOnShutdown { [HarmonyPostfix] private static void Postfix() { ProcessingServerUpdate = true; foreach (ConfigSync configSync in configSyncs) { configSync.resetConfigsFromServer(); configSync.IsSourceOfTruth = true; configSync.InitialSyncDone = false; } ProcessingServerUpdate = false; } } [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private class SendConfigsAfterLogin { [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] private class BufferingSocket : ZPlayFabSocket, ISocket { public volatile bool finished = false; public volatile int versionMatchQueued = -1; public readonly List Package = new List(); public readonly ISocket Original; public BufferingSocket(ISocket original) { Original = original; ((ZPlayFabSocket)this)..ctor(); } public bool IsConnected() { return Original.IsConnected(); } public ZPackage Recv() { return Original.Recv(); } public int GetSendQueueSize() { return Original.GetSendQueueSize(); } public int GetCurrentSendRate() { return Original.GetCurrentSendRate(); } public bool IsHost() { return Original.IsHost(); } public void Dispose() { Original.Dispose(); } public bool GotNewData() { return Original.GotNewData(); } public void Close() { Original.Close(); } public string GetEndPointString() { return Original.GetEndPointString(); } public void GetAndResetStats(out int totalSent, out int totalRecv) { Original.GetAndResetStats(ref totalSent, ref totalRecv); } public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec) { Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec); } public ISocket Accept() { return Original.Accept(); } public int GetHostPort() { return Original.GetHostPort(); } public bool Flush() { return Original.Flush(); } public string GetHostName() { return Original.GetHostName(); } public void VersionMatch() { if (finished) { Original.VersionMatch(); } else { versionMatchQueued = Package.Count; } } public void Send(ZPackage pkg) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown int pos = pkg.GetPos(); pkg.SetPos(0); int num = pkg.ReadInt(); if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished) { ZPackage val = new ZPackage(pkg.GetArray()); val.SetPos(pos); Package.Add(val); } else { pkg.SetPos(pos); Original.Send(pkg); } } } [HarmonyPriority(800)] [HarmonyPrefix] private static void Prefix([<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 2, 1, 1 })] ref Dictionary __state, ZNet __instance, ZRpc rpc) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 if (!__instance.IsServer()) { return; } BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket()); AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket); object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (val != null && (int)ZNet.m_onlineBackend > 0) { FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket"); object? value = fieldInfo.GetValue(val); ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null); if (val2 != null) { typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId); } fieldInfo.SetValue(val, bufferingSocket); } if (__state == null) { __state = new Dictionary(); } __state[Assembly.GetExecutingAssembly()] = bufferingSocket; } [HarmonyPostfix] private static void Postfix(Dictionary __state, ZNet __instance, ZRpc rpc) { ZNetPeer peer; if (__instance.IsServer()) { object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null); if (peer == null) { SendBufferedData(); } else { ((MonoBehaviour)__instance).StartCoroutine(sendAsync()); } } void SendBufferedData() { if (rpc.GetSocket() is BufferingSocket bufferingSocket) { AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket.Original); object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc }); ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null); if (val != null) { AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original); } } BufferingSocket bufferingSocket2 = __state[Assembly.GetExecutingAssembly()]; bufferingSocket2.finished = true; for (int i = 0; i < bufferingSocket2.Package.Count; i++) { if (i == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } bufferingSocket2.Original.Send(bufferingSocket2.Package[i]); } if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued) { bufferingSocket2.Original.VersionMatch(); } } IEnumerator sendAsync() { foreach (ConfigSync configSync in configSyncs) { List entries = new List(); if (configSync.CurrentVersion != null) { entries.Add(new PackageEntry { section = "Internal", key = "serverversion", type = typeof(string), value = configSync.CurrentVersion }); } MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); entries.Add(new PackageEntry { section = "Internal", key = "lockexempt", type = typeof(bool), value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2] { adminList, rpc.GetSocket().GetHostName() })) }); ZPackage package = ConfigsToPackage(configSync.allConfigs.Select([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false); yield return ((MonoBehaviour)__instance).StartCoroutine(configSync.sendZPackage(new List { peer }, package)); } SendBufferedData(); } } } [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] private class PackageEntry { public string section = null; public string key = null; public Type type = null; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] public object value; } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] [HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")] private static class PreventSavingServerInfo { [HarmonyPrefix] [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] private static bool Prefix(ConfigEntryBase __instance, ref string __result) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase)) { return true; } __result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType); return false; } } [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] [HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")] private static class PreventConfigRereadChangingValues { [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] [HarmonyPrefix] private static bool Prefix(ConfigEntryBase __instance, string value) { OwnConfigEntryBase ownConfigEntryBase = configData(__instance); if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null) { return true; } try { ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType); } catch (Exception ex) { Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}"); } return false; } } [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] private class InvalidDeserializationTypeException : Exception { public string expected = null; public string received = null; public string field = ""; } public static bool ProcessingServerUpdate; public readonly string Name; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] public string DisplayName; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] public string CurrentVersion; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] public string MinimumRequiredVersion; public bool ModRequired = false; private bool? forceConfigLocking; private bool isSourceOfTruth = true; private static readonly HashSet configSyncs; private readonly HashSet allConfigs = new HashSet(); private HashSet allCustomValues = new HashSet(); private static bool isServer; private static bool lockExempt; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private OwnConfigEntryBase lockedConfig = null; private const byte PARTIAL_CONFIGS = 1; private const byte FRAGMENTED_CONFIG = 2; private const byte COMPRESSED_CONFIG = 4; private readonly Dictionary> configValueCache = new Dictionary>(); [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 1, 0, 1 })] private readonly List> cacheExpirations = new List>(); private static long packageCounter; public bool IsLocked { get { bool? flag = forceConfigLocking; bool num; if (!flag.HasValue) { if (lockedConfig == null) { goto IL_0052; } num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0; } else { num = flag == true; } if (!num) { goto IL_0052; } int result = ((!lockExempt) ? 1 : 0); goto IL_0053; IL_0052: result = 0; goto IL_0053; IL_0053: return (byte)result != 0; } set { forceConfigLocking = value; } } public bool IsAdmin => lockExempt || isSourceOfTruth; public bool IsSourceOfTruth { get { return isSourceOfTruth; } private set { if (value != isSourceOfTruth) { isSourceOfTruth = value; this.SourceOfTruthChanged?.Invoke(value); } } } public bool InitialSyncDone { get; private set; } = false; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] [method: <9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(2)] [field: <1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] public event Action SourceOfTruthChanged; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] [method: <9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(2)] [field: <1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private event Action lockedConfigChanged; static ConfigSync() { ProcessingServerUpdate = false; configSyncs = new HashSet(); lockExempt = false; packageCounter = 0L; RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle); } public ConfigSync(string name) { Name = name; configSyncs.Add(this); new VersionCheck(this); } public SyncedConfigEntry AddConfigEntry<[<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] T>(ConfigEntry configEntry) { OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry); SyncedConfigEntry syncedEntry = ownConfigEntryBase as SyncedConfigEntry; if (syncedEntry == null) { syncedEntry = new SyncedConfigEntry(configEntry); AccessTools.DeclaredField(typeof(ConfigDescription), "k__BackingField").SetValue(((ConfigEntryBase)configEntry).Description, new object[1] { new ConfigurationManagerAttributes() }.Concat(((ConfigEntryBase)configEntry).Description.Tags ?? Array.Empty()).Concat(new SyncedConfigEntry[1] { syncedEntry }).ToArray()); configEntry.SettingChanged += [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (object _, EventArgs _) => { if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig) { Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry); } }; allConfigs.Add(syncedEntry); } return syncedEntry; } public SyncedConfigEntry AddLockingConfigEntry<[<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] T>(ConfigEntry lockingConfig) where T : IConvertible { if (lockedConfig != null) { throw new Exception("Cannot initialize locking ConfigEntry twice"); } lockedConfig = AddConfigEntry(lockingConfig); lockingConfig.SettingChanged += [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (object _, EventArgs _) => { this.lockedConfigChanged?.Invoke(); }; return (SyncedConfigEntry)lockedConfig; } internal void AddCustomValue(CustomSyncedValueBase customValue) { if (allCustomValues.Select([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue.Identifier)) { throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)"); } allCustomValues.Add(customValue); allCustomValues = new HashSet(allCustomValues.OrderByDescending([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (CustomSyncedValueBase v) => v.Priority)); customValue.ValueChanged += delegate { if (!ProcessingServerUpdate) { Broadcast(ZRoutedRpc.Everybody, customValue); } }; } private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package) { lockedConfigChanged += serverLockedSettingChanged; IsSourceOfTruth = false; if (HandleConfigSyncRPC(0L, package, clientUpdate: false)) { InitialSyncDone = true; } } private void RPC_FromOtherClientConfigSync(long sender, ZPackage package) { HandleConfigSyncRPC(sender, package, clientUpdate: true); } private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown try { if (isServer && IsLocked) { ZRpc currentRpc = SnatchCurrentlyHandlingRPC.currentRpc; object obj; if (currentRpc == null) { obj = null; } else { ISocket socket = currentRpc.GetSocket(); obj = ((socket != null) ? socket.GetHostName() : null); } string text = (string)obj; if (text != null) { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance); if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text })))) { return false; } } } cacheExpirations.RemoveAll(([<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 0, 1 })] KeyValuePair kv) => { if (kv.Key < DateTimeOffset.Now.Ticks) { configValueCache.Remove(kv.Value); return true; } return false; }); byte b = package.ReadByte(); if ((b & 2) != 0) { long num = package.ReadLong(); string text2 = sender.ToString() + num; if (!configValueCache.TryGetValue(text2, out var value)) { value = new SortedDictionary(); configValueCache[text2] = value; cacheExpirations.Add(new KeyValuePair(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2)); } int key = package.ReadInt(); int num2 = package.ReadInt(); value.Add(key, package.ReadByteArray()); if (value.Count < num2) { return false; } configValueCache.Remove(text2); package = new ZPackage(value.Values.SelectMany([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (byte[] a) => a).ToArray()); b = package.ReadByte(); } ProcessingServerUpdate = true; if ((b & 4) != 0) { byte[] buffer = package.ReadByteArray(); MemoryStream stream = new MemoryStream(buffer); MemoryStream memoryStream = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) { deflateStream.CopyTo(memoryStream); } package = new ZPackage(memoryStream.ToArray()); b = package.ReadByte(); } if ((b & 1) == 0) { resetConfigsFromServer(); } ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package); ConfigFile val2 = null; bool saveOnConfigSet = false; foreach (KeyValuePair configValue in parsedConfigs.configValues) { if (!isServer && configValue.Key.LocalBaseValue == null) { configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue; } if (val2 == null) { val2 = configValue.Key.BaseConfig.ConfigFile; saveOnConfigSet = val2.SaveOnConfigSet; val2.SaveOnConfigSet = false; } configValue.Key.BaseConfig.BoxedValue = configValue.Value; } if (val2 != null) { val2.SaveOnConfigSet = saveOnConfigSet; val2.Save(); } foreach (KeyValuePair customValue in parsedConfigs.customValues) { if (!isServer) { CustomSyncedValueBase key2 = customValue.Key; if (key2.LocalBaseValue == null) { key2.LocalBaseValue = customValue.Key.BoxedValue; } } customValue.Key.BoxedValue = customValue.Value; } Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name)); if (!isServer) { serverLockedSettingChanged(); } return true; } finally { ProcessingServerUpdate = false; } } private ParsedConfigs ReadConfigsFromPackage(ZPackage package) { ParsedConfigs parsedConfigs = new ParsedConfigs(); Dictionary dictionary = allConfigs.Where([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (OwnConfigEntryBase c) => c); Dictionary dictionary2 = allCustomValues.ToDictionary([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (CustomSyncedValueBase c) => c.Identifier, [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (CustomSyncedValueBase c) => c); int num = package.ReadInt(); for (int num2 = 0; num2 < num; num2++) { string text = package.ReadString(); string text2 = package.ReadString(); string text3 = package.ReadString(); Type type = Type.GetType(text3); if (text3 == "" || type != null) { object obj; try { obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type)); } catch (InvalidDeserializationTypeException ex) { Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected)); continue; } OwnConfigEntryBase value2; if (text == "Internal") { CustomSyncedValueBase value; if (text2 == "serverversion") { if (obj?.ToString() != CurrentVersion) { Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown"))); } } else if (text2 == "lockexempt") { if (obj is bool flag) { lockExempt = flag; } } else if (dictionary2.TryGetValue(text2, out value)) { if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3) { parsedConfigs.customValues[value] = obj; continue; } Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName)); } } else if (dictionary.TryGetValue(text + "_" + text2, out value2)) { Type type2 = configType(value2.BaseConfig); if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3) { parsedConfigs.configValues[value2] = obj; continue; } Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName)); } else { Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match.")); } continue; } Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs")); return new ParsedConfigs(); } return parsedConfigs; } private static bool isWritableConfig(OwnConfigEntryBase config) { ConfigSync configSync = configSyncs.FirstOrDefault([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (ConfigSync cs) => cs.allConfigs.Contains(config)); if (configSync == null) { return true; } return configSync.IsSourceOfTruth || !config.SynchronizedConfig || config.LocalBaseValue == null || (!configSync.IsLocked && (config != configSync.lockedConfig || lockExempt)); } private void serverLockedSettingChanged() { foreach (OwnConfigEntryBase allConfig in allConfigs) { configAttribute(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig); } } private void resetConfigsFromServer() { ConfigFile val = null; bool saveOnConfigSet = false; foreach (OwnConfigEntryBase item in allConfigs.Where([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (OwnConfigEntryBase config) => config.LocalBaseValue != null)) { if (val == null) { val = item.BaseConfig.ConfigFile; saveOnConfigSet = val.SaveOnConfigSet; val.SaveOnConfigSet = false; } item.BaseConfig.BoxedValue = item.LocalBaseValue; item.LocalBaseValue = null; } if (val != null) { val.SaveOnConfigSet = saveOnConfigSet; } foreach (CustomSyncedValueBase item2 in allCustomValues.Where([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (CustomSyncedValueBase config) => config.LocalBaseValue != null)) { item2.BoxedValue = item2.LocalBaseValue; item2.LocalBaseValue = null; } lockedConfigChanged -= serverLockedSettingChanged; serverLockedSettingChanged(); } private IEnumerator distributeConfigToPeers(ZNetPeer peer, ZPackage package) { ZRoutedRpc rpc = ZRoutedRpc.instance; if (rpc == null) { yield break; } byte[] data = package.GetArray(); if (data != null && data.LongLength > 250000) { int fragments = (int)(1 + (data.LongLength - 1) / 250000); long packageIdentifier = ++packageCounter; int fragment = 0; while (fragment < fragments) { foreach (bool item in waitForQueue()) { yield return item; } if (peer.m_socket.IsConnected()) { ZPackage fragmentedPackage = new ZPackage(); fragmentedPackage.Write((byte)2); fragmentedPackage.Write(packageIdentifier); fragmentedPackage.Write(fragment); fragmentedPackage.Write(fragments); fragmentedPackage.Write(data.Skip(250000 * fragment).Take(250000).ToArray()); SendPackage(fragmentedPackage); if (fragment != fragments - 1) { yield return true; } int num = fragment + 1; fragment = num; continue; } break; } yield break; } foreach (bool item2 in waitForQueue()) { yield return item2; } SendPackage(package); void SendPackage(ZPackage pkg) { string text = Name + " ConfigSync"; if (isServer) { peer.m_rpc.Invoke(text, new object[1] { pkg }); } else { rpc.InvokeRoutedRPC(peer.m_server ? 0 : peer.m_uid, text, new object[1] { pkg }); } } IEnumerable waitForQueue() { float timeout = Time.time + 30f; while (peer.m_socket.GetSendQueueSize() > 20000) { if (Time.time > timeout) { Debug.Log((object)$"Disconnecting {peer.m_uid} after 30 seconds config sending timeout"); peer.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 }); ZNet.instance.Disconnect(peer); break; } yield return false; } } } private IEnumerator sendZPackage(long target, ZPackage package) { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return Enumerable.Empty().GetEnumerator(); } List list = (List)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance); if (target != ZRoutedRpc.Everybody) { list = list.Where([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (ZNetPeer p) => p.m_uid == target).ToList(); } return sendZPackage(list, package); } private IEnumerator sendZPackage(List peers, ZPackage package) { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { yield break; } byte[] rawData = package.GetArray(); if (rawData != null && rawData.LongLength > 10000) { ZPackage compressedPackage = new ZPackage(); compressedPackage.Write((byte)4); MemoryStream output = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal)) { deflateStream.Write(rawData, 0, rawData.Length); } compressedPackage.Write(output.ToArray()); package = compressedPackage; } List> writers = (from p in peers where p.IsReady() select distributeConfigToPeers(p, package)).ToList(); writers.RemoveAll((IEnumerator writer) => !writer.MoveNext()); while (writers.Count > 0) { yield return null; writers.RemoveAll((IEnumerator writer) => !writer.MoveNext()); } } private void Broadcast(long target, params ConfigEntryBase[] configs) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(configs); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } private void Broadcast(long target, params CustomSyncedValueBase[] customValues) { if (!IsLocked || isServer) { ZPackage package = ConfigsToPackage(null, customValues); ZNet instance = ZNet.instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package)); } } } [return: <1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private static OwnConfigEntryBase configData(ConfigEntryBase config) { return config.Description.Tags?.OfType().SingleOrDefault(); } [return: <1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 2, 1 })] public static SyncedConfigEntry ConfigData<[<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] T>(ConfigEntry config) { return ((ConfigEntryBase)config).Description.Tags?.OfType>().SingleOrDefault(); } private static T configAttribute<[<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] T>(ConfigEntryBase config) { return config.Description.Tags.OfType().First(); } private static Type configType(ConfigEntryBase config) { return configType(config.SettingType); } private static Type configType(Type type) { return type.IsEnum ? Enum.GetUnderlyingType(type) : type; } private static ZPackage ConfigsToPackage([<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 2, 1 })] IEnumerable configs = null, [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 2, 1 })] IEnumerable customValues = null, [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 2, 1 })] IEnumerable packageEntries = null, bool partial = true) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown List list = configs?.Where([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List(); List list2 = customValues?.ToList() ?? new List(); ZPackage val = new ZPackage(); val.Write((byte)(partial ? 1 : 0)); val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0)); foreach (PackageEntry item in packageEntries ?? Array.Empty()) { AddEntryToPackage(val, item); } foreach (CustomSyncedValueBase item2 in list2) { AddEntryToPackage(val, new PackageEntry { section = "Internal", key = item2.Identifier, type = item2.Type, value = item2.BoxedValue }); } foreach (ConfigEntryBase item3 in list) { AddEntryToPackage(val, new PackageEntry { section = item3.Definition.Section, key = item3.Definition.Key, type = configType(item3), value = item3.BoxedValue }); } return val; } private static void AddEntryToPackage(ZPackage package, PackageEntry entry) { package.Write(entry.section); package.Write(entry.key); package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type)); AddValueToZPackage(package, entry.value); } private static string GetZPackageTypeString(Type type) { return type.AssemblyQualifiedName; } private static void AddValueToZPackage(ZPackage package, [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] object value) { Type type = value?.GetType(); if (value is Enum) { value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture); } else { if (value is ICollection collection) { package.Write(collection.Count); { foreach (object item in collection) { AddValueToZPackage(package, item); } return; } } if ((object)type != null && type.IsValueType && !type.IsPrimitive) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); package.Write(fields.Length); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { package.Write(GetZPackageTypeString(fieldInfo.FieldType)); AddValueToZPackage(package, fieldInfo.GetValue(value)); } return; } } ZRpc.Serialize(new object[1] { value }, ref package); } private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type) { if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num = package.ReadInt(); if (num != fields.Length) { throw new InvalidDeserializationTypeException { received = $"(field count: {num})", expected = $"(field count: {fields.Length})" }; } object uninitializedObject = FormatterServices.GetUninitializedObject(type); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { string text = package.ReadString(); if (text != GetZPackageTypeString(fieldInfo.FieldType)) { throw new InvalidDeserializationTypeException { received = text, expected = GetZPackageTypeString(fieldInfo.FieldType), field = fieldInfo.Name }; } fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType)); } return uninitializedObject; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { int num2 = package.ReadInt(); IDictionary dictionary = (IDictionary)Activator.CreateInstance(type); Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments); FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); for (int j = 0; j < num2; j++) { object obj = ReadValueWithTypeFromZPackage(package, type2); dictionary.Add(field.GetValue(obj), field2.GetValue(obj)); } return dictionary; } if (type != typeof(List) && type.IsGenericType) { Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]); if ((object)type3 != null && type3.IsAssignableFrom(type)) { int num3 = package.ReadInt(); object obj2 = Activator.CreateInstance(type); MethodInfo method = type3.GetMethod("Add"); for (int k = 0; k < num3; k++) { method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) }); } return obj2; } } ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo)); AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type); List source = new List(); ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source); return source.First(); } } [HarmonyPatch] [PublicAPI] [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(0)] [<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(1)] internal class VersionCheck { private static readonly HashSet versionChecks; private static readonly Dictionary notProcessedNames; public string Name; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private string displayName; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private string currentVersion; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private string minimumRequiredVersion; public bool ModRequired = true; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private string ReceivedCurrentVersion; [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private string ReceivedMinimumRequiredVersion; private readonly List ValidatedClients = new List(); [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] private ConfigSync ConfigSync; public string DisplayName { get { return displayName ?? Name; } set { displayName = value; } } public string CurrentVersion { get { return currentVersion ?? "0.0.0"; } set { currentVersion = value; } } public string MinimumRequiredVersion { get { return minimumRequiredVersion ?? (ModRequired ? CurrentVersion : "0.0.0"); } set { minimumRequiredVersion = value; } } private static void PatchServerSync() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null)); if (patchInfo != null && patchInfo.Postfixes.Count([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0) { return; } Harmony val = new Harmony("org.bepinex.helpers.ServerSync"); foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) }) where t.IsClass select t) { val.PatchAll(item); } } static VersionCheck() { versionChecks = new HashSet(); notProcessedNames = new Dictionary(); typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1] { new Action(PatchServerSync) }); } public VersionCheck(string name) { Name = name; ModRequired = true; versionChecks.Add(this); } public VersionCheck(ConfigSync configSync) { ConfigSync = configSync; Name = ConfigSync.Name; versionChecks.Add(this); } public void Initialize() { ReceivedCurrentVersion = null; ReceivedMinimumRequiredVersion = null; if (ConfigSync != null) { Name = ConfigSync.Name; DisplayName = ConfigSync.DisplayName; CurrentVersion = ConfigSync.CurrentVersion; MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion; ModRequired = ConfigSync.ModRequired; } } private bool IsVersionOk() { if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null) { return !ModRequired; } bool flag = new System.Version(CurrentVersion) >= new System.Version(ReceivedMinimumRequiredVersion); bool flag2 = new System.Version(ReceivedCurrentVersion) >= new System.Version(MinimumRequiredVersion); return flag && flag2; } private string ErrorClient() { if (ReceivedMinimumRequiredVersion == null) { return DisplayName + " is not installed on the server."; } return (new System.Version(CurrentVersion) >= new System.Version(ReceivedMinimumRequiredVersion)) ? (DisplayName + " may not be higher than version " + ReceivedCurrentVersion + ". You have version " + CurrentVersion + ".") : (DisplayName + " needs to be at least version " + ReceivedMinimumRequiredVersion + ". You have version " + CurrentVersion + "."); } private string ErrorServer(ZRpc rpc) { return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion; } private string Error([<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(2)] ZRpc rpc = null) { return (rpc == null) ? ErrorClient() : ErrorServer(rpc); } private static VersionCheck[] GetFailedClient() { return versionChecks.Where([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (VersionCheck check) => !check.IsVersionOk()).ToArray(); } private static VersionCheck[] GetFailedServer(ZRpc rpc) { return versionChecks.Where([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc)).ToArray(); } private static void Logout() { Game.instance.Logout(true, true); AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3); } private static void DisconnectClient(ZRpc rpc) { rpc.Invoke("Error", new object[1] { 3 }); } private static void CheckVersion(ZRpc rpc, ZPackage pkg) { CheckVersion(rpc, pkg, null); } private static void CheckVersion(ZRpc rpc, ZPackage pkg, [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(new byte[] { 2, 1, 1 })] Action original) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); bool flag = false; foreach (VersionCheck versionCheck in versionChecks) { if (!(text != versionCheck.Name)) { Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + ".")); versionCheck.ReceivedMinimumRequiredVersion = text2; versionCheck.ReceivedCurrentVersion = text3; if (ZNet.instance.IsServer() && versionCheck.IsVersionOk()) { versionCheck.ValidatedClients.Add(rpc); } flag = true; } } if (flag) { return; } pkg.SetPos(0); if (original != null) { original(rpc, pkg); if (pkg.GetPos() == 0) { notProcessedNames.Add(text, text3); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPrefix] private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance) { VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient()); if (array.Length == 0) { return true; } VersionCheck[] array2 = array; foreach (VersionCheck versionCheck in array2) { Debug.LogWarning((object)versionCheck.Error(rpc)); } if (__instance.IsServer()) { DisconnectClient(rpc); } else { Logout(); } return false; } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPrefix] private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown notProcessedNames.Clear(); IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc); if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck"))) { object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")]; Action action = (Action)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); peer.m_rpc.Register("ServerSync VersionCheck", (Action)([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (ZRpc rpc, [<1513dc90-670f-4f35-9177-defdddfcb8f6>Nullable(1)] ZPackage pkg) => { CheckVersion(rpc, pkg, action); })); } else { peer.m_rpc.Register("ServerSync VersionCheck", (Action)CheckVersion); } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.Initialize(); if (versionCheck.ModRequired || __instance.IsServer()) { Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + ".")); ZPackage val = new ZPackage(); val.Write(versionCheck.Name); val.Write(versionCheck.MinimumRequiredVersion); val.Write(versionCheck.CurrentVersion); peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val }); } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] [HarmonyPrefix] private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance) { if (!__instance.IsServer()) { return; } foreach (VersionCheck versionCheck in versionChecks) { versionCheck.ValidatedClients.Remove(peer.m_rpc); } } [HarmonyPostfix] [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] private static void ShowConnectionError(FejdStartup __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3) { return; } bool flag = false; VersionCheck[] failedClient = GetFailedClient(); if (failedClient.Length != 0) { string text = string.Join("\n", failedClient.Select([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (VersionCheck check) => check.Error())); TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + text; flag = true; } foreach (KeyValuePair item in notProcessedNames.OrderBy([<9180c701-1f9d-42c7-8900-0ab404f8ab1b>NullableContext(0)] (KeyValuePair kv) => kv.Key)) { if (!__instance.m_connectionFailedError.text.Contains(item.Key)) { TMP_Text connectionFailedError2 = __instance.m_connectionFailedError; connectionFailedError2.text = connectionFailedError2.text + "\nServer expects you to have " + item.Key + " (Version: " + item.Value + ") installed."; flag = true; } } if (flag) { RectTransform component = ((Component)__instance.m_connectionFailedPanel.transform.Find("Image")).GetComponent(); Vector2 sizeDelta = component.sizeDelta; sizeDelta.x = 675f; component.sizeDelta = sizeDelta; __instance.m_connectionFailedError.ForceMeshUpdate(false, false); float num = __instance.m_connectionFailedError.renderedHeight + 105f; RectTransform component2 = ((Component)((Component)component).transform.Find("ButtonOk")).GetComponent(); component2.anchoredPosition = new Vector2(component2.anchoredPosition.x, component2.anchoredPosition.y - (num - component.sizeDelta.y) / 2f); sizeDelta = component.sizeDelta; sizeDelta.y = num; component.sizeDelta = sizeDelta; } } } } namespace Microsoft.CodeAnalysis { [<6d463c54-f624-4899-917c-e19213cc0d35>Embedded] [CompilerGenerated] internal sealed class <6d463c54-f624-4899-917c-e19213cc0d35>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] [<6d463c54-f624-4899-917c-e19213cc0d35>Embedded] [CompilerGenerated] internal sealed class <2793e7dc-4349-40e4-b45b-e415cb206d6b>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <2793e7dc-4349-40e4-b45b-e415cb206d6b>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <2793e7dc-4349-40e4-b45b-e415cb206d6b>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [<6d463c54-f624-4899-917c-e19213cc0d35>Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContextAttribute : Attribute { public readonly byte Flag; public <0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContextAttribute(byte P_0) { Flag = P_0; } } [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [<6d463c54-f624-4899-917c-e19213cc0d35>Embedded] [CompilerGenerated] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ItemManager { [PublicAPI] internal enum CraftingTable { Disabled, Inventory, [InternalName("piece_workbench")] Workbench, [InternalName("piece_cauldron")] Cauldron, [InternalName("piece_MeadCauldron")] MeadCauldron, [InternalName("forge")] Forge, [InternalName("piece_artisanstation")] ArtisanTable, [InternalName("piece_stonecutter")] StoneCutter, [InternalName("piece_magetable")] MageTable, [InternalName("piece_preptable")] PrepTable, [InternalName("blackforge")] BlackForge, Custom } [PublicAPI] internal enum ConversionPiece { Disabled, [InternalName("smelter")] Smelter, [InternalName("charcoal_kiln")] CharcoalKiln, [InternalName("blastfurnace")] BlastFurnace, [InternalName("windmill")] Windmill, [InternalName("piece_spinningwheel")] SpinningWheel, [InternalName("eitrrefinery")] EitrRefinery, Custom } [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(1)] internal class InternalName : Attribute { public readonly string internalName; public InternalName(string internalName) { this.internalName = internalName; } } [PublicAPI] [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(1)] [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] internal class RequiredResourceList { public readonly List Requirements = new List(); public bool Free; public void Add(string itemName, int amount, int quality = 0) { Requirements.Add(new Requirement { itemName = itemName, amount = amount, quality = quality }); } public void Add(string itemName, ConfigEntry amountConfig, int quality = 0) { Requirements.Add(new Requirement { itemName = itemName, amountConfig = amountConfig, quality = quality }); } } [PublicAPI] [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(1)] internal class CraftingStationList { public readonly List Stations = new List(); public void Add(CraftingTable table, int level) { Stations.Add(new CraftingStationConfig { Table = table, level = level }); } public void Add(string customTable, int level) { Stations.Add(new CraftingStationConfig { Table = CraftingTable.Custom, level = level, custom = customTable }); } } [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(1)] [PublicAPI] internal class ItemRecipe { public readonly RequiredResourceList RequiredItems = new RequiredResourceList(); public readonly RequiredResourceList RequiredUpgradeItems = new RequiredResourceList(); public readonly CraftingStationList Crafting = new CraftingStationList(); public int CraftAmount = 1; public bool RequireOnlyOneIngredient; public float QualityResultAmountMultiplier = 1f; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] public ConfigEntryBase RecipeIsActive; } [PublicAPI] internal class Trade { public Trader Trader; public uint Price; public uint Stack = 1u; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] public string RequiredGlobalKey; } [PublicAPI] [Flags] internal enum Trader { None = 0, Haldor = 1, Hildir = 2 } internal struct Requirement { [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(1)] public string itemName; public int amount; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] public ConfigEntry amountConfig; [Description("Set to a non-zero value to apply the requirement only for a specific quality")] public int quality; } internal struct CraftingStationConfig { public CraftingTable Table; public int level; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] public string custom; } [Flags] internal enum Configurability { Disabled = 0, Recipe = 1, Stats = 2, Drop = 4, Trader = 8, Full = 0xF } [PublicAPI] [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(1)] internal class DropTargets { public readonly List Drops = new List(); public void Add(string creatureName, float chance, int min = 1, int? max = null, bool levelMultiplier = true) { Drops.Add(new DropTarget { creature = creatureName, chance = chance, min = min, max = (max ?? min), levelMultiplier = levelMultiplier }); } } internal struct DropTarget { [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(1)] public string creature; public int min; public int max; public float chance; public bool levelMultiplier; } internal enum Toggle { On = 1, Off = 0 } [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(1)] [PublicAPI] internal class Item { [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] private class ItemConfig { [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 2, 1 })] public ConfigEntry craft; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 2, 1 })] public ConfigEntry upgrade; public ConfigEntry table; public ConfigEntry tableLevel; public ConfigEntry customTable; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] public ConfigEntry maximumTableLevel; public ConfigEntry requireOneIngredient; public ConfigEntry qualityResultAmountMultiplier; } [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] private class TraderConfig { public ConfigEntry trader; public ConfigEntry price; public ConfigEntry stack; public ConfigEntry requiredGlobalKey; } [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] private class RequirementQuality { public int quality; } [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(2)] [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string Category; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 2, 1 })] [UsedImplicitly] public Action CustomDrawer; public Func browsability; } [PublicAPI] [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] public enum DamageModifier { Normal, Resistant, Weak, Immune, Ignore, VeryResistant, VeryWeak, None } [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] private delegate void setDmgFunc(ref DamageTypes dmg, float value); [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] private class SerializedRequirements { public readonly List Reqs; public SerializedRequirements(List reqs) { Reqs = reqs; } public SerializedRequirements(string reqs) : this(reqs.Split(new char[1] { ',' }).Select([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (string r) => { string[] array = r.Split(new char[1] { ':' }); int result; int result2; return new Requirement { itemName = array[0], amount = ((array.Length <= 1 || !int.TryParse(array[1], out result)) ? 1 : result), quality = ((array.Length > 2 && int.TryParse(array[2], out result2)) ? result2 : 0) }; }).ToList()) { } public override string ToString() { return string.Join(",", Reqs.Select([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Requirement r) => $"{r.itemName}:{r.amount}" + ((r.quality > 0) ? $":{r.quality}" : ""))); } [return: <2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] public static ItemDrop fetchByName(ObjectDB objectDB, string name) { GameObject itemPrefab = objectDB.GetItemPrefab(name); ItemDrop obj = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)obj == (Object)null) { Debug.LogWarning((object)("The required item '" + name + "' does not exist.")); } return obj; } public static Requirement[] toPieceReqs(ObjectDB objectDB, SerializedRequirements craft, SerializedRequirements upgrade) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_0194: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown Dictionary dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func)([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Requirement r) => r.itemName), (Func)([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Requirement r) => { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown ItemDrop val6 = ResItem(r); return (val6 != null) ? new Requirement { m_amount = (r.amountConfig?.Value ?? r.amount), m_resItem = val6, m_amountPerLevel = 0 } : ((Requirement)null); })); List list = dictionary.Values.Where([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Requirement v) => v != null).ToList(); foreach (Requirement item in upgrade.Reqs.Where((Requirement r) => r.itemName != "")) { if (item.quality > 0) { ItemDrop val = ResItem(item); if (val != null) { Requirement val2 = new Requirement { m_resItem = val, m_amountPerLevel = (item.amountConfig?.Value ?? item.amount), m_amount = 0 }; list.Add(val2); requirementQuality.Add(val2, new RequirementQuality { quality = item.quality }); } continue; } if (!dictionary.TryGetValue(item.itemName, out var value) || value == null) { ItemDrop val3 = ResItem(item); if (val3 != null) { string itemName = item.itemName; Requirement val4 = new Requirement { m_resItem = val3, m_amount = 0 }; Requirement val5 = val4; dictionary[itemName] = val4; value = val5; list.Add(value); } } if (value != null) { value.m_amountPerLevel = item.amountConfig?.Value ?? item.amount; } } return list.ToArray(); [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(2)] ItemDrop ResItem(Requirement r) { return fetchByName(objectDB, r.itemName); } } } [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] private class SerializedDrop { public readonly List Drops; public SerializedDrop(List drops) { Drops = drops; } public SerializedDrop(string drops) { Drops = ((drops == "") ? ((IEnumerable)Array.Empty()) : ((IEnumerable)drops.Split(new char[1] { ',' }))).Select([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (string r) => { string[] array = r.Split(new char[1] { ':' }); if (array.Length <= 2 || !int.TryParse(array[2], out var result)) { result = 1; } if (array.Length <= 3 || !int.TryParse(array[3], out var result2)) { result2 = result; } bool levelMultiplier = array.Length <= 4 || array[4] != "0"; float result3; return new DropTarget { creature = array[0], chance = ((array.Length > 1 && float.TryParse(array[1], out result3)) ? result3 : 1f), min = result, max = result2, levelMultiplier = levelMultiplier }; }).ToList(); } public override string ToString() { return string.Join(",", Drops.Select([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (DropTarget r) => $"{r.creature}:{r.chance.ToString(CultureInfo.InvariantCulture)}:{r.min}:" + ((r.min == r.max) ? "" : $"{r.max}") + (r.levelMultiplier ? "" : ":0"))); } [return: <2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private static Character fetchByName(ZNetScene netScene, string name) { GameObject prefab = netScene.GetPrefab(name); Character obj = ((prefab != null) ? prefab.GetComponent() : null); if ((Object)(object)obj == (Object)null) { Debug.LogWarning((object)("The drop target character '" + name + "' does not exist.")); } return obj; } public Dictionary toCharacterDrops(ZNetScene netScene, GameObject item) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown Dictionary dictionary = new Dictionary(); foreach (DropTarget drop in Drops) { Character val = fetchByName(netScene, drop.creature); if (val != null) { dictionary[val] = new Drop { m_prefab = item, m_amountMin = drop.min, m_amountMax = drop.max, m_chance = drop.chance, m_levelMultiplier = drop.levelMultiplier }; } } return dictionary; } } private static readonly List registeredItems = new List(); private static readonly Dictionary itemDropMap = new Dictionary(); private static Dictionary>> activeRecipes = new Dictionary>>(); [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 1, 1, 2 })] private static Dictionary hiddenCraftRecipes = new Dictionary(); [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 1, 1, 2 })] private static Dictionary hiddenUpgradeRecipes = new Dictionary(); private static Dictionary> itemCraftConfigs = new Dictionary>(); private static Dictionary> itemDropConfigs = new Dictionary>(); private Dictionary characterDrops = new Dictionary(); private readonly Dictionary statsConfigs = new Dictionary(); private static readonly ConditionalWeakTable requirementQuality = new ConditionalWeakTable(); public static Configurability DefaultConfigurability = Configurability.Full; public Configurability? Configurable; private Configurability configurationVisible = Configurability.Full; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private TraderConfig traderConfig; public readonly GameObject Prefab; [Description("Specifies the maximum required crafting station level to upgrade and repair the item.\nDefault is calculated from crafting station level and maximum quality.")] public int MaximumRequiredStationLevel = int.MaxValue; [Description("Assigns the item as a drop item to a creature.\nUses a creature name, a drop chance and a minimum and maximum amount.")] public readonly DropTargets DropsFrom = new DropTargets(); [Description("Configures whether the item can be bought at the trader.\nDon't forget to set cost to something above 0 or the item will be sold for free.")] public readonly Trade Trade = new Trade(); internal List Conversions = new List(); internal List conversions = new List(); public Dictionary Recipes = new Dictionary(); [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private LocalizeKey _name; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private LocalizeKey _description; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private static object configManager; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private static Localization _english; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private static BaseUnityPlugin _plugin; private static bool hasConfigSync = true; [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private static object _configSync; private Configurability configurability => Configurable ?? DefaultConfigurability; [Description("Specifies the resources needed to craft the item.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the item should need.")] public RequiredResourceList RequiredItems => this[""].RequiredItems; [Description("Specifies the resources needed to upgrade the item.\nUse .Add to add resources with their internal ID and an amount. This amount will be multipled by the item quality level.\nUse one .Add for each resource type the upgrade should need.")] public RequiredResourceList RequiredUpgradeItems => this[""].RequiredUpgradeItems; [Description("Specifies the crafting station needed to craft the item.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.\nUse one .Add for each crafting station.")] public CraftingStationList Crafting => this[""].Crafting; [Description("Specifies a config entry which toggles whether a recipe is active.")] [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] public ConfigEntryBase RecipeIsActive { [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(2)] get { return this[""].RecipeIsActive; } [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(2)] set { this[""].RecipeIsActive = value; } } [Description("Specifies the number of items that should be given to the player with a single craft of the item.\nDefaults to 1.")] public int CraftAmount { get { return this[""].CraftAmount; } set { this[""].CraftAmount = value; } } public bool RequireOnlyOneIngredient { get { return this[""].RequireOnlyOneIngredient; } set { this[""].RequireOnlyOneIngredient = value; } } public float QualityResultAmountMultiplier { get { return this[""].QualityResultAmountMultiplier; } set { this[""].QualityResultAmountMultiplier = value; } } public ItemRecipe this[string name] { get { if (Recipes.TryGetValue(name, out var value)) { return value; } return Recipes[name] = new ItemRecipe(); } } public LocalizeKey Name { get { LocalizeKey name = _name; if (name != null) { return name; } SharedData shared = Prefab.GetComponent().m_itemData.m_shared; if (shared.m_name.StartsWith("$")) { _name = new LocalizeKey(shared.m_name); } else { string text = "$item_" + ((Object)Prefab).name.Replace(" ", "_"); _name = new LocalizeKey(text).English(shared.m_name); shared.m_name = text; } return _name; } } public LocalizeKey Description { get { LocalizeKey description = _description; if (description != null) { return description; } SharedData shared = Prefab.GetComponent().m_itemData.m_shared; if (shared.m_description.StartsWith("$")) { _description = new LocalizeKey(shared.m_description); } else { string text = "$itemdesc_" + ((Object)Prefab).name.Replace(" ", "_"); _description = new LocalizeKey(text).English(shared.m_description); shared.m_description = text; } return _description; } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_plugin == null) { IEnumerable 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([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(2)] private static object configSync { [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(2)] get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " ItemManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } public Item(string assetBundleFileName, string prefabName, string folderName = "assets") : this(PrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName) { } public Item(AssetBundle bundle, string prefabName) : this(PrefabManager.RegisterPrefab(bundle, prefabName, addToObjectDb: true), skipRegistering: true) { } public Item(GameObject prefab, bool skipRegistering = false) { if (!skipRegistering) { PrefabManager.RegisterPrefab(prefab, addToObjectDb: true); } Prefab = prefab; registeredItems.Add(this); itemDropMap[Prefab.GetComponent()] = this; Prefab.GetComponent().m_itemData.m_dropPrefab = Prefab; } public void ToggleConfigurationVisibility(Configurability visible) { configurationVisible = visible; if (itemDropConfigs.TryGetValue(this, out var value)) { Toggle((ConfigEntryBase)(object)value, Configurability.Drop); } if (itemCraftConfigs.TryGetValue(this, out var value2)) { foreach (ItemConfig value4 in value2.Values) { ToggleObj(value4, Configurability.Recipe); } } foreach (Conversion conversion in Conversions) { if (conversion.config != null) { ToggleObj(conversion.config, Configurability.Recipe); } } foreach (KeyValuePair statsConfig in statsConfigs) { Toggle(statsConfig.Key, Configurability.Stats); if ((visible & Configurability.Stats) != Configurability.Disabled) { statsConfig.Value(); } } reloadConfigDisplay(); void Toggle(ConfigEntryBase cfg, Configurability check) { object[] tags = cfg.Description.Tags; for (int i = 0; i < tags.Length; i++) { if (tags[i] is ConfigurationManagerAttributes configurationManagerAttributes) { configurationManagerAttributes.Browsable = (visible & check) != Configurability.Disabled && (configurationManagerAttributes.browsability == null || configurationManagerAttributes.browsability()); } } } void ToggleObj(object obj, Configurability check) { FieldInfo[] fields = obj.GetType().GetFields(); for (int i = 0; i < fields.Length; i++) { object? value3 = fields[i].GetValue(obj); ConfigEntryBase val = (ConfigEntryBase)((value3 is ConfigEntryBase) ? value3 : null); if (val != null) { Toggle(val, check); } } } } internal static void reloadConfigDisplay() { object obj = configManager?.GetType().GetProperty("DisplayingWindow").GetValue(configManager); if (obj is bool && (bool)obj) { configManager.GetType().GetMethod("BuildSettingList").Invoke(configManager, Array.Empty()); } } private void UpdateItemTableConfig(string recipeKey, CraftingTable table, string customTableValue) { if (activeRecipes.ContainsKey(this) && activeRecipes[this].TryGetValue(recipeKey, out var value)) { value.First().m_enabled = table != CraftingTable.Disabled; if ((uint)table <= 1u) { value.First().m_craftingStation = null; } else if (table == CraftingTable.Custom) { Recipe obj = value.First(); GameObject prefab = ZNetScene.instance.GetPrefab(customTableValue); obj.m_craftingStation = ((prefab != null) ? prefab.GetComponent() : null); } else { value.First().m_craftingStation = ZNetScene.instance.GetPrefab(getInternalName(table)).GetComponent(); } } } private void UpdateCraftConfig(string recipeKey, SerializedRequirements craftRequirements, SerializedRequirements upgradeRequirements) { if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || !activeRecipes.ContainsKey(this) || !activeRecipes[this].TryGetValue(recipeKey, out var value)) { return; } foreach (Recipe item in value) { item.m_resources = SerializedRequirements.toPieceReqs(ObjectDB.instance, craftRequirements, upgradeRequirements); } } internal static void Patch_FejdStartup() { //IL_0e99: Unknown result type (might be due to invalid IL or missing references) //IL_0e9e: Unknown result type (might be due to invalid IL or missing references) //IL_2164: Unknown result type (might be due to invalid IL or missing references) //IL_216e: Expected O, but got Unknown //IL_0f62: Unknown result type (might be due to invalid IL or missing references) //IL_0f65: Unknown result type (might be due to invalid IL or missing references) //IL_0fbb: Expected I4, but got Unknown //IL_0b88: Unknown result type (might be due to invalid IL or missing references) //IL_0b92: Expected O, but got Unknown //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Expected O, but got Unknown //IL_10ef: Unknown result type (might be due to invalid IL or missing references) //IL_10f2: Unknown result type (might be due to invalid IL or missing references) //IL_10f4: Invalid comparison between Unknown and I4 //IL_10f6: Unknown result type (might be due to invalid IL or missing references) //IL_10fa: Invalid comparison between Unknown and I4 //IL_0cab: Unknown result type (might be due to invalid IL or missing references) //IL_0cb5: Expected O, but got Unknown //IL_0d56: Unknown result type (might be due to invalid IL or missing references) //IL_0d60: Expected O, but got Unknown //IL_10fc: Unknown result type (might be due to invalid IL or missing references) //IL_1100: Invalid comparison between Unknown and I4 //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Expected O, but got Unknown //IL_0e0a: Unknown result type (might be due to invalid IL or missing references) //IL_0e14: Expected O, but got Unknown //IL_12fb: Unknown result type (might be due to invalid IL or missing references) //IL_12fe: Unknown result type (might be due to invalid IL or missing references) //IL_1300: Invalid comparison between Unknown and I4 //IL_1302: Unknown result type (might be due to invalid IL or missing references) //IL_1306: Unknown result type (might be due to invalid IL or missing references) //IL_1308: Invalid comparison between Unknown and I4 //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Expected O, but got Unknown //IL_130a: Unknown result type (might be due to invalid IL or missing references) //IL_130e: Invalid comparison between Unknown and I4 //IL_13e3: Unknown result type (might be due to invalid IL or missing references) //IL_13e8: Unknown result type (might be due to invalid IL or missing references) //IL_13ea: Unknown result type (might be due to invalid IL or missing references) //IL_13ed: Invalid comparison between Unknown and I4 //IL_13ef: Unknown result type (might be due to invalid IL or missing references) //IL_13f3: Invalid comparison between Unknown and I4 //IL_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_06fa: Expected O, but got Unknown //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_065b: Expected O, but got Unknown //IL_1462: Unknown result type (might be due to invalid IL or missing references) //IL_1465: Unknown result type (might be due to invalid IL or missing references) //IL_1467: Invalid comparison between Unknown and I4 //IL_07fa: Unknown result type (might be due to invalid IL or missing references) //IL_0804: Expected O, but got Unknown //IL_1469: Unknown result type (might be due to invalid IL or missing references) //IL_146d: Unknown result type (might be due to invalid IL or missing references) //IL_146f: Invalid comparison between Unknown and I4 //IL_1471: Unknown result type (might be due to invalid IL or missing references) //IL_1475: Invalid comparison between Unknown and I4 //IL_15b2: Unknown result type (might be due to invalid IL or missing references) //IL_15b5: Invalid comparison between Unknown and I4 //IL_17b2: Unknown result type (might be due to invalid IL or missing references) //IL_17b9: Invalid comparison between Unknown and I4 //IL_1882: Unknown result type (might be due to invalid IL or missing references) //IL_1887: Unknown result type (might be due to invalid IL or missing references) //IL_1889: Unknown result type (might be due to invalid IL or missing references) //IL_188d: Unknown result type (might be due to invalid IL or missing references) //IL_188f: Invalid comparison between Unknown and I4 //IL_18fe: Unknown result type (might be due to invalid IL or missing references) //IL_1901: Unknown result type (might be due to invalid IL or missing references) //IL_1903: Invalid comparison between Unknown and I4 //IL_1528: Unknown result type (might be due to invalid IL or missing references) //IL_152d: Unknown result type (might be due to invalid IL or missing references) //IL_1905: Unknown result type (might be due to invalid IL or missing references) //IL_1909: Invalid comparison between Unknown and I4 //IL_190b: Unknown result type (might be due to invalid IL or missing references) //IL_190f: Invalid comparison between Unknown and I4 //IL_1d7c: Unknown result type (might be due to invalid IL or missing references) //IL_1d7f: Invalid comparison between Unknown and I4 Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager"); if (DefaultConfigurability != Configurability.Disabled) { bool saveOnConfigSet = plugin.Config.SaveOnConfigSet; plugin.Config.SaveOnConfigSet = false; foreach (Item item3 in registeredItems.Where([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Item i) => i.configurability != Configurability.Disabled)) { Item item = item3; string name = item.Prefab.GetComponent().m_itemData.m_shared.m_name; string englishName = new Regex("[=\\n\\t\\\\\"\\'\\[\\]]*").Replace(english.Localize(name), "").Trim(); string localizedName = Localization.instance.Localize(name).Trim(); int order = 0; if ((item.configurability & Configurability.Recipe) != Configurability.Disabled) { itemCraftConfigs[item] = new Dictionary(); foreach (string item4 in item.Recipes.Keys.DefaultIfEmpty("")) { string configKey = item4; string text = ((configKey == "") ? "" : (" (" + configKey + ")")); if (!item.Recipes.ContainsKey(configKey) || item.Recipes[configKey].Crafting.Stations.Count <= 0) { continue; } ItemConfig itemConfig = (itemCraftConfigs[item][configKey] = new ItemConfig()); ItemConfig cfg = itemConfig; List hideWhenNoneAttributes = new List(); cfg.table = config(englishName, "Crafting Station" + text, item.Recipes[configKey].Crafting.Stations.First().Table, new ConfigDescription("Crafting station where " + englishName + " is available.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = (order -= 1), Browsable = ((item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName } })); ConfigurationManagerAttributes customTableAttributes = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = CustomTableBrowsability, Browsable = (CustomTableBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; cfg.customTable = config(englishName, "Custom Crafting Station" + text, item.Recipes[configKey].Crafting.Stations.First().custom ?? "", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes })); cfg.table.SettingChanged += TableConfigChanged; cfg.customTable.SettingChanged += TableConfigChanged; ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = TableLevelBrowsability, Browsable = (TableLevelBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; hideWhenNoneAttributes.Add(configurationManagerAttributes); cfg.tableLevel = config(englishName, "Crafting Station Level" + text, item.Recipes[configKey].Crafting.Stations.First().level, new ConfigDescription("Required crafting station level to craft " + englishName + ".", (AcceptableValueBase)null, new object[1] { configurationManagerAttributes })); cfg.tableLevel.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { if (activeRecipes.ContainsKey(item) && activeRecipes[item].TryGetValue(configKey, out var value)) { value.First().m_minStationLevel = cfg.tableLevel.Value; } }; if (item.Prefab.GetComponent().m_itemData.m_shared.m_maxQuality > 1) { cfg.maximumTableLevel = config(englishName, "Maximum Crafting Station Level" + text, (item.MaximumRequiredStationLevel == int.MaxValue) ? (item.Recipes[configKey].Crafting.Stations.First().level + item.Prefab.GetComponent().m_itemData.m_shared.m_maxQuality - 1) : item.MaximumRequiredStationLevel, new ConfigDescription("Maximum crafting station level to upgrade and repair " + englishName + ".", (AcceptableValueBase)null, new object[1] { configurationManagerAttributes })); } cfg.requireOneIngredient = config(englishName, "Require only one resource" + text, item.Recipes[configKey].RequireOnlyOneIngredient ? Toggle.On : Toggle.Off, new ConfigDescription("Whether only one of the ingredients is needed to craft " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = (order -= 1), Category = localizedName } })); ConfigurationManagerAttributes qualityResultAttributes = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = QualityResultBrowsability, Browsable = (QualityResultBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; cfg.requireOneIngredient.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { if (activeRecipes.ContainsKey(item) && activeRecipes[item].TryGetValue(configKey, out var value)) { foreach (Recipe item5 in value) { item5.m_requireOnlyOneIngredient = cfg.requireOneIngredient.Value == Toggle.On; } } qualityResultAttributes.Browsable = QualityResultBrowsability(); reloadConfigDisplay(); }; cfg.qualityResultAmountMultiplier = config(englishName, "Quality Multiplier" + text, item.Recipes[configKey].QualityResultAmountMultiplier, new ConfigDescription("Multiplies the crafted amount based on the quality of the resources when crafting " + englishName + ". Only works, if Require Only One Resource is true.", (AcceptableValueBase)null, new object[1] { qualityResultAttributes })); cfg.qualityResultAmountMultiplier.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { if (activeRecipes.ContainsKey(item) && activeRecipes[item].TryGetValue(configKey, out var value)) { foreach (Recipe item6 in value) { item6.m_qualityResultAmountMultiplier = cfg.qualityResultAmountMultiplier.Value; } } }; if ((!item.Recipes[configKey].RequiredItems.Free || item.Recipes[configKey].RequiredItems.Requirements.Count > 0) && item.Recipes[configKey].RequiredItems.Requirements.All((Requirement r) => r.amountConfig == null)) { cfg.craft = itemConfig3("Crafting Costs" + text, new SerializedRequirements(item.Recipes[configKey].RequiredItems.Requirements).ToString(), "Item costs to craft " + englishName, isUpgrade: false); } if (item.Prefab.GetComponent().m_itemData.m_shared.m_maxQuality > 1 && (!item.Recipes[configKey].RequiredUpgradeItems.Free || item.Recipes[configKey].RequiredUpgradeItems.Requirements.Count > 0) && item.Recipes[configKey].RequiredUpgradeItems.Requirements.All((Requirement r) => r.amountConfig == null)) { cfg.upgrade = itemConfig3("Upgrading Costs" + text, new SerializedRequirements(item.Recipes[configKey].RequiredUpgradeItems.Requirements).ToString(), "Item costs per level to upgrade " + englishName, isUpgrade: true); } if (cfg.craft != null) { cfg.craft.SettingChanged += ConfigChanged; } if (cfg.upgrade != null) { cfg.upgrade.SettingChanged += ConfigChanged; } void ConfigChanged(object o, EventArgs e) { item.UpdateCraftConfig(configKey, new SerializedRequirements(cfg.craft?.Value ?? ""), new SerializedRequirements(cfg.upgrade?.Value ?? "")); } bool CustomTableBrowsability() { return cfg.table.Value == CraftingTable.Custom; } bool ItemBrowsability() { return cfg.table.Value != CraftingTable.Disabled; } bool QualityResultBrowsability() { return cfg.requireOneIngredient.Value == Toggle.On; } void TableConfigChanged(object o, EventArgs e) { item.UpdateItemTableConfig(configKey, cfg.table.Value, cfg.customTable.Value); customTableAttributes.Browsable = cfg.table.Value == CraftingTable.Custom; foreach (ConfigurationManagerAttributes item7 in hideWhenNoneAttributes) { item7.Browsable = cfg.table.Value != CraftingTable.Disabled; } reloadConfigDisplay(); } bool TableLevelBrowsability() { return cfg.table.Value != CraftingTable.Disabled; } ConfigEntry itemConfig3(string name2, string value, string desc, bool isUpgrade) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes2 = new ConfigurationManagerAttributes { CustomDrawer = drawRequirementsConfigTable(item, isUpgrade), Order = (order -= 1), browsability = ItemBrowsability, Browsable = (ItemBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; hideWhenNoneAttributes.Add(configurationManagerAttributes2); return config(englishName, name2, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes2 })); } } if ((item.configurability & Configurability.Drop) != Configurability.Disabled) { ConfigEntry val = (itemDropConfigs[item] = config(englishName, "Drops from", new SerializedDrop(item.DropsFrom.Drops).ToString(), new ConfigDescription(englishName + " drops from this creature.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { CustomDrawer = drawDropsConfigTable, Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Drop) != 0) } }))); val.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { item.UpdateCharacterDrop(); }; } for (int num = 0; num < item.Conversions.Count; num++) { string text2 = ((item.Conversions.Count > 1) ? $"{num + 1}. " : ""); Conversion conversion = item.Conversions[num]; conversion.config = new Conversion.ConversionConfig(); int index = num; conversion.config.input = config(englishName, text2 + "Conversion Input Item", conversion.Input, new ConfigDescription("Input item to create " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Recipe) != 0) } })); conversion.config.input.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { if (index < item.conversions.Count) { ObjectDB instance = ObjectDB.instance; if (instance != null) { ItemDrop val3 = SerializedRequirements.fetchByName(instance, conversion.config.input.Value); item.conversions[index].m_from = val3; UpdatePiece(); } } }; conversion.config.piece = config(englishName, text2 + "Conversion Piece", conversion.Piece, new ConfigDescription("Conversion piece used to create " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Recipe) != 0) } })); conversion.config.piece.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { UpdatePiece(); }; conversion.config.customPiece = config(englishName, text2 + "Conversion Custom Piece", conversion.customPiece ?? "", new ConfigDescription("Custom conversion piece to create " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Recipe) != 0) } })); conversion.config.customPiece.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { UpdatePiece(); }; void UpdatePiece() { if (index < item.conversions.Count && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text3 = ((conversion.config.piece.Value == ConversionPiece.Disabled) ? null : ((conversion.config.piece.Value == ConversionPiece.Custom) ? conversion.config.customPiece.Value : getInternalName(conversion.config.piece.Value))); string activePiece = conversion.config.activePiece; if (conversion.config.activePiece != null) { int num4 = ZNetScene.instance.GetPrefab(conversion.config.activePiece).GetComponent().m_conversion.IndexOf(item.conversions[index]); if (num4 >= 0) { Smelter[] array3 = Resources.FindObjectsOfTypeAll(); foreach (Smelter val3 in array3) { if (Utils.GetPrefabName(((Component)val3).gameObject) == activePiece) { val3.m_conversion.RemoveAt(num4); } } } conversion.config.activePiece = null; } if (item.conversions[index].m_from != null && conversion.config.piece.Value != ConversionPiece.Disabled) { GameObject prefab = ZNetScene.instance.GetPrefab(text3); if (((prefab != null) ? prefab.GetComponent() : null) != null) { conversion.config.activePiece = text3; Smelter[] array3 = Resources.FindObjectsOfTypeAll(); foreach (Smelter val4 in array3) { if (Utils.GetPrefabName(((Component)val4).gameObject) == text3) { val4.m_conversion.Add(item.conversions[index]); } } } } } } } } if ((item.configurability & Configurability.Stats) != Configurability.Disabled) { item.statsConfigs.Clear(); SharedData shared = item.Prefab.GetComponent().m_itemData.m_shared; ItemType itemType = shared.m_itemType; statcfg("Weight", "Weight of " + englishName + ".", (SharedData val3) => val3.m_weight, delegate(SharedData val3, float value) { val3.m_weight = value; }); statcfg("Trader Value", "Trader value of " + englishName + ".", (SharedData val3) => val3.m_value, delegate(SharedData val3, int value) { val3.m_value = value; }); bool flag; switch (itemType - 3) { case 0: case 1: case 2: case 3: case 4: case 8: case 9: case 11: case 14: case 16: case 19: flag = true; break; default: flag = false; break; } if (flag) { statcfg("Durability", "Durability of " + englishName + ".", (SharedData val3) => val3.m_maxDurability, delegate(SharedData val3, float value) { val3.m_maxDurability = value; }); statcfg("Durability per Level", "Durability gain per level of " + englishName + ".", (SharedData val3) => val3.m_durabilityPerLevel, delegate(SharedData val3, float value) { val3.m_durabilityPerLevel = value; }); statcfg("Movement Speed Modifier", "Movement speed modifier of " + englishName + ".", (SharedData val3) => val3.m_movementModifier, delegate(SharedData val3, float value) { val3.m_movementModifier = value; }); } if ((itemType - 3 <= 2 || (int)itemType == 14 || (int)itemType == 22) ? true : false) { statcfg("Block Armor", "Block armor of " + englishName + ".", (SharedData val3) => val3.m_blockPower, delegate(SharedData val3, float value) { val3.m_blockPower = value; }); statcfg("Block Armor per Level", "Block armor per level for " + englishName + ".", (SharedData val3) => val3.m_blockPowerPerLevel, delegate(SharedData val3, float value) { val3.m_blockPowerPerLevel = value; }); statcfg("Block Force", "Block force of " + englishName + ".", (SharedData val3) => val3.m_deflectionForce, delegate(SharedData val3, float value) { val3.m_deflectionForce = value; }); statcfg("Block Force per Level", "Block force per level for " + englishName + ".", (SharedData val3) => val3.m_deflectionForcePerLevel, delegate(SharedData val3, float value) { val3.m_deflectionForcePerLevel = value; }); statcfg("Parry Bonus", "Parry bonus of " + englishName + ".", (SharedData val3) => val3.m_timedBlockBonus, delegate(SharedData val3, float value) { val3.m_timedBlockBonus = value; }); } else if ((itemType - 6 <= 1 || itemType - 11 <= 1 || (int)itemType == 17) ? true : false) { statcfg("Armor", "Armor of " + englishName + ".", (SharedData val3) => val3.m_armor, delegate(SharedData val3, float value) { val3.m_armor = value; }); statcfg("Armor per Level", "Armor per level for " + englishName + ".", (SharedData val3) => val3.m_armorPerLevel, delegate(SharedData val3, float value) { val3.m_armorPerLevel = value; }); } SkillType skillType = shared.m_skillType; if (((int)skillType == 7 || (int)skillType == 12) ? true : false) { statcfg("Tool tier", "Tool tier of " + englishName + ".", (SharedData val3) => val3.m_toolTier, delegate(SharedData val3, int value) { val3.m_toolTier = value; }); } if ((itemType - 5 <= 2 || itemType - 11 <= 1 || (int)itemType == 17) ? true : false) { Dictionary modifiers = shared.m_damageModifiers.ToDictionary((DamageModPair d) => d.m_type, (DamageModPair d) => (DamageModifier)d.m_modifier); DamageType[] first = (DamageType[])Enum.GetValues(typeof(DamageType)); DamageType[] array = new DamageType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); foreach (DamageType damageType in first.Except((IEnumerable)(object)array)) { statcfg(((object)Unsafe.As(ref damageType)/*cast due to .constrained prefix*/).ToString() + " Resistance", ((object)Unsafe.As(ref damageType)/*cast due to .constrained prefix*/).ToString() + " resistance of " + englishName + ".", (SharedData _) => (!modifiers.TryGetValue(damageType, out var value)) ? DamageModifier.None : value, delegate(SharedData val4, DamageModifier value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) DamageModPair val3 = new DamageModPair { m_type = damageType, m_modifier = (DamageModifier)value }; for (int i = 0; i < val4.m_damageModifiers.Count; i++) { if (val4.m_damageModifiers[i].m_type == damageType) { if (value == DamageModifier.None) { val4.m_damageModifiers.RemoveAt(i); } else { val4.m_damageModifiers[i] = val3; } return; } } if (value != DamageModifier.None) { val4.m_damageModifiers.Add(val3); } }); } } if ((int)itemType == 2 && shared.m_food > 0f) { statcfg("Health", "Health value of " + englishName + ".", (SharedData val3) => val3.m_food, delegate(SharedData val3, float value) { val3.m_food = value; }); statcfg("Stamina", "Stamina value of " + englishName + ".", (SharedData val3) => val3.m_foodStamina, delegate(SharedData val3, float value) { val3.m_foodStamina = value; }); statcfg("Eitr", "Eitr value of " + englishName + ".", (SharedData val3) => val3.m_foodEitr, delegate(SharedData val3, float value) { val3.m_foodEitr = value; }); statcfg("Duration", "Duration of " + englishName + ".", (SharedData val3) => val3.m_foodBurnTime, delegate(SharedData val3, float value) { val3.m_foodBurnTime = value; }); statcfg("Health Regen", "Health regen value of " + englishName + ".", (SharedData val3) => val3.m_foodRegen, delegate(SharedData val3, float value) { val3.m_foodRegen = value; }); } if ((int)shared.m_skillType == 10) { statcfg("Health Cost", "Health cost of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackHealth, delegate(SharedData val3, float value) { val3.m_attack.m_attackHealth = value; }); statcfg("Health Cost Percentage", "Health cost percentage of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackHealthPercentage, delegate(SharedData val3, float value) { val3.m_attack.m_attackHealthPercentage = value; }); } skillType = shared.m_skillType; if (skillType - 9 <= 1) { statcfg("Eitr Cost", "Eitr cost of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackEitr, delegate(SharedData val3, float value) { val3.m_attack.m_attackEitr = value; }); } if ((itemType - 3 <= 1 || (int)itemType == 14 || (int)itemType == 22) ? true : false) { statcfg("Knockback", "Knockback of " + englishName + ".", (SharedData val3) => val3.m_attackForce, delegate(SharedData val3, float value) { val3.m_attackForce = value; }); statcfg("Backstab Bonus", "Backstab bonus of " + englishName + ".", (SharedData val3) => val3.m_backstabBonus, delegate(SharedData val3, float value) { val3.m_backstabBonus = value; }); statcfg("Attack Stamina", "Attack stamina of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackStamina, delegate(SharedData val3, float value) { val3.m_attack.m_attackStamina = value; }); SetDmg("True", (DamageTypes dmg) => dmg.m_damage, delegate(ref DamageTypes dmg, float damage) { dmg.m_damage = damage; }); SetDmg("Slash", (DamageTypes dmg) => dmg.m_slash, delegate(ref DamageTypes dmg, float slash) { dmg.m_slash = slash; }); SetDmg("Pierce", (DamageTypes dmg) => dmg.m_pierce, delegate(ref DamageTypes dmg, float pierce) { dmg.m_pierce = pierce; }); SetDmg("Blunt", (DamageTypes dmg) => dmg.m_blunt, delegate(ref DamageTypes dmg, float blunt) { dmg.m_blunt = blunt; }); SetDmg("Chop", (DamageTypes dmg) => dmg.m_chop, delegate(ref DamageTypes dmg, float chop) { dmg.m_chop = chop; }); SetDmg("Pickaxe", (DamageTypes dmg) => dmg.m_pickaxe, delegate(ref DamageTypes dmg, float pickaxe) { dmg.m_pickaxe = pickaxe; }); SetDmg("Fire", (DamageTypes dmg) => dmg.m_fire, delegate(ref DamageTypes dmg, float fire) { dmg.m_fire = fire; }); SetDmg("Poison", (DamageTypes dmg) => dmg.m_poison, delegate(ref DamageTypes dmg, float poison) { dmg.m_poison = poison; }); SetDmg("Frost", (DamageTypes dmg) => dmg.m_frost, delegate(ref DamageTypes dmg, float frost) { dmg.m_frost = frost; }); SetDmg("Lightning", (DamageTypes dmg) => dmg.m_lightning, delegate(ref DamageTypes dmg, float lightning) { dmg.m_lightning = lightning; }); SetDmg("Spirit", (DamageTypes dmg) => dmg.m_spirit, delegate(ref DamageTypes dmg, float spirit) { dmg.m_spirit = spirit; }); if ((int)itemType == 4) { statcfg("Projectiles", "Number of projectiles that " + englishName + " shoots at once.", (SharedData val3) => val3.m_attack.m_projectileBursts, delegate(SharedData val3, int value) { val3.m_attack.m_projectileBursts = value; }); statcfg("Burst Interval", "Time between the projectiles " + englishName + " shoots at once.", (SharedData val3) => val3.m_attack.m_burstInterval, delegate(SharedData val3, float value) { val3.m_attack.m_burstInterval = value; }); statcfg("Minimum Accuracy", "Minimum accuracy for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileAccuracyMin, delegate(SharedData val3, float value) { val3.m_attack.m_projectileAccuracyMin = value; }); statcfg("Accuracy", "Accuracy for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileAccuracy, delegate(SharedData val3, float value) { val3.m_attack.m_projectileAccuracy = value; }); statcfg("Minimum Velocity", "Minimum velocity for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileVelMin, delegate(SharedData val3, float value) { val3.m_attack.m_projectileVelMin = value; }); statcfg("Velocity", "Velocity for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileVel, delegate(SharedData val3, float value) { val3.m_attack.m_projectileVel = value; }); statcfg("Maximum Draw Time", "Time until " + englishName + " is fully drawn at skill level 0.", (SharedData val3) => val3.m_attack.m_drawDurationMin, delegate(SharedData val3, float value) { val3.m_attack.m_drawDurationMin = value; }); statcfg("Stamina Drain", "Stamina drain per second while drawing " + englishName + ".", (SharedData val3) => val3.m_attack.m_drawStaminaDrain, delegate(SharedData val3, float value) { val3.m_attack.m_drawStaminaDrain = value; }); } } } List traderAttributes; if ((item.configurability & Configurability.Trader) != Configurability.Disabled) { traderAttributes = new List(); item.traderConfig = new TraderConfig { trader = config(englishName, "Trader Selling", item.Trade.Trader, new ConfigDescription("Which traders sell " + englishName + ".", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = (order -= 1), Browsable = ((item.configurationVisible & Configurability.Trader) != 0), Category = localizedName } })) }; item.traderConfig.trader.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { item.ReloadTraderConfiguration(); foreach (ConfigurationManagerAttributes item8 in traderAttributes) { item8.Browsable = TraderBrowsability(); } reloadConfigDisplay(); }; item.traderConfig.price = traderConfig("Trader Price", item.Trade.Price, "Price of " + englishName + " at the trader."); item.traderConfig.stack = traderConfig("Trader Stack", item.Trade.Stack, "Stack size of " + englishName + " in the trader. Also known as the number of items sold by a trader in one transaction."); item.traderConfig.requiredGlobalKey = traderConfig("Trader Required Global Key", item.Trade.RequiredGlobalKey ?? "", "Required global key to unlock " + englishName + " at the trader."); if (item.traderConfig.trader.Value != Trader.None) { PrefabManager.AddItemToTrader(item.Prefab, item.traderConfig.trader.Value, item.traderConfig.price.Value, item.traderConfig.stack.Value, item.traderConfig.requiredGlobalKey.Value); } } else if (item.Trade.Trader != Trader.None) { PrefabManager.AddItemToTrader(item.Prefab, item.Trade.Trader, item.Trade.Price, item.Trade.Stack, item.Trade.RequiredGlobalKey); } void SetDmg(string dmgType, Func readDmg, setDmgFunc setDmg) { statcfg(dmgType + " Damage", dmgType + " damage dealt by " + englishName + ".", (SharedData val3) => readDmg(val3.m_damages), delegate(SharedData val3, float value) { setDmg(ref val3.m_damages, value); }); statcfg(dmgType + " Damage Per Level", dmgType + " damage dealt increase per level for " + englishName + ".", (SharedData val3) => readDmg(val3.m_damagesPerLevel), delegate(SharedData val3, float value) { setDmg(ref val3.m_damagesPerLevel, value); }); } bool TraderBrowsability() { return item.traderConfig.trader.Value != Trader.None; } void statcfg(string configName, string description, [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 1, 1, 0 })] Func readDefault, [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 1, 1, 0 })] Action setValue) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown SharedData shared2 = item.Prefab.GetComponent().m_itemData.m_shared; ConfigEntry cfg2 = config(englishName, configName, readDefault(shared2), new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Stats) != 0) } })); if ((item.configurationVisible & Configurability.Stats) != Configurability.Disabled) { setValue(shared2, cfg2.Value); } item.statsConfigs.Add((ConfigEntryBase)(object)cfg2, ApplyConfig); cfg2.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { if ((item.configurationVisible & Configurability.Stats) != Configurability.Disabled) { ApplyConfig(); } }; void ApplyConfig() { item.ApplyToAllInstances(delegate(ItemData val3) { setValue(val3.m_shared, cfg2.Value); }); } } [return: <2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 1, 0 })] ConfigEntry traderConfig(string name2, [<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(0)] T value, string desc) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes2 = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = TraderBrowsability, Browsable = (TraderBrowsability() && (item.configurationVisible & Configurability.Trader) != 0), Category = localizedName }; traderAttributes.Add(configurationManagerAttributes2); ConfigEntry obj = config(englishName, name2, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes2 })); obj.SettingChanged += [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (object _, EventArgs _) => { item.ReloadTraderConfiguration(); }; return obj; } } if (saveOnConfigSet) { plugin.Config.SaveOnConfigSet = true; plugin.Config.Save(); } } configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type)); foreach (Item registeredItem in registeredItems) { Item item2 = registeredItem; foreach (KeyValuePair recipe in item2.Recipes) { KeyValuePair kv = recipe; RequiredResourceList[] array2 = new RequiredResourceList[2] { kv.Value.RequiredItems, kv.Value.RequiredUpgradeItems }; foreach (RequiredResourceList requiredResourceList in array2) { for (int num3 = 0; num3 < requiredResourceList.Requirements.Count; num3++) { ConfigEntry amountCfg; int resourceIndex; if ((item2.configurability & Configurability.Recipe) != Configurability.Disabled) { amountCfg = requiredResourceList.Requirements[num3].amountConfig; if (amountCfg != null) { resourceIndex = num3; amountCfg.SettingChanged += ConfigChanged2; } } void ConfigChanged2(object o, EventArgs e) { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && activeRecipes.ContainsKey(item2) && activeRecipes[item2].TryGetValue(kv.Key, out var value)) { foreach (Recipe item9 in value) { item9.m_resources[resourceIndex].m_amount = amountCfg.Value; } } } } } } item2.InitializeNewRegisteredItem(); } } private void InitializeNewRegisteredItem() { foreach (KeyValuePair recipe in Recipes) { KeyValuePair kv = recipe; ConfigEntryBase enabledCfg = kv.Value.RecipeIsActive; if (enabledCfg != null) { ((object)enabledCfg).GetType().GetEvent("SettingChanged").AddEventHandler(enabledCfg, new EventHandler(ConfigChanged)); } void ConfigChanged(object o, EventArgs e) { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && activeRecipes.ContainsKey(this) && activeRecipes[this].TryGetValue(kv.Key, out var value)) { foreach (Recipe item in value) { item.m_enabled = (int)enabledCfg.BoxedValue != 0; } } } } } public void ReloadCraftingConfiguration() { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && ObjectDB.instance.GetItemPrefab(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name)) == null) { registerRecipesInObjectDB(ObjectDB.instance); ObjectDB.instance.m_items.Add(Prefab); ObjectDB.instance.m_itemByHash.Add(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name), Prefab); ZNetScene.instance.m_prefabs.Add(Prefab); ZNetScene.instance.m_namedPrefabs.Add(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name), Prefab); } foreach (string item in Recipes.Keys.DefaultIfEmpty("")) { if (Recipes.TryGetValue(item, out var value) && value.Crafting.Stations.Count > 0) { UpdateItemTableConfig(item, value.Crafting.Stations.First().Table, value.Crafting.Stations.First().custom ?? ""); UpdateCraftConfig(item, new SerializedRequirements(value.RequiredItems.Requirements), new SerializedRequirements(value.RequiredUpgradeItems.Requirements)); } } } private void ReloadTraderConfiguration() { if (traderConfig.trader.Value == Trader.None) { PrefabManager.RemoveItemFromTrader(Prefab); } else { PrefabManager.AddItemToTrader(Prefab, traderConfig.trader.Value, traderConfig.price.Value, traderConfig.stack.Value, traderConfig.requiredGlobalKey.Value); } } public static void ApplyToAllInstances(GameObject prefab, Action callback) { callback(prefab.GetComponent().m_itemData); string name = prefab.GetComponent().m_itemData.m_shared.m_name; Inventory[] source = (from c in Player.s_players.Select([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Player p) => ((Humanoid)p).GetInventory()).Concat(from c in Object.FindObjectsOfType() select c.GetInventory()) where c != null select c).ToArray(); foreach (ItemData item in (from i in (from p in ObjectDB.instance.m_items select p.GetComponent() into c where Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent()) select c).Concat(ItemDrop.s_instances) select i.m_itemData).Concat(source.SelectMany([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (Inventory i) => i.GetAllItems()))) { if (item.m_shared.m_name == name) { callback(item); } } } public void ApplyToAllInstances(Action callback) { ApplyToAllInstances(Prefab, callback); } [<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] [return: <2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(1)] private static string getInternalName(T value) where T : struct { return ((InternalName)typeof(T).GetMember(value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName; } private void registerRecipesInObjectDB(ObjectDB objectDB) { //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Expected O, but got Unknown activeRecipes[this] = new Dictionary>(); itemCraftConfigs.TryGetValue(this, out var value); foreach (KeyValuePair recipe in Recipes) { List list = new List(); foreach (CraftingStationConfig station in recipe.Value.Crafting.Stations) { ItemConfig itemConfig = value?[recipe.Key]; Recipe val = ScriptableObject.CreateInstance(); string name = ((Object)Prefab).name; CraftingTable table = station.Table; ((Object)val).name = name + "_Recipe_" + table; val.m_amount = recipe.Value.CraftAmount; bool enabled; if (itemConfig != null) { enabled = itemConfig.table.Value != CraftingTable.Disabled; } else { ConfigEntryBase recipeIsActive = recipe.Value.RecipeIsActive; enabled = (int)(((recipeIsActive != null) ? recipeIsActive.BoxedValue : null) ?? ((object)1)) != 0; } val.m_enabled = enabled; val.m_item = Prefab.GetComponent(); val.m_resources = SerializedRequirements.toPieceReqs(objectDB, (itemConfig?.craft == null) ? new SerializedRequirements(recipe.Value.RequiredItems.Requirements) : new SerializedRequirements(itemConfig.craft.Value), (itemConfig?.upgrade == null) ? new SerializedRequirements(recipe.Value.RequiredUpgradeItems.Requirements) : new SerializedRequirements(itemConfig.upgrade.Value)); table = ((itemConfig == null || list.Count > 0) ? station.Table : itemConfig.table.Value); if ((uint)table <= 1u) { val.m_craftingStation = null; } else if (((itemConfig == null || list.Count > 0) ? station.Table : itemConfig.table.Value) == CraftingTable.Custom) { GameObject prefab = ZNetScene.instance.GetPrefab((itemConfig == null || list.Count > 0) ? station.custom : itemConfig.customTable.Value); if (prefab != null) { val.m_craftingStation = prefab.GetComponent(); } else { Debug.LogWarning((object)("Custom crafting station '" + ((itemConfig == null || list.Count > 0) ? station.custom : itemConfig.customTable.Value) + "' does not exist")); } } else { val.m_craftingStation = ZNetScene.instance.GetPrefab(getInternalName((itemConfig == null || list.Count > 0) ? station.Table : itemConfig.table.Value)).GetComponent(); } val.m_minStationLevel = ((itemConfig == null || list.Count > 0) ? station.level : itemConfig.tableLevel.Value); val.m_requireOnlyOneIngredient = ((itemConfig == null) ? recipe.Value.RequireOnlyOneIngredient : (itemConfig.requireOneIngredient.Value == Toggle.On)); val.m_qualityResultAmountMultiplier = itemConfig?.qualityResultAmountMultiplier.Value ?? recipe.Value.QualityResultAmountMultiplier; list.Add(val); RequiredResourceList requiredItems = recipe.Value.RequiredItems; if (requiredItems != null && !requiredItems.Free) { List requirements = requiredItems.Requirements; if (requirements != null && requirements.Count == 0) { hiddenCraftRecipes.Add(val, recipe.Value.RecipeIsActive); } } requiredItems = recipe.Value.RequiredUpgradeItems; if (requiredItems != null && !requiredItems.Free) { List requirements = requiredItems.Requirements; if (requirements != null && requirements.Count == 0) { hiddenUpgradeRecipes.Add(val, recipe.Value.RecipeIsActive); } } } activeRecipes[this].Add(recipe.Key, list); objectDB.m_recipes.AddRange(list); } conversions = new List(); for (int i = 0; i < Conversions.Count; i++) { Conversion conversion = Conversions[i]; conversions.Add(new ItemConversion { m_from = SerializedRequirements.fetchByName(ObjectDB.instance, conversion.config?.input.Value ?? conversion.Input), m_to = Prefab.GetComponent() }); ConversionPiece conversionPiece = conversion.config?.piece.Value ?? conversion.Piece; string text = null; if (conversionPiece != ConversionPiece.Disabled && conversions[i].m_from != null) { text = ((conversionPiece != ConversionPiece.Custom) ? getInternalName(conversionPiece) : (conversion.config?.customPiece.Value ?? conversion.customPiece)); GameObject prefab2 = ZNetScene.instance.GetPrefab(text); Smelter val2 = ((prefab2 != null) ? prefab2.GetComponent() : null); if (val2 != null) { val2.m_conversion.Add(conversions[i]); } else { text = null; } } if (conversion.config != null) { conversion.config.activePiece = text; } } } [HarmonyPriority(0)] internal static void Patch_ObjectDBInit(ObjectDB __instance) { if ((Object)(object)__instance.GetItemPrefab("YagluthDrop") == (Object)null) { return; } hiddenCraftRecipes.Clear(); hiddenUpgradeRecipes.Clear(); foreach (Item registeredItem in registeredItems) { registeredItem.registerRecipesInObjectDB(__instance); } } internal static void Patch_TraderGetAvailableItems(Trader __instance, ref List __result) { string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject); Trader trader = ((prefabName == "Haldor") ? Trader.Haldor : ((prefabName == "Hildir") ? Trader.Hildir : Trader.None)); Trader trader2 = trader; __result.AddRange(from tuple in PrefabManager.CustomTradeItems.Values where (tuple.Item1 & trader2) != 0 select tuple.Item2 into tradeItem where string.IsNullOrEmpty(tradeItem.m_requiredGlobalKey) || ZoneSystem.instance.GetGlobalKey(tradeItem.m_requiredGlobalKey) select tradeItem); } internal static void Patch_OnAddSmelterInput(ItemData item, bool __result) { if (__result) { ((Humanoid)Player.m_localPlayer).UnequipItem(item, true); } } internal static void Patch_MaximumRequiredStationLevel(Recipe __instance, ref int __result, int quality) { if (!itemDropMap.TryGetValue(__instance.m_item, out var value)) { return; } IEnumerable source; if (!itemCraftConfigs.TryGetValue(value, out var value2)) { source = Enumerable.Empty(); } else { CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation(); if (currentCraftingStation != null) { string stationName = Utils.GetPrefabName(((Component)currentCraftingStation).gameObject); source = from c in value2.Where([<0a98a009-9db9-4afa-9a7f-6671605d707c>NullableContext(0)] (KeyValuePair c) => { switch (c.Value.table.Value) { case CraftingTable.Disabled: case CraftingTable.Inventory: return false; case CraftingTable.Custom: return c.Value.customTable.Value == stationName; default: return getInternalName(c.Value.table.Value) == stationName; } }) select c.Value; } else { source = value2.Values; } } __result = Mathf.Min(Mathf.Max(1, __instance.m_minStationLevel) + (quality - 1), (from cfg in source where cfg.maximumTableLevel != null select cfg.maximumTableLevel.Value).DefaultIfEmpty(value.MaximumRequiredStationLevel).Max()); } internal static void Patch_GetAvailableRecipesPrefix([<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 2, 1, 1, 1, 2 })] ref Dictionary> __state) { if (__state == null) { __state = new Dictionary>(); } Dictionary dictionary; if (InventoryGui.instance.InCraftTab()) { dictionary = hiddenCraftRecipes; } else { if (!InventoryGui.instance.InUpradeTab()) { return; } dictionary = hiddenUpgradeRecipes; } foreach (Recipe key in dictionary.Keys) { key.m_enabled = false; } __state[Assembly.GetExecutingAssembly()] = dictionary; } internal static void Patch_GetAvailableRecipesFinalizer([<2793e7dc-4349-40e4-b45b-e415cb206d6b>Nullable(new byte[] { 1, 1, 1, 1, 2 })] Dictionary> __state) { if (!__state.TryGetValue(Assembly.GetExecutingAssembly(), out var value)) { return; } foreach (KeyValuePair item in value) { Recipe key = item.Key; ConfigEntryBase value2 = item.Value; key.m_enabled = (int)(((value2 != null) ? value2.BoxedValue : null) ?? ((object)1)) != 0; } } internal static IEnumerable Transpile_SetupRequirementList(IEnumerable instructionsEnumerable, ILGenerator ilg) { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown List list = instructionsEnumerable.ToList(); MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(InventoryGui), "SetupRequirement", (Type[])null, (Type[])null); CodeInstruction val = null; CodeInstruction val2 = null; LocalBuilder localBuilder = ilg.DeclareLocal(typeof(int)); Dictionary dictionary = new Dictionary(); bool flag = false; int num = 0; int value = 0; Label? label = default(Label?); for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], methodInfo)) { val = list[i + 2]; val2 = list[i + 5]; flag = true; } if (flag) { if (CodeInstructionExtensions.Branches(list[i], ref label) && dictionary.TryGetValue(label.Value, out value)) { num = i; break; } continue; } foreach (Label label4 in list[i].labels) { dictionary[label4] = i; } } if (list[value - 3].opcode == OpCodes.Dup) { return list; } Label label2 = ilg.DefineLabel(); Label label3 = ilg.DefineLabel(); list[num + 1].labels.Add(label2); list.InsertRange(num + 1, (IEnumerable)(object)new CodeInstruction[11] { new CodeInstruction(OpCodes.Ldloc, (object)localBuilder), new CodeInstruction(OpCodes.Brfalse, (object)label2), val.Clone(), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.DeclaredField(typeof(InventoryGui), "m_recipeRequirementList")), new CodeInstruction(OpCodes.Ldlen, (object)null), new CodeInstruction(OpCodes.Bgt, (object)label2), new CodeInstruction(OpCodes.Ldc_I4_0, (object)null), val2.Clone(), new CodeInstruction(OpCodes.Ldc_I4_0, (object)null), new CodeInstruction(OpCodes.Br, (object)label3) }); list.InsertRange(value - 2, (IEnumerable)(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Dup, (object)null) { labels = new List