Please disclose if your mod was created primarily 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 balrond WeaponCrate v0.1.0
plugins/BalrondWeaponCrate.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using HarmonyLib; using LitJson2; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("BalrondWeaponCrate")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BalrondWeaponCrate")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("cde312a0-cf19-4264-8616-e1c74774beed")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace BalrondWeaponCrate { public class BalrondTranslator { public static Dictionary<string, Dictionary<string, string>> translations = new Dictionary<string, Dictionary<string, string>>(); public static Dictionary<string, string> getLanguage(string language) { Dictionary<string, string> result = null; try { result = translations[language]; } catch (Exception) { } return result; } } public static class ColliderSanitizer { public static void SanitizeForBuildPiece(GameObject visualRoot, bool removeAllMeshColliders, bool debugLog = false, string debugPrefix = null) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visualRoot == (Object)null) { return; } RemoveMeshColliders(visualRoot, removeAllMeshColliders, debugLog, debugPrefix); if (!((Object)(object)visualRoot.GetComponentInChildren<Collider>(true) != (Object)null)) { Renderer componentInChildren = visualRoot.GetComponentInChildren<Renderer>(true); if (!((Object)(object)componentInChildren == (Object)null)) { AddPrimitiveColliderFromBounds(visualRoot, componentInChildren.bounds, debugLog, debugPrefix); } } } private static void RemoveMeshColliders(GameObject root, bool removeAll, bool debugLog, string debugPrefix) { MeshCollider[] componentsInChildren = root.GetComponentsInChildren<MeshCollider>(true); foreach (MeshCollider val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Mesh sharedMesh = val.sharedMesh; if (removeAll || (Object)(object)sharedMesh == (Object)null || !sharedMesh.isReadable) { Object.Destroy((Object)(object)val); if (debugLog) { string text = (((Object)(object)sharedMesh != (Object)null) ? ((Object)sharedMesh).name : "null"); Debug.Log((object)(debugPrefix + " Removed MeshCollider on " + ((Object)root).name + " (mesh=" + text + ", removeAll=" + removeAll + ")")); } } } } private static void AddPrimitiveColliderFromBounds(GameObject root, Bounds worldBounds, bool debugLog, string debugPrefix) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0052: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) Vector3 center = root.transform.InverseTransformPoint(((Bounds)(ref worldBounds)).center); Vector3 lossyScale = root.transform.lossyScale; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(SafeDiv(((Bounds)(ref worldBounds)).size.x, lossyScale.x), SafeDiv(((Bounds)(ref worldBounds)).size.y, lossyScale.y), SafeDiv(((Bounds)(ref worldBounds)).size.z, lossyScale.z)); float num = Mathf.Max(val.x, val.z); if (val.y > num * 1.6f) { CapsuleCollider val2 = root.AddComponent<CapsuleCollider>(); val2.center = center; float num2 = num * 0.5f; val2.radius = Mathf.Max(0.01f, num2); val2.height = Mathf.Max(val2.radius * 2f, val.y); val2.direction = 1; if (debugLog) { Debug.Log((object)(debugPrefix + " Added CapsuleCollider fallback on " + ((Object)root).name)); } } else { BoxCollider val3 = root.AddComponent<BoxCollider>(); val3.center = center; val3.size = val; if (debugLog) { Debug.Log((object)(debugPrefix + " Added BoxCollider fallback on " + ((Object)root).name)); } } } private static float SafeDiv(float a, float b) { if (Mathf.Abs(b) < 0.0001f) { return a; } return a / b; } } public class DatabaseAddMethods { public void AddItems(List<GameObject> items) { foreach (GameObject item in items) { AddItem(item); } } public void AddRecipes(List<Recipe> recipes) { foreach (Recipe recipe in recipes) { AddRecipe(recipe); } } public void AddStatuseffects(List<StatusEffect> statusEffects) { foreach (StatusEffect statusEffect in statusEffects) { AddStatus(statusEffect); } } private bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0 && ObjectDB.instance.m_recipes.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } private void AddStatus(StatusEffect status) { if (!IsObjectDBValid()) { return; } if ((Object)(object)status != (Object)null) { if ((Object)(object)ObjectDB.instance.GetStatusEffect(status.m_nameHash) == (Object)null) { ObjectDB.instance.m_StatusEffects.Add(status); } else { Debug.Log((object)(Launch.projectName + ": " + ((Object)status).name + " - Status already in the game")); } } else { Debug.LogError((object)(Launch.projectName + ": " + ((Object)status).name + " - Status not found")); } } private void AddRecipe(Recipe recipe) { if (!IsObjectDBValid()) { return; } if ((Object)(object)recipe != (Object)null) { if ((Object)(object)ObjectDB.instance.m_recipes.Find((Recipe x) => ((Object)x).name == ((Object)recipe).name) == (Object)null) { if ((Object)(object)recipe.m_item != (Object)null) { ObjectDB.instance.m_recipes.Add(recipe); } } else { Debug.Log((object)(Launch.projectName + ": " + ((Object)recipe).name + " - Recipe with this name already in the Game")); } } else { Debug.LogError((object)(Launch.projectName + ": " + ((Object)recipe).name + " - Recipe not found")); } } private void AddItem(GameObject newPrefab) { if (!IsObjectDBValid()) { return; } ItemDrop component = newPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { if ((Object)(object)ObjectDB.instance.GetItemPrefab(((Object)newPrefab).name) == (Object)null) { ObjectDB.instance.m_items.Add(newPrefab); Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(ObjectDB.instance); dictionary[((Object)newPrefab).name.GetHashCode()] = newPrefab; } else { Debug.Log((object)(Launch.projectName + ": " + ((Object)newPrefab).name + " - ItemDrop already exist")); } } else { Debug.LogError((object)(Launch.projectName + ": " + ((Object)newPrefab).name + " - ItemDrop not found on prefab")); } } } [Serializable] public class MappedEffectList { public List<EffectInfo> pieceEffect; public List<EffectInfo> destroyedEffects; public List<EffectInfo> hitEffects; public List<EffectInfo> switchEffect; public List<EffectInfo> blockEffect; public List<EffectInfo> equipEffect; public List<EffectInfo> hitEffect; public List<EffectInfo> hitTerrainEffect; public List<EffectInfo> holdStartEffect; public List<EffectInfo> startEffect; public List<EffectInfo> trailStartEffect; public List<EffectInfo> triggerEffect; public List<EffectInfo> unequipEffect; public EffectList createEffectListFromInfo(List<EffectInfo> list) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown EffectList val = new EffectList(); List<EffectData> list2 = new List<EffectData>(); val.m_effectPrefabs = list2.ToArray(); return val; } private EffectData createEffectData(EffectInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown EffectData val = new EffectData(); val.m_inheritParentRotation = info.inheritRotation; val.m_multiplyParentVisualScale = info.multiplyScale; val.m_childTransform = info.childName; val.m_inheritParentScale = info.inheritScale; val.m_variant = info.variant; val.m_scale = info.scale; val.m_attach = info.attach; val.m_follow = info.follow; val.m_prefab = ZNetScene.instance.m_prefabs.Find((GameObject x) => ((Object)x).name == info.name); return val; } } [Serializable] public struct EffectInfo { public string name; public bool enabled; public int variant; public bool attach; public bool follow; public bool inheritRotation; public bool inheritScale; public bool multiplyScale; public bool radnomRotation; public bool scale; public string childName; public EffectInfo(string name, bool enabled = true, int variant = -1, bool attach = false, bool follow = false, bool inheritRotation = false, bool inheritScale = false, bool multiplyScale = false, bool radnomRotation = false, bool scale = false, string childName = null) { this.name = name; this.enabled = enabled; this.variant = variant; this.attach = attach; this.follow = follow; this.inheritRotation = inheritRotation; this.inheritScale = inheritScale; this.multiplyScale = multiplyScale; this.radnomRotation = radnomRotation; this.scale = scale; this.childName = childName; } } public sealed class ModResourceLoader { public AssetBundle assetBundle; public readonly List<GameObject> itemPrefabs = new List<GameObject>(); public readonly List<GameObject> otherPrefabs = new List<GameObject>(); public void loadAssets() { assetBundle = GetAssetBundleFromResources("balrondweaponcrate"); if ((Object)(object)assetBundle == (Object)null) { Debug.LogWarning((object)(Launch.projectName + " AssetBundle not found (embedded resource endswith 'balrondweaponcrate').")); return; } string basePath = "Assets/Custom/BalrondWeaponCrate/"; loadItems(basePath); loadOther(basePath); } public void AddPrefabsToZnetScene(ZNetScene zNetScene) { if (!((Object)(object)zNetScene == (Object)null)) { validateAddedPrefabs(itemPrefabs, zNetScene); validateAddedPrefabs(otherPrefabs, zNetScene); zNetScene.m_prefabs.RemoveAll((GameObject x) => (Object)(object)x == (Object)null); } } private void loadItems(string basePath) { string[] nameList = new string[1] { "WeaponCrate_bal" }; addNewPrefabToCollection(nameList, basePath, itemPrefabs, "item", requireZNetView: false); } private void loadOther(string basePath) { string mainPath = basePath + "Other/"; string[] nameList = new string[0]; addNewPrefabToCollection(nameList, mainPath, otherPrefabs, "other", requireZNetView: false); } private void validateAddedPrefabs(List<GameObject> list, ZNetScene zNetScene) { if (list == null || (Object)(object)zNetScene == (Object)null) { return; } for (int i = 0; i < list.Count; i++) { GameObject val = list[i]; if (!((Object)(object)val == (Object)null)) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val).name); if (zNetScene.m_namedPrefabs.ContainsKey(stableHashCode)) { Debug.LogWarning((object)("DUPLICATE: " + ((Object)val).name)); } else { zNetScene.m_prefabs.Add(val); } } } } private void addNewPrefabToCollection(string[] nameList, string mainPath, List<GameObject> prefabList, string typeName, bool requireZNetView) { if ((Object)(object)assetBundle == (Object)null || nameList == null || nameList.Length == 0) { return; } foreach (string text in nameList) { if (!string.IsNullOrEmpty(text)) { GameObject val = assetBundle.LoadAsset<GameObject>(mainPath + text + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find " + typeName + " with name: " + text + " at " + mainPath)); } else if (requireZNetView && (Object)(object)val.GetComponent<ZNetView>() == (Object)null) { Debug.LogWarning((object)("Prefab has no ZNetView (skipped): " + text)); } else { ShaderReplacment.Replace(val); prefabList.Add(val); bool flag = false; } } } } private static AssetBundle GetAssetBundleFromResources(string filenameSuffix) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith(filenameSuffix, StringComparison.OrdinalIgnoreCase)) { text = text2; break; } } if (text == null) { bool flag = false; return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { return null; } return AssetBundle.LoadFromStream(stream); } } public class ShaderReplacment { public static List<GameObject> prefabsToReplaceShader = new List<GameObject>(); public static List<Material> materialsInPrefabs = new List<Material>(); public string[] shaderlist = new string[49] { "Custom/AlphaParticle", "Custom/Blob", "Custom/Bonemass", "Custom/Clouds", "Custom/Creature", "Custom/Decal", "Custom/Distortion", "Custom/Flow", "Custom/FlowOpaque", "Custom/Grass", "Custom/GuiScroll", "Custom/Heightmap", "Custom/icon", "Custom/InteriorSide", "Custom/LitGui", "Custom/LitParticles", "Custom/mapshader", "Custom/ParticleDecal", "Custom/Piece", "Custom/Player", "Custom/Rug", "Custom/ShadowBlob", "Custom/SkyboxProcedural", "Custom/SkyObject", "Custom/StaticRock", "Custom/Tar", "Custom/Trilinearmap", "Custom/UI/BGBlur", "Custom/Vegetation", "Custom/Water", "Custom/WaterBottom", "Custom/WaterMask", "Custom/Yggdrasil", "Custom/Yggdrasil/root", "Hidden/BlitCopyHDRTonemap", "Hidden/Dof/DepthOfFieldHdr", "Hidden/Dof/DX11Dof", "Hidden/Internal-Loading", "Hidden/Internal-UIRDefaultWorld", "Hidden/SimpleClear", "Hidden/SunShaftsComposite", "Lux Lit Particles/ Bumped", "Lux Lit Particles/ Tess Bumped", "Particles/Standard Surface2", "Particles/Standard Unlit2", "Standard TwoSided", "ToonDeferredShading2017", "Unlit/DepthWrite", "Unlit/Lighting" }; public static List<Shader> shaders = new List<Shader>(); private static readonly HashSet<Shader> CachedShaders = new HashSet<Shader>(); public static bool debug = true; public static Shader findShader(string name) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); if (array.Length == 0) { Debug.LogWarning((object)"SHADER LIST IS EMPTY!"); return null; } if (debug) { } return shaders.Find((Shader x) => ((Object)x).name == name); } public static Shader GetShaderByName(string name) { return shaders.Find((Shader x) => ((Object)x).name == name.Trim()); } public static void debugShaderList(List<Shader> shadersRes) { foreach (Shader shadersRe in shadersRes) { Debug.LogWarning((object)("SHADER NAME IS: " + ((Object)shadersRe).name)); } debug = false; } public static void Replace(GameObject gameObject) { prefabsToReplaceShader.Add(gameObject); GetMaterialsInPrefab(gameObject); } public static void GetMaterialsInPrefab(GameObject gameObject) { Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } Material[] array2 = sharedMaterials; foreach (Material val2 in array2) { if ((Object)(object)val2 != (Object)null) { materialsInPrefabs.Add(val2); } } } } public static void getMeShaders() { AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>(); AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { IEnumerable<Shader> enumerable3; try { IEnumerable<Shader> enumerable2; if (!val.isStreamedSceneAssetBundle || !Object.op_Implicit((Object)(object)val)) { IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>(); enumerable2 = enumerable; } else { enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>) where (Object)(object)shader != (Object)null select shader; } enumerable3 = enumerable2; } catch (Exception) { continue; } if (enumerable3 == null) { continue; } foreach (Shader item in enumerable3) { CachedShaders.Add(item); } } } public static void runMaterialFix() { getMeShaders(); shaders.AddRange(CachedShaders); foreach (Material materialsInPrefab in materialsInPrefabs) { Shader shader = materialsInPrefab.shader; if (!((Object)(object)shader == (Object)null)) { string name = ((Object)shader).name; if (!(name == "Standard") && !name.Contains("ScrollingTex") && name.Contains("Balrond")) { setProperValue(materialsInPrefab, name); } } } } private static void setProperValue(Material material, string shaderName) { string name = shaderName.Replace("Balrond", "Custom"); name = checkNaming(name); Shader shaderByName = GetShaderByName(name); if ((Object)(object)shaderByName == (Object)null) { Debug.LogWarning((object)("Shader not found " + name)); } else { material.shader = shaderByName; } } private static string checkNaming(string name) { string result = name; if (name.Contains("Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Tess Bumped")) { result = name.Replace("Custom", "Lux Lit Particles"); } if (name.Contains("Standard Surface")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Surface2", "Standard Surface"); } if (name.Contains("Standard Unlit")) { result = name.Replace("Custom", "Particles"); result = result.Replace("Standard Unlit", "Standard Unlit2"); result = result.Replace("Standard Unlit22", "Standard Unlit2"); } return result; } } public class TableMapper { public static CraftingStation cauldron; public static CraftingStation workbench; public static CraftingStation heavyWorkbench; public static CraftingStation forge; public static CraftingStation ironworks; public static CraftingStation blackforge; public static CraftingStation stoneCutter; public static CraftingStation artisian; public static CraftingStation magetable; public static CraftingStation runeforge; public static CraftingStation tannery; public static CraftingStation fletcher; public static CraftingStation grill; public static CraftingStation alchemylab; public static CraftingStation shamantable; public static CraftingStation foodtable; public static List<GameObject> pieces = new List<GameObject>(); public static void setupTables(List<GameObject> list) { pieces = list; prepareTables(); } private static CraftingStation FindStation(List<GameObject> list, string name, string replacement = "piece_workbench") { GameObject val = list.Find((GameObject x) => ((Object)x).name == name); if ((Object)(object)val != (Object)null) { return val.GetComponent<CraftingStation>(); } if ((Object)(object)val == (Object)null) { val = list.Find((GameObject x) => ((Object)x).name == replacement); if ((Object)(object)val != (Object)null) { return val.GetComponent<CraftingStation>(); } } Debug.LogWarning((object)("TableMapper - Station not found: " + name)); return null; } private static void prepareTables() { cauldron = FindStation(pieces, "piece_cauldron"); workbench = FindStation(pieces, "piece_workbench"); heavyWorkbench = FindStation(pieces, "piece_heavy_workbench_bal"); forge = FindStation(pieces, "forge"); ironworks = FindStation(pieces, "piece_metalworks_bal", "forge"); blackforge = FindStation(pieces, "blackforge"); stoneCutter = FindStation(pieces, "piece_stonecutter"); artisian = FindStation(pieces, "piece_artisanstation"); runeforge = FindStation(pieces, "piece_runeforge_bal", "blackforge"); magetable = FindStation(pieces, "piece_magetable"); fletcher = FindStation(pieces, "piece_fletcher_bal"); shamantable = FindStation(pieces, "piece_shamantable_bal", "piece_magetable"); foodtable = FindStation(pieces, "piece_preptable"); alchemylab = FindStation(pieces, "piece_MeadCauldron"); } } public class ItemUtils { public static bool IsWeaponType(ItemType type, bool shieldsAreWeapons) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 if ((int)type == 3) { return true; } if ((int)type == 14) { return true; } if ((int)type == 22) { return true; } if ((int)type == 4) { return true; } if ((int)type == 15) { return true; } if ((int)type == 5) { return shieldsAreWeapons; } return false; } public static bool IsArmorType(ItemType type, bool shieldsAreWeapons) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 if ((int)type == 6) { return true; } if ((int)type == 7) { return true; } if ((int)type == 11) { return true; } if ((int)type == 17) { return true; } if ((int)type == 18) { return true; } if ((int)type == 5) { return !shieldsAreWeapons; } return false; } public static bool HasAnyIcon(ItemDrop drop) { if ((Object)(object)drop == (Object)null || drop.m_itemData == null || drop.m_itemData.m_shared == null) { return false; } try { Sprite[] icons = drop.m_itemData.m_shared.m_icons; return icons != null && icons.Length != 0 && (Object)(object)icons[0] != (Object)null; } catch { return false; } } public static Sprite SafeFirstIcon(ItemDrop drop) { try { Sprite[] icons = drop.m_itemData.m_shared.m_icons; if (icons != null && icons.Length != 0) { return icons[0]; } } catch { } return null; } public static bool HasUsableVisual(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return false; } Transform val = FindChildRecursiveByName(prefab.transform, "attach"); if ((Object)(object)val != (Object)null && !((Object)val).name.Equals("attach_skin", StringComparison.OrdinalIgnoreCase)) { return true; } MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return false; } foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { GameObject gameObject = ((Component)val2).gameObject; if (!((Object)(object)gameObject == (Object)null) && !((Object)(object)gameObject.GetComponent<SkinnedMeshRenderer>() != (Object)null)) { return true; } } } return false; } public static Transform FindChildRecursiveByName(Transform root, string wantedName) { if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(wantedName)) { return null; } Queue<Transform> queue = new Queue<Transform>(); queue.Enqueue(root); while (queue.Count > 0) { Transform val = queue.Dequeue(); if (!((Object)(object)val == (Object)null)) { if (!string.IsNullOrEmpty(((Object)val).name) && ((Object)val).name.Equals(wantedName, StringComparison.OrdinalIgnoreCase)) { return val; } for (int i = 0; i < val.childCount; i++) { queue.Enqueue(val.GetChild(i)); } } } return null; } public static GameObject PickVisualRoot(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return null; } Transform val = FindChildRecursiveByName(prefab.transform, "attach"); if ((Object)(object)val != (Object)null && !((Object)val).name.Equals("attach_skin", StringComparison.OrdinalIgnoreCase)) { return ((Component)val).gameObject; } MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return null; } foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { GameObject gameObject = ((Component)val2).gameObject; if (!((Object)(object)gameObject == (Object)null) && !((Object)(object)gameObject.GetComponent<SkinnedMeshRenderer>() != (Object)null)) { return gameObject; } } } return null; } } public class JsonLoader { public string defaultPath = string.Empty; public void loadJson() { LoadTranslations(); justDefaultPath(); } public void justDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "ZBalrondWeaponCrate-translation/"); defaultPath = text; } public void createDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "ZBalrondWeaponCrate-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("ZBalrondWeaponCrate: Folder already exists: " + text)); } defaultPath = text; } private string[] jsonFilePath(string folderName, string extension) { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "ZBalrondWeaponCrate-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("ZBalrondWeaponCrate: Folder already exists: " + text)); } string[] files = Directory.GetFiles(text, extension); Debug.Log((object)("ZBalrondWeaponCrate:" + folderName + " Json Files Found: " + files.Length)); return files; } private static void CreateFolder(string path) { try { Directory.CreateDirectory(path); Debug.Log((object)"ZBalrondWeaponCrate: Folder created successfully."); } catch (Exception ex) { Debug.Log((object)("ZBalrondWeaponCrate: Error creating folder: " + ex.Message)); } } private void LoadTranslations() { int num = 0; string[] array = jsonFilePath("Translation", "*.json"); foreach (string text in array) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); string json = File.ReadAllText(text); JsonData jsonData = JsonMapper.ToObject(json); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string key in jsonData.Keys) { dictionary[key] = jsonData[key].ToString(); } if (dictionary != null) { BalrondTranslator.translations.Add(fileNameWithoutExtension, dictionary); Debug.Log((object)("ZBalrondWeaponCrate: Json Files Language: " + fileNameWithoutExtension)); num++; } else { Debug.LogError((object)("ZBalrondWeaponCrate: Loading FAILED file: " + text)); } } Debug.Log((object)("ZBalrondWeaponCrate: Translation JsonFiles Loaded: " + num)); } } [BepInPlugin("balrond.astafaraios.ZBalrondWeaponCrate", "ZBalrondWeaponCrate", "0.1.0")] public sealed class Launch : BaseUnityPlugin { [HarmonyPatch(typeof(FejdStartup), "SetupGui")] private static class FejdStartup_SetupGUI { private static void Postfix() { bool flag = false; string selectedLanguage = Localization.instance.GetSelectedLanguage(); Dictionary<string, string> dictionary = BalrondTranslator.getLanguage("English"); if ("English" != selectedLanguage) { Dictionary<string, string> language = BalrondTranslator.getLanguage(selectedLanguage); if (language != null) { dictionary = language; } else { Debug.Log((object)"ZBalrondWeaponCrate: Did not find translation file loading English"); } } if (dictionary != null) { foreach (KeyValuePair<string, string> item in dictionary) { Localization.instance.AddWord(item.Key, item.Value); } return; } Debug.LogWarning((object)"ZBalrondWeaponCrate: No translation file found!"); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "SetupLanguage")] private static class Translation_SetupLanguage { private static void Prefix(Localization __instance, string language) { bool flag = false; Dictionary<string, string> dictionary = BalrondTranslator.getLanguage("English"); if ("English" != language) { Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language); if (language2 != null) { dictionary = language2; } else { Debug.Log((object)"ZBalrondWeaponCrate: Did not find translation file loading English"); } } if (dictionary != null) { foreach (KeyValuePair<string, string> item in dictionary) { __instance.AddWord(item.Key, item.Value); } return; } Debug.LogWarning((object)"ZBalrondWeaponCrate: No translation file found!"); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "LoadCSV")] private static class Translation_LoadCSV { private static void Prefix(Localization __instance, string language) { bool flag = false; Dictionary<string, string> dictionary = BalrondTranslator.getLanguage("English"); if ("English" != language) { Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language); if (language2 != null) { dictionary = language2; } else { Debug.Log((object)"ZBalrondWeaponCrate: Did not find translation file loading English"); } } if (dictionary != null) { foreach (KeyValuePair<string, string> item in dictionary) { __instance.AddWord(item.Key, item.Value); } return; } Debug.LogWarning((object)"ZBalrondWeaponCrate: No translation file found!"); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Path { private static bool ranFix; private static void Prefix(ZNetScene __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) bool flag = false; if (!((Object)(object)__instance == (Object)null)) { modResourceLoader.AddPrefabsToZnetScene(__instance); if (!ranFix && !new ZNet().IsDedicated()) { ShaderReplacment.runMaterialFix(); ranFix = true; } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Path { private static void Postfix() { bool flag = false; if (IsObjectDBValid()) { databaseAddMethods.AddItems(modResourceLoader.itemPrefabs); recipeFactory.EnsureRecipes(); weaponCrateBuilder.BuildWeaponCratePieces(); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class Object_CopyOtherDB_Path { private static void Postfix() { bool flag = false; if (IsObjectDBValid()) { databaseAddMethods.AddItems(modResourceLoader.itemPrefabs); recipeFactory.EnsureRecipes(); weaponCrateBuilder.BuildWeaponCratePieces(); } } } private Harmony harmony; public const string PluginGUID = "balrond.astafaraios.ZBalrondWeaponCrate"; public const string PluginName = "ZBalrondWeaponCrate"; public const string PluginVersion = "0.1.0"; public static DatabaseAddMethods databaseAddMethods = new DatabaseAddMethods(); public static readonly ModResourceLoader modResourceLoader = new ModResourceLoader(); public static readonly WeaponCrateBuilder weaponCrateBuilder = new WeaponCrateBuilder(); public static readonly RecipeFactory recipeFactory = new RecipeFactory(); public static readonly JsonLoader jsonLoader = new JsonLoader(); public static readonly string projectName = "[ZBalrondWeaponCrate]"; public const bool Enabled = true; public const bool DebugLog = false; public const string WeaponCratePrefabName = "WeaponCrate_bal"; public const string TemplatePrefabName = "FierySvinstew"; public const PieceCategory WeaponCategory = 6; public const PieceCategory ArmorCategory = 5; public const bool ShieldsAreWeapons = true; public const bool ForceCostToSelf = true; public const int CostAmount = 1; public const bool RequireAttachChild = false; public static readonly string[] ManualIncludeWeapons = new string[0]; public static readonly string[] ManualIncludeArmors = new string[0]; public static readonly string[] ManualExclude = new string[0]; private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown jsonLoader.loadJson(); bool flag = true; modResourceLoader.loadAssets(); harmony = new Harmony("balrond.astafaraios.ZBalrondWeaponCrate"); harmony.PatchAll(); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static bool IsObjectDBValid() { return (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null && ObjectDB.instance.m_items.Count != 0 && (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } internal static void Log(string msg) { bool flag = false; } } public static class ItemVfxApplier { public static GameObject ApplyTemplateSparkles(GameObject targetPrefab, Transform templateSparkles, bool debugLog = false, string debugPrefix = null) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)targetPrefab == (Object)null || (Object)(object)templateSparkles == (Object)null) { return null; } Transform val = ItemUtils.FindChildRecursiveByName(targetPrefab.transform, ((Object)templateSparkles).name); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } try { GameObject val2 = Object.Instantiate<GameObject>(((Component)templateSparkles).gameObject); ((Object)val2).name = ((Object)templateSparkles).name; val2.transform.SetParent(targetPrefab.transform, false); val2.transform.localPosition = templateSparkles.localPosition; val2.transform.localRotation = templateSparkles.localRotation; val2.transform.localScale = templateSparkles.localScale; return val2; } catch (Exception ex) { if (debugLog) { Debug.LogWarning((object)(debugPrefix + " Failed cloning sparkles onto " + ((Object)targetPrefab).name + ": " + ex)); } return null; } } public static void StripRootParticleSystems(GameObject targetPrefab, bool debugLog = false, string debugPrefix = null) { if ((Object)(object)targetPrefab == (Object)null) { return; } try { ParticleSystem[] components = targetPrefab.GetComponents<ParticleSystem>(); ParticleSystem[] array = components; foreach (ParticleSystem val in array) { Object.Destroy((Object)(object)val); } ParticleSystemRenderer[] components2 = targetPrefab.GetComponents<ParticleSystemRenderer>(); ParticleSystemRenderer[] array2 = components2; foreach (ParticleSystemRenderer val2 in array2) { Object.Destroy((Object)(object)val2); } } catch (Exception ex) { if (debugLog) { Debug.LogWarning((object)(debugPrefix + " Failed stripping root ParticleSystems on " + ((Object)targetPrefab).name + ": " + ex)); } } } public static GameObject ApplySparklesAndCleanRoot(GameObject targetPrefab, Transform templateSparkles, bool debugLog = false, string debugPrefix = null) { GameObject result = ApplyTemplateSparkles(targetPrefab, templateSparkles, debugLog, debugPrefix); StripRootParticleSystems(targetPrefab, debugLog, debugPrefix); return result; } } public class PieceNTearSetter { public static void CopyPieceSettings(ItemDrop drop, Piece dst, Piece src) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) dst.m_allowAltGroundPlacement = true; dst.m_allowedInDungeons = true; dst.m_allowRotatedOverlap = true; dst.m_blockingPieces = src.m_blockingPieces; dst.m_blockRadius = 0f; dst.m_notOnTiltingSurface = false; dst.m_canBeRemoved = true; dst.m_canRotate = true; if (!ItemUtils.IsArmorType(drop.m_itemData.m_shared.m_itemType, shieldsAreWeapons: true)) { dst.m_clipEverything = true; dst.m_clipGround = true; } dst.m_comfort = 0; dst.m_comfortGroup = src.m_comfortGroup; dst.m_comfortObject = src.m_comfortObject; dst.m_connectRadius = src.m_connectRadius; dst.m_craftingStation = src.m_craftingStation; dst.m_cultivatedGroundOnly = false; dst.m_groundOnly = src.m_groundOnly; dst.m_groundPiece = src.m_groundPiece; ((StaticTarget)dst).m_haveCenter = ((StaticTarget)src).m_haveCenter; dst.m_inCeilingOnly = src.m_inCeilingOnly; dst.m_isUpgrade = false; dst.m_mustBeAboveConnected = src.m_mustBeAboveConnected; dst.m_mustConnectTo = src.m_mustConnectTo; dst.m_waterPiece = src.m_waterPiece; dst.m_vegetationGroundOnly = false; dst.m_targetNonPlayerBuilt = false; dst.m_spaceRequirement = 0f; dst.m_placeEffect = src.m_placeEffect; dst.m_returnResourceHeightOffset = src.m_returnResourceHeightOffset; } public static void CopyWearNTearSettings(WearNTear dst, WearNTear src) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) dst.m_ashDamageImmune = src.m_ashDamageImmune; dst.m_ashDamageResist = src.m_ashDamageResist; dst.m_ashMaterialValue = src.m_ashMaterialValue; dst.m_ashDamageTime = src.m_ashDamageTime; dst.m_ashroof = src.m_ashroof; dst.m_autoCreateFragments = src.m_autoCreateFragments; dst.m_biome = src.m_biome; dst.m_health = src.m_health; dst.m_hitEffect = src.m_hitEffect; dst.m_hitNoise = src.m_hitNoise; dst.m_minToolTier = src.m_minToolTier; dst.m_burnable = src.m_burnable; dst.m_destroyedEffect = src.m_destroyedEffect; dst.m_switchEffect = src.m_switchEffect; dst.m_damages = src.m_damages; dst.m_destroyNoise = src.m_destroyNoise; dst.m_support = src.m_support; dst.m_staticPosition = src.m_staticPosition; dst.m_noSupportWear = src.m_noSupportWear; dst.m_noRoofWear = src.m_noRoofWear; } public static void SetSingleRequirement(Piece piece, string resPrefabName, int amount, int amountPerLevel, bool recover) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(resPrefabName); if ((Object)(object)itemPrefab == (Object)null) { Debug.LogWarning((object)(Launch.projectName + " Cost item not found: " + resPrefabName + " (fallback Wood)")); itemPrefab = ObjectDB.instance.GetItemPrefab("Wood"); } Requirement val = new Requirement { m_resItem = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null), m_amount = amount, m_amountPerLevel = amountPerLevel, m_recover = recover }; piece.m_resources = (Requirement[])(object)new Requirement[1] { val }; } } public sealed class RecipeFactory { private const string DefaultStationPrefab = "piece_workbench"; private const int DefaultStationLevel = 1; public void EnsureRecipes() { if (Launch.IsObjectDBValid()) { EnsureWeaponCrateRecipe(); } } private void EnsureWeaponCrateRecipe() { string text = "WeaponCrate_bal"; string text2 = "Recipe_" + text; ItemDrop val = ResolveItemDrop(text, allowInjectIntoObjectDB: true); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("ZBalrondWeaponCrate: RecipeFactory - could not resolve ItemDrop for: " + text + " (not found in ObjectDB nor ZNetScene)")); return; } Recipe val2 = FindRecipeByName(text2); if ((Object)(object)val2 != (Object)null) { return; } Recipe val3 = FindRecipeByItem(val); if (!((Object)(object)val3 != (Object)null)) { Recipe val4 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val4).name = text2; val4.m_item = val; val4.m_amount = 1; val4.m_enabled = true; val4.m_craftingStation = FindStation("piece_workbench"); val4.m_minStationLevel = 1; val4.m_repairStation = val4.m_craftingStation; List<Requirement> list = new List<Requirement> { CreateReq("Wood", 10, 0, recover: true), CreateReq("BronzeNails", 2, 0, recover: true) }; list.RemoveAll((Requirement r) => r == null || (Object)(object)r.m_resItem == (Object)null); val4.m_resources = list.ToArray(); if (ObjectDB.instance.m_recipes == null) { ObjectDB.instance.m_recipes = new List<Recipe>(); } ObjectDB.instance.m_recipes.Add(val4); RefreshObjectDBLookups(ObjectDB.instance); Debug.Log((object)("ZBalrondWeaponCrate: Added recipe: " + text2 + " (station=" + (((Object)(object)val4.m_craftingStation != (Object)null) ? ((Object)val4.m_craftingStation).name : "none/hand") + ")")); } } private static ItemDrop ResolveItemDrop(string itemPrefabName, bool allowInjectIntoObjectDB) { if (string.IsNullOrEmpty(itemPrefabName)) { return null; } GameObject val = null; if ((Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetItemPrefab(itemPrefabName); if ((Object)(object)val == (Object)null && ObjectDB.instance.m_items != null) { val = ObjectDB.instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == itemPrefabName); } } if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { val = ZNetScene.instance.GetPrefab(itemPrefabName); } if ((Object)(object)val == (Object)null) { return null; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return null; } if (allowInjectIntoObjectDB && (Object)(object)ObjectDB.instance != (Object)null) { if (ObjectDB.instance.m_items == null) { ObjectDB.instance.m_items = new List<GameObject>(); } bool flag = false; for (int i = 0; i < ObjectDB.instance.m_items.Count; i++) { GameObject val2 = ObjectDB.instance.m_items[i]; if ((Object)(object)val2 != (Object)null && ((Object)val2).name == ((Object)val).name) { flag = true; break; } } if (!flag) { ObjectDB.instance.m_items.Add(val); RefreshObjectDBLookups(ObjectDB.instance); bool flag2 = false; } } return component; } private static CraftingStation FindStation(string stationPrefabName) { if (string.IsNullOrEmpty(stationPrefabName)) { return null; } if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab(stationPrefabName); if ((Object)(object)prefab == (Object)null) { return null; } return prefab.GetComponent<CraftingStation>(); } private static Requirement CreateReq(string itemPrefabName, int amount, int amountPerLevel, bool recover) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown if (string.IsNullOrEmpty(itemPrefabName) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject val = ObjectDB.instance.GetItemPrefab(itemPrefabName); if ((Object)(object)val == (Object)null && ObjectDB.instance.m_items != null) { val = ObjectDB.instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == itemPrefabName); } if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("ZBalrondWeaponCrate: RecipeFactory - requirement item not found: " + itemPrefabName)); return null; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)("ZBalrondWeaponCrate: RecipeFactory - requirement ItemDrop missing: " + itemPrefabName)); return null; } return new Requirement { m_resItem = component, m_amount = amount, m_amountPerLevel = amountPerLevel, m_recover = recover }; } private static Recipe FindRecipeByName(string recipeName) { if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_recipes == null || string.IsNullOrEmpty(recipeName)) { return null; } for (int i = 0; i < ObjectDB.instance.m_recipes.Count; i++) { Recipe val = ObjectDB.instance.m_recipes[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == recipeName) { return val; } } return null; } private static Recipe FindRecipeByItem(ItemDrop item) { if ((Object)(object)item == (Object)null || (Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_recipes == null) { return null; } for (int i = 0; i < ObjectDB.instance.m_recipes.Count; i++) { Recipe val = ObjectDB.instance.m_recipes[i]; if ((Object)(object)val != (Object)null && (Object)(object)val.m_item == (Object)(object)item) { return val; } if ((Object)(object)val != (Object)null && (Object)(object)val.m_item != (Object)null && (Object)(object)((Component)val.m_item).gameObject != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null && ((Object)((Component)val.m_item).gameObject).name == ((Object)((Component)item).gameObject).name) { return val; } } return null; } private static void RefreshObjectDBLookups(ObjectDB db) { if (!((Object)(object)db == (Object)null)) { InvokeIfExists(db, "UpdateItemHashes"); InvokeIfExists(db, "UpdateRecipeHashes"); InvokeIfExists(db, "UpdateCraftingStations"); } } private static void InvokeIfExists(object target, string methodName) { try { if (target != null && !string.IsNullOrEmpty(methodName)) { MethodInfo method = target.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method == null) && method.GetParameters().Length == 0) { method.Invoke(target, null); } } } catch (Exception) { bool flag = false; } } } [HarmonyPatch] public static class WeaponCrateRotatePatch { public sealed class WeaponCratePieceMarker : MonoBehaviour { } private sealed class State { public int GhostId = -1; public int XStep = 0; public int ZStep = 0; public bool AltWasDown = false; public bool CtrlWasDown = false; } private const float StepDegrees = 30f; private static readonly int StepCount = Mathf.RoundToInt(12f); private static readonly ConditionalWeakTable<Player, State> s_state = new ConditionalWeakTable<Player, State>(); private static State Get(Player p) { return s_state.GetOrCreateValue(p); } private static bool AltDown() { return ZInput.GetKey((KeyCode)308, true) || ZInput.GetKey((KeyCode)307, true); } private static bool CtrlDown() { return ZInput.GetKey((KeyCode)306, true) || ZInput.GetKey((KeyCode)305, true); } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] [HarmonyPostfix] private static void UpdatePlacementGhost_Postfix(Player __instance, bool flashGuardStone) { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || !((Character)__instance).InPlaceMode()) { return; } GameObject placementGhost = __instance.m_placementGhost; if (!((Object)(object)placementGhost == (Object)null) && !((Object)(object)placementGhost.GetComponent<WeaponCratePieceMarker>() == (Object)null)) { State state = Get(__instance); int instanceID = ((Object)placementGhost).GetInstanceID(); if (state.GhostId != instanceID) { state.GhostId = instanceID; state.XStep = 0; state.ZStep = 0; state.AltWasDown = false; state.CtrlWasDown = false; } bool flag = AltDown(); if (flag && !state.AltWasDown) { state.ZStep = (state.ZStep + 1) % StepCount; } state.AltWasDown = flag; bool flag2 = CtrlDown(); if (flag2 && !state.CtrlWasDown) { state.XStep = (state.XStep + 1) % StepCount; } state.CtrlWasDown = flag2; float num = (float)state.XStep * 30f; float num2 = (float)state.ZStep * 30f; if (state.XStep != 0 || state.ZStep != 0) { placementGhost.transform.rotation = placementGhost.transform.rotation * Quaternion.Euler(num, 0f, num2); } } } } public sealed class WeaponCrateBuilder { private const string SparklesChildName = "fx_ItemSparkles"; private const bool RemoveAllMeshColliders = false; public void BuildWeaponCratePieces() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) if (!Launch.IsObjectDBValid()) { return; } ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || !TryGetCratePieceTable(instance, "WeaponCrate_bal", out var table) || !TryResolveTemplateAll("FierySvinstew", out var templateGo, out var templatePiece, out var templateWnt)) { return; } Transform templateSparkles = ItemUtils.FindChildRecursiveByName(templateGo.transform, "fx_ItemSparkles"); if (table.m_pieces == null) { table.m_pieces = new List<GameObject>(); } HashSet<string> exclude = ToSet(Launch.ManualExclude); HashSet<string> names = ToSet(Launch.ManualIncludeWeapons); HashSet<string> names2 = ToSet(Launch.ManualIncludeArmors); int num = 0; int num2 = 0; int skippedNoIcon = 0; int skippedNoVisual = 0; for (int i = 0; i < instance.m_items.Count; i++) { GameObject prefab = instance.m_items[i]; if (!IsCandidatePrefab(prefab, exclude, out var drop, out var isWeapon, out var _, ref skippedNoIcon, ref skippedNoVisual)) { continue; } PieceCategory category = (PieceCategory)(isWeapon ? 6 : 5); if (PrepareBuildPiece(prefab, drop, templatePiece, templateWnt, templateSparkles, category) && EnsureInPieceTable(table, prefab)) { if (isWeapon) { num++; } else { num2++; } } } num += AddManualList(instance, table, names, exclude, templatePiece, templateWnt, templateSparkles, (PieceCategory)6, ref skippedNoIcon, ref skippedNoVisual); num2 += AddManualList(instance, table, names2, exclude, templatePiece, templateWnt, templateSparkles, (PieceCategory)5, ref skippedNoIcon, ref skippedNoVisual); Debug.Log((object)(Launch.projectName + $" WeaponCrate pieces ensured. Weapons={num} Armors={num2} Skipped(NoIcon)={skippedNoIcon} Skipped(NoVisual)={skippedNoVisual}")); } private static bool PrepareBuildPiece(GameObject prefab, ItemDrop drop, Piece templatePiece, WearNTear templateWnt, Transform templateSparkles, PieceCategory category) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) GameObject val = ItemUtils.PickVisualRoot(prefab); if ((Object)(object)val == (Object)null) { return false; } bool flag = false; ColliderSanitizer.SanitizeForBuildPiece(val, removeAllMeshColliders: false, debugLog: false, Launch.projectName); Piece val2 = prefab.GetComponent<Piece>(); if ((Object)(object)val2 == (Object)null) { val2 = prefab.AddComponent<Piece>(); } PieceNTearSetter.CopyPieceSettings(drop, val2, templatePiece); val2.m_category = category; val2.m_icon = ItemUtils.SafeFirstIcon(drop); val2.m_name = drop.m_itemData.m_shared.m_name; val2.m_description = drop.m_itemData.m_shared.m_description; bool flag2 = true; PieceNTearSetter.SetSingleRequirement(val2, ((Object)prefab).name, 1, 0, recover: true); WearNTear val3 = prefab.GetComponent<WearNTear>(); if ((Object)(object)val3 == (Object)null) { val3 = prefab.AddComponent<WearNTear>(); } PieceNTearSetter.CopyWearNTearSettings(val3, templateWnt); val3.m_new = val; val3.m_worn = val; val3.m_broken = val; if ((Object)(object)prefab.GetComponent<WeaponCrateRotatePatch.WeaponCratePieceMarker>() == (Object)null) { prefab.AddComponent<WeaponCrateRotatePatch.WeaponCratePieceMarker>(); } GameObject val4 = ItemVfxApplier.ApplySparklesAndCleanRoot(prefab, templateSparkles, debugLog: false, Launch.projectName); if ((Object)(object)val4 != (Object)null) { drop.m_pieceDisabledObj = val4; } GameObject val5 = FindEnabledObjectCandidate(prefab); if ((Object)(object)val5 != (Object)null) { drop.m_pieceEnableObj = val5; } bool flag3 = false; return true; } private static bool IsCandidatePrefab(GameObject prefab, HashSet<string> exclude, out ItemDrop drop, out bool isWeapon, out bool isArmor, ref int skippedNoIcon, ref int skippedNoVisual) { //IL_007d: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) drop = null; isWeapon = false; isArmor = false; if ((Object)(object)prefab == (Object)null) { return false; } if (exclude != null && exclude.Contains(((Object)prefab).name)) { return false; } drop = prefab.GetComponent<ItemDrop>(); if ((Object)(object)drop == (Object)null || drop.m_itemData == null || drop.m_itemData.m_shared == null) { return false; } ItemType itemType = drop.m_itemData.m_shared.m_itemType; isWeapon = ItemUtils.IsWeaponType(itemType, shieldsAreWeapons: true); isArmor = ItemUtils.IsArmorType(itemType, shieldsAreWeapons: true); if (!isWeapon && !isArmor) { return false; } if (!ItemUtils.HasAnyIcon(drop)) { skippedNoIcon++; return false; } if (!ItemUtils.HasUsableVisual(prefab)) { skippedNoVisual++; return false; } return true; } private static int AddManualList(ObjectDB db, PieceTable table, HashSet<string> names, HashSet<string> exclude, Piece templatePiece, WearNTear templateWnt, Transform templateSparkles, PieceCategory category, ref int skippedNoIcon, ref int skippedNoVisual) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if (names == null || names.Count == 0) { return 0; } int num = 0; foreach (string i in names) { if (!string.IsNullOrEmpty(i) && (exclude == null || !exclude.Contains(i))) { GameObject val = db.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == i); ItemDrop drop; bool isWeapon; bool isArmor; if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)(Launch.projectName + " Manual include not found: " + i)); } else if (IsCandidatePrefab(val, null, out drop, out isWeapon, out isArmor, ref skippedNoIcon, ref skippedNoVisual) && PrepareBuildPiece(val, drop, templatePiece, templateWnt, templateSparkles, category) && EnsureInPieceTable(table, val)) { num++; } } } return num; } private static bool EnsureInPieceTable(PieceTable table, GameObject prefab) { for (int i = 0; i < table.m_pieces.Count; i++) { GameObject val = table.m_pieces[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == ((Object)prefab).name) { return false; } } table.m_pieces.Add(prefab); return true; } private static bool TryGetCratePieceTable(ObjectDB db, string cratePrefabName, out PieceTable table) { table = null; if (string.IsNullOrEmpty(cratePrefabName)) { return false; } GameObject val = db.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == cratePrefabName); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)(Launch.projectName + " Weapon crate prefab not found in ObjectDB: " + cratePrefabName)); return false; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { Debug.LogWarning((object)(Launch.projectName + " Weapon crate ItemDrop/shared missing: " + cratePrefabName)); return false; } table = component.m_itemData.m_shared.m_buildPieces; if ((Object)(object)table == (Object)null) { Debug.LogWarning((object)(Launch.projectName + " Weapon crate has no PieceTable (m_buildPieces null): " + cratePrefabName)); return false; } if (table.m_pieces == null) { table.m_pieces = new List<GameObject>(); } return true; } private static GameObject FindEnabledObjectCandidate(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return null; } Transform val = ItemUtils.FindChildRecursiveByName(prefab.transform, "equiped"); if ((Object)(object)val == (Object)null) { val = ItemUtils.FindChildRecursiveByName(prefab.transform, "equipped"); } if ((Object)(object)val == (Object)null) { val = ItemUtils.FindChildRecursiveByName(prefab.transform, "effects"); } return ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null; } private static GameObject FindPrefabAny(string name) { if (string.IsNullOrEmpty(name)) { return null; } if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name); if ((Object)(object)itemPrefab != (Object)null) { return itemPrefab; } GameObject val = ObjectDB.instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == name); if ((Object)(object)val != (Object)null) { return val; } } if ((Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab(name); if ((Object)(object)prefab != (Object)null) { return prefab; } } return null; } private static bool TryResolveTemplateAll(string requestedName, out GameObject templateGo, out Piece templatePiece, out WearNTear templateWnt) { templateGo = null; templatePiece = null; templateWnt = null; string[] array = new string[5] { requestedName, "piece_chest_wood", "wood_wall", "wood_floor", "piece_chest" }; foreach (string text in array) { if (string.IsNullOrEmpty(text)) { continue; } GameObject val = FindPrefabAny(text); if (!((Object)(object)val == (Object)null)) { Piece component = val.GetComponent<Piece>(); WearNTear component2 = val.GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { templateGo = val; templatePiece = component; templateWnt = component2; bool flag = false; return true; } } } Debug.LogWarning((object)(Launch.projectName + " Could not resolve template Piece+WearNTear. Requested=" + requestedName)); return false; } private static HashSet<string> ToSet(string[] arr) { HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); if (arr == null) { return hashSet; } foreach (string text in arr) { if (!string.IsNullOrEmpty(text)) { hashSet.Add(text); } } return hashSet; } } } namespace LitJson2 { internal enum JsonType { None, Object, Array, String, Int, Long, Double, Boolean } internal interface IJsonWrapper : IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable { bool IsArray { get; } bool IsBoolean { get; } bool IsDouble { get; } bool IsInt { get; } bool IsLong { get; } bool IsObject { get; } bool IsString { get; } bool GetBoolean(); double GetDouble(); int GetInt(); JsonType GetJsonType(); long GetLong(); string GetString(); void SetBoolean(bool val); void SetDouble(double val); void SetInt(int val); void SetJsonType(JsonType type); void SetLong(long val); void SetString(string val); string ToJson(); void ToJson(JsonWriter writer); } internal class JsonData : IJsonWrapper, IList, IOrderedDictionary, IDictionary, ICollection, IEnumerable, IEquatable<JsonData> { private IList<JsonData> inst_array; private bool inst_boolean; private double inst_double; private int inst_int; private long inst_long; private IDictionary<string, JsonData> inst_object; private string inst_string; private string json; private JsonType type; private IList<KeyValuePair<string, JsonData>> object_list; public int Count => EnsureCollection().Count; public bool IsArray => type == JsonType.Array; public bool IsBoolean => type == JsonType.Boolean; public bool IsDouble => type == JsonType.Double; public bool IsInt => type == JsonType.Int; public bool IsLong => type == JsonType.Long; public bool IsObject => type == JsonType.Object; public bool IsString => type == JsonType.String; public ICollection<string> Keys { get { EnsureDictionary(); return inst_object.Keys; } } int ICollection.Count => Count; bool ICollection.IsSynchronized => EnsureCollection().IsSynchronized; object ICollection.SyncRoot => EnsureCollection().SyncRoot; bool IDictionary.IsFixedSize => EnsureDictionary().IsFixedSize; bool IDictionary.IsReadOnly => EnsureDictionary().IsReadOnly; ICollection IDictionary.Keys { get { EnsureDictionary(); IList<string> list = new List<string>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Key); } return (ICollection)list; } } ICollection IDictionary.Values { get { EnsureDictionary(); IList<JsonData> list = new List<JsonData>(); foreach (KeyValuePair<string, JsonData> item in object_list) { list.Add(item.Value); } return (ICollection)list; } } bool IJsonWrapper.IsArray => IsArray; bool IJsonWrapper.IsBoolean => IsBoolean; bool IJsonWrapper.IsDouble => IsDouble; bool IJsonWrapper.IsInt => IsInt; bool IJsonWrapper.IsLong => IsLong; bool IJsonWrapper.IsObject => IsObject; bool IJsonWrapper.IsString => IsString; bool IList.IsFixedSize => EnsureList().IsFixedSize; bool IList.IsReadOnly => EnsureList().IsReadOnly; object IDictionary.this[object key] { get { return EnsureDictionary()[key]; } set { if (!(key is string)) { throw new ArgumentException("The key has to be a string"); } JsonData value2 = ToJsonData(value); this[(string)key] = value2; } } object IOrderedDictionary.this[int idx] { get { EnsureDictionary(); return object_list[idx].Value; } set { EnsureDictionary(); JsonData value2 = ToJsonData(value); KeyValuePair<string, JsonData> keyValuePair = object_list[idx]; inst_object[keyValuePair.Key] = value2; KeyValuePair<string, JsonData> value3 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value2); object_list[idx] = value3; } } object IList.this[int index] { get { return EnsureList()[index]; } set { EnsureList(); JsonData value2 = ToJsonData(value); this[index] = value2; } } public JsonData this[string prop_name] { get { EnsureDictionary(); return inst_object[prop_name]; } set { EnsureDictionary(); KeyValuePair<string, JsonData> keyValuePair = new KeyValuePair<string, JsonData>(prop_name, value); if (inst_object.ContainsKey(prop_name)) { for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == prop_name) { object_list[i] = keyValuePair; break; } } } else { object_list.Add(keyValuePair); } inst_object[prop_name] = value; json = null; } } public JsonData this[int index] { get { EnsureCollection(); if (type == JsonType.Array) { return inst_array[index]; } return object_list[index].Value; } set { EnsureCollection(); if (type == JsonType.Array) { inst_array[index] = value; } else { KeyValuePair<string, JsonData> keyValuePair = object_list[index]; KeyValuePair<string, JsonData> value2 = new KeyValuePair<string, JsonData>(keyValuePair.Key, value); object_list[index] = value2; inst_object[keyValuePair.Key] = value; } json = null; } } public JsonData() { } public JsonData(bool boolean) { type = JsonType.Boolean; inst_boolean = boolean; } public JsonData(double number) { type = JsonType.Double; inst_double = number; } public JsonData(int number) { type = JsonType.Int; inst_int = number; } public JsonData(long number) { type = JsonType.Long; inst_long = number; } public JsonData(object obj) { if (obj is bool) { type = JsonType.Boolean; inst_boolean = (bool)obj; return; } if (obj is double) { type = JsonType.Double; inst_double = (double)obj; return; } if (obj is int) { type = JsonType.Int; inst_int = (int)obj; return; } if (obj is long) { type = JsonType.Long; inst_long = (long)obj; return; } if (obj is string) { type = JsonType.String; inst_string = (string)obj; return; } throw new ArgumentException("Unable to wrap the given object with JsonData"); } public JsonData(string str) { type = JsonType.String; inst_string = str; } public static implicit operator JsonData(bool data) { return new JsonData(data); } public static implicit operator JsonData(double data) { return new JsonData(data); } public static implicit operator JsonData(int data) { return new JsonData(data); } public static implicit operator JsonData(long data) { return new JsonData(data); } public static implicit operator JsonData(string data) { return new JsonData(data); } public static explicit operator bool(JsonData data) { if (data.type != JsonType.Boolean) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_boolean; } public static explicit operator double(JsonData data) { if (data.type != JsonType.Double) { throw new InvalidCastException("Instance of JsonData doesn't hold a double"); } return data.inst_double; } public static explicit operator int(JsonData data) { if (data.type != JsonType.Int) { throw new InvalidCastException("Instance of JsonData doesn't hold an int"); } return data.inst_int; } public static explicit operator long(JsonData data) { if (data.type != JsonType.Long) { throw new InvalidCastException("Instance of JsonData doesn't hold an int"); } return data.inst_long; } public static explicit operator string(JsonData data) { if (data.type != JsonType.String) { throw new InvalidCastException("Instance of JsonData doesn't hold a string"); } return data.inst_string; } void ICollection.CopyTo(Array array, int index) { EnsureCollection().CopyTo(array, index); } void IDictionary.Add(object key, object value) { JsonData value2 = ToJsonData(value); EnsureDictionary().Add(key, value2); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>((string)key, value2); object_list.Add(item); json = null; } void IDictionary.Clear() { EnsureDictionary().Clear(); object_list.Clear(); json = null; } bool IDictionary.Contains(object key) { return EnsureDictionary().Contains(key); } IDictionaryEnumerator IDictionary.GetEnumerator() { return ((IOrderedDictionary)this).GetEnumerator(); } void IDictionary.Remove(object key) { EnsureDictionary().Remove(key); for (int i = 0; i < object_list.Count; i++) { if (object_list[i].Key == (string)key) { object_list.RemoveAt(i); break; } } json = null; } IEnumerator IEnumerable.GetEnumerator() { return EnsureCollection().GetEnumerator(); } bool IJsonWrapper.GetBoolean() { if (type != JsonType.Boolean) { throw new InvalidOperationException("JsonData instance doesn't hold a boolean"); } return inst_boolean; } double IJsonWrapper.GetDouble() { if (type != JsonType.Double) { throw new InvalidOperationException("JsonData instance doesn't hold a double"); } return inst_double; } int IJsonWrapper.GetInt() { if (type != JsonType.Int) { throw new InvalidOperationException("JsonData instance doesn't hold an int"); } return inst_int; } long IJsonWrapper.GetLong() { if (type != JsonType.Long) { throw new InvalidOperationException("JsonData instance doesn't hold a long"); } return inst_long; } string IJsonWrapper.GetString() { if (type != JsonType.String) { throw new InvalidOperationException("JsonData instance doesn't hold a string"); } return inst_string; } void IJsonWrapper.SetBoolean(bool val) { type = JsonType.Boolean; inst_boolean = val; json = null; } void IJsonWrapper.SetDouble(double val) { type = JsonType.Double; inst_double = val; json = null; } void IJsonWrapper.SetInt(int val) { type = JsonType.Int; inst_int = val; json = null; } void IJsonWrapper.SetLong(long val) { type = JsonType.Long; inst_long = val; json = null; } void IJsonWrapper.SetString(string val) { type = JsonType.String; inst_string = val; json = null; } string IJsonWrapper.ToJson() { return ToJson(); } void IJsonWrapper.ToJson(JsonWriter writer) { ToJson(writer); } int IList.Add(object value) { return Add(value); } void IList.Clear() { EnsureList().Clear(); json = null; } bool IList.Contains(object value) { return EnsureList().Contains(value); } int IList.IndexOf(object value) { return EnsureList().IndexOf(value); } void IList.Insert(int index, object value) { EnsureList().Insert(index, value); json = null; } void IList.Remove(object value) { EnsureList().Remove(value); json = null; } void IList.RemoveAt(int index) { EnsureList().RemoveAt(index); json = null; } IDictionaryEnumerator IOrderedDictionary.GetEnumerator() { EnsureDictionary(); return new OrderedDictionaryEnumerator(object_list.GetEnumerator()); } void IOrderedDictionary.Insert(int idx, object key, object value) { string text = (string)key; JsonData value2 = (this[text] = ToJsonData(value)); KeyValuePair<string, JsonData> item = new KeyValuePair<string, JsonData>(text, value2); object_list.Insert(idx, item); } void IOrderedDictionary.RemoveAt(int idx) { EnsureDictionary(); inst_object.Remove(object_list[idx].Key); object_list.RemoveAt(idx); } private ICollection EnsureCollection() { if (type == JsonType.Array) { return (ICollection)inst_array; } if (type == JsonType.Object) { return (ICollection)inst_object; } throw new InvalidOperationException("The JsonData instance has to be initialized first"); } private IDictionary EnsureDictionary() { if (type == JsonType.Object) { return (IDictionary)inst_object; } if (type != 0) { throw new InvalidOperationException("Instance of JsonData is not a dictionary"); } type = JsonType.Object; inst_object = new Dictionary<string, JsonData>(); object_list = new List<KeyValuePair<string, JsonData>>(); return (IDictionary)inst_object; } private IList EnsureList() { if (type == JsonType.Array) { return (IList)inst_array; } if (type != 0) { throw new InvalidOperationException("Instance of JsonData is not a list"); } type = JsonType.Array; inst_array = new List<JsonData>(); return (IList)inst_array; } private JsonData ToJsonData(object obj) { if (obj == null) { return null; } if (obj is JsonData) { return (JsonData)obj; } return new JsonData(obj); } private static void WriteJson(IJsonWrapper obj, JsonWriter writer) { if (obj == null) { writer.Write(null); } else if (obj.IsString) { writer.Write(obj.GetString()); } else if (obj.IsBoolean) { writer.Write(obj.GetBoolean()); } else if (obj.IsDouble) { writer.Write(obj.GetDouble()); } else if (obj.IsInt) { writer.Write(obj.GetInt()); } else if (obj.IsLong) { writer.Write(obj.GetLong()); } else if (obj.IsArray) { writer.WriteArrayStart(); foreach (object item in (IEnumerable)obj) { WriteJson((JsonData)item, writer); } writer.WriteArrayEnd(); } else { if (!obj.IsObject) { return; } writer.WriteObjectStart(); foreach (DictionaryEntry item2 in (IDictionary)obj) { writer.WritePropertyName((string)item2.Key); WriteJson((JsonData)item2.Value, writer); } writer.WriteObjectEnd(); } } public int Add(object value) { JsonData value2 = ToJsonData(value); json = null; return EnsureList().Add(value2); } public void Clear() { if (IsObject) { ((IDictionary)this).Clear(); } else if (IsArray) { ((IList)this).Clear(); } } public bool Equals(JsonData x) { if (x == null) { return false; } if (x.type != type) { return false; } return type switch { JsonType.None => true, JsonType.Object => inst_object.Equals(x.inst_object), JsonType.Array => inst_array.Equals(x.inst_array), JsonType.String => inst_string.Equals(x.inst_string), JsonType.Int => inst_int.Equals(x.inst_int), JsonType.Long => inst_long.Equals(x.inst_long), JsonType.Double => inst_double.Equals(x.inst_double), JsonType.Boolean => inst_boolean.Equals(x.inst_boolean), _ => false, }; } public JsonType GetJsonType() { return type; } public void SetJsonType(JsonType type) { if (this.type != type) { switch (type) { case JsonType.Object: inst_object = new Dictionary<string, JsonData>(); object_list = new List<KeyValuePair<string, JsonData>>(); break; case JsonType.Array: inst_array = new List<JsonData>(); break; case JsonType.String: inst_string = null; break; case JsonType.Int: inst_int = 0; break; case JsonType.Long: inst_long = 0L; break; case JsonType.Double: inst_double = 0.0; break; case JsonType.Boolean: inst_boolean = false; break; } this.type = type; } } public string ToJson() { if (json != null) { return json; } StringWriter stringWriter = new StringWriter(); JsonWriter jsonWriter = new JsonWriter(stringWriter); jsonWriter.Validate = false; WriteJson(this, jsonWriter); json = stringWriter.ToString(); return json; } public void ToJson(JsonWriter writer) { bool validate = writer.Validate; writer.Validate = false; WriteJson(this, writer); writer.Validate = validate; } public override string ToString() { return type switch { JsonType.Array => "JsonData array", JsonType.Boolean => inst_boolean.ToString(), JsonType.Double => inst_double.ToString(), JsonType.Int => inst_int.ToString(), JsonType.Long => inst_long.ToString(), JsonType.Object => "JsonData object", JsonType.String => inst_string, _ => "Uninitialized JsonData", }; } } internal class OrderedDictionaryEnumerator : IDictionaryEnumerator, IEnumerator { private IEnumerator<KeyValuePair<string, JsonData>> list_enumerator; public object Current => Entry; public DictionaryEntry Entry { get { KeyValuePair<string, JsonData> current = list_enumerator.Current; return new DictionaryEntry(current.Key, current.Value); } } public object Key => list_enumerator.Current.Key; public object Value => list_enumerator.Current.Value; public OrderedDictionaryEnumerator(IEnumerator<KeyValuePair<string, JsonData>> enumerator) { list_enumerator = enumerator; } public bool MoveNext() { return list_enumerator.MoveNext(); } public void Reset() { list_enumerator.Reset(); } } internal class JsonException : ApplicationException { public JsonException() { } internal JsonException(ParserToken token) : base($"Invalid token '{token}' in input string") { } internal JsonException(ParserToken token, Exception inner_exception) : base($"Invalid token '{token}' in input string", inner_exception) { } internal JsonException(int c) : base($"Invalid character '{(char)c}' in input string") { } internal JsonException(int c, Exception inner_exception) : base($"Invalid character '{(char)c}' in input string", inner_exception) { } public JsonException(string message) : base(message) { } public JsonException(string message, Exception inner_exception) : base(message, inner_exception) { } } internal struct PropertyMetadata { public MemberInfo Info; public bool IsField; public Type Type; } internal struct ArrayMetadata { private Type element_type; private bool is_array; private bool is_list; public Type ElementType { get { if (element_type == null) { return typeof(JsonData); } return element_type; } set { element_type = value; } } public bool IsArray { get { return is_array; } set { is_array = value; } } public bool IsList { get { return is_list; } set { is_list = value; } } } internal struct ObjectMetadata { private Type element_type; private bool is_dictionary; private IDictionary<string, PropertyMetadata> properties; public Type ElementType { get { if (element_type == null) { return typeof(JsonData); } return element_type; } set { element_type = value; } } public bool IsDictionary { get { return is_dictionary; } set { is_dictionary = value; } } public IDictionary<string, PropertyMetadata> Properties { get { return properties; } set { properties = value; } } } internal delegate void ExporterFunc(object obj, JsonWriter writer); internal delegate void ExporterFunc<T>(T obj, JsonWriter writer); internal delegate object ImporterFunc(object input); internal delegate TValue ImporterFunc<TJson, TValue>(TJson input); internal delegate IJsonWrapper WrapperFactory(); internal class JsonMapper { private static int max_nesting_depth; private static IFormatProvider datetime_format; private static IDictionary<Type, ExporterFunc> base_exporters_table; private static IDictionary<Type, ExporterFunc> custom_exporters_table; private static IDictionary<Type, IDictionary<Type, ImporterFunc>> base_importers_table; private static IDictionary<Type, IDictionary<Type, ImporterFunc>> custom_importers_table; private static IDictionary<Type, ArrayMetadata> array_metadata; private static readonly object array_metadata_lock; private static IDictionary<Type, IDictionary<Type, MethodInfo>> conv_ops; private static readonly object conv_ops_lock; private static IDictionary<Type, ObjectMetadata> object_metadata; private static readonly object object_metadata_lock; private static IDictionary<Type, IList<PropertyMetadata>> type_properties; private static readonly object type_properties_lock; private static JsonWriter static_writer; private static readonly object static_writer_lock; static JsonMapper() { array_metadata_lock = new object(); conv_ops_lock = new object(); object_metadata_lock = new object(); type_properties_lock = new object(); static_writer_lock = new object(); max_nesting_depth = 100; array_metadata = new Dictionary<Type, ArrayMetadata>(); conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>>(); object_metadata = new Dictionary<Type, ObjectMetadata>(); type_properties = new Dictionary<Type, IList<PropertyMetadata>>(); static_writer = new JsonWriter(); datetime_format = DateTimeFormatInfo.InvariantInfo; base_exporters_table = new Dictionary<Type, ExporterFunc>(); custom_exporters_table = new Dictionary<Type, ExporterFunc>(); base_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>(); custom_importers_table = new Dictionary<Type, IDictionary<Type, ImporterFunc>>(); RegisterBaseExporters(); RegisterBaseImporters(); } private static void AddArrayMetadata(Type type) { if (array_metadata.ContainsKey(type)) { return; } ArrayMetadata value = default(ArrayMetadata); value.IsArray = type.IsArray; if (type.GetInterface("System.Collections.IList") != null) { value.IsList = true; } PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.Name != "Item")) { ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters(); if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(int)) { value.ElementType = propertyInfo.PropertyType; } } } lock (array_metadata_lock) { try { array_metadata.Add(type, value); } catch (ArgumentException) { } } } private static void AddObjectMetadata(Type type) { if (object_metadata.ContainsKey(type)) { return; } ObjectMetadata value = default(ObjectMetadata); if (type.GetInterface("System.Collections.IDictionary") != null) { value.IsDictionary = true; } value.Properties = new Dictionary<string, PropertyMetadata>(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.Name == "Item") { ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters(); if (indexParameters.Length == 1 && indexParameters[0].ParameterType == typeof(string)) { value.ElementType = propertyInfo.PropertyType; } } else { PropertyMetadata value2 = default(PropertyMetadata); value2.Info = propertyInfo; value2.Type = propertyInfo.PropertyType; value.Properties.Add(propertyInfo.Name, value2); } } FieldInfo[] fields = type.GetFields(); foreach (FieldInfo fieldInfo in fields) { PropertyMetadata value3 = default(PropertyMetadata); value3.Info = fieldInfo; value3.IsField = true; value3.Type = fieldInfo.FieldType; value.Properties.Add(fieldInfo.Name, value3); } lock (object_metadata_lock) { try { object_metadata.Add(type, value); } catch (ArgumentException) { } } } private static void AddTypeProperties(Type type) { if (type_properties.ContainsKey(type)) { return; } IList<PropertyMetadata> list = new List<PropertyMetadata>(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.Name == "Item")) { PropertyMetadata item = default(PropertyMetadata); item.Info = propertyInfo; item.IsField = false; list.Add(item); } } FieldInfo[] fields = type.GetFields(); foreach (FieldInfo info in fields) { PropertyMetadata item2 = default(PropertyMetadata); item2.Info = info; item2.IsField = true; list.Add(item2); } lock (type_properties_lock) { try { type_properties.Add(type, list); } catch (ArgumentException) { } } } private static MethodInfo GetConvOp(Type t1, Type t2) { lock (conv_ops_lock) { if (!conv_ops.ContainsKey(t1)) { conv_ops.Add(t1, new Dictionary<Type, MethodInfo>()); } } if (conv_ops[t1].ContainsKey(t2)) { return conv_ops[t1][t2]; } MethodInfo method = t1.GetMethod("op_Implicit", new Type[1] { t2 }); lock (conv_ops_lock) { try { conv_ops[t1].Add(t2, method); return method; } catch (ArgumentException) { return conv_ops[t1][t2]; } } } private static object ReadValue(Type inst_type, JsonReader reader) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd) { return null; } Type underlyingType = Nullable.GetUnderlyingType(inst_type); Type type = underlyingType ?? inst_type; if (reader.Token == JsonToken.Null) { if (inst_type.IsClass || underlyingType != null) { return null; } throw new JsonException($"Can't assign null to an instance of type {inst_type}"); } if (reader.Token == JsonToken.Double || reader.Token == JsonToken.Int || reader.Token == JsonToken.Long || reader.Token == JsonToken.String || reader.Token == JsonToken.Boolean) { Type type2 = reader.Value.GetType(); if (type.IsAssignableFrom(type2)) { return reader.Value; } if (custom_importers_table.ContainsKey(type2) && custom_importers_table[type2].ContainsKey(type)) { ImporterFunc importerFunc = custom_importers_table[type2][type]; return importerFunc(reader.Value); } if (base_importers_table.ContainsKey(type2) && base_importers_table[type2].ContainsKey(type)) { ImporterFunc importerFunc2 = base_importers_table[type2][type]; return importerFunc2(reader.Value); } if (type.IsEnum) { return Enum.ToObject(type, reader.Value); } MethodInfo convOp = GetConvOp(type, type2); if (convOp != null) { return convOp.Invoke(null, new object[1] { reader.Value }); } throw new JsonException($"Can't assign value '{reader.Value}' (type {type2}) to type {inst_type}"); } object obj = null; if (reader.Token == JsonToken.ArrayStart) { AddArrayMetadata(inst_type); ArrayMetadata arrayMetadata = array_metadata[inst_type]; if (!arrayMetadata.IsArray && !arrayMetadata.IsList) { throw new JsonException($"Type {inst_type} can't act as an array"); } IList list; Type elementType; if (!arrayMetadata.IsArray) { list = (IList)Activator.CreateInstance(inst_type); elementType = arrayMetadata.ElementType; } else { list = new ArrayList(); elementType = inst_type.GetElementType(); } while (true) { object obj2 = ReadValue(elementType, reader); if (obj2 == null && reader.Token == JsonToken.ArrayEnd) { break; } list.Add(obj2); } if (arrayMetadata.IsArray) { int count = list.Count; obj = Array.CreateInstance(elementType, count); for (int i = 0; i < count; i++) { ((Array)obj).SetValue(list[i], i); } } else { obj = list; } } else if (reader.Token == JsonToken.ObjectStart) { AddObjectMetadata(type); ObjectMetadata objectMetadata = object_metadata[type]; obj = Activator.CreateInstance(type); while (true) { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { break; } string text = (string)reader.Value; if (objectMetadata.Properties.ContainsKey(text)) { PropertyMetadata propertyMetadata = objectMetadata.Properties[text]; if (propertyMetadata.IsField) { ((FieldInfo)propertyMetadata.Info).SetValue(obj, ReadValue(propertyMetadata.Type, reader)); continue; } PropertyInfo propertyInfo = (PropertyInfo)propertyMetadata.Info; if (propertyInfo.CanWrite) { propertyInfo.SetValue(obj, ReadValue(propertyMetadata.Type, reader), null); } else { ReadValue(propertyMetadata.Type, reader); } } else if (!objectMetadata.IsDictionary) { if (!reader.SkipNonMembers) { throw new JsonException($"The type {inst_type} doesn't have the property '{text}'"); } ReadSkip(reader); } else { ((IDictionary)obj).Add(text, ReadValue(objectMetadata.ElementType, reader)); } } } return obj; } private static IJsonWrapper ReadValue(WrapperFactory factory, JsonReader reader) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd || reader.Token == JsonToken.Null) { return null; } IJsonWrapper jsonWrapper = factory(); if (reader.Token == JsonToken.String) { jsonWrapper.SetString((string)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Double) { jsonWrapper.SetDouble((double)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Int) { jsonWrapper.SetInt((int)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Long) { jsonWrapper.SetLong((long)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.Boolean) { jsonWrapper.SetBoolean((bool)reader.Value); return jsonWrapper; } if (reader.Token == JsonToken.ArrayStart) { jsonWrapper.SetJsonType(JsonType.Array); while (true) { IJsonWrapper jsonWrapper2 = ReadValue(factory, reader); if (jsonWrapper2 == null && reader.Token == JsonToken.ArrayEnd) { break; } jsonWrapper.Add(jsonWrapper2); } } else if (reader.Token == JsonToken.ObjectStart) { jsonWrapper.SetJsonType(JsonType.Object); while (true) { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { break; } string key = (string)reader.Value; jsonWrapper[key] = ReadValue(factory, reader); } } return jsonWrapper; } private static void ReadSkip(JsonReader reader) { ToWrapper(() => new JsonMockWrapper(), reader); } private static void RegisterBaseExporters() { base_exporters_table[typeof(byte)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((byte)obj)); }; base_exporters_table[typeof(char)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToString((char)obj)); }; base_exporters_table[typeof(DateTime)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToString((DateTime)obj, datetime_format)); }; base_exporters_table[typeof(decimal)] = delegate(object obj, JsonWriter writer) { writer.Write((decimal)obj); }; base_exporters_table[typeof(sbyte)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((sbyte)obj)); }; base_exporters_table[typeof(short)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((short)obj)); }; base_exporters_table[typeof(ushort)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToInt32((ushort)obj)); }; base_exporters_table[typeof(uint)] = delegate(object obj, JsonWriter writer) { writer.Write(Convert.ToUInt64((uint)obj)); }; base_exporters_table[typeof(ulong)] = delegate(object obj, JsonWriter writer) { writer.Write((ulong)obj); }; } private static void RegisterBaseImporters() { ImporterFunc importer = (object input) => Convert.ToByte((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(byte), importer); importer = (object input) => Convert.ToUInt64((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(ulong), importer); importer = (object input) => Convert.ToSByte((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(sbyte), importer); importer = (object input) => Convert.ToInt16((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(short), importer); importer = (object input) => Convert.ToUInt16((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(ushort), importer); importer = (object input) => Convert.ToUInt32((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(uint), importer); importer = (object input) => Convert.ToSingle((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(float), importer); importer = (object input) => Convert.ToDouble((int)input); RegisterImporter(base_importers_table, typeof(int), typeof(double), importer); importer = (object input) => Convert.ToDecimal((double)input); RegisterImporter(base_importers_table, typeof(double), typeof(decimal), importer); importer = (object input) => Convert.ToUInt32((long)input); RegisterImporter(base_importers_table, typeof(long), typeof(uint), importer); importer = (object input) => Convert.ToChar((string)input); RegisterImporter(base_importers_table, typeof(string), typeof(char), importer); importer = (object input) => Convert.ToDateTime((string)input, datetime_format); RegisterImporter(base_importers_table, typeof(string), typeof(DateTime), importer); } private static void RegisterImporter(IDictionary<Type, IDictionary<Type, ImporterFunc>> table, Type json_type, Type value_type, ImporterFunc importer) { if (!table.ContainsKey(json_type)) { table.Add(json_type, new Dictionary<Type, ImporterFunc>()); } table[json_type][value_type] = importer; } private static void WriteValue(object obj, JsonWriter writer, bool writer_is_private, int depth) { if (depth > max_nesting_depth) { throw new JsonException($"Max allowed object depth reached while trying to export from type {obj.GetType()}"); } if (obj == null) { writer.Write(null); return; } if (obj is IJsonWrapper) { if (writer_is_private) { writer.TextWriter.Write(((IJsonWrapper)obj).ToJson()); } else { ((IJsonWrapper)obj).ToJson(writer); } return; } if (obj is string) { writer.Write((string)obj); return; } if (obj is double) { writer.Write((double)obj); return; } if (obj is int) { writer.Write((int)obj); return; } if (obj is bool) { writer.Write((bool)obj); return; } if (obj is long) { writer.Write((long)obj); return; } if (obj is Array) { writer.WriteArrayStart(); foreach (object item in (Array)obj) { WriteValue(item, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IList) { writer.WriteArrayStart(); foreach (object item2 in (IList)obj) { WriteValue(item2, writer, writer_is_private, depth + 1); } writer.WriteArrayEnd(); return; } if (obj is IDictionary) { writer.WriteObjectStart(); foreach (DictionaryEntry item3 in (IDictionary)obj) { writer.WritePropertyName((string)item3.Key); WriteValue(item3.Value, writer, writer_is_private, depth + 1); } writer.WriteObjectEnd(); return; } Type type = obj.GetType(); if (custom_exporters_table.ContainsKey(type)) { ExporterFunc exporterFunc = custom_exporters_table[type]; exporterFunc(obj, writer); return; } if (base_exporters_table.ContainsKey(type)) { ExporterFunc exporterFunc2 = base_exporters_table[type]; exporterFunc2(obj, writer); return; } if (obj is Enum) { Type underlyingType = Enum.GetUnderlyingType(type); if (underlyingType == typeof(long) || underlyingType == typeof(uint) || underlyingType == typeof(ulong)) { writer.Write((ulong)obj); } else { writer.Write((int)obj); } return; } AddTypeProperties(type); IList<PropertyMetadata> list = type_properties[t