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 balrond bundling machine v1.0.2
plugins/BalrondPackager.dll
Decompiled an hour 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 BalrondPackager; 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("BalrondPackager")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BalrondPackager")] [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] public static class BalrondHashCompat { private static readonly MethodInfo _getStableHashCodeStringBool; private static readonly MethodInfo _getStableHashCodeString; private static readonly bool _initialized; static BalrondHashCompat() { try { Type typeFromHandle = typeof(StringExtensionMethods); _getStableHashCodeStringBool = typeFromHandle.GetMethod("GetStableHashCode", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(bool) }, null); _getStableHashCodeString = typeFromHandle.GetMethod("GetStableHashCode", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); _initialized = true; } catch { _initialized = false; } } public static int StableHash(string value) { if (value == null) { return 0; } try { if (_getStableHashCodeStringBool != null) { return (int)_getStableHashCodeStringBool.Invoke(null, new object[2] { value, false }); } if (_getStableHashCodeString != null) { return (int)_getStableHashCodeString.Invoke(null, new object[1] { value }); } } catch { } return FallbackStableHash(value); } private static int FallbackStableHash(string value) { int num = 5381; int num2 = num; for (int i = 0; i < value.Length; i += 2) { num = ((num << 5) + num) ^ value[i]; if (i == value.Length - 1) { break; } num2 = ((num2 << 5) + num2) ^ value[i + 1]; } return num + num2 * 1566083941; } } public class BalrondUnpackager : MonoBehaviour, Hoverable, Interactable { private const string PackageAmountKey = "BalrondPackageAmount"; private const string PackageIndexPrefix = "BalrondPackageIndex-"; private const string PackagePrefabName = "CustomPackageItem_bal"; public string m_name = "$tag_unpackager_bal"; public string m_useItemText = "$tag_use_me"; public ItemDrop m_requiredItem; public Transform m_itemSpawnPoint; public float m_SpawnDelay = 2f; [Header("Effects")] public EffectList m_spawnStartEffects = new EffectList(); public EffectList m_spawnFinishEffects = new EffectList(); public Transform m_roofCheckPoint; public bool m_requiresRoof; private ZNetView m_nview; private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)m_nview == (Object)null || m_nview.GetZDO() == null) { ZLog.Log((object)"Missing ZNetView Component"); } else if ((Object)(object)m_requiredItem == (Object)null) { m_requiredItem = FindRequiredItem(); } } private static ItemDrop FindRequiredItem() { if ((Object)(object)ZNetScene.instance == (Object)null || ZNetScene.instance.m_prefabs == null) { return null; } GameObject val = ZNetScene.instance.m_prefabs.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == "CustomPackageItem_bal"); return ((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null; } public string GetHoverText() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return Localization.instance.Localize(m_name + "\n$piece_noaccess"); } string text = string.Empty; if ((Object)(object)m_requiredItem != (Object)null && m_requiredItem.m_itemData != null && m_requiredItem.m_itemData.m_shared != null) { text = Localization.instance.Localize(m_requiredItem.m_itemData.m_shared.m_name); } return Localization.instance.Localize(m_name + "\n[<color=yellow><b>1-8</b></color>] \n" + m_useItemText) + " " + text; } public string GetHoverName() { return m_name; } public bool Interact(Humanoid user, bool hold, bool alt) { return true; } public bool UseItem(Humanoid user, ItemData item) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)user != (Object)(object)Player.m_localPlayer) { return true; } if ((Object)(object)user == (Object)null || item == null || (Object)(object)item.m_dropPrefab == (Object)null) { return true; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if ((Object)(object)m_requiredItem == (Object)null || !((Object)item.m_dropPrefab).name.Contains(((Object)m_requiredItem).name)) { ((Character)user).Message((MessageType)2, "$tag_cant_unpack", 0, (Sprite)null); return true; } if ((Object)(object)m_itemSpawnPoint != (Object)null) { m_spawnStartEffects.Create(m_itemSpawnPoint.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); SpawnItems(item); m_spawnFinishEffects.Create(m_itemSpawnPoint.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } ((Character)user).ShowRemovedMessage(item, 1); user.GetInventory().RemoveItem(item); ((Character)user).Message((MessageType)2, "$tag_unpacked_it", 0, (Sprite)null); return true; } public bool CheckUsable(Player player, bool showMessage) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } if (m_requiresRoof && !player.NoCostCheat()) { if ((Object)(object)m_roofCheckPoint == (Object)null) { return false; } float num = default(float); bool flag = default(bool); Cover.GetCoverForPoint(m_roofCheckPoint.position, ref num, ref flag, 0.5f); if (!flag) { if (showMessage) { ((Character)player).Message((MessageType)2, "$msg_stationneedroof", 0, (Sprite)null); } return false; } if (num < 0.7f) { if (showMessage) { ((Character)player).Message((MessageType)2, "$msg_stationtooexposed", 0, (Sprite)null); } return false; } } return true; } private Vector3 GetSpawnPosition() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_002a: Unknown result type (might be due to invalid IL or missing references) return ((Object)(object)m_itemSpawnPoint != (Object)null) ? m_itemSpawnPoint.position : ((Component)this).transform.position; } private void SpawnItems(ItemData itemData) { if (itemData == null || itemData.m_customData == null || !itemData.m_customData.TryGetValue("BalrondPackageAmount", out var value) || !int.TryParse(value, out var result) || result <= 0) { return; } for (int i = 0; i < result; i++) { if (itemData.m_customData.TryGetValue("BalrondPackageIndex-" + i, out var value2)) { SpawnPackedItem(value2); } } } private void SpawnPackedItem(string itemString) { //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(itemString)) { return; } int num = itemString.LastIndexOf('.'); if (num <= 0 || num >= itemString.Length - 1) { Debug.LogWarning((object)(Launch.projectName + ": Invalid package item data: " + itemString)); return; } string itemName = itemString.Substring(0, num); string s = itemString.Substring(num + 1); if (!int.TryParse(s, out var result) || result <= 0) { Debug.LogWarning((object)(Launch.projectName + ": Invalid package stack amount: " + itemString)); } else { if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null) { return; } GameObject val = ObjectDB.instance.m_items.Find((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == itemName); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)(Launch.projectName + ": Packed item prefab not found: " + itemName)); return; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)(Launch.projectName + ": Packed item prefab has no ItemDrop: " + itemName)); return; } ItemDrop val2 = Object.Instantiate<ItemDrop>(component, GetSpawnPosition(), Quaternion.identity); val2.m_itemData.m_stack = result; } } } namespace BalrondPackager { 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 class BalrondPackager2 : MonoBehaviour { public enum Response { Fail, Success, Conversion, Empty } public Switch m_incinerateSwitch; public Container m_container; public Animator m_leverAnim; public EffectList m_leverEffects = new EffectList(); public float m_effectDelayMin = 10f; public float m_effectDelayMax = 15f; [Header("Conversion")] public ItemDrop m_defaultResult; public int m_defaultCost = 1; private ZNetView m_nview; private bool isInUse; public Transform output; public GameObject m_enabled; public EffectList m_produceEffects = new EffectList(); private void Awake() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown Switch incinerateSwitch = m_incinerateSwitch; incinerateSwitch.m_onUse = (Callback)Delegate.Combine((Delegate?)(object)incinerateSwitch.m_onUse, (Delegate?)new Callback(OnIncinerate)); Switch incinerateSwitch2 = m_incinerateSwitch; incinerateSwitch2.m_onHover = (TooltipCallback)Delegate.Combine((Delegate?)(object)incinerateSwitch2.m_onHover, (Delegate?)new TooltipCallback(GetLeverHoverText)); m_nview = ((Component)this).GetComponent<ZNetView>(); if (!((Object)(object)m_nview == (Object)null) && m_nview.GetZDO() != null) { m_nview.Register<long>("RPC_RequestPackage", (Action<long, long>)RPC_RequestPackage); m_nview.Register<int>("RPC_PackageRespons", (Action<long, int>)RPC_PackageRespons); m_nview.Register("RPC_AnimateLever", (Action<long>)RPC_AnimateLever); m_nview.Register("RPC_AnimateLeverReturn", (Action<long>)RPC_AnimateLeverReturn); if ((Object)(object)m_enabled != (Object)null) { m_enabled.SetActive(false); } } } private void StopAOE() { isInUse = false; } public string GetLeverHoverText() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return Localization.instance.Localize("$piece_packager\n$piece_noaccess"); } return Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] $piece_pulllever"); } private bool OnIncinerate(Switch sw, Humanoid user, ItemData item) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || !m_nview.HasOwner() || !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return false; } m_nview.InvokeRPC("RPC_RequestPackage", new object[1] { Game.instance.GetPlayerProfile().GetPlayerID() }); return true; } private void RPC_RequestPackage(long uid, long playerID) { if (!m_nview.IsOwner()) { m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { 0 }); return; } if (m_container.IsInUse() || isInUse) { m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { 0 }); return; } Inventory inventory = m_container.GetInventory(); if (inventory.NrOfItems() == 0) { m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { 3 }); } else { ((MonoBehaviour)this).StartCoroutine(Package(uid)); } } private IEnumerator Package(long uid) { isInUse = true; m_nview.InvokeRPC(ZNetView.Everybody, "RPC_AnimateLever", Array.Empty<object>()); m_leverEffects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); if ((Object)(object)m_enabled != (Object)null) { m_enabled.SetActive(true); } yield return (object)new WaitForSeconds(Random.Range(m_effectDelayMin, m_effectDelayMax)); m_nview.InvokeRPC(ZNetView.Everybody, "RPC_AnimateLeverReturn", Array.Empty<object>()); if ((Object)(object)m_enabled != (Object)null) { m_enabled.SetActive(false); } if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || !m_nview.IsOwner() || m_container.IsInUse()) { isInUse = false; yield break; } ((MonoBehaviour)this).Invoke("StopAOE", 4f); Inventory inventory = m_container.GetInventory(); List<ItemData> items = inventory.GetAllItems(); int responseCode = 1; if (items.Count == 0) { responseCode = 3; } string description = "Contains: \n"; ItemData invalidItem = null; ItemDrop package = Object.Instantiate<ItemDrop>(m_defaultResult, output.position, output.rotation); m_produceEffects.Create(output.position, output.rotation, (Transform)null, 1f, -1); package.m_itemData.m_customData.Add("BalrondPackageAmount", items.Count.ToString()); bool teleportable = true; int counter = 0; float totalWeight = 0f; foreach (ItemData item in items) { if (!ValidateItemType(item.m_shared.m_itemType) || ((Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name.Contains("CustomPackageItem_bal"))) { responseCode = 99; invalidItem = item; break; } description += $"{item.m_shared.m_name} x{item.m_stack}\n"; totalWeight += item.m_shared.m_weight * (float)item.m_stack; package.m_itemData.m_customData.Add("BalrondPackageIndex-" + counter, ((Object)item.m_dropPrefab).name + "." + item.m_stack); if (!item.m_shared.m_teleportable) { teleportable = false; } counter++; } if (responseCode == 1) { float finalWeight = totalWeight / 2f; package.m_itemData.m_customData.Add("BalrondPackageDescription", description); package.m_itemData.m_customData.Add("BalrondPackageWeight", finalWeight.ToString()); package.m_itemData.m_customData.Add("BalrondPackageTeleportable", teleportable ? "1" : "0"); package.m_itemData.m_shared.m_description = description; package.m_itemData.m_shared.m_teleportable = teleportable; package.m_itemData.m_shared.m_weight = finalWeight; package.Save(); inventory.RemoveAll(); } else { Object.DestroyImmediate((Object)(object)((Component)package).gameObject); if (invalidItem != null) { Debug.Log((object)("Can't make bundle - wrong item: " + ((Object)invalidItem.m_dropPrefab).name)); } } m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { responseCode }); isInUse = false; } private bool ValidateItemType(ItemType itemType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 return (int)itemType == 1 || (int)itemType == 2 || (int)itemType == 9 || (int)itemType == 16 || (int)itemType == 13; } private void RPC_PackageRespons(long uid, int responseCode) { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { string text = "$piece_packager_fail"; switch (responseCode) { case 1: text = "$piece_packager_success"; break; case 2: text = "$piece_packager_conversion"; break; case 3: text = "$piece_packager_empty"; break; } ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null); } } private void RPC_AnimateLever(long uid) { ZLog.Log((object)"Animating lever!"); if ((Object)(object)m_leverAnim != (Object)null) { m_leverAnim.SetBool("Pulled", true); } } private void RPC_AnimateLeverReturn(long uid) { ZLog.Log((object)"Lever returning"); if ((Object)(object)m_leverAnim != (Object)null) { m_leverAnim.SetBool("Pulled", false); } } } public class BalrondPackager : MonoBehaviour { public enum Response { Fail, Success, Conversion, Empty } private const string PackageAmountKey = "BalrondPackageAmount"; private const string PackageDescriptionKey = "BalrondPackageDescription"; private const string PackageWeightKey = "BalrondPackageWeight"; private const string PackageTeleportableKey = "BalrondPackageTeleportable"; private const string PackageIndexPrefix = "BalrondPackageIndex-"; private const string PackagePrefabName = "CustomPackageItem_bal"; public Switch m_incinerateSwitch; public Container m_container; public Animator m_leverAnim; public EffectList m_leverEffects = new EffectList(); public float m_effectDelayMin = 10f; public float m_effectDelayMax = 15f; [Header("Conversion")] public ItemDrop m_defaultResult; public int m_defaultCost = 1; public Transform output; public GameObject m_enabled; public EffectList m_produceEffects = new EffectList(); private ZNetView m_nview; private bool isInUse; private void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown if ((Object)(object)m_incinerateSwitch != (Object)null) { Switch incinerateSwitch = m_incinerateSwitch; incinerateSwitch.m_onUse = (Callback)Delegate.Combine((Delegate?)(object)incinerateSwitch.m_onUse, (Delegate?)new Callback(OnIncinerate)); Switch incinerateSwitch2 = m_incinerateSwitch; incinerateSwitch2.m_onHover = (TooltipCallback)Delegate.Combine((Delegate?)(object)incinerateSwitch2.m_onHover, (Delegate?)new TooltipCallback(GetLeverHoverText)); } else { Debug.LogWarning((object)(Launch.projectName + ": Missing Switch on packager: " + ((Object)((Component)this).gameObject).name)); } m_nview = ((Component)this).GetComponent<ZNetView>(); if (!((Object)(object)m_nview == (Object)null) && m_nview.GetZDO() != null) { m_nview.Register<long>("RPC_RequestPackage", (Action<long, long>)RPC_RequestPackage); m_nview.Register<int>("RPC_PackageRespons", (Action<long, int>)RPC_PackageRespons); m_nview.Register("RPC_AnimateLever", (Action<long>)RPC_AnimateLever); m_nview.Register("RPC_AnimateLeverReturn", (Action<long>)RPC_AnimateLeverReturn); if ((Object)(object)m_enabled != (Object)null) { m_enabled.SetActive(false); } } } private void StopAOE() { isInUse = false; } public string GetLeverHoverText() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return Localization.instance.Localize("$piece_packager\n$piece_noaccess"); } return Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] $piece_pulllever"); } private bool OnIncinerate(Switch sw, Humanoid user, ItemData item) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || !m_nview.HasOwner() || !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return false; } if ((Object)(object)Game.instance == (Object)null || Game.instance.GetPlayerProfile() == null) { return false; } m_nview.InvokeRPC("RPC_RequestPackage", new object[1] { Game.instance.GetPlayerProfile().GetPlayerID() }); return true; } private void RPC_RequestPackage(long uid, long playerID) { ZLog.Log((object)("Player " + uid + " wants to package " + ((Object)((Component)this).gameObject).name + " im: " + ZDOMan.GetSessionID())); if ((Object)(object)m_nview == (Object)null || !m_nview.IsOwner()) { ZLog.Log((object)" but im not the owner"); } else if ((Object)(object)m_container == (Object)null || m_container.GetInventory() == null) { m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { 0 }); } else if (m_container.IsInUse() || isInUse) { m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { 0 }); ZLog.Log((object)" but it's in use"); } else if (m_container.GetInventory().NrOfItems() == 0) { m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { 3 }); ZLog.Log((object)" but it's empty"); } else { ((MonoBehaviour)this).StartCoroutine(Package(uid)); } } private IEnumerator Package(long uid) { isInUse = true; m_nview.InvokeRPC(ZNetView.Everybody, "RPC_AnimateLever", Array.Empty<object>()); m_leverEffects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); if ((Object)(object)m_enabled != (Object)null) { m_enabled.SetActive(true); } yield return (object)new WaitForSeconds(Random.Range(m_effectDelayMin, m_effectDelayMax)); m_nview.InvokeRPC(ZNetView.Everybody, "RPC_AnimateLeverReturn", Array.Empty<object>()); if ((Object)(object)m_enabled != (Object)null) { m_enabled.SetActive(false); } if (!m_nview.IsValid() || !m_nview.IsOwner() || (Object)(object)m_container == (Object)null || m_container.IsInUse()) { isInUse = false; yield break; } ((MonoBehaviour)this).Invoke("StopAOE", 4f); int response = TryCreatePackage(); m_nview.InvokeRPC(uid, "RPC_PackageRespons", new object[1] { response }); } private int TryCreatePackage() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = m_container.GetInventory(); if (inventory == null) { return 0; } List<ItemData> allItems = inventory.GetAllItems(); if (allItems == null || allItems.Count == 0) { return 3; } if ((Object)(object)m_defaultResult == (Object)null || (Object)(object)output == (Object)null) { Debug.LogWarning((object)(Launch.projectName + ": Packager missing result item or output transform.")); return 0; } ItemDrop val = Object.Instantiate<ItemDrop>(m_defaultResult, output.position, output.rotation); if ((Object)(object)val == (Object)null || val.m_itemData == null) { return 0; } m_produceEffects.Create(output.position, output.rotation, (Transform)null, 1f, -1); SetCustomData(val.m_itemData, "BalrondPackageAmount", allItems.Count.ToString()); StringBuilder stringBuilder = new StringBuilder("Contains: \n"); bool flag = true; float num = 0f; for (int i = 0; i < allItems.Count; i++) { ItemData val2 = allItems[i]; if (!IsValidPackageItem(val2)) { if ((Object)(object)((Component)val).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } string text = ((val2 != null && (Object)(object)val2.m_dropPrefab != (Object)null) ? ((Object)val2.m_dropPrefab).name : "null"); Debug.Log((object)("Cant make bundle - wrong item: " + text)); return 99; } stringBuilder.Append(val2.m_shared.m_name).Append(" x").Append(val2.m_stack) .Append('\n'); num += val2.m_shared.m_weight * (float)val2.m_stack; SetCustomData(val.m_itemData, "BalrondPackageIndex-" + i, ((Object)val2.m_dropPrefab).name + "." + val2.m_stack); if (!val2.m_shared.m_teleportable) { flag = false; } } float weight = num / 2f; string text2 = stringBuilder.ToString(); SetCustomData(val.m_itemData, "BalrondPackageDescription", text2); SetCustomData(val.m_itemData, "BalrondPackageWeight", weight.ToString()); SetCustomData(val.m_itemData, "BalrondPackageTeleportable", flag ? "1" : "0"); val.m_itemData.m_shared.m_description = text2; val.m_itemData.m_shared.m_teleportable = flag; val.m_itemData.m_shared.m_weight = weight; val.Save(); inventory.RemoveAll(); return 1; } private static void SetCustomData(ItemData itemData, string key, string value) { if (itemData != null && itemData.m_customData != null && !string.IsNullOrEmpty(key)) { itemData.m_customData[key] = value; } } private static bool IsValidPackageItem(ItemData item) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (item == null || item.m_shared == null || (Object)(object)item.m_dropPrefab == (Object)null) { return false; } if (((Object)item.m_dropPrefab).name.Contains("CustomPackageItem_bal")) { return false; } return ValidateItemType(item.m_shared.m_itemType); } private static bool ValidateItemType(ItemType itemType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 return (int)itemType == 1 || (int)itemType == 2 || (int)itemType == 9 || (int)itemType == 16 || (int)itemType == 13; } private void RPC_PackageRespons(long uid, int response) { if (!((Object)(object)Player.m_localPlayer == (Object)null)) { ((Character)Player.m_localPlayer).Message((MessageType)2, (Response)response switch { Response.Success => "$piece_packager_success", Response.Conversion => "$piece_packager_conversion", Response.Empty => "$piece_packager_empty", _ => "$piece_packager_fail", }, 0, (Sprite)null); } } private void RPC_AnimateLever(long uid) { if ((Object)(object)m_leverAnim != (Object)null) { m_leverAnim.SetBool("Pulled", true); } } private void RPC_AnimateLeverReturn(long uid) { if ((Object)(object)m_leverAnim != (Object)null) { m_leverAnim.SetBool("Pulled", false); } } } public class BalrondUnpackager2 : MonoBehaviour, Hoverable, Interactable { public string m_name = "$tag_unpackager_bal"; public string m_useItemText = "$tag_use_me"; public ItemDrop m_requiredItem; public Transform m_itemSpawnPoint; public float m_SpawnDelay = 2f; [Header("Effects")] public EffectList m_spawnStartEffects = new EffectList(); public EffectList m_spawnFinishEffects = new EffectList(); public Transform m_roofCheckPoint; public bool m_requiresRoof = false; private ZNetView m_nview; private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)m_nview == (Object)null || m_nview.GetZDO() == null) { ZLog.Log((object)"Missing ZNetView Component"); } else if ((Object)(object)m_requiredItem == (Object)null) { GameObject val = ZNetScene.instance.m_prefabs.Find((GameObject x) => ((Object)x).name == "CustomPackageItem_bal"); if ((Object)(object)val != (Object)null) { m_requiredItem = val.GetComponent<ItemDrop>(); } } } public string GetHoverText() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize(m_name + "\n$piece_noaccess"); } return Localization.instance.Localize(m_name + "\n[<color=yellow><b>1-8</b></color>] \n" + m_useItemText) + " " + Localization.instance.Localize(m_requiredItem.m_itemData.m_shared.m_name); } public string GetHoverName() { return m_name; } public bool Interact(Humanoid user, bool hold, bool alt) { return true; } public bool UseItem(Humanoid user, ItemData item) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)user != (Object)(object)Player.m_localPlayer) { return true; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (!((Object)item.m_dropPrefab).name.Contains(((Object)m_requiredItem).name)) { ((Character)user).Message((MessageType)2, "tag_cant_unpack", 0, (Sprite)null); return true; } if ((Object)(object)m_itemSpawnPoint != (Object)null) { m_spawnStartEffects.Create(m_itemSpawnPoint.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); SpawnItems(item); } ((Character)user).ShowRemovedMessage(item, 1); user.GetInventory().RemoveItem(item); ((Character)user).Message((MessageType)2, "$tag_unpacked_it", 0, (Sprite)null); return true; } public bool CheckUsable(Player player, bool showMessage) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (m_requiresRoof && !player.NoCostCheat()) { float num = default(float); bool flag = default(bool); Cover.GetCoverForPoint(m_roofCheckPoint.position, ref num, ref flag, 0.5f); if (!flag) { if (showMessage) { ((Character)player).Message((MessageType)2, "$msg_stationneedroof", 0, (Sprite)null); } return false; } if (num < 0.7f) { if (showMessage) { ((Character)player).Message((MessageType)2, "$msg_stationtooexposed", 0, (Sprite)null); } return false; } } return true; } private Vector3 GetSpawnPosition() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_002a: Unknown result type (might be due to invalid IL or missing references) return ((Object)(object)m_itemSpawnPoint != (Object)null) ? m_itemSpawnPoint.position : ((Component)this).transform.position; } private void SpawnItems(ItemData itemData) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (!itemData.m_customData.TryGetValue("BalrondPackageAmount", out var value) || string.IsNullOrEmpty(value) || !int.TryParse(value, out var result)) { return; } for (int i = 0; i < result; i++) { if (!itemData.m_customData.TryGetValue("BalrondPackageIndex-" + i, out var value2) || string.IsNullOrEmpty(value2)) { continue; } string[] array = value2.Split(new char[1] { '.' }); if (array.Length != 2) { continue; } string itemName = array[0]; if (int.TryParse(array[1], out var result2)) { GameObject val = ObjectDB.instance.m_items.Find((GameObject x) => ((Object)x).name == itemName); if (!((Object)(object)val == (Object)null)) { ItemDrop val2 = Object.Instantiate<ItemDrop>(val.GetComponent<ItemDrop>(), GetSpawnPosition(), Quaternion.identity); val2.m_itemData.m_stack = result2; } } } } } 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.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 && (Object)(object)recipe.m_item != (Object)null) { ObjectDB.instance.m_recipes.Add(recipe); } } else { Debug.LogError((object)(Launch.projectName + ": " + ((Object)recipe).name + " - Recipe not found")); } } private void AddItem(GameObject newPrefab) { if (!IsObjectDBValid() || (Object)(object)newPrefab == (Object)null) { return; } ItemDrop component = newPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogError((object)(Launch.projectName + ": " + ((Object)newPrefab).name + " - ItemDrop not found on prefab")); return; } if (component.m_itemData == null || component.m_itemData.m_shared == null) { Debug.LogError((object)(Launch.projectName + ": " + ((Object)newPrefab).name + " - ItemData or SharedData is null")); return; } ObjectDB instance = ObjectDB.instance; if (!instance.m_items.Contains(newPrefab)) { instance.m_items.Add(newPrefab); } instance.m_itemByHash[BalrondHashCompat.StableHash(((Object)newPrefab).name)] = newPrefab; instance.m_itemByData[component.m_itemData.m_shared] = newPrefab; } } public class ModResourceLoader { public AssetBundle assetBundle; public List<GameObject> buildPrefabs = new List<GameObject>(); public List<GameObject> plantPrefabs = new List<GameObject>(); public List<GameObject> itemPrefabs = new List<GameObject>(); public List<GameObject> monsterPrefabs = new List<GameObject>(); public List<GameObject> vegetationPrefabs = new List<GameObject>(); public List<GameObject> clutterPrefabs = new List<GameObject>(); public List<GameObject> locationPrefabs = new List<GameObject>(); public List<GameObject> roomPrefabs = new List<GameObject>(); public List<GameObject> vfxPrefabs = new List<GameObject>(); public List<Sprite> backgrounds = new List<Sprite>(); public List<Recipe> recipes = new List<Recipe>(); public List<StatusEffect> statusEffects = new List<StatusEffect>(); public static Sprite scrapCopper; public StatusEffect newBarleyStatus; public ShaderReplacment shaderReplacment = new ShaderReplacment(); public Sprite newLogo; public void LoadAssets() { assetBundle = GetAssetBundleFromResources("balrondpackager"); string basePath = "Assets/Custom/Comission/BalrondPackager/"; LoadPieces(basePath); LoadItems(basePath); LoadOther(basePath); } public void AddPrefabsToZnetScene(ZNetScene zNetScene) { AddUniquePrefabs(itemPrefabs, zNetScene); AddUniquePrefabs(plantPrefabs, zNetScene); AddUniquePrefabs(vfxPrefabs, zNetScene); AddUniquePrefabs(buildPrefabs, zNetScene); zNetScene.m_prefabs.RemoveAll((GameObject x) => (Object)(object)x == (Object)null); foreach (GameObject go in zNetScene.m_prefabs) { List<GameObject> list = zNetScene.m_prefabs.Where((GameObject x) => ((Object)x).name == ((Object)go).name).ToList(); if (list.Count > 1) { Debug.LogWarning((object)("DUPLICATE: " + ((Object)go).name)); } } SetupBuildPiecesList(zNetScene); SetupPackager(zNetScene); SetupUnpackager(zNetScene); } private void AddUniquePrefabs(List<GameObject> list, ZNetScene zNetScene) { foreach (GameObject gameObject in list) { if (zNetScene.m_prefabs.Any((GameObject x) => ((Object)x).name == ((Object)gameObject).name)) { Debug.LogWarning((object)("DUPLICATE: " + ((Object)gameObject).name)); } else { zNetScene.m_prefabs.Add(gameObject); } } } private void SetupBuildPiecesList(ZNetScene zNetScene) { string[] array = new string[4] { "Hammer", "HammerIron_bal", "HammerDverger_bal", "HammerBlackmetal_bal" }; GameObject val = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == "Hammer"); if ((Object)(object)val == (Object)null) { return; } PieceTable buildPieces = val.GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces; string[] array2 = array; foreach (string name in array2) { AddTableToTool(name, buildPieces, zNetScene); } List<GameObject> pieces = buildPieces.m_pieces; foreach (GameObject buildPrefab in buildPrefabs) { SetupRavenGuide(buildPrefab, zNetScene.m_prefabs); AddToBuildList(buildPrefab, pieces); } } private void AddTableToTool(string name, PieceTable pieceTable, ZNetScene zNetScene) { GameObject val = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == name); if (!((Object)(object)val == (Object)null)) { val.GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces = pieceTable; } } public void SetupRavenGuide(GameObject gameObject, List<GameObject> gameObjects) { Transform val = gameObject.transform.Find("GuidePoint"); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = gameObjects.Find((GameObject x) => ((Object)x).name == "piece_workbench"); if ((Object)(object)val2 == (Object)null) { return; } Transform val3 = val2.transform.Find("GuidePoint"); if (!((Object)(object)val3 == (Object)null)) { GuidePoint component = ((Component)val3).GetComponent<GuidePoint>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)"Ravens not found"); } else { ((Component)val).GetComponent<GuidePoint>().m_ravenPrefab = component.m_ravenPrefab; } } } public void SetupBuildPiecesListDB() { GameObject val = ObjectDB.instance.m_items.Find((GameObject x) => ((Object)x).name == "Hammer"); if ((Object)(object)val == (Object)null) { return; } List<GameObject> pieces = val.GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces.m_pieces; foreach (GameObject buildPrefab in buildPrefabs) { AddToBuildList(buildPrefab, pieces); } } private void AddToBuildList(GameObject prefab, List<GameObject> buildPieces) { if (!buildPieces.Exists((GameObject x) => ((Object)x).name == ((Object)prefab).name)) { buildPieces.Add(prefab); } } private AssetBundle GetAssetBundleFromResources(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename)); using Stream stream = executingAssembly.GetManifestResourceStream(name); return AssetBundle.LoadFromStream(stream); } private void LoadPieces(string basePath) { string text = basePath + "Pieces/"; string[] buildPieces = BuildPieceList.buildPieces; foreach (string text2 in buildPieces) { GameObject val = assetBundle.LoadAsset<GameObject>(text + text2 + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find piece with name: " + text2)); continue; } ShaderReplacment.Replace(val); buildPrefabs.Add(val); } } private void LoadItems(string basePath) { string text = basePath + "Items/"; string[] items = ItemList.items; foreach (string text2 in items) { GameObject val = assetBundle.LoadAsset<GameObject>(text + text2 + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find item with name: " + text2)); continue; } ShaderReplacment.Replace(val); itemPrefabs.Add(val); } } private void LoadOther(string basePath) { string text = basePath + "Other/"; string[] array = new string[0]; string[] array2 = array; foreach (string text2 in array2) { GameObject val = assetBundle.LoadAsset<GameObject>(text + text2 + ".prefab"); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Could not find object with name: " + text2)); continue; } ShaderReplacment.Replace(val); vfxPrefabs.Add(val); } } private void SetupPackager(ZNetScene zNetScene) { GameObject val = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == "packager_bal"); if ((Object)(object)val == (Object)null) { return; } BalrondPackager balrondPackager = val.GetComponent<BalrondPackager>(); if ((Object)(object)balrondPackager == (Object)null) { balrondPackager = val.AddComponent<BalrondPackager>(); } Incinerator component = val.GetComponent<Incinerator>(); if ((Object)(object)component != (Object)null) { balrondPackager.m_container = component.m_container; balrondPackager.m_leverAnim = component.m_leverAnim; balrondPackager.m_leverEffects = component.m_leverEffects; balrondPackager.m_enabled = ((Component)val.transform.Find("_enabled")).gameObject; balrondPackager.output = val.transform.Find("output"); BalrondPackager balrondPackager2 = balrondPackager; GameObject? obj = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == "CustomPackageItem_bal"); balrondPackager2.m_defaultResult = ((obj != null) ? obj.GetComponent<ItemDrop>() : null); balrondPackager.m_defaultCost = 1; balrondPackager.m_incinerateSwitch = component.m_incinerateSwitch; Object.Destroy((Object)(object)component); } } private void SetupUnpackager(ZNetScene zNetScene) { GameObject val = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == "unpackager_bal"); if (!((Object)(object)val == (Object)null)) { BalrondUnpackager balrondUnpackager = val.GetComponent<BalrondUnpackager>(); if ((Object)(object)balrondUnpackager == (Object)null) { balrondUnpackager = val.AddComponent<BalrondUnpackager>(); } balrondUnpackager.m_requiresRoof = false; BalrondUnpackager balrondUnpackager2 = balrondUnpackager; GameObject? obj = zNetScene.m_prefabs.Find((GameObject x) => ((Object)x).name == "CustomPackageItem_bal"); balrondUnpackager2.m_requiredItem = ((obj != null) ? obj.GetComponent<ItemDrop>() : null); balrondUnpackager.m_itemSpawnPoint = ((Component)balrondUnpackager).transform.Find("spawnpoint"); balrondUnpackager.m_roofCheckPoint = ((Component)balrondUnpackager).transform.Find("roof_check_pint"); } } } 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 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) { GameObject val = list.Find((GameObject x) => ((Object)x).name == name); 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"); blackforge = FindStation(pieces, "blackforge"); stoneCutter = FindStation(pieces, "piece_stonecutter"); artisian = FindStation(pieces, "piece_artisanstation"); runeforge = FindStation(pieces, "piece_runeforge_bal"); magetable = FindStation(pieces, "piece_magetable"); fletcher = FindStation(pieces, "piece_fletcher_bal"); } } internal class BuildPieceList { public static string[] buildPieces = new string[2] { "packager_bal", "unpackager_bal" }; } internal class ItemList { public static string[] items = new string[1] { "CustomPackageItem_bal" }; } 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, "BalrondPackager-translation/"); defaultPath = text; } public void createDefaultPath() { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "BalrondPackager-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("BalrondPackager: Folder already exists: " + text)); } defaultPath = text; } private string[] jsonFilePath(string folderName, string extension) { string configPath = Paths.ConfigPath; string text = Path.Combine(configPath, "BalrondPackager-translation/"); if (!Directory.Exists(text)) { CreateFolder(text); } else { Debug.Log((object)("BalrondPackager: Folder already exists: " + text)); } string[] files = Directory.GetFiles(text, extension); Debug.Log((object)("BalrondPackager:" + folderName + " Json Files Found: " + files.Length)); return files; } private static void CreateFolder(string path) { try { Directory.CreateDirectory(path); Debug.Log((object)"BalrondPackager: Folder created successfully."); } catch (Exception ex) { Debug.Log((object)("BalrondPackager: 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)("BalrondPackager: Json Files Language: " + fileNameWithoutExtension)); num++; } else { Debug.LogError((object)("BalrondPackager: Loading FAILED file: " + text)); } } Debug.Log((object)("BalrondPackager: Translation JsonFiles Loaded: " + num)); } } [BepInPlugin("balrond.astafaraios.BalrondPackager", "BalrondPackager", "1.0.2")] public class Launch : BaseUnityPlugin { [HarmonyPatch(typeof(FejdStartup), "SetupGui")] private static class FejdStartup_SetupGUI { private static void Postfix() { if (Localization.instance != null) { AddTranslations(Localization.instance, Localization.instance.GetSelectedLanguage()); } } } [HarmonyPatch(typeof(AudioMan), "Awake")] private static class AudioMan_Awake_Patch { private static void Postfix(AudioMan __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_masterMixer == (Object)null) { return; } List<List<GameObject>> list = new List<List<GameObject>> { modResourceLoader.itemPrefabs, modResourceLoader.buildPrefabs, modResourceLoader.monsterPrefabs, modResourceLoader.vfxPrefabs, modResourceLoader.vegetationPrefabs }; for (int i = 0; i < list.Count; i++) { List<GameObject> list2 = list[i]; if (list2 == null) { continue; } for (int j = 0; j < list2.Count; j++) { GameObject val = list2[j]; if ((Object)(object)val == (Object)null) { continue; } AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { val2.outputAudioMixerGroup = __instance.m_masterMixer.outputAudioMixerGroup; } } } } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class Object_CopyOtherDB_Path { private static void Postfix() { RegisterObjectDBContent(); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Path { private static void Postfix() { if (IsObjectDBValid()) { RegisterObjectDBContent(); databaseAddMethods.AddStatuseffects(modResourceLoader.statusEffects); databaseAddMethods.AddRecipes(modResourceLoader.recipes); if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_recipes != null) { ObjectDB.instance.m_recipes.Sort(SortByScore); } } } private static int SortByScore(Recipe p1, Recipe p2) { if ((Object)(object)p1 == (Object)null || (Object)(object)p1.m_item == (Object)null) { return (!((Object)(object)p2 == (Object)null) && !((Object)(object)p2.m_item == (Object)null)) ? (-1) : 0; } if ((Object)(object)p2 == (Object)null || (Object)(object)p2.m_item == (Object)null) { return 1; } return string.Compare(((Object)p1.m_item).name, ((Object)p2.m_item).name, StringComparison.Ordinal); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Path { private static void Prefix(ZNetScene __instance) { if ((Object)(object)__instance == (Object)null) { Debug.LogWarning((object)(projectName + ": No ZNetScene found")); return; } modResourceLoader.AddPrefabsToZnetScene(__instance); if (!hasSpawned) { buildPieceBuilder.SetupBuildPieces(__instance.m_prefabs); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) { hasSpawned = true; return; } ShaderReplacment.runMaterialFix(); hasSpawned = true; } } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "SetupLanguage")] private static class Translation_SetupLanguage { private static void Prefix(Localization __instance, string language) { AddTranslations(__instance, language); } } [HarmonyPriority(800)] [HarmonyPatch(typeof(Localization), "LoadCSV")] private static class Translation_LoadCSV { private static void Prefix(Localization __instance, string language) { AddTranslations(__instance, language); } } private readonly Harmony harmony = new Harmony("balrond.astafaraios.BalrondPackager"); public const string PluginGUID = "balrond.astafaraios.BalrondPackager"; public const string PluginName = "BalrondPackager"; public const string PluginVersion = "1.0.2"; public static ModResourceLoader modResourceLoader = new ModResourceLoader(); public static DatabaseAddMethods databaseAddMethods = new DatabaseAddMethods(); public static BuildPieceBuilder buildPieceBuilder = new BuildPieceBuilder(); public static JsonLoader jsonLoader = new JsonLoader(); public static GameObject RootObject; public static GameObject PrefabContainer; public static bool hasSpawned; public static string projectName = "BalrondPackager"; private void Awake() { jsonLoader.loadJson(); CreatePrefabContainer(); modResourceLoader.LoadAssets(); harmony.PatchAll(); } private static void CreatePrefabContainer() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (!((Object)(object)RootObject != (Object)null)) { RootObject = new GameObject("_ValheimReforgedRoot"); Object.DontDestroyOnLoad((Object)(object)RootObject); PrefabContainer = new GameObject("Prefabs"); PrefabContainer.transform.parent = RootObject.transform; PrefabContainer.SetActive(false); } } public static GameObject CloneMe(GameObject source, string name) { if ((Object)(object)source == (Object)null) { Debug.LogWarning((object)("BalrondPackager: CloneMe source is null for " + name)); return null; } if ((Object)(object)PrefabContainer == (Object)null) { CreatePrefabContainer(); } GameObject val = Object.Instantiate<GameObject>(source, PrefabContainer.transform); ((Object)val).name = name; FixMaterials(val, source); val.SetActive(true); return val; } public static GameObject FixMaterials(GameObject clone, GameObject source) { if ((Object)(object)clone == (Object)null || (Object)(object)source == (Object)null) { return clone; } MeshRenderer[] componentsInChildren = source.GetComponentsInChildren<MeshRenderer>(true); MeshRenderer[] componentsInChildren2 = clone.GetComponentsInChildren<MeshRenderer>(true); Dictionary<string, MeshRenderer> dictionary = new Dictionary<string, MeshRenderer>(); foreach (MeshRenderer val in componentsInChildren2) { if ((Object)(object)val != (Object)null && !dictionary.ContainsKey(((Object)val).name)) { dictionary.Add(((Object)val).name, val); } } foreach (MeshRenderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && dictionary.TryGetValue(((Object)val2).name, out var value) && !((Object)(object)value == (Object)null)) { Material[] sharedMaterials = ((Renderer)val2).sharedMaterials; ((Renderer)value).sharedMaterials = sharedMaterials; } } return clone; } private void OnDestroy() { harmony.UnpatchSelf(); } private static bool IsObjectDBValid() { ObjectDB instance = ObjectDB.instance; return (Object)(object)instance != (Object)null && instance.m_items != null && instance.m_recipes != null && instance.m_items.Count > 0 && instance.m_recipes.Count > 0 && (Object)(object)instance.GetItemPrefab("Amber") != (Object)null; } private static void AddTranslations(Localization localization, string language) { if (localization == null) { return; } Dictionary<string, string> dictionary = BalrondTranslator.getLanguage("English"); if (!string.Equals(language, "English", StringComparison.OrdinalIgnoreCase)) { Dictionary<string, string> language2 = BalrondTranslator.getLanguage(language); if (language2 != null) { dictionary = language2; } else { Debug.Log((object)"BalrondPackager: Did not find translation file; loading English"); } } if (dictionary == null) { Debug.LogWarning((object)"BalrondPackager: No translation file found!"); return; } foreach (KeyValuePair<string, string> item in dictionary) { localization.AddWord(item.Key, item.Value); } } private static void RegisterObjectDBContent() { if (IsObjectDBValid()) { modResourceLoader.SetupBuildPiecesListDB(); databaseAddMethods.AddItems(modResourceLoader.itemPrefabs); } } } public class BuildPieceBuilder { private static readonly string[] PieceNames = new string[2] { "packager_bal", "unpackager_bal" }; private List<GameObject> prefabList; private Dictionary<string, GameObject> prefabByName; public void SetupBuildPieces(List<GameObject> prefabs) { if (prefabs == null) { Debug.LogWarning((object)(Launch.projectName + ": SetupBuildPieces received null prefab list.")); return; } TableMapper.setupTables(prefabs); prefabList = prefabs; prefabByName = BuildPrefabLookup(prefabs); for (int i = 0; i < PieceNames.Length; i++) { GameObject val = FindPrefab(PieceNames[i]); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Can't find build piece with name: " + PieceNames[i])); } else { EditBuildPiece(val); } } } private static Dictionary<string, GameObject> BuildPrefabLookup(List<GameObject> prefabs) { Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); for (int i = 0; i < prefabs.Count; i++) { GameObject val = prefabs[i]; if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(((Object)val).name) && !dictionary.ContainsKey(((Object)val).name)) { dictionary.Add(((Object)val).name, val); } } return dictionary; } private void EditBuildPiece(GameObject gameObject) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gameObject == (Object)null) { return; } Piece component = gameObject.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)(Launch.projectName + ": Build piece has no Piece component: " + ((Object)gameObject).name)); return; } List<Requirement> list = new List<Requirement>(); if (component.m_resources != null) { list.AddRange(component.m_resources); } string name = ((Object)component).name; string text = name; if (!(text == "packager_bal")) { if (!(text == "unpackager_bal")) { return; } SetStation(component, TableMapper.workbench); AddOrUpdateResource(list, "Stone", 10); AddOrUpdateResource(list, "Wood", 10); component.m_category = (PieceCategory)1; } else { SetStation(component, TableMapper.forge); AddOrUpdateResource(list, "ElderBark", 20); AddOrUpdateResource(list, "SurtlingCore", 5); AddOrUpdateResource(list, "Stone", 10); AddOrUpdateResource(list, "Iron", 10); AddOrUpdateResource(list, "RoundLog", 10); component.m_category = (PieceCategory)1; } component.m_resources = list.ToArray(); } private static void SetStation(Piece piece, CraftingStation station) { if ((Object)(object)piece != (Object)null) { piece.m_craftingStation = station; } } private void AddOrUpdateResource(List<Requirement> requirements, string itemName, int amount, int amountPerLevel = 0, bool recover = true) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown if (requirements == null) { return; } GameObject val = FindItem(itemName); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("Resource item '" + itemName + "' not found. Skipping.")); return; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Debug.LogWarning((object)(Launch.projectName + ": Resource prefab has no ItemDrop component: " + ((Object)val).name)); return; } for (int i = 0; i < requirements.Count; i++) { Requirement val2 = requirements[i]; if (val2 != null && (Object)(object)val2.m_resItem == (Object)(object)component) { val2.m_amount = amount; val2.m_amountPerLevel = amountPerLevel; val2.m_recover = recover; requirements[i] = val2; return; } } requirements.Add(new Requirement { m_resItem = component, m_amount = amount, m_amountPerLevel = amountPerLevel, m_recover = recover }); } private GameObject FindPrefab(string name) { if (string.IsNullOrEmpty(name)) { return null; } if (prefabByName != null && prefabByName.TryGetValue(name, out var value)) { return value; } if (prefabList == null) { return null; } for (int i = 0; i < prefabList.Count; i++) { GameObject val = prefabList[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == name) { return val; } } return null; } private GameObject FindItem(string name, bool isStation = false) { GameObject val = FindPrefab(name); if ((Object)(object)val != (Object)null) { return val; } if (isStation) { return null; } Debug.LogWarning((object)(Launch.projectName + ": Item Not Found - " + name + ", Replaced With Wood")); return FindPrefab("Wood"); } public CraftingStation FindStation(List<GameObject> prefabs, string name) { if (prefabs != null && prefabs != prefabList) { prefabList = prefabs; prefabByName = BuildPrefabLookup(prefabs); } GameObject val = FindItem(name, isStation: true); return ((Object)(object)val != (Object)null) ? val.GetComponent<CraftingStation>() : null; } } } 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((sh