Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RuneVault v1.0.0
RuneVault.dll
Decompiled 5 months 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.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("RuneVault")] [assembly: AssemblyDescription("A virtual bank for Valheim building materials")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Ruijven")] [assembly: AssemblyProduct("RuneVault")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.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")] namespace RuneVault; public class ConfigManager { [CompilerGenerated] private sealed class <ReloadConfigDelayed>d__29 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ConfigManager <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ReloadConfigDelayed>d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.ReloadConfig(); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "RuneVault: Configuration reloaded", 0, (Sprite)null); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private string configDir; private string allowedItemsPath; private DateTime lastConfigReloadTime = DateTime.MinValue; private ConfigFile bepInExConfig; private readonly HashSet<string> autoAllowedItems = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, string> ItemNameMappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "boar_meat", "rawmeat" }, { "mushroomcommon", "mushroom" }, { "mushroom_yellow", "yellowmushroom" }, { "mushroom_blue", "bluemushroom" }, { "mushroom_jotunpuffs", "mushroomjotunpuffs" }, { "mushroom_magecap", "mushroommagecap" }, { "mushroom_smokepuff", "mushroomsmokepuff" }, { "Raspberry", "raspberry" }, { "Cloudberry", "cloudberry" }, { "Bloodbag", "bloodbag" }, { "AmberPearl", "amberpearl" } }; public static ConfigManager Instance { get; private set; } public RuneVaultConfig Config { get; private set; } private void LoadConfig() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown try { if (!Directory.Exists(configDir)) { Directory.CreateDirectory(configDir); } if (File.Exists(allowedItemsPath)) { string text = File.ReadAllText(allowedItemsPath); IDeserializer val = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); Config = val.Deserialize<RuneVaultConfig>(text); Logger.LogInfo((object)$"RuneVault: Loaded {Config.AllowedItems.Count} allowed items from config"); } else { CreateDefaultAllowedItemsFile(); } } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error loading config: " + ex.Message)); CreateDefaultAllowedItemsFile(); } } public bool IsItemAllowed(string itemName) { if (string.IsNullOrEmpty(itemName)) { Logger.LogWarning((object)"RuneVault: Empty item name provided to IsItemAllowed"); return false; } string lowerItemName = itemName.ToLowerInvariant(); if (itemName.StartsWith("Trophy", StringComparison.OrdinalIgnoreCase) || lowerItemName.Contains("trophy")) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Auto-allowing trophy '" + itemName + "'")); } return true; } if (lowerItemName.Contains("gemstone") || lowerItemName.Contains("socket") || lowerItemName.Contains("uncut")) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Auto-allowing jewelcrafting item '" + itemName + "'")); } return true; } if ((lowerItemName.Contains("raspberry") || lowerItemName.Contains("cloudberry") || lowerItemName.Contains("blueberry") || lowerItemName.Contains("mushroom")) && Config.AllowedItems.Any(delegate(AllowedItem item) { string text = item.ItemName.ToLowerInvariant(); return (lowerItemName.Contains("raspberry") && text.Contains("raspberry")) || (lowerItemName.Contains("cloudberry") && text.Contains("cloudberry")) || (lowerItemName.Contains("blueberry") && text.Contains("blueberry")) || (lowerItemName.Contains("mushroom") && text.Contains("mushroom")); })) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Special berry/mushroom match for '" + itemName + "'")); } return true; } bool flag = IsItemInAllowedList(itemName); if (Config.StrictYamlFiltering) { if (!flag) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' is not in the allowed list from YAML (strict mode)")); } return false; } ItemData itemDataFromPrefabName = GetItemDataFromPrefabName(itemName); if (itemDataFromPrefabName != null) { if (IsCraftingMaterial(itemDataFromPrefabName)) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' is in YAML and is a crafting material (strict mode)")); } return true; } if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' is in YAML but is NOT a crafting material (strict mode)")); } return false; } if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' is in YAML but couldn't get item data, allowing it (strict mode)")); } return true; } if (flag) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' is in YAML list - non-strict mode, allowing")); } return true; } string item2 = NormalizeItemName(itemName); if (autoAllowedItems.Contains(item2)) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' is in auto-detected allowed set")); } return true; } ItemData itemDataFromPrefabName2 = GetItemDataFromPrefabName(itemName); if (itemDataFromPrefabName2 != null) { if (IsCraftingMaterial(itemDataFromPrefabName2)) { autoAllowedItems.Add(item2); if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' auto-detected as crafting material and added to allowed set")); } return true; } if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' auto-detected as NOT a crafting material")); } return false; } if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Item '" + itemName + "' not in YAML and item data could not be resolved; disallowing")); } return false; } private ItemData GetItemDataFromPrefabName(string prefabName) { try { ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab(prefabName) : null); if ((Object)(object)val != (Object)null) { ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && component.m_itemData != null) { return component.m_itemData; } } } catch (Exception ex) { if (Config.DebugMode) { Logger.LogWarning((object)("RuneVault: Error getting item data for " + prefabName + ": " + ex.Message)); } } return null; } private bool IsItemInAllowedList(string itemName) { if (string.IsNullOrEmpty(itemName)) { return false; } string normalizedItemName = NormalizeItemName(itemName); List<AllowedItem> list = Config.AllowedItems.Where((AllowedItem item) => NormalizeItemName(item.ItemName).Equals(normalizedItemName, StringComparison.OrdinalIgnoreCase)).ToList(); if (list.Count > 0) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Found direct match in config: " + list[0].ItemName)); } return true; } if (normalizedItemName.StartsWith("$")) { string withoutPrefix = normalizedItemName.Substring(1); List<AllowedItem> list2 = Config.AllowedItems.Where((AllowedItem item) => NormalizeItemName(item.ItemName).Equals(withoutPrefix, StringComparison.OrdinalIgnoreCase)).ToList(); if (list2.Count > 0) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Found match without $ prefix: " + list2[0].ItemName)); } return true; } } List<AllowedItem> list3 = Config.AllowedItems.Where(delegate(AllowedItem item) { string text2 = NormalizeItemName(item.ItemName); return text2.StartsWith("$") && text2.Substring(1).Equals(normalizedItemName, StringComparison.OrdinalIgnoreCase); }).ToList(); if (list3.Count > 0) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Found match with $ prefix in config: " + list3[0].ItemName)); } return true; } if (normalizedItemName.Contains("berry") || normalizedItemName.Contains("mushroom")) { string itemType = ExtractItemType(normalizedItemName); if (!string.IsNullOrEmpty(itemType)) { List<AllowedItem> list4 = Config.AllowedItems.Where((AllowedItem item) => NormalizeItemName(item.ItemName).Contains(itemType)).ToList(); if (list4.Count > 0) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Found special match for " + itemType + ": " + list4[0].ItemName)); } return true; } } } List<AllowedItem> list5 = Config.AllowedItems.Where(delegate(AllowedItem item) { string text = NormalizeItemName(item.ItemName); return normalizedItemName.Contains(text) && text.Length >= 5; }).ToList(); if (list5.Count > 0) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Found safe partial match in config: " + list5[0].ItemName)); } return true; } return false; } private string ExtractItemType(string itemName) { if (string.IsNullOrEmpty(itemName)) { return string.Empty; } string text = (itemName.StartsWith("$") ? itemName.Substring(1) : itemName); string[] array = new string[2] { "item_", "material_" }; string[] array2 = array; foreach (string text2 in array2) { if (text.StartsWith(text2, StringComparison.OrdinalIgnoreCase)) { text = text.Substring(text2.Length); break; } } return text; } private bool IsCraftingMaterial(ItemData item) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return false; } if (IsSpecialCaseMaterial(item)) { return true; } if ((int)item.m_shared.m_itemType == 1) { return true; } if ((int)item.m_shared.m_itemType == 13) { return true; } if ((int)item.m_shared.m_itemType == 2) { return true; } if (item.m_shared.m_maxStackSize > 1 && (int)item.m_shared.m_itemType != 9 && !IsExcludedStackableItem(item)) { return true; } return false; } private bool IsSpecialCaseMaterial(ItemData item) { if (item == null || item.m_shared == null) { return false; } string text = item.m_shared.m_name.ToLowerInvariant(); if (text.Contains("cloudberry") || text.Contains("raspberry") || text.Contains("blueberry") || text.Contains("mushroom")) { return true; } if (text.Contains("trophy")) { return true; } if (text.Contains("gemstone") || text.Contains("socket") || text.Contains("uncut")) { return true; } return false; } private bool IsExcludedStackableItem(ItemData item) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Invalid comparison between Unknown and I4 if (item == null || item.m_shared == null) { return false; } if ((int)item.m_shared.m_itemType == 3 || (int)item.m_shared.m_itemType == 14 || (int)item.m_shared.m_itemType == 4 || (int)item.m_shared.m_itemType == 5 || (int)item.m_shared.m_itemType == 19 || (int)item.m_shared.m_itemType == 15) { return true; } if ((int)item.m_shared.m_itemType == 6 || (int)item.m_shared.m_itemType == 7 || (int)item.m_shared.m_itemType == 11 || (int)item.m_shared.m_itemType == 17) { return true; } if (item.m_shared.m_name.ToLowerInvariant().Contains("piece") || item.m_shared.m_description.ToLowerInvariant().Contains("build")) { return true; } return false; } private string SimplifyModdedItemName(string itemName) { if (string.IsNullOrEmpty(itemName)) { return string.Empty; } string text = itemName.ToLowerInvariant(); StringBuilder stringBuilder = new StringBuilder(); bool flag = false; bool flag2 = false; string text2 = text; foreach (char c in text2) { if (char.IsLetter(c)) { flag = true; flag2 = true; stringBuilder.Append(c); } else if (char.IsWhiteSpace(c) && flag2) { stringBuilder.Append(c); } else if (char.IsDigit(c) && flag2) { stringBuilder.Append(c); } else if (flag2) { stringBuilder.Append(' '); flag2 = false; } } if (!flag) { return text; } string text3 = stringBuilder.ToString().Trim(); while (text3.Contains(" ")) { text3 = text3.Replace(" ", " "); } return text3; } private string NormalizeItemName(string itemName) { if (string.IsNullOrEmpty(itemName)) { return string.Empty; } string text = itemName; if (itemName.StartsWith("$item_", StringComparison.OrdinalIgnoreCase)) { itemName = itemName.Substring(6); } if (itemName.StartsWith("item_", StringComparison.OrdinalIgnoreCase)) { itemName = itemName.Substring(5); } if (ItemNameMappings.TryGetValue(itemName, out var value)) { if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Special case mapping: " + text + " -> " + itemName + " -> " + value)); } return value; } string text2 = itemName.ToLowerInvariant(); text2 = text2.Replace("_", ""); if (Config.DebugMode) { Logger.LogDebug((object)("RuneVault: Normalized item name: " + text + " -> " + itemName + " -> " + text2)); } return text2; } public ConfigManager(ConfigFile configFile) { Instance = this; bepInExConfig = configFile; configDir = Path.Combine(Paths.ConfigPath, "RuneVault"); Directory.CreateDirectory(configDir); allowedItemsPath = Path.Combine(configDir, "RuneVaultItems.yaml"); InitConfig(); SetupConfigFileWatcher(); } private void InitConfig() { Config = new RuneVaultConfig(); Config.DebugMode = bepInExConfig.Bind<bool>("General", "DebugMode", false, "Enable debug mode").Value; Config.VaultRange = bepInExConfig.Bind<float>("General", "VaultRange", 35f, "Range in meters at which the RuneVault can be accessed").Value; if (!File.Exists(allowedItemsPath)) { Logger.LogWarning((object)("RuneVault: YAML file not found at " + allowedItemsPath + ". Creating default file.")); CreateDefaultAllowedItemsFile(); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "RuneVault: Created default items config file.", 0, (Sprite)null); } } LoadAllowedItems(); Logger.LogInfo((object)$"RuneVault: Loaded {Config.AllowedItems.Count} allowed items from config"); if (!Config.DebugMode) { return; } foreach (AllowedItem allowedItem in Config.AllowedItems) { Logger.LogDebug((object)("RuneVault: Allowed item: " + allowedItem.ItemName)); } } private void LoadAllowedItems() { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown if (!File.Exists(allowedItemsPath)) { Logger.LogError((object)("RuneVault: YAML file not found at " + allowedItemsPath + ". No items will be allowed.")); Config.AllowedItems = new List<AllowedItem>(); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "RuneVault: Items config file missing! Check logs.", 0, (Sprite)null); } return; } try { string text = File.ReadAllText(allowedItemsPath); if (string.IsNullOrEmpty(text)) { Logger.LogError((object)("RuneVault: YAML file at " + allowedItemsPath + " is empty.")); Config.AllowedItems = new List<AllowedItem>(); return; } IDeserializer val = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); try { RuneVaultConfig runeVaultConfig = val.Deserialize<RuneVaultConfig>(text); if (runeVaultConfig != null && runeVaultConfig.AllowedItems != null && runeVaultConfig.AllowedItems.Count > 0) { Config.AllowedItems = runeVaultConfig.AllowedItems; Logger.LogInfo((object)$"RuneVault: Successfully loaded {Config.AllowedItems.Count} items directly from YAML."); return; } } catch (Exception) { Logger.LogDebug((object)"RuneVault: Direct deserialization failed, trying AllowedItemsConfig format."); } AllowedItemsConfig allowedItemsConfig = val.Deserialize<AllowedItemsConfig>(text); if (allowedItemsConfig != null && allowedItemsConfig.Items != null && allowedItemsConfig.Items.Count > 0) { Config.AllowedItems = allowedItemsConfig.Items; Logger.LogInfo((object)$"RuneVault: Successfully loaded {Config.AllowedItems.Count} items from YAML using AllowedItemsConfig format."); } else { Logger.LogWarning((object)("RuneVault: YAML file at " + allowedItemsPath + " contains no items or has invalid format.")); Config.AllowedItems = new List<AllowedItem>(); } } catch (Exception ex2) { Logger.LogError((object)("RuneVault: Error loading allowed items: " + ex2.Message + "\n" + ex2.StackTrace)); Config.AllowedItems = new List<AllowedItem>(); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "RuneVault: Error loading items config! Check logs.", 0, (Sprite)null); } } } private void SetupConfigFileWatcher() { try { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher { Path = configDir, NotifyFilter = (NotifyFilters.LastWrite | NotifyFilters.CreationTime), Filter = "RuneVaultItems.yaml", EnableRaisingEvents = true }; fileSystemWatcher.Changed += OnConfigFileChanged; fileSystemWatcher.Created += OnConfigFileChanged; Logger.LogInfo((object)("RuneVault: Config file watcher set up for " + allowedItemsPath)); } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error setting up config file watcher: " + ex.Message)); } } private void OnConfigFileChanged(object sender, FileSystemEventArgs e) { if (!(DateTime.Now.Subtract(lastConfigReloadTime).TotalSeconds < 2.0)) { lastConfigReloadTime = DateTime.Now; Logger.LogInfo((object)("RuneVault: Config file changed: " + e.FullPath + ", reloading...")); RuneVault runeVault = Object.FindObjectOfType<RuneVault>(); if (runeVault != null) { ((MonoBehaviour)runeVault).StartCoroutine(ReloadConfigDelayed()); } } } [IteratorStateMachine(typeof(<ReloadConfigDelayed>d__29))] private IEnumerator ReloadConfigDelayed() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ReloadConfigDelayed>d__29(0) { <>4__this = this }; } public void ReloadConfig() { try { Logger.LogInfo((object)"RuneVault: Reloading configuration..."); LoadAllowedItems(); Logger.LogInfo((object)$"RuneVault: Reloaded {Config.AllowedItems.Count} allowed items from config"); if (!Config.DebugMode) { return; } foreach (AllowedItem allowedItem in Config.AllowedItems) { Logger.LogDebug((object)("RuneVault: Allowed item: " + allowedItem.ItemName)); } } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error reloading config: " + ex.Message)); } } private void CreateDefaultAllowedItemsFile() { //IL_0c48: Unknown result type (might be due to invalid IL or missing references) //IL_0c57: Expected O, but got Unknown RuneVaultConfig runeVaultConfig = new RuneVaultConfig { enableMod = true, DebugMode = false, VaultRange = 35f, AllowedItems = new List<AllowedItem> { new AllowedItem { ItemName = "Wood" }, new AllowedItem { ItemName = "FineWood" }, new AllowedItem { ItemName = "RoundLog" }, new AllowedItem { ItemName = "ElderBark" }, new AllowedItem { ItemName = "YggdrasilWood" }, new AllowedItem { ItemName = "Blackwood" }, new AllowedItem { ItemName = "BirchSeeds" }, new AllowedItem { ItemName = "BeechSeeds" }, new AllowedItem { ItemName = "Acorn" }, new AllowedItem { ItemName = "FirCone" }, new AllowedItem { ItemName = "PineCone" }, new AllowedItem { ItemName = "AncientSeed" }, new AllowedItem { ItemName = "Stone" }, new AllowedItem { ItemName = "Flint" }, new AllowedItem { ItemName = "Obsidian" }, new AllowedItem { ItemName = "BlackMarble" }, new AllowedItem { ItemName = "Grausten" }, new AllowedItem { ItemName = "CopperOre" }, new AllowedItem { ItemName = "TinOre" }, new AllowedItem { ItemName = "IronOre" }, new AllowedItem { ItemName = "SilverOre" }, new AllowedItem { ItemName = "BlackMetalOre" }, new AllowedItem { ItemName = "BlackMetalScrap" }, new AllowedItem { ItemName = "BronzeScrap" }, new AllowedItem { ItemName = "CopperScrap" }, new AllowedItem { ItemName = "IronScrap" }, new AllowedItem { ItemName = "FlametalOreNew" }, new AllowedItem { ItemName = "Copper" }, new AllowedItem { ItemName = "Tin" }, new AllowedItem { ItemName = "Bronze" }, new AllowedItem { ItemName = "Iron" }, new AllowedItem { ItemName = "Silver" }, new AllowedItem { ItemName = "BlackMetal" }, new AllowedItem { ItemName = "FlametalNew" }, new AllowedItem { ItemName = "Ruby" }, new AllowedItem { ItemName = "Amber" }, new AllowedItem { ItemName = "AmberPearl" }, new AllowedItem { ItemName = "Coins" }, new AllowedItem { ItemName = "SilverNecklace" }, new AllowedItem { ItemName = "Thistle" }, new AllowedItem { ItemName = "Dandelion" }, new AllowedItem { ItemName = "Turnip" }, new AllowedItem { ItemName = "Carrot" }, new AllowedItem { ItemName = "Onion" }, new AllowedItem { ItemName = "TurnipSeeds" }, new AllowedItem { ItemName = "CarrotSeeds" }, new AllowedItem { ItemName = "OnionSeeds" }, new AllowedItem { ItemName = "Blueberries" }, new AllowedItem { ItemName = "Raspberry" }, new AllowedItem { ItemName = "Cloudberry" }, new AllowedItem { ItemName = "BarleyFlour" }, new AllowedItem { ItemName = "Barley" }, new AllowedItem { ItemName = "Vineberry" }, new AllowedItem { ItemName = "VineberrySeeds" }, new AllowedItem { ItemName = "VineGreenSeeds" }, new AllowedItem { ItemName = "Mushroom" }, new AllowedItem { ItemName = "YellowMushroom" }, new AllowedItem { ItemName = "BlueMushroom" }, new AllowedItem { ItemName = "MushroomBlue" }, new AllowedItem { ItemName = "MushroomYellow" }, new AllowedItem { ItemName = "MushroomJotunPuffs" }, new AllowedItem { ItemName = "MushroomMagecap" }, new AllowedItem { ItemName = "MushroomSmokePuff" }, new AllowedItem { ItemName = "Fiddleheadfern" }, new AllowedItem { ItemName = "Honey" }, new AllowedItem { ItemName = "QueenBee" }, new AllowedItem { ItemName = "RoyalJelly" }, new AllowedItem { ItemName = "NeckTail" }, new AllowedItem { ItemName = "Bloodbag" }, new AllowedItem { ItemName = "RawMeat" }, new AllowedItem { ItemName = "DeerMeat" }, new AllowedItem { ItemName = "FishRaw" }, new AllowedItem { ItemName = "SerpentMeat" }, new AllowedItem { ItemName = "Entrails" }, new AllowedItem { ItemName = "WolfMeat" }, new AllowedItem { ItemName = "LoxMeat" }, new AllowedItem { ItemName = "HareMeat" }, new AllowedItem { ItemName = "ChickenMeat" }, new AllowedItem { ItemName = "BugMeat" }, new AllowedItem { ItemName = "VoltureMeat" }, new AllowedItem { ItemName = "AsksvinMeat" }, new AllowedItem { ItemName = "BoneMawSerpentMeat" }, new AllowedItem { ItemName = "LeatherScraps" }, new AllowedItem { ItemName = "DeerHide" }, new AllowedItem { ItemName = "TrollHide" }, new AllowedItem { ItemName = "WolfPelt" }, new AllowedItem { ItemName = "LoxPelt" }, new AllowedItem { ItemName = "ScaleHide" }, new AllowedItem { ItemName = "AskHide" }, new AllowedItem { ItemName = "Chitin" }, new AllowedItem { ItemName = "SerpentScale" }, new AllowedItem { ItemName = "Carapace" }, new AllowedItem { ItemName = "BonemawSerpentScale" }, new AllowedItem { ItemName = "Resin" }, new AllowedItem { ItemName = "GreydwarfEye" }, new AllowedItem { ItemName = "Coal" }, new AllowedItem { ItemName = "BoneFragments" }, new AllowedItem { ItemName = "Feathers" }, new AllowedItem { ItemName = "Chain" }, new AllowedItem { ItemName = "Root" }, new AllowedItem { ItemName = "WitheredBone" }, new AllowedItem { ItemName = "Guck" }, new AllowedItem { ItemName = "Ooze" }, new AllowedItem { ItemName = "WolfFang" }, new AllowedItem { ItemName = "WolfClaw" }, new AllowedItem { ItemName = "WolfHairBundle" }, new AllowedItem { ItemName = "FreezeGland" }, new AllowedItem { ItemName = "Crystal" }, new AllowedItem { ItemName = "DragonEgg" }, new AllowedItem { ItemName = "Needle" }, new AllowedItem { ItemName = "Tar" }, new AllowedItem { ItemName = "Eitr" }, new AllowedItem { ItemName = "Mandible" }, new AllowedItem { ItemName = "BileBag" }, new AllowedItem { ItemName = "Softtissue" }, new AllowedItem { ItemName = "AskBladder" }, new AllowedItem { ItemName = "BonemawSerpentTooth" }, new AllowedItem { ItemName = "CelestialFeather" }, new AllowedItem { ItemName = "Charcoalresin" }, new AllowedItem { ItemName = "CharredBone" }, new AllowedItem { ItemName = "SurtlingCore" }, new AllowedItem { ItemName = "BlackCore" }, new AllowedItem { ItemName = "MoltenCore" }, new AllowedItem { ItemName = "JuteRed" }, new AllowedItem { ItemName = "Flax" }, new AllowedItem { ItemName = "LinenThread" }, new AllowedItem { ItemName = "JuteBlue" }, new AllowedItem { ItemName = "IronNails" }, new AllowedItem { ItemName = "BronzeNails" } } }; try { ISerializer val = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); string contents = val.Serialize((object)runeVaultConfig); File.WriteAllText(allowedItemsPath, contents); Config.AllowedItems = runeVaultConfig.AllowedItems; Logger.LogInfo((object)$"RuneVault: Created default allowed items file at {allowedItemsPath} with {runeVaultConfig.AllowedItems.Count} items"); } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error creating default allowed items file: " + ex.Message)); } } } public class RuneVaultConfig { public bool enableMod { get; set; } = true; public bool DebugMode { get; set; } = false; public float VaultRange { get; set; } = 35f; public bool StrictYamlFiltering { get; set; } = true; public List<AllowedItem> AllowedItems { get; set; } = new List<AllowedItem>(); } public class AllowedItemsConfig { public List<AllowedItem> Items { get; set; } = new List<AllowedItem>(); } public class AllowedItem { public string ItemName { get; set; } } public class GlobalMaterialBank { private Dictionary<string, int> materialCounts = new Dictionary<string, int>(); private const string BANK_DATA_KEY = "$runevault_bank_data"; private static bool _hasShownEmptyBankWarning; private Player player; private bool dataLoaded = false; private bool initialized = false; public static GlobalMaterialBank Instance { get; private set; } public event Action OnBankChanged; private string GetPlayerSpecificKey(Player p) { if ((Object)(object)p == (Object)null) { return "$runevault_bank_data"; } return "$runevault_bank_data_" + p.GetPlayerID(); } public void SetDataLoaded(bool loaded) { dataLoaded = loaded; Logger.LogInfo((object)$"RuneVault: Data loaded flag set to {loaded}"); } public GlobalMaterialBank() { Instance = this; } public void Init() { ZoneManager.OnVanillaLocationsAvailable += OnWorldLoaded; Logger.LogInfo((object)"RuneVault: Registering for game events"); Logger.LogInfo((object)"RuneVault: Will handle player events in InitializeAfterWorldLoad"); } private void OnWorldLoaded() { InitializeAfterWorldLoad(); } private void InitializeAfterWorldLoad() { if (!initialized) { if ((Object)(object)Player.m_localPlayer != (Object)null) { Player localPlayer = Player.m_localPlayer; ((Character)localPlayer).m_onDeath = (Action)Delegate.Combine(((Character)localPlayer).m_onDeath, new Action(OnPlayerDied)); } if ((Object)(object)ZNet.instance != (Object)null) { Logger.LogInfo((object)"RuneVault: Will save data on game save"); } if ((Object)(object)Player.m_localPlayer != (Object)null) { OnPlayerSpawned(Player.m_localPlayer); } initialized = true; Logger.LogInfo((object)"RuneVault: GlobalMaterialBank initialized successfully"); } } public void SetPlayerReference(Player p) { bool flag = (Object)(object)player != (Object)(object)p; player = p; Logger.LogInfo((object)"RuneVault: Player reference set"); if (flag) { Logger.LogInfo((object)"RuneVault: Player changed, reloading bank data"); materialCounts = new Dictionary<string, int>(); SetDataLoaded(loaded: false); LoadBankData(); } } public void OnPlayerSpawned(Player p) { SetPlayerReference(p); } private void OnPlayerDied() { Logger.LogInfo((object)"RuneVault: Player died"); } private void OnPlayerSpawnedEvent() { if ((Object)(object)Player.m_localPlayer != (Object)null) { OnPlayerSpawned(Player.m_localPlayer); } } private void OnWorldSavingEvent(object sender, EventArgs e) { SaveBankData(); } private void OnWorldSaving() { SaveBankData(); } public bool Deposit(string itemName, int amount) { EnsureBankDataLoaded(); if (string.IsNullOrEmpty(itemName) || amount <= 0) { return false; } if (!materialCounts.ContainsKey(itemName)) { materialCounts[itemName] = 0; } materialCounts[itemName] += amount; this.OnBankChanged?.Invoke(); SaveBankData(); return true; } public bool Withdraw(string itemName, int amount) { EnsureBankDataLoaded(); bool flag = ConfigManager.Instance != null && ConfigManager.Instance.Config != null && ConfigManager.Instance.Config.DebugMode; if (flag) { Logger.LogInfo((object)"===== BANK WITHDRAW DEBUG START ====="); Logger.LogInfo((object)$"Attempting to withdraw {amount}x {itemName}"); Logger.LogInfo((object)"Current bank contents before withdrawal:"); foreach (KeyValuePair<string, int> materialCount in materialCounts) { Logger.LogInfo((object)$" {materialCount.Key}: {materialCount.Value}"); } } if (amount <= 0) { Logger.LogWarning((object)$"Withdraw failed: Amount {amount} is <= 0"); return false; } if (!materialCounts.TryGetValue(itemName, out var value)) { Logger.LogWarning((object)("Withdraw failed: Item " + itemName + " not found in bank")); return false; } if (value < amount) { Logger.LogWarning((object)$"Withdraw failed: Not enough {itemName} in bank. Requested: {amount}, Available: {value}"); return false; } materialCounts[itemName] -= amount; if (flag) { Logger.LogInfo((object)$"Withdrew {amount}x {itemName}, new amount: {materialCounts[itemName]}"); } if (materialCounts[itemName] <= 0) { if (flag) { Logger.LogInfo((object)("Removed " + itemName + " from bank as amount is now 0")); } materialCounts.Remove(itemName); } if (flag) { Logger.LogInfo((object)"Current bank contents after withdrawal:"); foreach (KeyValuePair<string, int> materialCount2 in materialCounts) { Logger.LogInfo((object)$" {materialCount2.Key}: {materialCount2.Value}"); } } SaveBankData(); if (flag) { Logger.LogInfo((object)"Bank data saved after withdrawal"); Logger.LogInfo((object)"Notifying listeners that bank has changed"); } this.OnBankChanged?.Invoke(); if (flag) { Logger.LogInfo((object)"===== BANK WITHDRAW DEBUG END ====="); } return true; } public bool HasItem(string itemName, int amount) { EnsureBankDataLoaded(); if (string.IsNullOrEmpty(itemName) || amount <= 0) { return false; } if (!materialCounts.ContainsKey(itemName)) { return false; } return materialCounts[itemName] >= amount; } public int GetItemAmount(string itemName) { EnsureBankDataLoaded(); if (string.IsNullOrEmpty(itemName)) { return 0; } if (!materialCounts.ContainsKey(itemName)) { return 0; } return materialCounts[itemName]; } public Dictionary<string, int> GetAllItems() { EnsureBankDataLoaded(); return new Dictionary<string, int>(materialCounts); } public void SaveBankData() { if ((Object)(object)player == (Object)null) { Logger.LogWarning((object)"RuneVault: Cannot save bank data, player is null"); return; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Logger.LogWarning((object)"RuneVault: Cannot save bank data, player network view is invalid"); return; } string text = SerializeBankData(); Logger.LogDebug((object)$"RuneVault: Saving bank data with {materialCounts.Count} items"); string playerSpecificKey = GetPlayerSpecificKey(player); player.m_customData[playerSpecificKey] = text; ZDO zDO = component.GetZDO(); zDO.Set(playerSpecificKey, text); zDO.SetOwner(zDO.GetOwner()); dataLoaded = true; _hasShownEmptyBankWarning = false; } public bool EnsureBankDataLoaded() { if (dataLoaded) { return true; } Logger.LogDebug((object)"RuneVault: Loading bank data on demand"); LoadBankData(); return dataLoaded; } public void LoadBankData() { if ((Object)(object)player == (Object)null) { Logger.LogWarning((object)"RuneVault: Cannot load bank data, player is null"); materialCounts = new Dictionary<string, int>(); return; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Logger.LogWarning((object)"RuneVault: Cannot load bank data, player network view is invalid"); materialCounts = new Dictionary<string, int>(); dataLoaded = true; return; } string playerSpecificKey = GetPlayerSpecificKey(player); string text = null; if (player.m_customData.ContainsKey(playerSpecificKey)) { text = player.m_customData[playerSpecificKey]; Logger.LogDebug((object)"RuneVault: Found bank data in player's custom data"); } if (string.IsNullOrEmpty(text)) { text = component.GetZDO().GetString(playerSpecificKey, ""); if (!string.IsNullOrEmpty(text)) { Logger.LogDebug((object)"RuneVault: Found bank data in player's ZDO"); } } if (string.IsNullOrEmpty(text)) { if (!_hasShownEmptyBankWarning) { Logger.LogWarning((object)"RuneVault: No bank data found, initializing empty bank"); _hasShownEmptyBankWarning = true; } else { Logger.LogDebug((object)"RuneVault: No bank data found, initializing empty bank"); } materialCounts = new Dictionary<string, int>(); return; } try { DeserializeBankData(text); Logger.LogDebug((object)$"RuneVault: Loaded bank data with {materialCounts.Count} items"); SetDataLoaded(loaded: true); this.OnBankChanged?.Invoke(); } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error deserializing bank data: " + ex.Message)); materialCounts = new Dictionary<string, int>(); } } public void SaveToZDO(ZDO zdo) { if (zdo != null) { string text = SerializeBankData(); string text2 = (((Object)(object)player != (Object)null) ? GetPlayerSpecificKey(player) : "$runevault_bank_data"); zdo.Set(text2, text); this.OnBankChanged?.Invoke(); } } public void LoadFromZDO(ZDO zdo) { if (zdo != null) { string text = (((Object)(object)player != (Object)null) ? GetPlayerSpecificKey(player) : "$runevault_bank_data"); string @string = zdo.GetString(text, ""); if (string.IsNullOrEmpty(@string)) { materialCounts = new Dictionary<string, int>(); return; } DeserializeBankData(@string); this.OnBankChanged?.Invoke(); } } private string SerializeBankData() { return string.Join(",", materialCounts.Select((KeyValuePair<string, int> kv) => $"{kv.Key}:{kv.Value}")); } private void DeserializeBankData(string bankData) { materialCounts.Clear(); string[] array = bankData.Split(new char[1] { ',' }); string[] array2 = array; foreach (string text in array2) { if (string.IsNullOrEmpty(text)) { continue; } string[] array3 = text.Split(new char[1] { ':' }); if (array3.Length == 2) { string key = array3[0]; if (int.TryParse(array3[1], out var result) && result > 0) { materialCounts[key] = result; } } } } public void ClearBank() { materialCounts.Clear(); this.OnBankChanged?.Invoke(); SaveBankData(); } public bool RemoveItem(string itemName) { EnsureBankDataLoaded(); bool flag = ConfigManager.Instance != null && ConfigManager.Instance.Config != null && ConfigManager.Instance.Config.DebugMode; if (flag) { Logger.LogInfo((object)"===== BANK REMOVE ITEM DEBUG START ====="); Logger.LogInfo((object)("Attempting to remove item: " + itemName)); } if (string.IsNullOrEmpty(itemName)) { Logger.LogWarning((object)"Remove failed: Item name is null or empty"); return false; } if (!materialCounts.ContainsKey(itemName)) { Logger.LogWarning((object)("Remove failed: Item " + itemName + " not found in bank")); return false; } materialCounts.Remove(itemName); if (flag) { Logger.LogInfo((object)("Successfully removed " + itemName + " from the bank")); } SaveBankData(); if (flag) { Logger.LogInfo((object)"Bank data saved after item removal"); Logger.LogInfo((object)"Notifying listeners that bank has changed"); } this.OnBankChanged?.Invoke(); if (flag) { Logger.LogInfo((object)"===== BANK REMOVE ITEM DEBUG END ====="); } return true; } public bool IsPlayerNearRuneVault() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { player = Player.m_localPlayer; if ((Object)(object)player == (Object)null) { return false; } } bool flag = RuneVaultPrefab.IsNearRuneVaultForInteraction(((Component)player).transform.position); if (!flag) { Piece[] array = Object.FindObjectsOfType<Piece>(); Piece[] array2 = array; foreach (Piece val in array2) { if ((Object)(object)val != (Object)null && val.m_name != null && (val.m_name.Contains("runevault") || val.m_name.Contains("$piece_runevault") || ((Object)(object)((Component)val).gameObject != (Object)null && ((Object)((Component)val).gameObject).name.Contains("runevault")))) { float num = Vector3.Distance(((Component)player).transform.position, ((Component)val).transform.position); if (num <= 5f) { return true; } } } } return flag; } public static bool IsNearRuneVault(bool forCrafting = true) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (Instance == null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } if (forCrafting) { return RuneVaultPrefab.IsNearRuneVaultForBuilding(((Component)Player.m_localPlayer).transform.position); } return Instance.IsPlayerNearRuneVault(); } } [BepInPlugin("ruijven.runevault", "RuneVault", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class RuneVault : BaseUnityPlugin { public const string PluginGUID = "ruijven.runevault"; public const string PluginName = "RuneVault"; public const string PluginVersion = "1.0.0"; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); private GlobalMaterialBank materialBank; private ConfigManager configManager; private RuneVaultPrefab prefabManager; private RuneVaultSync syncManager; private RuneVaultUI uiManager; private RuneVaultDebug debugManager; private RuneVaultCompatibility compatibilityManager; private Harmony harmony; public static ManualLogSource Logger; public static RuneVault Instance { get; private set; } private void Awake() { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; try { Logger.LogInfo((object)"Ensuring YamlDotNet is loaded..."); YamlDotNetLoader.EnsureYamlDotNetLoaded(); Logger.LogInfo((object)"YamlDotNet loaded successfully"); } catch (Exception ex) { Logger.LogError((object)("Failed to load YamlDotNet: " + ex.Message)); Logger.LogError((object)"Please ensure YamlDotNet.dll is in your BepInEx/plugins folder"); Logger.LogError((object)ex.StackTrace); } configManager = new ConfigManager(((BaseUnityPlugin)this).Config); materialBank = new GlobalMaterialBank(); syncManager = ((Component)this).gameObject.AddComponent<RuneVaultSync>(); uiManager = ((Component)this).gameObject.AddComponent<RuneVaultUI>(); debugManager = ((Component)this).gameObject.AddComponent<RuneVaultDebug>(); compatibilityManager = ((Component)this).gameObject.AddComponent<RuneVaultCompatibility>(); prefabManager = new RuneVaultPrefab(); PrefabManager.OnPrefabsRegistered += RegisterPrefabsAndPieces; ZoneManager.OnVanillaLocationsAvailable += OnWorldLoaded; harmony = new Harmony("ruijven.runevault"); } private void OnWorldLoaded() { materialBank.Init(); syncManager.Init(materialBank, configManager); uiManager.Init(materialBank, configManager); debugManager.Init(materialBank, configManager); compatibilityManager.Init(materialBank, configManager); Logger.LogInfo((object)"RuneVault world initialization complete"); } private void Start() { harmony.PatchAll(typeof(RuneVaultPatches)); Logger.LogInfo((object)"RuneVault initialized"); } private void OnDestroy() { harmony.UnpatchSelf(); } private void RegisterPrefabsAndPieces() { prefabManager.RegisterPrefabAndPiece(); PrefabManager.OnPrefabsRegistered -= RegisterPrefabsAndPieces; } public static bool IsDebug() { return (Object)(object)Instance != (Object)null && Instance.configManager != null && Instance.configManager.Config.DebugMode; } } public class RuneVaultCompatibility : MonoBehaviour { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static CoroutineHandler <>9__20_1; public static CoroutineHandler <>9__20_3; internal IEnumerator <InitializeNetworkHandlers>b__20_1(long sender, ZPackage package) { return null; } internal IEnumerator <InitializeNetworkHandlers>b__20_3(long sender, ZPackage package) { return null; } } private HashSet<long> m_knownPeers = new HashSet<long>(); private float m_peerCheckInterval = 2f; private float m_peerCheckTimer = 0f; private GlobalMaterialBank materialBank; private ConfigManager configManager; private List<string> connectedPlayers = new List<string>(); private CustomRPC clientConnectedRPC; private CustomRPC clientDisconnectedRPC; private CustomRPC versionInfoRPC; private const string RPC_VERSION_INFO = "RuneVault_VersionInfo"; private Dictionary<long, string> peerVersions = new Dictionary<long, string>(); private Dictionary<long, bool> trackedPlayers = new Dictionary<long, bool>(); private const string COMPATIBILITY_VERSION = "0.1.0"; private bool initialized = false; public static RuneVaultCompatibility Instance { get; private set; } public void Init(GlobalMaterialBank bank, ConfigManager config) { Instance = this; materialBank = bank; configManager = config; Logger.LogInfo((object)"RuneVault: Compatibility manager initialized"); ZoneManager.OnVanillaLocationsAvailable += OnWorldLoaded; } private void OnWorldLoaded() { InitializeNetworkHandlers(); } private void InitializeNetworkHandlers() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0098: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00c5: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown if (initialized || NetworkManager.Instance == null) { return; } NetworkManager instance = NetworkManager.Instance; CoroutineHandler val = delegate(long sender, ZPackage package) { OnClientConnected(sender); return null; }; object obj = <>c.<>9__20_1; if (obj == null) { CoroutineHandler val2 = (long sender, ZPackage package) => null; <>c.<>9__20_1 = val2; obj = (object)val2; } clientConnectedRPC = instance.AddRPC("RuneVault_ClientConnected", val, (CoroutineHandler)obj); NetworkManager instance2 = NetworkManager.Instance; CoroutineHandler val3 = delegate(long sender, ZPackage package) { OnClientDisconnected(sender); return null; }; object obj2 = <>c.<>9__20_3; if (obj2 == null) { CoroutineHandler val4 = (long sender, ZPackage package) => null; <>c.<>9__20_3 = val4; obj2 = (object)val4; } clientDisconnectedRPC = instance2.AddRPC("RuneVault_ClientDisconnected", val3, (CoroutineHandler)obj2); versionInfoRPC = NetworkManager.Instance.AddRPC("RuneVault_VersionInfo", (CoroutineHandler)delegate(long senderId, ZPackage package) { HandleVersionInfo(senderId, package); return null; }, (CoroutineHandler)delegate(long senderId, ZPackage package) { HandleVersionInfo(senderId, package); return null; }); Logger.LogInfo((object)"RuneVault: Setting up peer connection handlers"); ZRoutedRpc.instance.Register<ZPackage>("PlayerConnected", (Action<long, ZPackage>)delegate(long sender, ZPackage pkg) { OnClientConnected(sender); }); m_knownPeers = new HashSet<long>(); if ((Object)(object)ZNet.instance != (Object)null) { foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers()) { if (connectedPeer != null) { m_knownPeers.Add(connectedPeer.m_uid); } } } Logger.LogInfo((object)"RuneVault: Registered for peer connection events"); Logger.LogInfo((object)"RuneVault: Compatibility manager initialized"); initialized = true; } private void OnServerStarted() { Logger.LogInfo((object)"RuneVault: Server started"); } private void Update() { if ((Object)(object)ZNet.instance != (Object)null) { m_peerCheckTimer -= Time.deltaTime; if (m_peerCheckTimer <= 0f) { m_peerCheckTimer = m_peerCheckInterval; CheckForDisconnectedPeers(); } } } private void CheckForDisconnectedPeers() { if ((Object)(object)ZNet.instance == (Object)null) { return; } HashSet<long> hashSet = new HashSet<long>(); foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers()) { if (connectedPeer != null) { hashSet.Add(connectedPeer.m_uid); } } foreach (long knownPeer in m_knownPeers) { if (!hashSet.Contains(knownPeer)) { OnClientDisconnected(knownPeer); } } m_knownPeers = hashSet; } private void OnDestroy() { Instance = null; } private void OnClientDisconnected(long peerId) { Logger.LogInfo((object)$"RuneVault: Client disconnected {peerId}"); if (trackedPlayers.ContainsKey(peerId)) { trackedPlayers.Remove(peerId); } } public CustomRPC GetVersionInfoRPC() { return versionInfoRPC; } private void OnClientConnected(long peerId) { try { if (trackedPlayers.ContainsKey(peerId)) { return; } trackedPlayers.Add(peerId, value: true); Logger.LogInfo((object)$"RuneVault: Player connected: {peerId}"); if ((Object)(object)ZNet.instance != (Object)null) { ZNetPeer peer = ZNet.instance.GetPeer(peerId); if (peer != null) { CheckVersionCompatibility(peer); } } } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error handling client connection: " + ex.Message)); } } private void HandleVersionInfo(long senderId, ZPackage package) { try { string text = package.ReadString(); Logger.LogInfo((object)$"RuneVault: Received version info from peer {senderId}: {text}"); if (!peerVersions.ContainsKey(senderId)) { peerVersions[senderId] = text; } else { peerVersions[senderId] = text; } } catch (Exception ex) { Logger.LogWarning((object)("RuneVault: Error handling version info: " + ex.Message)); } } private void OnClientDisconnected(ZNetPeer peer) { try { if (trackedPlayers.ContainsKey(peer.m_uid)) { trackedPlayers.Remove(peer.m_uid); Logger.LogInfo((object)$"RuneVault: Player disconnected: {peer.m_playerName} ({peer.m_uid})"); } } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error handling client disconnection: " + ex.Message)); } } private void CheckVersionCompatibility(ZNetPeer peer) { try { string peerVersion = GetPeerVersion(peer); if (string.IsNullOrEmpty(peerVersion)) { return; } if (!IsVersionCompatible(peerVersion)) { Logger.LogWarning((object)("RuneVault: Version mismatch with " + peer.m_playerName + ": " + peerVersion + " vs 1.0.0")); if (ZNet.instance.IsServer()) { ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "ChatMessage", new object[3] { 0L, 2, "[RuneVault] Warning: Version mismatch. Server: 1.0.0, Client: " + peerVersion }); } } else { Logger.LogInfo((object)("RuneVault: Version compatible with " + peer.m_playerName + ": " + peerVersion)); } } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error checking version compatibility: " + ex.Message)); } } private string GetPeerVersion(ZNetPeer peer) { try { if (peer.m_rpc != null && peer.m_rpc.GetSocket() != null && peer.m_rpc.GetSocket().GetHostName().Contains("RuneVault")) { string hostName = peer.m_rpc.GetSocket().GetHostName(); string[] array = hostName.Split(new string[1] { "RuneVault/" }, StringSplitOptions.None); if (array.Length > 1) { return array[1].Split(' ', ',')[0]; } } return null; } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error getting peer version: " + ex.Message)); return null; } } private bool IsVersionCompatible(string peerVersion) { try { string[] array = "1.0.0".Split(new char[1] { '.' }); string[] array2 = peerVersion.Split(new char[1] { '.' }); if (array.Length >= 2 && array2.Length >= 2) { int num = int.Parse(array[0]); int num2 = int.Parse(array[1]); int num3 = int.Parse(array2[0]); int num4 = int.Parse(array2[1]); return num == num3 && num2 == num4; } return false; } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error checking version compatibility: " + ex.Message)); return false; } } public static void CheckModConflicts() { try { List<string> list = new List<string>(); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { string name = pluginInfo.Value.Metadata.Name; if (name.Contains("BuildFromContainers") || name.Contains("CraftFromContainers") || name.Contains("InventoryManager")) { list.Add(name); } } if (list.Count <= 0) { return; } Logger.LogWarning((object)"RuneVault: Potential mod conflicts detected:"); foreach (string item in list) { Logger.LogWarning((object)(" - " + item)); } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, $"[RuneVault] Warning: {list.Count} potentially conflicting mods detected. Check logs for details.", 0, (Sprite)null); } } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error checking mod conflicts: " + ex.Message)); } } } [HarmonyPatch] public static class MultiplayerPatches { [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPostfix] private static void ZNet_RPC_PeerInfo_Postfix(ZNet __instance, ZRpc rpc, ZPackage pkg) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown try { long num = rpc.GetSocket().GetHostName().GetHashCode(); ZNetPeer peer = __instance.GetPeer(num); if (peer == null) { return; } try { ZPackage val = new ZPackage(); val.Write("RuneVault/1.0.0"); if ((Object)(object)RuneVaultCompatibility.Instance != (Object)null && RuneVaultCompatibility.Instance.GetVersionInfoRPC() != null) { RuneVaultCompatibility.Instance.GetVersionInfoRPC().SendPackage(peer.m_uid, val); } else { Logger.LogWarning((object)"RuneVault: versionInfoRPC is not initialized, cannot send version info"); } } catch (Exception ex) { Logger.LogWarning((object)("RuneVault: Could not send version info: " + ex.Message)); } } catch (Exception ex2) { Logger.LogError((object)("RuneVault: Error patching ZNet.RPC_PeerInfo: " + ex2.Message)); } } [HarmonyPatch(typeof(Game), "Start")] [HarmonyPostfix] private static void Game_Start_Postfix() { try { RuneVaultCompatibility.CheckModConflicts(); } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error patching Game.Start: " + ex.Message)); } } } public class RuneVaultDebug : MonoBehaviour { private float _lastProximityCheckTime = 0f; private bool? _isNearRuneVault = null; private GameObject debugPanel; private GUIStyle labelStyle; private GUIStyle buttonStyle; private GlobalMaterialBank materialBank; private ConfigManager configManager; private bool showDebugInfo = false; private Vector2 scrollPosition = Vector2.zero; private string debugItemName = "Wood"; private int debugItemAmount = 100; private const float DEBUG_PANEL_WIDTH = 400f; private const float DEBUG_PANEL_HEIGHT = 600f; private const int DEBUG_BUTTON_HEIGHT = 30; public static RuneVaultDebug Instance { get; private set; } public void Init(GlobalMaterialBank bank, ConfigManager config) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if (RuneVault.IsDebug()) { Instance = this; materialBank = bank; configManager = config; materialBank.OnBankChanged += UpdateDebugInfo; CreateStyles(); debugPanel = new GameObject("RuneVaultDebugPanel"); debugPanel.SetActive(false); Logger.LogInfo((object)"RuneVault: Debug tools initialized"); } } private void CreateStyles() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown labelStyle = new GUIStyle(); buttonStyle = new GUIStyle(); if ((Object)(object)GUI.skin != (Object)null) { if (GUI.skin.label != null) { labelStyle = new GUIStyle(GUI.skin.label); } if (GUI.skin.button != null) { buttonStyle = new GUIStyle(GUI.skin.button); } } labelStyle.fontSize = 14; labelStyle.normal.textColor = Color.white; buttonStyle.fontSize = 14; buttonStyle.normal.textColor = Color.white; } private void UpdateDebugInfo() { if (RuneVault.IsDebug() && showDebugInfo) { Repaint(); } } private void Repaint() { if ((Object)(object)debugPanel != (Object)null) { debugPanel.SetActive(false); debugPanel.SetActive(true); } } private void OnGUI() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) if (!RuneVault.IsDebug()) { return; } if (labelStyle == null || buttonStyle == null) { CreateStyles(); } Rect val = new Rect((float)(Screen.width - 150), 10f, 140f, 30f); string obj = (showDebugInfo ? "Hide Debug" : "Show Debug"); object obj2 = buttonStyle; if (obj2 == null) { GUISkin skin = GUI.skin; obj2 = ((skin != null) ? skin.button : null); } if (GUI.Button(val, obj, (GUIStyle)obj2)) { showDebugInfo = !showDebugInfo; UpdateDebugInfo(); } if (!showDebugInfo) { return; } try { GUI.Box(new Rect((float)Screen.width - 400f - 10f, 50f, 400f, 600f), "RuneVault Debug"); GUILayout.BeginArea(new Rect((float)Screen.width - 400f - 5f, 80f, 390f, 560f)); scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, true, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(390f), GUILayout.Height(510f) }); DrawDebugInfo(); GUILayout.EndScrollView(); DrawDebugControls(); GUILayout.EndArea(); } catch (Exception ex) { Logger.LogError((object)("RuneVault Debug UI error: " + ex.Message)); } } private void DrawDebugInfo() { //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) try { object obj = labelStyle; if (obj == null) { GUISkin skin = GUI.skin; obj = ((object)((skin != null) ? skin.label : null)) ?? ((object)new GUIStyle()); } GUIStyle val = (GUIStyle)obj; GUILayout.Label("Player Info:", val, Array.Empty<GUILayoutOption>()); Player localPlayer = Player.m_localPlayer; GUILayout.Label("Name: " + (((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "N/A"), val, Array.Empty<GUILayoutOption>()); Player localPlayer2 = Player.m_localPlayer; object obj2; if (localPlayer2 == null) { obj2 = null; } else { Vector3 position = ((Component)localPlayer2).transform.position; obj2 = ((object)(Vector3)(ref position)).ToString(); } if (obj2 == null) { obj2 = "N/A"; } GUILayout.Label("Position: " + (string?)obj2, val, Array.Empty<GUILayoutOption>()); if (!_isNearRuneVault.HasValue || Time.time - _lastProximityCheckTime >= 2f) { _lastProximityCheckTime = Time.time; _isNearRuneVault = GlobalMaterialBank.IsNearRuneVault(); } GUILayout.Label($"Near RuneVault: {_isNearRuneVault}", val, Array.Empty<GUILayoutOption>()); GUILayout.Label("", val, Array.Empty<GUILayoutOption>()); GUILayout.Label("Bank Info:", val, Array.Empty<GUILayoutOption>()); if (materialBank != null) { Dictionary<string, int> allItems = materialBank.GetAllItems(); foreach (KeyValuePair<string, int> item in allItems) { GUILayout.Label($"{item.Key}: {item.Value}", val, Array.Empty<GUILayoutOption>()); } } else { GUILayout.Label("Material bank not initialized", val, Array.Empty<GUILayoutOption>()); } GUILayout.Label("", val, Array.Empty<GUILayoutOption>()); GUILayout.Label("Config Info:", val, Array.Empty<GUILayoutOption>()); if (configManager != null && configManager.Config != null) { GUILayout.Label($"Debug Mode: {configManager.Config.DebugMode}", val, Array.Empty<GUILayoutOption>()); GUILayout.Label($"Vault Range: {configManager.Config.VaultRange}", val, Array.Empty<GUILayoutOption>()); GUILayout.Label($"Allowed Items: {configManager.Config.AllowedItems?.Count ?? 0}", val, Array.Empty<GUILayoutOption>()); } else { GUILayout.Label("Config manager not initialized", val, Array.Empty<GUILayoutOption>()); } } catch (Exception ex) { Logger.LogError((object)("RuneVault DrawDebugInfo error: " + ex.Message)); try { GUIStyle val2 = new GUIStyle { fontSize = 14 }; val2.normal.textColor = Color.red; GUILayout.Label("Error displaying debug info", val2, Array.Empty<GUILayoutOption>()); } catch { } } } private void DrawDebugControls() { //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) try { object obj = labelStyle; if (obj == null) { GUISkin skin = GUI.skin; obj = ((object)((skin != null) ? skin.label : null)) ?? ((object)new GUIStyle()); } GUIStyle val = (GUIStyle)obj; object obj2 = buttonStyle; if (obj2 == null) { GUISkin skin2 = GUI.skin; obj2 = ((object)((skin2 != null) ? skin2.button : null)) ?? ((object)new GUIStyle()); } GUIStyle val2 = (GUIStyle)obj2; GUILayout.Label("", val, Array.Empty<GUILayoutOption>()); GUILayout.Label("Debug Controls:", val, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Item Name:", val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); debugItemName = GUILayout.TextField(debugItemName ?? "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(280f) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Amount:", val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }); string s = GUILayout.TextField(debugItemAmount.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(280f) }); if (int.TryParse(s, out var result)) { debugItemAmount = result; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Add Item", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { AddDebugItem(); } if (GUILayout.Button("Remove Item", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { RemoveDebugItem(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Clear Bank", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { ClearBank(); } if (GUILayout.Button("Reload Config", val2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { ReloadConfig(); } GUILayout.EndHorizontal(); } catch (Exception ex) { Logger.LogError((object)("RuneVault DrawDebugControls error: " + ex.Message)); try { GUIStyle val3 = new GUIStyle { fontSize = 14 }; val3.normal.textColor = Color.red; GUILayout.Label("Error displaying debug controls", val3, Array.Empty<GUILayoutOption>()); } catch { } } } private void AddDebugItem() { try { if (!string.IsNullOrEmpty(debugItemName)) { if (materialBank == null) { Logger.LogError((object)"RuneVault Debug: Material bank not initialized"); return; } materialBank.Deposit(debugItemName, debugItemAmount); Logger.LogInfo((object)$"RuneVault Debug: Added {debugItemAmount} {debugItemName} to bank"); } } catch (Exception ex) { Logger.LogError((object)("RuneVault Debug: Error adding item: " + ex.Message)); } } private void RemoveDebugItem() { try { if (!string.IsNullOrEmpty(debugItemName)) { if (materialBank == null) { Logger.LogError((object)"RuneVault Debug: Material bank not initialized"); return; } materialBank.Withdraw(debugItemName, debugItemAmount); Logger.LogInfo((object)$"RuneVault Debug: Removed {debugItemAmount} {debugItemName} from bank"); } } catch (Exception ex) { Logger.LogError((object)("RuneVault Debug: Error removing item: " + ex.Message)); } } private void ClearBank() { try { if (materialBank == null) { Logger.LogError((object)"RuneVault Debug: Material bank not initialized"); return; } Dictionary<string, int> allItems = materialBank.GetAllItems(); foreach (KeyValuePair<string, int> item in allItems) { materialBank.Withdraw(item.Key, item.Value); } Logger.LogInfo((object)"RuneVault Debug: Cleared bank"); } catch (Exception ex) { Logger.LogError((object)("RuneVault Debug: Error clearing bank: " + ex.Message)); } } private void ReloadConfig() { try { Logger.LogInfo((object)"RuneVault Debug: Config reload not available - config is loaded at startup only"); } catch (Exception ex) { Logger.LogError((object)("RuneVault Debug: Error in config reload: " + ex.Message)); } } } public class RuneVaultInteraction : MonoBehaviour, Interactable { private Piece piece; private ZNetView zNetView; private void Awake() { piece = ((Component)this).GetComponent<Piece>(); zNetView = ((Component)this).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)piece)) { RuneVaultPrefab.AddRuneVaultPiece(piece); } } private void OnDestroy() { if (Object.op_Implicit((Object)(object)piece)) { RuneVaultPrefab.RemoveRuneVaultPiece(piece); } } public string GetHoverText() { return Localization.instance.Localize("$piece_runevault") + "\n[<color=yellow><b>$KEY_Use</b></color>] $piece_use"; } public string GetHoverName() { return Localization.instance.Localize("$piece_runevault"); } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (hold) { return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { ((Character)user).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null); return false; } Player val = (Player)(object)((user is Player) ? user : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } val.SetControls(Vector3.zero, false, false, false, false, false, false, false, false, false, false, false); InventoryGui.instance.Show((Container)null, 1); RuneVaultUI.Instance?.Show(); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } } [HarmonyPatch] public class RuneVaultPatches { private enum LogLevel { None, Critical, Important, Verbose } private static float lastProximityCheckTime = 0f; private static bool lastProximityCheckResult = false; private static float proximityCheckInterval = 1f; private static LogLevel CurrentLogLevel { get { if (!ConfigManager.Instance.Config.enableMod) { return LogLevel.None; } if (!ConfigManager.Instance.Config.DebugMode) { return LogLevel.Critical; } return LogLevel.Important; } } private static GlobalMaterialBank materialBank => GlobalMaterialBank.Instance; private static void Log(string message, LogLevel level) { if (level <= CurrentLogLevel) { Logger.LogInfo((object)("RuneVault: " + message)); } } [HarmonyPatch(typeof(ZNet), "Save")] [HarmonyPrefix] public static void ZNet_Save_Prefix() { if (materialBank != null) { Log("ZNet.Save detected, saving bank data", LogLevel.Important); materialBank.SaveBankData(); } } [HarmonyPatch(typeof(Player), "SetLocalPlayer")] [HarmonyPostfix] public static void Player_SetLocalPlayer_Postfix(Player __instance) { if (materialBank != null && (Object)(object)__instance != (Object)null) { Log("Player.SetLocalPlayer detected, setting player reference", LogLevel.Important); materialBank.SetPlayerReference(__instance); } } private static bool IsNearRuneVaultCached(bool forCrafting = true) { if (Time.time - lastProximityCheckTime > proximityCheckInterval) { lastProximityCheckResult = GlobalMaterialBank.IsNearRuneVault(forCrafting); lastProximityCheckTime = Time.time; string text = (forCrafting ? "35m (crafting)" : "5m (interaction)"); Log("Player is " + (lastProximityCheckResult ? "near" : "not near") + " RuneVault using " + text + " radius", LogLevel.Verbose); } return lastProximityCheckResult; } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Recipe), typeof(bool), typeof(int), typeof(int) })] [HarmonyPrefix] public static bool Player_HaveRequirements_Prefix(ref bool __result, Player __instance, Recipe recipe, bool discover, int qualityLevel, int amount = 1) { if (materialBank == null || !ConfigManager.Instance.Config.enableMod) { return true; } if (!IsNearRuneVaultCached()) { return true; } if (discover) { return true; } bool flag = true; Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val.m_resItem == (Object)null)) { string name = ((Object)val.m_resItem).name; string name2 = val.m_resItem.m_itemData.m_shared.m_name; int num = val.GetAmount(qualityLevel) * amount; int num2 = Math.Max(((Humanoid)__instance).GetInventory().CountItems(name, -1, true), ((Humanoid)__instance).GetInventory().CountItems(name2, -1, true)); int num3 = Math.Max(materialBank.GetItemAmount(name), materialBank.GetItemAmount(name2)); Log($"Checking requirement {name}/{name2}: Need {num}, Have {num2} in inventory + {num3} in bank", LogLevel.Verbose); if (num2 + num3 < num) { flag = false; Log("Not enough " + name + "/" + name2 + " for crafting", LogLevel.Verbose); break; } } } if (flag && !__result) { __result = true; Log("Allowing crafting with RuneVault resources", LogLevel.Verbose); } return !flag; } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] [HarmonyPrefix] public static bool Player_HaveRequirements_Piece_Prefix(ref bool __result, Player __instance, Piece piece, RequirementMode mode) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (materialBank == null || !ConfigManager.Instance.Config.enableMod) { return true; } if (!IsNearRuneVaultCached()) { return true; } if ((int)mode > 0) { return true; } if (ZoneSystem.instance.GetGlobalKey(piece.FreeBuildKey())) { return true; } if ((Object)(object)piece.m_craftingStation != (Object)null && !Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position)) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)22)) { Log("Required crafting station " + piece.m_craftingStation.m_name + " not in range", LogLevel.Verbose); return true; } bool flag = true; Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val.m_resItem == (Object)null)) { string name = ((Object)val.m_resItem).name; string name2 = val.m_resItem.m_itemData.m_shared.m_name; int amount = val.m_amount; int num = Math.Max(((Humanoid)__instance).GetInventory().CountItems(name, -1, true), ((Humanoid)__instance).GetInventory().CountItems(name2, -1, true)); int num2 = Math.Max(materialBank.GetItemAmount(name), materialBank.GetItemAmount(name2)); Log($"Checking building requirement {name}/{name2}: Need {amount}, Have {num} in inventory + {num2} in bank", LogLevel.Verbose); if (num + num2 < amount) { flag = false; Log("Not enough " + name + "/" + name2 + " for building", LogLevel.Verbose); break; } } } if (flag && !__result) { __result = true; Log("Allowing building with RuneVault resources", LogLevel.Verbose); } return !flag; } [HarmonyPatch(typeof(Player), "ConsumeResources", new Type[] { typeof(Requirement[]), typeof(int), typeof(int), typeof(int) })] [HarmonyPrefix] public static bool Player_ConsumeResources_Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int multiplier) { if (materialBank == null || !ConfigManager.Instance.Config.enableMod) { return true; } if (!IsNearRuneVaultCached()) { return true; } if (ConfigManager.Instance.Config.DebugMode) { Log($"ConsumeResources called for {requirements.Length} requirements", LogLevel.Verbose); } foreach (Requirement val in requirements) { if ((Object)(object)val.m_resItem == (Object)null) { continue; } string name = ((Object)val.m_resItem).name; string name2 = val.m_resItem.m_itemData.m_shared.m_name; int num = val.GetAmount(qualityLevel) * multiplier; int val2 = ((Humanoid)__instance).GetInventory().CountItems(name, -1, true); int num2 = ((Humanoid)__instance).GetInventory().CountItems(name2, -1, true); string text = ((num2 > 0) ? name2 : name); int num3 = Math.Max(val2, num2); if (ConfigManager.Instance.Config.DebugMode) { Log($"Consuming {num} of {name}/{name2}, have {num3} in inventory", LogLevel.Verbose); } int num4 = Math.Min(num3, num); if (num4 > 0) { ((Humanoid)__instance).GetInventory().RemoveItem(text, num4, -1, true); Log($"Consumed {num4} {text} from inventory", LogLevel.Important); } int num5 = num - num4; if (num5 > 0) { int itemAmount = materialBank.GetItemAmount(name); int itemAmount2 = materialBank.GetItemAmount(name2); if (itemAmount >= num5) { materialBank.Withdraw(name, num5); Log($"Consumed {num5} {name} from bank", LogLevel.Important); continue; } if (itemAmount2 >= num5) { materialBank.Withdraw(name2, num5); Log($"Consumed {num5} {name2} from bank", LogLevel.Important); continue; } Log($"Not enough {name}/{name2} in bank! Need {num5}, have {itemAmount}/{itemAmount2}", LogLevel.Critical); } } return false; } [HarmonyPatch(typeof(Smelter), "OnAddOre")] [HarmonyPrefix] public static bool Smelter_OnAddOre_Prefix(ref bool __result, Smelter __instance, Switch sw, Humanoid user, ItemData item) { return true; } [HarmonyPatch(typeof(Smelter), "OnAddFuel")] [HarmonyPrefix] public static bool Smelter_OnAddFuel_Prefix(ref bool __result, Smelter __instance, Switch sw, Humanoid user, ItemData item) { return true; } } public class RuneVaultPrefab { public const string AssetBundleName = "runevaultbundle_ru"; public const string PrefabName = "runevault_ru"; public const string DisplayName = "RuneVault"; public const string IconName = "runevault_icon"; public const string InternalPrefabName = "runevault_ru"; private CustomPiece customPiece; private static List<GameObject> runeVaultPieces = new List<GameObject>(); private static bool _loggedTrackingInfo = false; private static bool _loggedFallbackWarning = false; private static float _lastFallbackScanTime = 0f; private static readonly float FallbackScanInterval = 5f; public void RegisterPrefabAndPiece() { //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Expected O, but got Unknown try { Logger.LogInfo((object)"RuneVault: Beginning prefab registration for runevault_ru"); GameObject val = LoadRuneVaultPrefab(); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"RuneVault: Failed to load prefab from asset bundle, using mock prefab instead"); val = CreateMockRuneVaultPrefab(); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"RuneVault: Failed to create mock prefab - this will cause proximity detection to fail"); return; } Logger.LogInfo((object)("RuneVault: Created mock prefab with name: " + ((Object)val).name)); } else { Logger.LogInfo((object)("RuneVault: Successfully loaded prefab from asset bundle with name: " + ((Object)val).name)); } if (((Object)val).name != "runevault_ru") { Logger.LogInfo((object)("RuneVault: Renaming prefab from '" + ((Object)val).name + "' to 'runevault_ru'")); ((Object)val).name = "runevault_ru"; } Sprite val2 = null; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetName().Name + ".Assets.runevaultbundle_ru"; using Stream stream = executingAssembly.GetManifestResourceStream(name); if (stream != null) { byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); AssetBundle val3 = AssetBundle.LoadFromMemory(array); if ((Object)(object)val3 != (Object)null) { val2 = val3.LoadAsset<Sprite>("runevault_icon"); if ((Object)(object)val2 != (Object)null) { Logger.LogInfo((object)"RuneVault: Loaded icon sprite 'runevault_icon' from asset bundle"); Logger.LogInfo((object)"RuneVault: Successfully loaded icon sprite 'runevault_icon'"); } else { Logger.LogWarning((object)"RuneVault: Icon sprite 'runevault_icon' not found in asset bundle"); } val3.Unload(false); } else { Logger.LogWarning((object)"RuneVault: Could not load asset bundle for icon registration"); } } else { Logger.LogWarning((object)"RuneVault: Could not get asset bundle stream for icon registration"); } } catch (Exception ex) { Logger.LogWarning((object)("RuneVault: Exception during icon sprite loading/registration: " + ex.Message)); } PieceConfig val4 = new PieceConfig(); val4.Name = "$piece_runevault"; val4.Description = "$piece_runevault_description"; val4.PieceTable = "Hammer"; val4.Category = "Misc"; val4.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig { Item = "Stone", Amount = 50, Recover = true }, new RequirementConfig { Item = "Thistle", Amount = 20, Recover = true }, new RequirementConfig { Item = "SurtlingCore", Amount = 5, Recover = true } }; val4.CraftingStation = "Workbench"; val4.Icon = (((Object)(object)val2 != (Object)null) ? val2 : null); PieceConfig val5 = val4; val5.CraftingStation = "Workbench"; customPiece = new CustomPiece(val, false, val5); PieceManager.Instance.AddPiece(customPiece); RegisterLocalization(); VerifyPrefabRegistration(); Logger.LogInfo((object)"RuneVault: Registered RuneVault prefab and piece"); } catch (Exception ex2) { Logger.LogError((object)("RuneVault: Error registering RuneVault prefab and piece: " + ex2.Message + "\n" + ex2.StackTrace)); } } private void VerifyPrefabRegistration() { try { GameObject prefab = PrefabManager.Instance.GetPrefab("runevault_ru"); if ((Object)(object)prefab != (Object)null) { Logger.LogInfo((object)"RuneVault: Successfully verified prefab registration for runevault_ru"); Piece component = prefab.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { Logger.LogInfo((object)("RuneVault: Prefab has Piece component with name: " + component.m_name)); } else { Logger.LogWarning((object)"RuneVault: Prefab is missing Piece component!"); } RuneVaultInteraction component2 = prefab.GetComponent<RuneVaultInteraction>(); if ((Object)(object)component2 != (Object)null) { Logger.LogInfo((object)"RuneVault: Prefab has RuneVaultInteraction component"); } else { Logger.LogWarning((object)"RuneVault: Prefab is missing RuneVaultInteraction component!"); } return; } Logger.LogError((object)"RuneVault: Failed to verify prefab registration for runevault_ru"); GameObject[] array = Object.FindObjectsOfType<GameObject>(); GameObject[] array2 = array; foreach (GameObject val in array2) { if (((Object)val).name.Contains("runevault")) { Logger.LogInfo((object)("RuneVault: Found object with similar name: " + ((Object)val).name)); } } } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error verifying prefab registration: " + ex.Message)); } } private void RegisterLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "piece_runevault", "RuneVault" }, { "piece_runevault_description", "A mystical runestone that stores building materials across dimensions." } }); } private GameObject LoadRuneVaultPrefab() { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = executingAssembly.GetName().Name + ".Assets.runevaultbundle_ru"; Logger.LogInfo((object)("RuneVault: Loading asset bundle from " + text)); using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { Logger.LogError((object)("RuneVault: Failed to load asset bundle stream from " + text)); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); AssetBundle val = AssetBundle.LoadFromMemory(array); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"RuneVault: Failed to load asset bundle from memory"); return null; } GameObject val2 = val.LoadAsset<GameObject>("runevault_ru"); if ((Object)(object)val2 == (Object)null) { Logger.LogError((object)"RuneVault: Failed to load prefab runevault_ru from asset bundle"); val.Unload(false); return null; } EnsureRequiredComponents(val2); val.Unload(false); Logger.LogInfo((object)"RuneVault: Successfully loaded prefab runevault_ru from asset bundle"); return val2; } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error loading asset bundle: " + ex.Message)); return null; } } private void EnsureRequiredComponents(GameObject prefab) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) if (prefab.layer != LayerMask.NameToLayer("piece")) { prefab.layer = LayerMask.NameToLayer("piece"); } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<ZNetView>())) { Logger.LogWarning((object)"RuneVault: ZNetView component missing from prefab, adding one"); prefab.AddComponent<ZNetView>(); } Piece val = prefab.GetComponent<Piece>(); if (!Object.op_Implicit((Object)(object)val)) { Logger.LogWarning((object)"RuneVault: Piece component missing from prefab, adding one"); val = prefab.AddComponent<Piece>(); } val.m_name = "$piece_runevault"; val.m_description = "$piece_runevault_description"; try { Sprite sprite = GUIManager.Instance.GetSprite("runevault_icon"); if ((Object)(object)sprite != (Object)null) { val.m_icon = sprite; } } catch (Exception ex) { Logger.LogWarning((object)("RuneVault: Could not load icon: " + ex.Message)); } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<Collider>())) { Logger.LogWarning((object)"RuneVault: Collider component missing from prefab, adding one"); CapsuleCollider val2 = prefab.AddComponent<CapsuleCollider>(); val2.radius = 0.5f; val2.height = 2f; ((Collider)val2).isTrigger = false; } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<WearNTear>())) { WearNTear val3 = prefab.AddComponent<WearNTear>(); val3.m_health = 1500f; val3.m_damages = default(DamageModifiers); val3.m_damages.m_blunt = (DamageModifier)0; val3.m_damages.m_slash = (DamageModifier)1; val3.m_damages.m_pierce = (DamageModifier)1; val3.m_supports = true; } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<HoverText>())) { HoverText val4 = prefab.AddComponent<HoverText>(); val4.m_text = "$piece_runevault"; } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<ZNetView>())) { prefab.AddComponent<ZNetView>(); } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<RuneVaultInteraction>())) { prefab.AddComponent<RuneVaultInteraction>(); } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<RuneVaultInteraction>())) { prefab.AddComponent<RuneVaultInteraction>(); } if (!Object.op_Implicit((Object)(object)prefab.GetComponent<LODGroup>())) { Logger.LogWarning((object)"RuneVault: LODGroup component missing from prefab"); } } private GameObject CreateMockRuneVaultPrefab() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) try { Logger.LogInfo((object)"RuneVault: Creating mock prefab with name 'runevault_ru'"); GameObject val = new GameObject("runevault_ru"); ZNetView val2 = val.AddComponent<ZNetView>(); Piece val3 = val.AddComponent<Piece>(); val3.m_name = "$piece_runevault"; val3.m_description = "$piece_runevault_description"; val3.m_comfort = 0; val3.m_groundPiece = true; val3.m_allowedInDungeons = false; val3.m_cultivatedGroundOnly = false; val3.m_waterPiece = false; val3.m_noInWater = true; val3.m_notOnWood = false; val3.m_notOnTiltingSurface = true; val3.m_vegetationGroundOnly = false; val.layer = LayerMask.NameToLayer("piece"); CapsuleCollider val4 = val.AddComponent<CapsuleCollider>(); val4.radius = 0.5f; val4.height = 2f; ((Collider)val4).isTrigger = false; WearNTear val5 = val.AddComponent<WearNTear>(); val5.m_health = 1500f; val5.m_damages = default(DamageModifiers); val5.m_supports = true; HoverText val6 = val.AddComponent<HoverText>(); val6.m_text = "$piece_runevault"; RuneVaultInteraction runeVaultInteraction = val.AddComponent<RuneVaultInteraction>(); GameObject val7 = GameObject.CreatePrimitive((PrimitiveType)2); val7.transform.SetParent(val.transform); val7.transform.localPosition = Vector3.zero; val7.transform.localScale = new Vector3(0.5f, 1f, 0.5f); Logger.LogInfo((object)("RuneVault: Mock prefab created successfully with name '" + ((Object)val).name + "'")); return val; } catch (Exception ex) { Logger.LogError((object)("RuneVault: Error creating mock prefab: " + ex.Message + "\n" + ex.StackTrace)); return null; } } public static void AddRuneVaultPiece(Piece piece) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)piece == (Object)null) && !((Object)(object)((Component)piece).gameObject == (Object)null)) { GameObject gameObject = ((Component)piece).gameObject; if (!runeVaultPieces.Contains(gameObject)) { runeVaultPieces.Add(gameObject); Logger.LogInfo((object)$"RuneVault: Added RuneVault piece at {((Component)piece).transform.position}"); } } } public static void RemoveRuneVaultPiece(Piece piece) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)piece == (Object)null) && !((Object)(object)((Component)piece).gameObject == (Object)null)) { GameObject gameObject = ((Component)piece).gameObject; if (runeVaultPieces.Contains(gameObject)) { runeVaultPieces.Remove(gameObject); Logger.LogInfo((object)$"RuneVault: Removed RuneVault piece at {((Component)piece).transform.position}"); } } } public static bool IsNearRuneVault(Vector3 position, float maxDistance) { //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) if (!_loggedTrackingInfo) { Logger.LogDebug((object)$"RuneVault: Proximity check system using {runeVaultPieces.Count} tracked pieces"); _loggedTrackingInfo = true; } if (runeVaultPieces.Count == 0) { if (Time.time - _lastFallbackScanTime < FallbackScanInterval) { return false; } _lastFallbackScanTime = Time.time; if (!_loggedFallbackWarning) { Logger.LogWarning((object)"RuneVault: No RuneVault pieces are being tracked! Using fallback detection method."); _loggedFallbackWarning = true; GameObject prefab = PrefabManager.Instance.GetPrefab("runevault_ru"); if ((Object)(object)prefab != (Object)null) { Logger.LogDebug((object)("RuneVault: Found prefab instance via PrefabManager: " + ((Object)prefab).name)); } else { Logger.LogWarning((object)"RuneVault: Could not find prefab 'runevault_ru' via PrefabManager"); } } Piece[] array = Object.FindObjectsOfType<Piece>(); Piece[] array2 = array; foreach (Piece val in array2) { if ((Object)(object)val == (Object)null || val.m_name == null || (!val.m_name.Contains("runevault") && !val.m_name.Contains("$piece_runevault") && (!((Object)(object)((Component)val).gameObject != (Object)null) || !((Object)((Component)val).gameObject).name.Contains("runevault")))) { continue; } float num = Vector3.Distance(position, ((Component)val).transform.position); if (num <= maxDistance) { GameObject gameObject = ((Component)val).gameObject; if (!runeVaultPieces.Contains(gameObject)) { runeVaultPieces.Add(gameObject); Logger.LogInfo((object)"RuneVault: Added previously untracked RuneVault piece to tracking list"); } return true; } } return false; } foreach (GameObject runeVaultPiece in runeVaultPieces) { if ((Object)(object)runeVaultPiece == (Object)null) { continue; } Piece component = runeVaultPiece.GetComponent<Piece>(); if (!((Object)(object)component == (Object)null)) { float num2 = Vector3.Distance(position, runeVaultPiece.transform.position); if (num2 <= maxDistance) { return true; } } } return false; } public static bool IsNearRuneVaultForInteraction(Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return IsNearRuneVault(position, 5f); } public static bool IsNearRuneVaultForBuilding(Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return IsNearRuneVault(position, 35f); } } public class RuneVaultSync : MonoBehaviour { private GlobalMaterialBank materialBank; private ConfigManager configManager; private const string RPC_DEPOSIT = "RuneVault_Deposit"; private const string RPC_WITHDRAW = "RuneVault_Withdraw"; private const string RPC_CONSUME = "RuneVault_Consume"; private bool rpcRegistered = false; public static RuneVaultSync Instance { get; private set; } public void Init(GlobalMaterialBank bank, ConfigManager config) { Instance = this; materialBank = bank; configManager = config; Logger.LogInfo((object)"RuneVault: Sync manager initialized"); } private void Update() { if (!rpcRegistered && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<ZPackage>("RuneVault_Deposit", (Action<long, ZPackage>)RPC_DepositHandler); ZRoutedRpc.instance.Register<ZPackage>("RuneVault_Withdraw", (Action<long, ZPackage>)RPC_WithdrawHandler); ZRoutedRpc.instance.Register<ZPackage>("RuneVault_Consume", (Action<long, ZPackage>)RPC_ConsumeHandler); rpcRegistered = true; Logger.LogInfo((object)"RuneVault: RPC methods registered"); } } public bool RequestDeposit(string itemName, int amount) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return false; } if (!GlobalMaterialBank.IsNearRuneVault()) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$msg_toofar", 0, (Sprite)null); return false; } if (!configManager.IsItemAllowed(itemName)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$msg_itemnotallowed", 0, (Sprite)null); return false; } ZPackage val = new ZPackage(); val.Write(Player.m_localPlayer.GetPlayerID()); val.Write(itemName); val.Write(amount); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RuneVault_Deposit", new object[1] { val }); return true; } public bool RequestWithdr