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