Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Armory v1.4.3
Armory.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.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 ArmoryHotFixes; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ItemManager; using JetBrains.Annotations; using Jewelcrafting; using LocalizationManager; using MagicaCloth2; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using PieceManager; using ServerSync; using SoundMixManager; using TMPro; using UnityEngine; using UnityEngine.Audio; 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: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: ComVisible(false)] [assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")] [assembly: AssemblyFileVersion("1.4.3")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Therzie")] [assembly: AssemblyProduct("Armory")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: AssemblyTitle("Armory")] [assembly: AssemblyDescription("")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public static class ArmoryQualityRequirementPatch { [HarmonyPatch(typeof(Player), "HaveRequirementItems")] public static class HaveRequirementItemsPatch { public static void Postfix(Player __instance, Recipe piece, bool discover, int qualityLevel, int amount, ref bool __result) { if ((discover | __result) || (Object)(object)piece.m_item == (Object)null || !((Object)((Component)piece.m_item).gameObject).name.EndsWith("_TW")) { return; } Inventory inventory = ((Humanoid)__instance).GetInventory(); CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation(); bool flag = true; Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if ((Object.op_Implicit((Object)(object)currentCraftingStation) && currentCraftingStation.m_upgrader != val.m_upgraderResource) || (!Object.op_Implicit((Object)(object)currentCraftingStation) && val.m_upgraderResource) || !Object.op_Implicit((Object)(object)val.m_resItem)) { continue; } int num = val.GetAmount(qualityLevel) * amount; string name = val.m_resItem.m_itemData.m_shared.m_name; Dictionary<int, int> dictionary = new Dictionary<int, int>(); foreach (ItemData allItem in inventory.GetAllItems()) { if (!(allItem.m_shared.m_name != name)) { dictionary.TryGetValue(allItem.m_quality, out var value); dictionary[allItem.m_quality] = value + allItem.m_stack; } } int num2 = 0; foreach (int value2 in dictionary.Values) { if (value2 > num2) { num2 = value2; } } if (piece.m_requireOnlyOneIngredient) { if (num2 >= num) { __result = true; return; } } else if (num2 < num) { flag = false; break; } } if (!piece.m_requireOnlyOneIngredient) { __result = flag; } } } [HarmonyPatch(typeof(Player), "GetFirstRequiredItem")] public static class GetFirstRequiredItemPatch { public static void Postfix(Player __instance, Inventory inventory, Recipe recipe, int qualityLevel, int craftMultiplier, ref ItemData __result, ref int amount, ref int extraAmount) { if (__result != null || (Object)(object)recipe.m_item == (Object)null || !((Object)((Component)recipe.m_item).gameObject).name.EndsWith("_TW")) { return; } CraftingStation currentCraftingStation = __instance.GetCurrentCraftingStation(); Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if ((Object.op_Implicit((Object)(object)currentCraftingStation) && currentCraftingStation.m_upgrader != val.m_upgraderResource) || (!Object.op_Implicit((Object)(object)currentCraftingStation) && val.m_upgraderResource) || !Object.op_Implicit((Object)(object)val.m_resItem)) { continue; } int num = val.GetAmount(qualityLevel) * craftMultiplier; string name = val.m_resItem.m_itemData.m_shared.m_name; Dictionary<int, int> dictionary = new Dictionary<int, int>(); foreach (ItemData allItem in inventory.GetAllItems()) { if (!(allItem.m_shared.m_name != name)) { dictionary.TryGetValue(allItem.m_quality, out var value); dictionary[allItem.m_quality] = value + allItem.m_stack; } } foreach (KeyValuePair<int, int> item in dictionary) { if (item.Value >= num) { amount = num; extraAmount = val.m_extraAmountOnlyOneIngredient; __result = inventory.GetItem(name, item.Key, false); return; } } } } } } namespace PieceManager { internal static class PieceManagerCategorySync { private const string RegistryKey = "PieceManager.CategoryRegistry"; private static Dictionary<string, int>? _registry; private static readonly Type PiecePrefabManagerType; private static readonly FieldInfo PieceCategoriesField; private static readonly FieldInfo CustomCategoryValuesField; private static readonly FieldInfo CustomCategoryNamesField; private static readonly FieldInfo OwnCategoryLabelsField; private static readonly MethodInfo GetCategoryTokenMethod; private const int CustomTagIdBase = 16777216; private static Dictionary<string, int> Registry { get { if (_registry != null) { return _registry; } if (AppDomain.CurrentDomain.GetData("PieceManager.CategoryRegistry") is Dictionary<string, int> registry) { _registry = registry; } else { _registry = new Dictionary<string, int>(); AppDomain.CurrentDomain.SetData("PieceManager.CategoryRegistry", _registry); } return _registry; } } public static void Init() { } static PieceManagerCategorySync() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00e3: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown PiecePrefabManagerType = typeof(PiecePrefabManager); PieceCategoriesField = AccessTools.Field(PiecePrefabManagerType, "PieceCategories"); CustomCategoryValuesField = AccessTools.Field(PiecePrefabManagerType, "customCategoryValues"); CustomCategoryNamesField = AccessTools.Field(PiecePrefabManagerType, "customCategoryNames"); OwnCategoryLabelsField = AccessTools.Field(PiecePrefabManagerType, "OwnCategoryLabels"); GetCategoryTokenMethod = AccessTools.Method(PiecePrefabManagerType, "GetCategoryToken", new Type[1] { typeof(string) }, (Type[])null); Harmony val = new Harmony("org.bepinex.helpers.PieceManager.CategorySync"); val.Patch((MethodBase)AccessTools.DeclaredMethod(PiecePrefabManagerType, "GetCategory", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ByUsagePieceList), "UpdateAvailableTags", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "DedupAvailableTags", (Type[])null, (Type[])null)) { priority = -1000 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ByUsagePieceList), "GetAvailablePiecesWithTag", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PieceManagerCategorySync), "DedupAvailablePiecesWithTag", (Type[])null, (Type[])null)) { priority = -1000 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool Prefix(string name, ref PieceCategory __result) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected I4, but got Unknown if (!Registry.TryGetValue(name, out var value)) { return true; } Dictionary<string, PieceCategory> dictionary = (Dictionary<string, PieceCategory>)PieceCategoriesField.GetValue(null); if (dictionary.ContainsKey(name)) { return true; } PieceCategory val = (dictionary[name] = (PieceCategory)value); PieceCategory[] array = (PieceCategory[])CustomCategoryValuesField.GetValue(null); CustomCategoryValuesField.SetValue(null, AddToArray(array, val)); string[] array2 = (string[])CustomCategoryNamesField.GetValue(null); CustomCategoryNamesField.SetValue(null, AddToArray(array2, name)); string text = (string)GetCategoryTokenMethod.Invoke(null, new object[1] { name }); Dictionary<PieceCategory, string> dictionary2 = (Dictionary<PieceCategory, string>)OwnCategoryLabelsField.GetValue(null); dictionary2[val] = "$" + text; Localization.instance.AddWord(text, name); __result = (PieceCategory)(int)val; return false; } private static void Postfix(string name, PieceCategory __result) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected I4, but got Unknown Dictionary<string, PieceCategory> dictionary = (Dictionary<string, PieceCategory>)PieceCategoriesField.GetValue(null); if (dictionary.ContainsKey(name) && !Registry.ContainsKey(name)) { Registry[name] = (int)__result; } } private static void DedupAvailableTags(ByUsagePieceList __instance) { if (Registry.Count == 0) { return; } HashSet<int> hashSet = new HashSet<int>(); foreach (int value in Registry.Values) { hashSet.Add(16777216 + value); } List<int> availableTags = __instance.m_availableTags; HashSet<int> hashSet2 = new HashSet<int>(); for (int num = availableTags.Count - 1; num >= 0; num--) { int item = availableTags[num]; if (hashSet.Contains(item) && !hashSet2.Add(item)) { availableTags.RemoveAt(num); } } } private static void DedupAvailablePiecesWithTag(int tagId, IList<Piece> resultOut) { if (tagId < 16777216) { return; } int num = tagId - 16777216; bool flag = false; foreach (int value in Registry.Values) { if (value == num) { flag = true; break; } } if (!flag) { return; } HashSet<Piece> hashSet = new HashSet<Piece>(); for (int num2 = resultOut.Count - 1; num2 >= 0; num2--) { if (!hashSet.Add(resultOut[num2])) { resultOut.RemoveAt(num2); } } } private static T[] AddToArray<T>(T[] array, T item) { T[] array2 = new T[array.Length + 1]; Array.Copy(array, array2, array.Length); array2[^1] = item; return array2; } } } namespace ArmoryHotFixes { [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ColliderFix { [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { GameObject prefab = __instance.GetPrefab("ArmorRogueChest_TW"); object obj; if (prefab == null) { obj = null; } else { Transform obj2 = prefab.transform.Find("log"); obj = ((obj2 != null) ? ((Component)obj2).gameObject : null); } GameObject val = (GameObject)obj; if ((Object)(object)val != (Object)null && !val.activeSelf) { val.SetActive(true); } } } public static class CapeClothColliderFix { [HarmonyPatch(typeof(VisEquipment), "AttachArmor")] private static class AttachArmor_Patch { private static void Postfix(VisEquipment __instance, int itemHash, List<GameObject> __result) { if (__result == null || !s_registered.Contains(itemHash)) { return; } foreach (GameObject item in __result) { BodyClothColliders.ApplyTo(__instance, item); } } } [HarmonyPatch(typeof(VisEquipment), "AttachItem")] private static class AttachItem_Patch { private static void Postfix(VisEquipment __instance, int itemHash, GameObject __result) { if (!((Object)(object)__result == (Object)null) && s_registered.Contains(itemHash)) { BodyClothColliders.ApplyTo(__instance, __result); } } } [Serializable] private class MagicaColliderData { public Vector3 center; public Vector3 size; public int direction = 1; public bool reverseDirection; public bool radiusSeparation; public bool alignedOnCenter = true; } private class BodyClothColliders : MonoBehaviour { private class Entry { public Transform source; public MagicaColliderData data; public bool isSphere; public CapsuleCollider collider; public float extraRadius; public float extraLength; public float trimTop; } private readonly List<Entry> m_entries = new List<Entry>(); private CapsuleCollider[] m_colliderArray = (CapsuleCollider[])(object)new CapsuleCollider[0]; private GameObject m_root; private readonly List<Cloth> m_cloths = new List<Cloth>(); public static void ApplyTo(VisEquipment vis, GameObject item) { if ((Object)(object)vis == (Object)null || (Object)(object)item == (Object)null) { return; } Cloth[] componentsInChildren = item.GetComponentsInChildren<Cloth>(true); if (componentsInChildren.Length == 0) { return; } BodyClothColliders bodyClothColliders = ((Component)vis).GetComponent<BodyClothColliders>(); if ((Object)(object)bodyClothColliders == (Object)null) { bodyClothColliders = ((Component)vis).gameObject.AddComponent<BodyClothColliders>(); bodyClothColliders.Build(vis); } if (bodyClothColliders.m_colliderArray.Length == 0) { return; } Cloth[] array = componentsInChildren; foreach (Cloth val in array) { List<CapsuleCollider> list = new List<CapsuleCollider>(bodyClothColliders.m_colliderArray); if (val.capsuleColliders != null) { CapsuleCollider[] capsuleColliders = val.capsuleColliders; foreach (CapsuleCollider val2 in capsuleColliders) { if ((Object)(object)val2 != (Object)null && !list.Contains(val2)) { list.Add(val2); } } } val.capsuleColliders = list.ToArray(); if (val.clothSolverFrequency < 240f) { val.clothSolverFrequency = 240f; } bodyClothColliders.m_cloths.Add(val); } ((Behaviour)bodyClothColliders).enabled = true; bodyClothColliders.Sync(); } private void Build(VisEquipment vis) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown m_root = new GameObject("CapeClothColliders_" + ((Object)((Component)vis).gameObject).name); int num = LayerMask.NameToLayer("effect"); if (vis.m_clothColliders != null) { foreach (ColliderComponent clothCollider in vis.m_clothColliders) { if ((Object)(object)clothCollider == (Object)null) { continue; } string text = (((Object)(object)((Component)clothCollider).transform.parent != (Object)null) ? ((Object)((Component)clothCollider).transform.parent).name : ""); if (s_skipBones.Contains(text)) { continue; } string name = ((object)clothCollider).GetType().Name; bool flag = name == "MagicaSphereCollider"; bool flag2 = name == "MagicaCapsuleCollider"; if (flag || flag2) { MagicaColliderData data = JsonUtility.FromJson<MagicaColliderData>(JsonUtility.ToJson((object)clothCollider)); GameObject val = new GameObject(name + "_" + text); val.transform.SetParent(m_root.transform, false); if (num >= 0) { val.layer = num; } CapsuleCollider val2 = val.AddComponent<CapsuleCollider>(); ((Collider)val2).isTrigger = true; val2.direction = 1; s_adjustByBone.TryGetValue(text, out (float, float) value); s_trimTopByBone.TryGetValue(text, out var value2); m_entries.Add(new Entry { source = ((Component)clothCollider).transform, data = data, isSphere = flag, collider = val2, extraRadius = value.Item1, extraLength = value.Item2, trimTop = value2 }); } } } if (m_entries.Count == 0) { Debug.LogWarning((object)("[CapeClothColliderFix] No MagicaCloth body colliders found on " + ((Object)((Component)vis).gameObject).name)); } m_colliderArray = m_entries.ConvertAll((Entry e) => e.collider).ToArray(); Sync(); } private void LateUpdate() { for (int num = m_cloths.Count - 1; num >= 0; num--) { if ((Object)(object)m_cloths[num] == (Object)null) { m_cloths.RemoveAt(num); } } if (m_cloths.Count == 0) { ((Behaviour)this).enabled = false; } else { Sync(); } } private void Sync() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0212: 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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) foreach (Entry entry in m_entries) { if ((Object)(object)entry.source == (Object)null) { continue; } MagicaColliderData data = entry.data; Vector3 lossyScale = entry.source.lossyScale; float num = Mathf.Max(new float[3] { Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z) }); float num2 = (data.radiusSeparation ? Mathf.Max(data.size.x, data.size.y) : data.size.x); float num3 = Mathf.Max(0.001f, num2 * num + entry.extraRadius); Vector3 val = entry.source.TransformPoint(data.center); Transform transform = ((Component)entry.collider).transform; entry.collider.radius = num3; if (entry.isSphere) { transform.position = val; transform.rotation = Quaternion.identity; entry.collider.height = num3 * 2f; continue; } Vector3 val2 = ((data.direction == 0) ? Vector3.right : ((data.direction == 2) ? Vector3.forward : Vector3.up)); if (data.reverseDirection) { val2 = -val2; } Vector3 val3 = entry.source.TransformDirection(val2); Vector3 normalized = ((Vector3)(ref val3)).normalized; float num4 = Mathf.Max(0f, data.size.z * num + entry.extraLength); if (!data.alignedOnCenter) { val += normalized * (num4 * 0.5f); } if (entry.trimTop > 0f) { float num5 = Mathf.Min(entry.trimTop, num4); Vector3 val4 = ((Vector3.Dot(normalized, Vector3.up) >= 0f) ? normalized : (-normalized)); val -= val4 * (num5 * 0.5f); num4 -= num5; } transform.position = val; transform.rotation = Quaternion.FromToRotation(Vector3.up, normalized); entry.collider.height = num4 + num3 * 2f; } } private void OnEnable() { if ((Object)(object)m_root != (Object)null) { m_root.SetActive(true); } } private void OnDisable() { if ((Object)(object)m_root != (Object)null) { m_root.SetActive(false); } } private void OnDestroy() { if ((Object)(object)m_root != (Object)null) { Object.Destroy((Object)(object)m_root); } } } private static readonly HashSet<int> s_registered = new HashSet<int>(); private static readonly Dictionary<string, (float extraRadius, float extraLength)> s_adjustByBone = new Dictionary<string, (float, float)> { { "Spine1", (0.025f, 0f) } }; private static readonly Dictionary<string, float> s_trimTopByBone = new Dictionary<string, float>(); private static readonly HashSet<string> s_skipBones = new HashSet<string>(); private const float ClothSolverFrequency = 240f; public static void Register(string itemPrefabName) { if (!string.IsNullOrEmpty(itemPrefabName)) { s_registered.Add(StringExtensionMethods.GetStableHashCode(itemPrefabName)); } } } } namespace StatusEffectManager { [PublicAPI] [Description("The ItemDrop effect to apply the status effect")] public enum EffectType { Equip, Attack, Consume, Set } public struct SE_Item { public StatusEffect Effect; public EffectType Type; } [PublicAPI] public class CustomSE { private static readonly List<CustomSE> RegisteredEffects = new List<CustomSE>(); private static readonly Dictionary<StatusEffect, CustomSE> CustomEffectMap = new Dictionary<StatusEffect, CustomSE>(); internal static readonly List<StatusEffect> CustomSEs = new List<StatusEffect>(); internal static readonly Dictionary<SE_Item, string> AddToPrefabs = new Dictionary<SE_Item, string>(); [Description("Instance of the StatusEffect.")] public readonly StatusEffect Effect; public EffectType Type; private string _folderName = "icons"; private AssetBundle _assetBundle = null; [Description("Sets the icon for the StatusEffect. Must be 64x64")] public Sprite? IconSprite = null; private string? IconName = null; private LocalizeKey? _name; private static Localization? _english; private static BaseUnityPlugin? _plugin; private static bool hasConfigSync = true; private static object? _configSync; [Description("Sets the icon for the StatusEffect. Must be 64x64")] public string? Icon { get { return IconName; } set { IconName = value; IconSprite = ((IconName == null) ? null : loadSprite(IconName)); Effect.m_icon = IconSprite; } } [Description("Sets the in-game name for the StatusEffect")] public LocalizeKey Name { get { LocalizeKey name = _name; if (name != null) { return name; } StatusEffect effect = Effect; if (effect.m_name.StartsWith("$")) { _name = new LocalizeKey(effect.m_name); } else { string text = "$statuseffect_" + ((Object)Effect).name.Replace(" ", "_"); _name = new LocalizeKey(text).English(effect.m_name); effect.m_name = text; } return _name; } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static object? configSync { get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " ItemManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } public CustomSE(string assetBundleFileName, string customEffectName, string folderName = "assets") : this(EffectManager.RegisterAssetBundle(assetBundleFileName, folderName), customEffectName) { } public CustomSE(AssetBundle bundle, string customEffectName) { Effect = EffectManager.RegisterCustomSE(bundle, customEffectName); RegisteredEffects.Add(this); CustomEffectMap[Effect] = this; } public CustomSE(string customEffectName) { Effect = ScriptableObject.CreateInstance<StatusEffect>(); EffectManager.RegisterCustomSE(Effect, customEffectName); RegisteredEffects.Add(this); CustomEffectMap[Effect] = this; } private byte[]? ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + ((_folderName == "") ? "" : ".") + _folderName + "." + name); if (manifestResourceStream == null) { return null; } manifestResourceStream.CopyTo(memoryStream); return memoryStream.ToArray(); } private Texture2D? loadTexture(string name) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown byte[] array = ReadEmbeddedFileBytes(name); if (array != null) { Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, array); return val; } return null; } private Sprite loadSprite(string name) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Texture2D val = loadTexture(name); if (val != null) { return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), Vector2.zero); } AssetBundle assetBundle = _assetBundle; Sprite val2 = ((assetBundle != null) ? assetBundle.LoadAsset<Sprite>(name) : null); if (val2 != null) { return val2; } throw new FileNotFoundException("Could not find a file named " + name + " for the effect icon"); } public void AddSEToPrefab(CustomSE customSE, string prefabName) { SE_Item key = new SE_Item { Effect = customSE.Effect, Type = customSE.Type }; AddToPrefabs.Add(key, prefabName); } private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description) { ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry<T> config<T>(string group, string name, T value, string description) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } } [PublicAPI] public class LocalizeKey { private static readonly List<LocalizeKey> keys = new List<LocalizeKey>(); public readonly string Key; public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>(); public LocalizeKey(string key) { Key = key.Replace("$", ""); keys.Add(this); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; if (Localization.m_instance != null) { Localization.instance.AddWord(Key, Localization.instance.Localize(alias)); } } public LocalizeKey English(string key) { return addForLang("English", key); } public LocalizeKey Swedish(string key) { return addForLang("Swedish", key); } public LocalizeKey French(string key) { return addForLang("French", key); } public LocalizeKey Italian(string key) { return addForLang("Italian", key); } public LocalizeKey German(string key) { return addForLang("German", key); } public LocalizeKey Spanish(string key) { return addForLang("Spanish", key); } public LocalizeKey Russian(string key) { return addForLang("Russian", key); } public LocalizeKey Romanian(string key) { return addForLang("Romanian", key); } public LocalizeKey Bulgarian(string key) { return addForLang("Bulgarian", key); } public LocalizeKey Macedonian(string key) { return addForLang("Macedonian", key); } public LocalizeKey Finnish(string key) { return addForLang("Finnish", key); } public LocalizeKey Danish(string key) { return addForLang("Danish", key); } public LocalizeKey Norwegian(string key) { return addForLang("Norwegian", key); } public LocalizeKey Icelandic(string key) { return addForLang("Icelandic", key); } public LocalizeKey Turkish(string key) { return addForLang("Turkish", key); } public LocalizeKey Lithuanian(string key) { return addForLang("Lithuanian", key); } public LocalizeKey Czech(string key) { return addForLang("Czech", key); } public LocalizeKey Hungarian(string key) { return addForLang("Hungarian", key); } public LocalizeKey Slovak(string key) { return addForLang("Slovak", key); } public LocalizeKey Polish(string key) { return addForLang("Polish", key); } public LocalizeKey Dutch(string key) { return addForLang("Dutch", key); } public LocalizeKey Portuguese_European(string key) { return addForLang("Portuguese_European", key); } public LocalizeKey Portuguese_Brazilian(string key) { return addForLang("Portuguese_Brazilian", key); } public LocalizeKey Chinese(string key) { return addForLang("Chinese", key); } public LocalizeKey Japanese(string key) { return addForLang("Japanese", key); } public LocalizeKey Korean(string key) { return addForLang("Korean", key); } public LocalizeKey Hindi(string key) { return addForLang("Hindi", key); } public LocalizeKey Thai(string key) { return addForLang("Thai", key); } public LocalizeKey Abenaki(string key) { return addForLang("Abenaki", key); } public LocalizeKey Croatian(string key) { return addForLang("Croatian", key); } public LocalizeKey Georgian(string key) { return addForLang("Georgian", key); } public LocalizeKey Greek(string key) { return addForLang("Greek", key); } public LocalizeKey Serbian(string key) { return addForLang("Serbian", key); } public LocalizeKey Ukrainian(string key) { return addForLang("Ukrainian", key); } private LocalizeKey addForLang(string lang, string value) { Localizations[lang] = value; if (Localization.m_instance != null) { if (Localization.instance.GetSelectedLanguage() == lang) { Localization.instance.AddWord(Key, value); } else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key)) { Localization.instance.AddWord(Key, value); } } return this; } [HarmonyPriority(300)] internal static void AddLocalizedKeys(Localization __instance, string language) { foreach (LocalizeKey key in keys) { string value2; if (key.Localizations.TryGetValue(language, out 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)); } } } } public static class LocalizationCache { private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>(); internal static void LocalizationPostfix(Localization __instance, string language) { string key = localizations.FirstOrDefault((KeyValuePair<string, Localization> l) => l.Value == __instance).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance); } } public static Localization ForLanguage(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; } } public static class EffectManager { private struct BundleId { [UsedImplicitly] public string assetBundleFileName; [UsedImplicitly] public string folderName; } private static readonly Dictionary<BundleId, AssetBundle> bundleCache; static EffectManager() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown bundleCache = new Dictionary<BundleId, AssetBundle>(); Harmony val = new Harmony("org.bepinex.helpers.StatusEffectManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(EffectManager), "Patch_ObjectDBInit", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(EffectManager), "Patch_ZNetSceneAwake", (Type[])null, (Type[])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(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); } public static AssetBundle RegisterAssetBundle(string assetBundleFileName, string folderName = "assets") { BundleId key = new BundleId { assetBundleFileName = assetBundleFileName, folderName = folderName }; if (!bundleCache.TryGetValue(key, out var value)) { Dictionary<BundleId, AssetBundle> dictionary = bundleCache; AssetBundle? obj = ((IEnumerable<AssetBundle>)Resources.FindObjectsOfTypeAll<AssetBundle>()).FirstOrDefault((Func<AssetBundle, bool>)((AssetBundle a) => ((Object)a).name == assetBundleFileName)) ?? AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + ((folderName == "") ? "" : ".") + folderName + "." + assetBundleFileName)); AssetBundle result = obj; dictionary[key] = obj; return result; } return value; } public static StatusEffect RegisterCustomSE(string assetBundleFileName, string customEffectName, string folderName = "assets") { return RegisterCustomSE(RegisterAssetBundle(assetBundleFileName, folderName), customEffectName); } public static StatusEffect RegisterCustomSE(AssetBundle assets, string customEffectName) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown StatusEffect val = (StatusEffect)assets.LoadAsset<ScriptableObject>(customEffectName); CustomSE.CustomSEs.Add(val); return val; } public static StatusEffect RegisterCustomSE(StatusEffect customSE, string customEffectName) { ((Object)customSE).name = customEffectName; CustomSE.CustomSEs.Add(customSE); return customSE; } [HarmonyPriority(700)] private static void Patch_ObjectDBInit(ObjectDB __instance) { foreach (StatusEffect customSE in CustomSE.CustomSEs) { if (!__instance.m_StatusEffects.Contains(customSE)) { __instance.m_StatusEffects.Add(customSE); } } __instance.UpdateRegisters(); } [HarmonyPriority(700)] private static void Patch_ZNetSceneAwake(ZNetScene __instance) { foreach (KeyValuePair<SE_Item, string> addToPrefab in CustomSE.AddToPrefabs) { try { GameObject prefab = __instance.GetPrefab(addToPrefab.Value); ItemDrop val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<ItemDrop>() : prefab.GetComponentInChildren<ItemDrop>()); Aoe val2 = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<Aoe>() : prefab.GetComponentInChildren<Aoe>()); EffectArea val3 = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<EffectArea>() : prefab.GetComponentInChildren<EffectArea>()); if (Object.op_Implicit((Object)(object)val)) { switch (addToPrefab.Key.Type) { case EffectType.Equip: val.m_itemData.m_shared.m_equipStatusEffect = addToPrefab.Key.Effect; break; case EffectType.Attack: val.m_itemData.m_shared.m_attackStatusEffect = addToPrefab.Key.Effect; break; case EffectType.Consume: val.m_itemData.m_shared.m_consumeStatusEffect = addToPrefab.Key.Effect; break; case EffectType.Set: val.m_itemData.m_shared.m_setSize = 1; val.m_itemData.m_shared.m_setName = ((Object)addToPrefab.Key.Effect).name; val.m_itemData.m_shared.m_setStatusEffect = addToPrefab.Key.Effect; break; default: throw new ArgumentOutOfRangeException(); } } else if (Object.op_Implicit((Object)(object)val2)) { val2.m_statusEffect = ((Object)addToPrefab.Key.Effect).name; } else if (Object.op_Implicit((Object)(object)val3)) { val3.m_statusEffect = ((Object)addToPrefab.Key.Effect).name; } else { Debug.LogWarning((object)("The prefab '" + ((Object)prefab).name + "' does not have an ItemDrop, AOE, or EffectArea component. Cannot add the StatusEffect to the prefab.")); } } catch (Exception arg) { Debug.LogWarning((object)$"BROKE : {arg}"); } } } } public static class StatusEffectManagerVersion { public const string Version = "1.0.0"; } } namespace SoundMixManager { public static class AudioMixerFix { private static readonly Harmony _harmony; private static ManualLogSource Logger; private static readonly List<Hook> _hooks; private static bool _hooksInstalled; private static readonly List<GameObject> TrackedPrefabs; private static readonly HashSet<AudioMixer> KnownDuplicateMixers; private static bool _fixedOnce; private static readonly Type EffectListType; private static readonly Type GameObjectType; private static readonly Type GameObjectArrayType; private static readonly Type GameObjectListType; static AudioMixerFix() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _harmony = new Harmony("org.bepinex.helpers.Armory.AudioMixerFix"); _hooks = new List<Hook>(); TrackedPrefabs = new List<GameObject>(); KnownDuplicateMixers = new HashSet<AudioMixer>(); EffectListType = typeof(EffectList); GameObjectType = typeof(GameObject); GameObjectArrayType = typeof(GameObject[]); GameObjectListType = typeof(List<GameObject>); _harmony.PatchAll(typeof(AudioMixerFix)); } public static void Init(ManualLogSource logger) { Logger = logger; if (!_hooksInstalled) { _hooksInstalled = true; InstallRegistrationHooks(); } Logger.LogDebug((object)"AudioMixerFix initialized."); } private static void Install(string label, MethodBase target, Delegate hook) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown if (target == null) { ManualLogSource logger = Logger; if (logger != null) { logger.LogWarning((object)("Could not find " + label + " - prefabs registered through it won't get the audio fix.")); } return; } try { _hooks.Add(new Hook(target, hook)); ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogDebug((object)("Hooked " + label)); } } catch (Exception arg) { ManualLogSource logger3 = Logger; if (logger3 != null) { logger3.LogError((object)$"Failed to hook {label}: {arg}"); } } } public static void Track(GameObject prefab) { if (!((Object)(object)prefab == (Object)null)) { TrackedPrefabs.Add(prefab); ManualLogSource logger = Logger; if (logger != null) { logger.LogDebug((object)("Track: " + ((Object)prefab).name)); } } } [HarmonyPostfix] [HarmonyPatch(typeof(AudioMan), "Awake")] private static void Postfix_AudioManAwake(AudioMan __instance) { if (_fixedOnce || (Object)(object)__instance.m_masterMixer == (Object)null) { return; } _fixedOnce = true; AudioMixer masterMixer = __instance.m_masterMixer; ManualLogSource logger = Logger; if (logger != null) { logger.LogDebug((object)$"Postfix_AudioManAwake firing. TrackedPrefabs={TrackedPrefabs.Count}, realMixer={((Object)masterMixer).name}"); } HashSet<GameObject> hashSet = new HashSet<GameObject>(); foreach (GameObject trackedPrefab in TrackedPrefabs) { if ((Object)(object)trackedPrefab == (Object)null) { continue; } try { FixPrefabAndEffects(trackedPrefab, masterMixer, hashSet); } catch (Exception arg) { ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogError((object)$"Exception fixing prefab '{((Object)trackedPrefab).name}': {arg}"); } } } ManualLogSource logger3 = Logger; if (logger3 != null) { logger3.LogDebug((object)$"Postfix_AudioManAwake done. KnownDuplicateMixers={KnownDuplicateMixers.Count}, EffectPrefabsVisited={hashSet.Count}"); } } private static void FixPrefabAndEffects(GameObject prefab, AudioMixer realMixer, HashSet<GameObject> visited) { if ((Object)(object)prefab == (Object)null || !visited.Add(prefab)) { return; } AudioSource[] componentsInChildren = prefab.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource src in componentsInChildren) { FixAudioSource(src, realMixer); } Component[] componentsInChildren2 = prefab.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren2) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { Type fieldType = fieldInfo.FieldType; bool flag = fieldType == EffectListType; bool flag2 = fieldType == GameObjectType; bool flag3 = fieldType == GameObjectArrayType; bool flag4 = fieldType == GameObjectListType; if (!flag && !flag2 && !flag3 && !flag4) { continue; } object value; try { value = fieldInfo.GetValue(val); } catch (Exception ex) { ManualLogSource logger = Logger; if (logger != null) { logger.LogWarning((object)("Could not read field '" + fieldInfo.Name + "' on '" + type.Name + "' (" + ((Object)prefab).name + "): " + ex.Message)); } continue; } if (flag) { EffectList val2 = (EffectList)((value is EffectList) ? value : null); if (val2 == null) { continue; } EffectData[] effectPrefabs = val2.m_effectPrefabs; if (effectPrefabs == null) { continue; } EffectData[] array = effectPrefabs; for (int l = 0; l < array.Length; l++) { GameObject val3 = array[l]?.m_prefab; if (!((Object)(object)val3 == (Object)null)) { ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogDebug((object)("Following EffectList '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> effect prefab '" + ((Object)val3).name + "'")); } FixPrefabAndEffects(val3, realMixer, visited); } } } else if (flag2) { GameObject val4 = (GameObject)((value is GameObject) ? value : null); if (val4 != null && !((Object)(object)val4 == (Object)null)) { ManualLogSource logger3 = Logger; if (logger3 != null) { logger3.LogDebug((object)("Following GameObject field '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> '" + ((Object)val4).name + "'")); } FixPrefabAndEffects(val4, realMixer, visited); } } else if (flag3) { if (!(value is GameObject[] array2)) { continue; } GameObject[] array3 = array2; foreach (GameObject val5 in array3) { if (!((Object)(object)val5 == (Object)null)) { ManualLogSource logger4 = Logger; if (logger4 != null) { logger4.LogDebug((object)("Following GameObject[] field '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> '" + ((Object)val5).name + "'")); } FixPrefabAndEffects(val5, realMixer, visited); } } } else { if (!flag4 || !(value is List<GameObject> list)) { continue; } foreach (GameObject item in list) { if (!((Object)(object)item == (Object)null)) { ManualLogSource logger5 = Logger; if (logger5 != null) { logger5.LogDebug((object)("Following List<GameObject> field '" + type.Name + "." + fieldInfo.Name + "' on '" + ((Object)prefab).name + "' -> '" + ((Object)item).name + "'")); } FixPrefabAndEffects(item, realMixer, visited); } } } } } } private static void FixAudioSource(AudioSource src, AudioMixer realMixer) { if ((Object)(object)src.outputAudioMixerGroup == (Object)null) { AudioMixerGroup[] array = realMixer.FindMatchingGroups("SFX"); if (array.Length == 0) { array = realMixer.FindMatchingGroups("Sfx"); } if (array.Length != 0) { ManualLogSource logger = Logger; if (logger != null) { logger.LogDebug((object)("Assigned mixer group to previously-ungrouped AudioSource '" + ((Object)((Component)src).gameObject).name + "': null -> " + ((Object)realMixer).name + "/" + ((Object)array[0]).name)); } src.outputAudioMixerGroup = array[0]; } else { ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogWarning((object)("AudioSource '" + ((Object)((Component)src).gameObject).name + "' has no mixer group and no SFX/Sfx group found on real mixer '" + ((Object)realMixer).name + "' - left ungrouped.")); } } if (src.bypassEffects) { src.bypassEffects = false; } return; } AudioMixer audioMixer = src.outputAudioMixerGroup.audioMixer; if ((Object)(object)audioMixer == (Object)(object)realMixer) { if (src.bypassEffects) { src.bypassEffects = false; } return; } KnownDuplicateMixers.Add(audioMixer); string name = ((Object)src.outputAudioMixerGroup).name; AudioMixerGroup[] array2 = realMixer.FindMatchingGroups(name); if (array2.Length == 0) { array2 = realMixer.FindMatchingGroups("SFX"); } if (array2.Length == 0) { array2 = realMixer.FindMatchingGroups("Sfx"); } if (array2.Length != 0) { ManualLogSource logger3 = Logger; if (logger3 != null) { logger3.LogDebug((object)("Fixed AudioSource '" + ((Object)((Component)src).gameObject).name + "': " + ((Object)audioMixer).name + "/" + name + " -> " + ((Object)realMixer).name + "/" + ((Object)array2[0]).name)); } src.outputAudioMixerGroup = array2[0]; } else { ManualLogSource logger4 = Logger; if (logger4 != null) { logger4.LogWarning((object)("No matching group for '" + name + "' (or SFX/Sfx fallback) on real mixer '" + ((Object)realMixer).name + "' - '" + ((Object)((Component)src).gameObject).name + "' left unfixed.")); } } if (src.bypassEffects) { src.bypassEffects = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(ZSFX), "Awake")] private static void ZsfxCatchAll(ZSFX __instance) { if (KnownDuplicateMixers.Count == 0) { return; } AudioSource component = ((Component)__instance).GetComponent<AudioSource>(); if ((Object)(object)component == (Object)null || (Object)(object)component.outputAudioMixerGroup == (Object)null) { return; } AudioMixer audioMixer = component.outputAudioMixerGroup.audioMixer; if (!KnownDuplicateMixers.Contains(audioMixer)) { return; } AudioMan instance = AudioMan.instance; AudioMixer val = (((Object)(object)instance != (Object)null) ? instance.m_masterMixer : null); if ((Object)(object)val == (Object)null) { return; } string name = ((Object)component.outputAudioMixerGroup).name; AudioMixerGroup[] array = val.FindMatchingGroups(name); if (array.Length == 0) { array = val.FindMatchingGroups("SFX"); } if (array.Length == 0) { array = val.FindMatchingGroups("Sfx"); } if (array.Length != 0) { ManualLogSource logger = Logger; if (logger != null) { logger.LogDebug((object)("ZsfxCatchAll fixed '" + ((Object)((Component)__instance).gameObject).name + "': " + ((Object)audioMixer).name + "/" + name + " -> " + ((Object)val).name + "/" + ((Object)array[0]).name)); } component.outputAudioMixerGroup = array[0]; } if (component.bypassEffects) { component.bypassEffects = false; } } private static void InstallRegistrationHooks() { Install("ItemManager.PrefabManager.RegisterPrefab", AccessTools.Method(typeof(PrefabManager), "RegisterPrefab", new Type[3] { typeof(AssetBundle), typeof(string), typeof(bool) }, (Type[])null), (Func<Func<AssetBundle, string, bool, GameObject>, AssetBundle, string, bool, GameObject>)delegate(Func<AssetBundle, string, bool, GameObject> orig, AssetBundle assets, string prefabName, bool flag) { GameObject val = orig(assets, prefabName, flag); Track(val); return val; }); Install("PieceManager.PiecePrefabManager.RegisterPrefab", AccessTools.Method(typeof(PiecePrefabManager), "RegisterPrefab", new Type[2] { typeof(AssetBundle), typeof(string) }, (Type[])null), (Func<Func<AssetBundle, string, GameObject>, AssetBundle, string, GameObject>)delegate(Func<AssetBundle, string, GameObject> orig, AssetBundle assets, string prefabName) { GameObject val = orig(assets, prefabName); Track(val); return val; }); } } } namespace SkillManager { [PublicAPI] public class Skill { public static class LocalizationCache { private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>(); internal static void LocalizationPostfix(Localization __instance, string language) { string key = localizations.FirstOrDefault((KeyValuePair<string, Localization> l) => l.Value == __instance).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance); } } public static Localization ForLanguage(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] public class LocalizeKey { private static readonly List<LocalizeKey> keys = new List<LocalizeKey>(); public readonly string Key; public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>(); public LocalizeKey(string key) { Key = key.Replace("$", ""); keys.Add(this); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; if (Localization.m_instance != null) { Localization.instance.AddWord(Key, Localization.instance.Localize(alias)); } } public LocalizeKey English(string key) { return addForLang("English", key); } public LocalizeKey Swedish(string key) { return addForLang("Swedish", key); } public LocalizeKey French(string key) { return addForLang("French", key); } public LocalizeKey Italian(string key) { return addForLang("Italian", key); } public LocalizeKey German(string key) { return addForLang("German", key); } public LocalizeKey Spanish(string key) { return addForLang("Spanish", key); } public LocalizeKey Russian(string key) { return addForLang("Russian", key); } public LocalizeKey Romanian(string key) { return addForLang("Romanian", key); } public LocalizeKey Bulgarian(string key) { return addForLang("Bulgarian", key); } public LocalizeKey Macedonian(string key) { return addForLang("Macedonian", key); } public LocalizeKey Finnish(string key) { return addForLang("Finnish", key); } public LocalizeKey Danish(string key) { return addForLang("Danish", key); } public LocalizeKey Norwegian(string key) { return addForLang("Norwegian", key); } public LocalizeKey Icelandic(string key) { return addForLang("Icelandic", key); } public LocalizeKey Turkish(string key) { return addForLang("Turkish", key); } public LocalizeKey Lithuanian(string key) { return addForLang("Lithuanian", key); } public LocalizeKey Czech(string key) { return addForLang("Czech", key); } public LocalizeKey Hungarian(string key) { return addForLang("Hungarian", key); } public LocalizeKey Slovak(string key) { return addForLang("Slovak", key); } public LocalizeKey Polish(string key) { return addForLang("Polish", key); } public LocalizeKey Dutch(string key) { return addForLang("Dutch", key); } public LocalizeKey Portuguese_European(string key) { return addForLang("Portuguese_European", key); } public LocalizeKey Portuguese_Brazilian(string key) { return addForLang("Portuguese_Brazilian", key); } public LocalizeKey Chinese(string key) { return addForLang("Chinese", key); } public LocalizeKey Japanese(string key) { return addForLang("Japanese", key); } public LocalizeKey Korean(string key) { return addForLang("Korean", key); } public LocalizeKey Hindi(string key) { return addForLang("Hindi", key); } public LocalizeKey Thai(string key) { return addForLang("Thai", key); } public LocalizeKey Abenaki(string key) { return addForLang("Abenaki", key); } public LocalizeKey Croatian(string key) { return addForLang("Croatian", key); } public LocalizeKey Georgian(string key) { return addForLang("Georgian", key); } public LocalizeKey Greek(string key) { return addForLang("Greek", key); } public LocalizeKey Serbian(string key) { return addForLang("Serbian", key); } public LocalizeKey Ukrainian(string key) { return addForLang("Ukrainian", key); } private LocalizeKey addForLang(string lang, string value) { Localizations[lang] = value; if (Localization.m_instance != null) { if (Localization.instance.GetSelectedLanguage() == lang) { Localization.instance.AddWord(Key, value); } else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key)) { Localization.instance.AddWord(Key, value); } } return this; } [HarmonyPriority(300)] internal static void AddLocalizedKeys(Localization __instance, string language) { foreach (LocalizeKey key in keys) { string value2; if (key.Localizations.TryGetValue(language, out 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)); } } } } private class ConfigurationManagerAttributes { [UsedImplicitly] public string? Category; } [HarmonyPatch(typeof(Skills), "IsSkillValid")] private static class Patch_Skills_IsSkillValid { private static void Postfix(SkillType type, ref bool __result) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!__result && skills.ContainsKey(type)) { __result = true; } } } private static readonly Dictionary<SkillType, Skill> skills; internal static readonly Dictionary<string, Skill> skillByName; private readonly string skillName; private readonly string internalSkillName; private readonly SkillDef skillDef; public readonly LocalizeKey Name; public readonly LocalizeKey Description; private float skillEffectFactor = 1f; private int skillLoss = 5; public bool Configurable = false; private static bool InitializedTerminal; private static Localization? _english; private static BaseUnityPlugin? _plugin; private static bool hasConfigSync; private static object? _configSync; public float SkillGainFactor { get { return skillDef.m_increseStep; } set { skillDef.m_increseStep = value; this.SkillGainFactorChanged?.Invoke(value); } } public float SkillEffectFactor { get { return skillEffectFactor; } set { skillEffectFactor = value; this.SkillEffectFactorChanged?.Invoke(value); } } public int SkillLoss { get { return skillLoss; } set { skillLoss = value; this.SkillLossChanged?.Invoke(value); } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown object obj = _plugin; if (obj == null) { BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Assembly.GetExecutingAssembly().DefinedTypes.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); _plugin = val; obj = (object)val; } return (BaseUnityPlugin)obj; } } private static object? configSync { get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } public event Action<float>? SkillGainFactorChanged; public event Action<float>? SkillEffectFactorChanged; public event Action<float>? SkillLossChanged; public Skill(string englishName, string icon) : this(englishName, loadSprite(icon, 64, 64)) { } public 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<SkillType, Skill>(); skillByName = new Dictionary<string, Skill>(); InitializedTerminal = false; hasConfigSync = true; Harmony val = new Harmony("org.bepinex.helpers.skillmanager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null); } private static void Patch_FejdStartup() { //IL_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<float> skillGain = config(text, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillGainFactor = skillGain.Value; skillGain.SettingChanged += delegate { skill.SkillGainFactor = skillGain.Value; }; ConfigEntry<float> skillEffect = config(text, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.SkillEffectFactor = skillEffect.Value; skillEffect.SettingChanged += delegate { skill.SkillEffectFactor = skillEffect.Value; }; ConfigEntry<int> skillLoss = config(text, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new ConfigurationManagerAttributes { Category = category } })); skill.skillLoss = skillLoss.Value; skillLoss.SettingChanged += delegate { skill.skillLoss = skillLoss.Value; }; } } } private static void Patch_Skills_GetSkillDef(ref SkillDef? __result, List<SkillDef> ___m_skills, SkillType type) { //IL_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, false); 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, ref Dictionary<SkillType, Skill>? __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<SkillType, Skill>(); } foreach (KeyValuePair<SkillType, Skill> skill in skills) { if (__instance.m_skillData.TryGetValue(skill.Key, out var value)) { __state[skill.Key] = value; if (skill.Value.skillLoss > 0) { Skill obj = value; obj.m_level -= value.m_level * (float)skill.Value.SkillLoss / 100f; value.m_accumulator = 0f; } __instance.m_skillData.Remove(skill.Key); } } } private static void Patch_Skills_OnDeath_Finalizer(Skills __instance, ref Dictionary<SkillType, Skill>? __state) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { return; } foreach (KeyValuePair<SkillType, Skill> item in __state) { __instance.m_skillData[item.Key] = item.Value; } __state = null; } private static void Patch_Terminal_InitTerminal_Prefix() { InitializedTerminal = Terminal.m_terminalInitialized; } private static void Patch_Terminal_InitTerminal() { if (!InitializedTerminal) { AddSkill(Terminal.commands["raiseskill"]); AddSkill(Terminal.commands["resetskill"]); } static void AddSkill(ConsoleCommand command) { //IL_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)delegate { List<string> list = fetcher.Invoke(); list.AddRange(skills.Values.Select((Skill skill) => skill.internalSkillName)); return list; }; } } 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<T> config<T>(string group, string name, T value, ConfigDescription description) { ConfigEntry<T> val = plugin.Config.Bind<T>(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry<T> config<T>(string group, string name, T value, string description) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } } public static class SkillManagerVersion { public const string Version = "1.7.0"; } [PublicAPI] public static class SkillExtensions { public static float GetSkillFactor(this Character character, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return character.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static float GetSkillFactor(this Skills skills, string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return skills.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor; } public static void RaiseSkill(this Character character, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) character.RaiseSkill(Skill.fromName(name), value); } public static void RaiseSkill(this Skills skill, string name, float value = 1f) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) skill.RaiseSkill(Skill.fromName(name), value); } public static void LowerSkill(this Character character, string name, float factor = 1f) { character.GetSkills().LowerSkill(name, factor); } public static void LowerSkill(this Skills skills, string name, float factor) { //IL_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 LocalizationManager { [PublicAPI] public class Localizer { private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } public static event Action? OnLocalizationComplete; private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out var value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out var value2)) { text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary<string, Func<string>>(); } config.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } public static void Load() { _ = plugin; } public static void LoadLocalizationLater(Localization __instance) { LoadLocalization(Localization.instance, __instance.GetSelectedLanguage()); } public static void SafeCallLocalizeComplete() { Localizer.OnLocalizationComplete?.Invoke(); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string[] array = Path.GetFileNameWithoutExtension(item).Split('.'); if (array.Length >= 2) { string text = array[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } } byte[] array2 = LoadTranslationFromAssembly("English"); if (array2 == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array2)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.TryGetValue(language, out var value)) { text2 = File.ReadAllText(value); } else { byte[] array3 = LoadTranslationFromAssembly(language); if (array3 != null) { text2 = Encoding.UTF8.GetString(array3); } } } if (text2 == null && dictionary.TryGetValue("English", out var value2)) { text2 = File.ReadAllText(value2); } if (text2 != null) { foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair<string, string> item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string>(2) { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager." + Assembly.GetExecutingAssembly().GetName().Name); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } public static class LocalizationManagerVersion { public const string Version = "1.4.3"; } } namespace ItemManager { [PublicAPI] public 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] public enum ConversionPiece { Disabled, [InternalName("smelter")] Smelter, [InternalName("charcoal_kiln")] CharcoalKiln, [InternalName("blastfurnace")] BlastFurnace, [InternalName("windmill")] Windmill, [InternalName("piece_spinningwheel")] SpinningWheel, [InternalName("eitrrefinery")] EitrRefinery, Custom } public class InternalName : Attribute { public readonly string internalName; public InternalName(string internalName) { this.internalName = internalName; } } [PublicAPI] public class RequiredResourceList { public readonly List<Requirement> Requirements = new List<Requirement>(); public bool Free = false; public void Add(string itemName, int amount, int quality = 0, bool upgraderResource = false) { Requirements.Add(new Requirement { itemName = itemName, amount = amount, quality = quality, upgraderResource = upgraderResource }); } public void Add(string itemName, ConfigEntry<int> amountConfig, int quality = 0, bool upgraderResource = false) { Requirements.Add(new Requirement { itemName = itemName, amountConfig = amountConfig, quality = quality, upgraderResource = upgraderResource }); } } [PublicAPI] public class CraftingStationList { public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>(); 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 }); } } [PublicAPI] public 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 = false; public float QualityResultAmountMultiplier = 1f; public ConfigEntryBase? RecipeIsActive = null; } [PublicAPI] public class Trade { public Trader Trader = Trader.None; public uint Price = 0u; public uint Stack = 1u; public string? RequiredGlobalKey = null; } [PublicAPI] [Flags] public enum Trader { None = 0, Haldor = 1, Hildir = 2 } public struct Requirement { public string itemName; public int amount; public ConfigEntry<int>? amountConfig; [Description("Set to a non-zero value to apply the requirement only for a specific quality")] public int quality; public bool upgraderResource; } public struct CraftingStationConfig { public CraftingTable Table; public int level; public string? custom; } [Flags] public enum Configurability { Disabled = 0, Recipe = 1, Stats = 2, Drop = 4, Trader = 8, Full = 0xF } [PublicAPI] public class DropTargets { public readonly List<DropTarget> Drops = new List<DropTarget>(); 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 }); } } public struct DropTarget { public string creature; public int min; public int max; public float chance; public bool levelMultiplier; } public enum Toggle { On = 1, Off = 0 } [PublicAPI] public class Item { private class ItemConfig { public ConfigEntry<string>? craft; public ConfigEntry<string>? upgrade; public ConfigEntry<CraftingTable> table = null; public ConfigEntry<int> tableLevel = null; public ConfigEntry<string> customTable = null; public ConfigEntry<int>? maximumTableLevel; public ConfigEntry<Toggle> requireOneIngredient = null; public ConfigEntry<float> qualityResultAmountMultiplier = null; } private class TraderConfig { public ConfigEntry<Trader> trader = null; public ConfigEntry<uint> price = null; public ConfigEntry<uint> stack = null; public ConfigEntry<string> requiredGlobalKey = null; } private class RequirementQuality { public int quality; } private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string? Category; [UsedImplicitly] public Action<ConfigEntryBase>? CustomDrawer; public Func<bool>? browsability; } [PublicAPI] public enum DamageModifier { Normal, Resistant, Weak, Immune, Ignore, VeryResistant, VeryWeak, None } private delegate void setDmgFunc(ref DamageTypes dmg, float value); private class SerializedRequirements { public readonly List<Requirement> Reqs; public SerializedRequirements(List<Requirement> reqs) { Reqs = reqs; } public SerializedRequirements(string reqs) : this(reqs.Split(',').Select(delegate(string r) { string[] array = r.Split(':'); 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), upgraderResource = (array.Length > 3 && array[3] == "U") }; }).ToList()) { } public override string ToString() { return string.Join(",", Reqs.Select(delegate(Requirement r) { string text = $"{r.itemName}:{r.amount}"; if (r.quality > 0 || r.upgraderResource) { text += $":{r.quality}"; } if (r.upgraderResource) { text += ":U"; } return text; })); } public static ItemDrop? fetchByName(ObjectDB objectDB, string name) { GameObject itemPrefab = objectDB.GetItemPrefab(name); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("The required item '" + name + "' does not exist.")); } return val; } public static Requirement[] toPieceReqs(ObjectDB objectDB, SerializedRequirements craft, SerializedRequirements upgrade) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0209: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown Dictionary<string, Requirement> dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func<Requirement, string>)((Requirement r) => r.itemName), (Func<Requirement, Requirement>)delegate(Requirement r) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL o