Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Valheim Advance TG Server v2.3.0
plugins/SeidrChest.dll
Decompiled 2 years agousing 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; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SeidrChest")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SeidrChest")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9f8a1b6e-6d0e-4dab-bbd8-9ed433836544")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace neobotics.ValheimMods; internal class CustomDataWrapper { private Dictionary<string, string> playerData; private CustomDataWrapper instance; private Dictionary<string, string> Data { get; set; } public CustomDataWrapper(Dictionary<string, string> sourceData, string keyPrefix) { CustomDataWrapper customDataWrapper = this; playerData = sourceData; Data = new Dictionary<string, string>(); sourceData.Keys.ToList().ForEach(delegate(string key) { if (key.StartsWith(keyPrefix)) { customDataWrapper.Data.Add(key, sourceData[key]); } }); } public void Add(string key, string value) { Data.Add(key, value); playerData.Add(key, value); } public bool Remove(string key) { return Data.Remove(key) & playerData.Remove(key); } public void Set(string key, string value) { if (Data.ContainsKey(key)) { Data[key] = value; } else { Data.Add(key, value); } if (playerData.ContainsKey(key)) { playerData[key] = value; } else { playerData.Add(key, value); } } public string Get(string key) { if (Data.ContainsKey(key)) { return Data[key]; } return null; } public bool ContainsKey(string key) { return Data.ContainsKey(key); } public void PreSaveSync() { foreach (KeyValuePair<string, string> datum in Data) { if (!playerData.ContainsKey(datum.Key)) { playerData.Add(datum.Key, datum.Value); } } } } internal class DebugUtils { public static void ObjectInspector(object o) { if (o == null) { Debug.Log((object)"Object is null"); return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type type = o.GetType(); Debug.Log((object)(o.ToString() + " Type " + type.Name)); PropertyInfo[] properties = type.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { Debug.Log((object)$"{type.Name}.{propertyInfo.Name} = {propertyInfo.GetValue(o)}"); } FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo field in fields) { FieldPrinter(o, type, field); } } public static void MethodInspector(object o) { if (o == null) { Debug.Log((object)"Object is null"); return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type type = o.GetType(); Debug.Log((object)(o.ToString() + " Type " + type.Name)); MethodInfo[] methods = type.GetMethods(bindingAttr); foreach (MethodInfo methodInfo in methods) { methodInfo.GetParameters(); string arg = string.Join(", ", (from x in methodInfo.GetParameters() select x.ParameterType?.ToString() + " " + x.Name).ToArray()); Debug.Log((object)$"{methodInfo.ReturnType} {methodInfo.Name} ({arg})"); } } private static void ItemDataInspector(ItemData item) { ObjectInspector(item); ObjectInspector(item.m_shared); } private static void FieldPrinter(object o, Type t, FieldInfo field) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown try { if (field.FieldType == typeof(ItemData)) { ItemData val = (ItemData)field.GetValue(o); if (val != null) { ItemDataInspector(val); } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else if (field.FieldType == typeof(Transform)) { Transform val2 = (Transform)field.GetValue(o); if ((Object)(object)val2 != (Object)null) { Debug.Log((object)("\tTransform.parent = " + ((Object)val2.parent).name)); } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else if (field.FieldType == typeof(EffectList)) { EffectList val3 = (EffectList)field.GetValue(o); if (val3 != null) { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}:"); EffectData[] effectPrefabs = val3.m_effectPrefabs; foreach (EffectData val4 in effectPrefabs) { Debug.Log((object)("\tEffectData.m_prefab = " + ((Object)val4.m_prefab).name)); } } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}"); } } catch (Exception) { Debug.Log((object)("Exception accessing " + t?.Name + "." + field?.Name)); } } public static void GameObjectInspector(GameObject go) { Debug.Log((object)("\n\nInspecting GameObject " + ((Object)go).name)); ObjectInspector(go); Component[] componentsInChildren = go.GetComponentsInChildren<Component>(); foreach (Component val in componentsInChildren) { try { string obj = ((val != null) ? ((Object)val).name : null); object obj2; if (val == null) { obj2 = null; } else { Transform transform = val.transform; if (transform == null) { obj2 = null; } else { Transform parent = transform.parent; obj2 = ((parent != null) ? ((Object)parent).name : null); } } Debug.Log((object)("\n\nInspecting Component " + obj + " with parent " + (string?)obj2)); ObjectInspector(val); } catch (Exception) { } } } public static void ComponentInspector(Component c) { Debug.Log((object)("\n\nInspecting Component " + ((Object)c).name)); ObjectInspector(c); } public static void EffectsInspector(EffectList e) { EffectData[] effectPrefabs = e.m_effectPrefabs; Debug.Log((object)$"Effect list has effects {e.HasEffects()} count {effectPrefabs.Length}"); EffectData[] array = effectPrefabs; foreach (EffectData val in array) { Debug.Log((object)$"Effect Data {val} prefab name {((Object)val.m_prefab).name} prefab GameObject name {((Object)val.m_prefab.gameObject).name}"); } } public static void PrintInventory() { foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems()) { Debug.Log((object)allItem.m_shared.m_name); } } public static void PrintAllObjects() { ZNetScene.instance.m_prefabs.ForEach(delegate(GameObject x) { Debug.Log((object)("GameObject " + ((Object)x).name)); }); } public static void PrintAllCharacters() { Character.GetAllCharacters().ForEach(delegate(Character x) { Debug.Log((object)("Character " + ((Object)x).name)); }); } public static void PrintAllLayers() { string[] array = (from index in Enumerable.Range(0, 31) select LayerMask.LayerToName(index) into l where !string.IsNullOrEmpty(l) select l).ToArray(); foreach (string text in array) { Debug.Log((object)("Layer " + text + " " + Convert.ToString(LayerMask.NameToLayer(text), 2).PadLeft(32, '0'))); } } } public class DelegatedConfigEntry<T> : DelegatedConfigEntryBase { private ConfigEntry<T> _entry; private EventHandler rootHandler; private Action<object, EventArgs> clientDelegate; private Logging Log; public ConfigEntry<T> ConfigEntry { get { return _entry; } set { _entry = value; if (_entry != null && rootHandler != null) { _entry.SettingChanged += rootHandler; } Name = ((ConfigEntryBase)_entry).Definition.Key; Section = ((ConfigEntryBase)_entry).Definition.Section; ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue(); Log.Trace("Set " + Section + " " + Name + " to serialized value " + ServerValue); } } public T Value { get { return _entry.Value; } set { _entry.Value = value; } } public DelegatedConfigEntry(bool useServerDelegate = false) : this((Action<object, EventArgs>)null, useServerDelegate) { } public DelegatedConfigEntry(Action<object, EventArgs> delegateHandler, bool useServerDelegate = false) { Log = Logging.GetLogger(); Log.Trace("DelegatedConfigEntry"); if (delegateHandler != null) { clientDelegate = delegateHandler; } if (useServerDelegate) { Log.Trace("Configuring server delegate"); rootHandler = delegate(object s, EventArgs e) { ServerDelegate(s, e); }; ServerConfiguration.ServerDelegatedEntries.Add(this); } else if (clientDelegate != null) { rootHandler = delegate(object s, EventArgs e) { clientDelegate(s, e); }; } } private void ServerDelegate(object sender, EventArgs args) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown Logging.GetLogger().Trace("ServerDelegate"); _entry.SettingChanged -= rootHandler; ZNet instance = ZNet.instance; bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : null); if (flag.HasValue) { if (flag == false && ServerConfiguration.Instance.ReceivedServerValues) { if (ServerValue != null) { ((ConfigEntryBase)_entry).SetSerializedValue(ServerValue); Log.Debug("Setting " + Name + " to server value " + ServerValue); } } else if (flag == true) { ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue(); ServerConfiguration.Instance.SendConfigToAllClients(sender, (SettingChangedEventArgs)args); } } if (clientDelegate != null) { clientDelegate(sender, args); } _entry.SettingChanged += rootHandler; } public void EnableHandler(bool setActive) { if (setActive) { _entry.SettingChanged += rootHandler; } else { _entry.SettingChanged -= rootHandler; } } public bool IsKeyPressed() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } public bool IsKeyDown() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } public bool IsKeyReleased() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKeyUp(modifier)) { return false; } } if (!Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } } public class DelegatedConfigEntryBase { public string Name; public string Section; public string ServerValue; } public class Logging { public enum LogLevels { Critical, Error, Warning, Info, Debug, Trace } private static Logging _logger; public LogLevels LogLevel { get; set; } public string ModName { get; set; } private Logging(LogLevels level, string name) { LogLevel = level; ModName = name; } public static Logging GetLogger(LogLevels level, string name) { if (_logger == null) { _logger = new Logging(level, name); } return _logger; } public static Logging GetLogger() { if (_logger == null) { throw new NullReferenceException("Logger not initialized"); } return _logger; } public void Trace(string msg) { if (LogLevel >= LogLevels.Trace) { Debug.Log((object)Message(msg)); } } public void Debug(string msg) { if (LogLevel >= LogLevels.Debug) { Debug.Log((object)Message(msg)); } } public void Info(string msg) { if (LogLevel >= LogLevels.Info) { Debug.Log((object)Message(msg)); } } public void Warning(string msg) { if (LogLevel >= LogLevels.Warning) { Debug.LogWarning((object)Message(msg)); } } public void Error(string msg) { if (LogLevel >= LogLevels.Error) { Debug.LogWarning((object)Message(msg)); } } public void Error(Exception e) { Error(e, stackTrace: false); } public void Error(Exception e, bool stackTrace) { if (LogLevel >= LogLevels.Error) { Warning(Message(e.Message)); if (stackTrace) { Warning(e.StackTrace); } } } public void Critical(Exception e) { if (LogLevel >= LogLevels.Critical) { Debug(Message(e.Message)); Error(e.StackTrace); } } private string Message(string msg) { return ModName + ": " + msg; } public static void ChangeLogging(object s, EventArgs e) { SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); GetLogger().Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); GetLogger().LogLevel = Cfg.debugLevel.Value; } } public class ServerConfiguration { [HarmonyPatch(typeof(ZNet), "StopAll")] private static class ZNet_Shutdown_Patch { [HarmonyPrefix] private static void ZNet_StopAll_Prefix(ZNet __instance) { Log.Debug("ZNet_StopAll_Patch_Prefix"); Instance.ReceivedServerValues = false; } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class ZNet_OnNewConnection_Patch { private static void Postfix(ZNet __instance, ZNetPeer peer) { Log.Debug("ZNet OnNewConnection postfix"); if (!__instance.IsServer()) { try { peer.m_rpc.Register<ZPackage>("ClientConfigReceiver." + GetPluginGuid(), (Action<ZRpc, ZPackage>)Instance.RPC_ClientConfigReceiver); Log.Debug("Player registered RPC_ClientConfigReceiver"); return; } catch (Exception) { Log.Warning("Failed to register RPC"); return; } } try { Instance.SendConfigToClient(peer); } catch (Exception) { Log.Warning("Error sending server configuration to client"); } } } public static List<DelegatedConfigEntryBase> ServerDelegatedEntries = new List<DelegatedConfigEntryBase>(); private static ConfigFile LocalConfig; private static BaseUnityPlugin Mod; private static string ConfigFileName; private static ServerConfiguration _instance; private static Logging Log; public bool IsSetup; public bool ReceivedServerValues; public FileSystemWatcher ConfigWatcher; private const string NOT_CONFIGURED = "ServerConfiguration not initialized. Setup first."; public static ServerConfiguration Instance { get { if (_instance == null) { _instance = new ServerConfiguration(); } return _instance; } } private ServerConfiguration() { } public void Setup(ConfigFile config, BaseUnityPlugin modInstance) { LocalConfig = config; Log = Logging.GetLogger(); Log.Trace("ServerConfiguration Setup"); Mod = modInstance; ConfigFileName = Path.GetFileName(LocalConfig.ConfigFilePath); IsSetup = true; } public void CreateConfigWatcher() { ConfigWatcher = Utils.CreateFileWatcher(LocalConfig.ConfigFilePath, LoadConfig); } private void LoadConfig(object sender, FileSystemEventArgs e) { if (!File.Exists(LocalConfig.ConfigFilePath)) { return; } try { Log.Debug($"Loading configuration {e.ChangeType}"); LocalConfig.Reload(); } catch { Log.Error("Error loading configuration file " + ConfigFileName); } } public static string GetPluginGuid() { return Mod.Info.Metadata.GUID; } public void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package) { if (!Instance.IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); return; } Log.Debug("ClientConfigReceiver"); string section; string name; while (package.GetPos() < package.Size()) { section = package.ReadString(); name = package.ReadString(); string text = package.ReadString(); Log.Trace("Reading " + section + " " + name + " value " + text + " from ZPackage"); DelegatedConfigEntryBase delegatedConfigEntryBase = ServerDelegatedEntries.Find((DelegatedConfigEntryBase e) => e.Name == name && e.Section == section); if (delegatedConfigEntryBase != null) { Log.Trace("Found DCEB on client and setting to server value " + text); delegatedConfigEntryBase.ServerValue = text; } ConfigEntryBase val = LocalConfig[section, name]; if (val != null) { Log.Trace("Found local CEB and setting underlying config value " + text); val.SetSerializedValue(text); } } ReceivedServerValues = true; } internal void WriteConfigEntries(ZPackage zpkg) { foreach (DelegatedConfigEntryBase serverDelegatedEntry in ServerDelegatedEntries) { Log.Trace("Writing " + serverDelegatedEntry.Section + " " + serverDelegatedEntry.Name + " value " + serverDelegatedEntry.ServerValue + " to ZPackage"); zpkg.Write(serverDelegatedEntry.Section); zpkg.Write(serverDelegatedEntry.Name); zpkg.Write(serverDelegatedEntry.ServerValue); } } internal void SendConfigToClient(ZNetPeer peer) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (!Instance.IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); return; } Log.Debug("SendConfigToClient"); ZPackage val = new ZPackage(); WriteConfigEntries(val); peer.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { val }); Log.Trace("Invoked ClientConfigReceiver on peer"); } public void SendConfigToAllClients(object o, SettingChangedEventArgs e) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if (!IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); } else if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() > 0) { Log.Debug("SendConfigToAllClients"); ZPackage zpkg = new ZPackage(); WriteConfigEntries(zpkg); ((MonoBehaviour)Mod).StartCoroutine(_instance.Co_BroadcastConfig(zpkg)); } } private IEnumerator Co_BroadcastConfig(ZPackage zpkg) { Log.Debug("Co_BroadcastConfig"); List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers(); foreach (ZNetPeer item in connectedPeers) { if (item != ZNet.instance.GetServerPeer()) { item.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { zpkg }); Log.Trace("Invoked ClientConfigReceiver on peer"); } yield return null; } } } internal class Utils { public static TEnum Guardrails<TEnum>(string value, TEnum enumDefault) where TEnum : struct { if (Enum.TryParse<TEnum>(value, ignoreCase: true, out var result)) { return result; } return enumDefault; } public static int Guardrails(int value, int lbound, int ubound) { if (value < lbound) { return lbound; } if (value > ubound) { return ubound; } return value; } public static string truncate(string value, int maxChars) { if (value == null) { return null; } if (value.Length <= maxChars) { return value; } return value.Substring(0, maxChars); } public static void GetCharactersInRangeXZ(Vector3 point, float radius, List<Character> characters) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) float num = radius * radius; foreach (Character s_character in Character.s_characters) { if (DistanceSqrXZ(((Component)s_character).transform.position, point) < num) { characters.Add(s_character); } } } public static float DistanceSqr(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.y - v0.y; float num3 = v1.z - v0.z; return num * num + num2 * num2 + num3 * num3; } public static float DistanceSqrXZ(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.z - v0.z; return num * num + num2 * num2; } public static float DistanceXZ(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.z - v0.z; return Mathf.Sqrt(num * num + num2 * num2); } public static float Guardrails(float value, float lbound, float ubound) { if (value < lbound) { return lbound; } if (value > ubound) { return ubound; } return value; } public static string UnClonifiedName(string name) { if (name == null) { return null; } int num = name.IndexOf("(Clone)"); if (num < 1) { return name; } return name.Substring(0, num); } public static void SetTranslator(int id, string idText) { typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Localization.instance, new object[2] { "skill_" + id, idText }); } public static string GetTranslated(int id) { Logging.GetLogger().Debug(string.Format("Got translation for id {0} to {1}", id, Localization.instance.Localize("skill_" + id))); return Localization.instance.Localize("$skill_" + id); } public static string GetAssemblyPathedFile(string fileName) { return new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName.Replace('\\', '/') + "/" + fileName; } public static Sprite GetPrefabIcon(string prefabName) { Sprite result = null; GameObject prefab = GetPrefab(prefabName); ItemDrop val = default(ItemDrop); if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val)) { result = val.m_itemData.GetIcon(); } return result; } public static Player GetPlayerByZDOID(ZDOID zid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) foreach (Player allPlayer in Player.GetAllPlayers()) { ZDOID zDOID = ((Character)allPlayer).GetZDOID(); if (((ZDOID)(ref zDOID)).Equals(zid)) { return allPlayer; } } return null; } public static Character GetCharacterByZDOID(string cid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) foreach (Character allCharacter in Character.GetAllCharacters()) { ZDOID zDOID = allCharacter.GetZDOID(); if (((object)(ZDOID)(ref zDOID)).ToString().Equals(cid)) { return allCharacter; } } return null; } public static Character GetCharacterByZDOID(ZDOID cid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) foreach (Character allCharacter in Character.GetAllCharacters()) { ZDOID zDOID = allCharacter.GetZDOID(); if (((ZDOID)(ref zDOID)).Equals(cid)) { return allCharacter; } } return null; } public static ZNetPeer GetPeerByRPC(ZRpc rpc) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer.m_rpc == rpc) { return peer; } } return null; } public static List<GameObject> GetGameObjectsOfType(Type t) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); Object[] array = Object.FindObjectsOfType(t); foreach (Object val in array) { list.Add(((Component)val).gameObject); } return list; } public static GameObject GetClosestGameObjectOfType(Type t, Vector3 point, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetGameObjectsOfTypeInRangeByDistance(t, point, radius)?[0]; } public static List<GameObject> GetGameObjectsOfTypeInRangeByDistance(Type t, Vector3 point, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>(); List<GameObject> gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius); if (gameObjectsOfTypeInRange.Count > 0) { foreach (GameObject item in gameObjectsOfTypeInRange) { list.Add(new KeyValuePair<GameObject, float>(item, Vector3.Distance(item.transform.position, point))); } list.Sort((KeyValuePair<GameObject, float> pair1, KeyValuePair<GameObject, float> pair2) => pair1.Value.CompareTo(pair2.Value)); return list.ConvertAll((KeyValuePair<GameObject, float> x) => x.Key); } return null; } public static List<GameObject> GetGameObjectsOfTypeInRange(Type t, Vector3 point, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return (from x in GetGameObjectsOfType(t) where Vector3.Distance(x.transform.position, point) < radius select x).ToList(); } public static float GetPointDepth(Vector3 p) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return ZoneSystem.instance.m_waterLevel - GetSolidHeight(p); } public static List<string> GetDelimitedStringAsList(string delimitedString, char delimiter) { List<string> list = new List<string>(); string[] array = delimitedString.Split(new char[1] { delimiter }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { list.Add(text.Trim()); } return list; } public static float GetSolidHeight(Vector3 p) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) int solidRayMask = ZoneSystem.instance.m_solidRayMask; float result = 0f; p.y += 1000f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(p, Vector3.down, ref val, 2000f, solidRayMask) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody)) { result = ((RaycastHit)(ref val)).point.y; } return result; } public static Transform FindChild(Transform aParent, string aName) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown foreach (Transform item in aParent) { Transform val = item; if (((Object)val).name == aName) { return val; } Transform val2 = FindChild(val, aName); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } public static Transform FindParent(Transform go) { while ((Object)(object)go.parent != (Object)null) { go = go.parent; } return go; } public static GameObject GetPrefab(int prefabHash) { return GetPrefabByHash(prefabHash); } public static GameObject GetPrefabByHash(int prefabHash) { GameObject val = ObjectDB.instance.GetItemPrefab(prefabHash); Logging logger = Logging.GetLogger(); if ((Object)(object)val != (Object)null) { logger.Debug("Found prefab in ObjectDB"); } else { ZNetScene instance = ZNetScene.instance; val = ((instance != null) ? instance.GetPrefab(prefabHash) : null); if ((Object)(object)val != (Object)null) { logger.Debug("Found prefab in Scene"); } } return val; } public static GameObject GetPrefab(string prefabName) { GameObject val = ObjectDB.instance.GetItemPrefab(prefabName); Logging logger = Logging.GetLogger(); if ((Object)(object)val != (Object)null) { logger.Debug("Found " + prefabName + " in ObjectDB"); } else { ZNetScene instance = ZNetScene.instance; val = ((instance != null) ? instance.GetPrefab(prefabName) : null); if ((Object)(object)val != (Object)null) { logger.Debug("Found " + prefabName + " in Scene"); } } return val; } public static string SerializeFromDictionary<K, V>(string delimp, string delimc, IDictionary<K, V> dict) { if (dict == null) { return null; } IEnumerable<string> values = dict.Select(delegate(KeyValuePair<K, V> kvp) { KeyValuePair<K, V> keyValuePair = kvp; string? obj = keyValuePair.Key?.ToString(); string text = delimc; keyValuePair = kvp; return obj + text + keyValuePair.Value; }); return string.Join(delimp, values); } public static void DeserializeToDictionary<K, V>(string serializedString, string delimp, string delimc, ref IDictionary<K, V> dict) { if (dict == null) { return; } dict.Clear(); string[] separator = new string[1] { delimp }; string[] separator2 = new string[1] { delimc }; string[] array = serializedString.Split(separator, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2) { dict.Add(TypedValue<K>(array2[0]), TypedValue<V>(array2[1])); } } } public static FileSystemWatcher CreateFileWatcher(string fullPath, FileSystemEventHandler handler) { string fileName = Path.GetFileName(fullPath); FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(fullPath.Substring(0, fullPath.Length - fileName.Length), fileName); fileSystemWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime; fileSystemWatcher.Changed += handler; fileSystemWatcher.Created += handler; fileSystemWatcher.IncludeSubdirectories = false; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; return fileSystemWatcher; } public static T TypedValue<T>(object a) { return (T)Convert.ChangeType(a, typeof(T)); } public static float TimeAdjustedRamp(float maxValue, float duration, float elapsedTime, float pctFromStartRise, float pctFromEndFall) { float num = elapsedTime / duration; if (num <= pctFromStartRise) { return maxValue * (num / pctFromStartRise); } if (num >= 1f - pctFromEndFall) { return maxValue * ((1f - num) / pctFromEndFall); } return maxValue; } public static bool CopyComponentToGameObject(Component original, ref GameObject destination) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown Logging logger = Logging.GetLogger(); Type type = ((object)original).GetType(); logger.Debug($"Original Type is {type}"); GameObject obj = destination; logger.Debug("Destination GameObject " + ((obj != null) ? ((Object)obj).name : null)); Component val = destination.GetComponent(type); if ((Object)(object)val == (Object)null) { val = destination.AddComponent(type); } if ((Object)(object)val == (Object)null) { logger.Debug("Destination component is null"); return false; } Component val2 = (Component)Activator.CreateInstance(type); if ((Object)(object)val2 == (Object)null) { logger.Debug("Destination component is null"); return false; } if ((Object)(object)val2 == (Object)null) { logger.Debug("Boxed component is null"); return false; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val2, fieldInfo.GetValue(original)); } val = val2; return true; } public static bool CopyObject(object original, object target) { Logging logger = Logging.GetLogger(); Type type = original.GetType(); Type type2 = target.GetType(); if (type == null) { logger.Warning("Copy Object: Source object is null"); Activator.CreateInstance(type); return false; } if (type2 == null) { logger.Warning("Copy Object: Destination object is null"); return false; } if (type2 != type) { logger.Warning("Copy Object: Source and destination components are different types"); return false; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(target, fieldInfo.GetValue(original)); } return true; } } internal class Cfg { public static KeyCode[] keyModifiers = (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }; public static KeyboardShortcut chestBindKeyDefault = new KeyboardShortcut((KeyCode)106, keyModifiers); public static DelegatedConfigEntry<Logging.LogLevels> debugLevel = null; public static DelegatedConfigEntry<KeyboardShortcut> chestBindKey = null; public static KeyboardShortcut chestOpenKeyDefault = new KeyboardShortcut((KeyCode)104, Array.Empty<KeyCode>()); public static DelegatedConfigEntry<KeyboardShortcut> chestOpenKey = null; public static DelegatedConfigEntry<bool> useStrictCost = null; public static DelegatedConfigEntry<bool> teleportRestriction = null; public static DelegatedConfigEntry<int> bindCost = null; public static DelegatedConfigEntry<int> openCost = null; public static DelegatedConfigEntry<SeidrChest.ChestModes> chestMode = null; public static DelegatedConfigEntry<SeidrChest.CostModes> costMode = null; public static DelegatedConfigEntry<bool> invertEnderKey = null; public static void BepInExConfig(BaseUnityPlugin _instance) { //IL_00d0: 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_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Expected O, but got Unknown debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(Logging.ChangeLogging); debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log. Default is 'Info'"); SeidrChest.Log.LogLevel = debugLevel.Value; chestMode = new DelegatedConfigEntry<SeidrChest.ChestModes>(useServerDelegate: true); chestMode.ConfigEntry = _instance.Config.Bind<SeidrChest.ChestModes>("General", "ChestMode", SeidrChest.ChestModes.SeidrChest, "Seidr mode allows accessing the Seidr chest anyhwere. Ender mode links all personal chests to the same Seidr chest; you must open them to access the common toInventory."); costMode = new DelegatedConfigEntry<SeidrChest.CostModes>(useServerDelegate: true); costMode.ConfigEntry = _instance.Config.Bind<SeidrChest.CostModes>("Cost", "CostType", SeidrChest.CostModes.EitrThenStamina, "Set the type of energy used to bind and open Seidr chests. Can be exclusivley Eitr or Stamina, or Eitr first, followed by Stamina."); chestBindKey = new DelegatedConfigEntry<KeyboardShortcut>(); chestBindKey.ConfigEntry = _instance.Config.Bind<KeyboardShortcut>("General", "BindSeidrChest", chestBindKeyDefault, "Press this key to seidr bind a Personal Chest to a Seidr Chest."); chestOpenKey = new DelegatedConfigEntry<KeyboardShortcut>(); chestOpenKey.ConfigEntry = _instance.Config.Bind<KeyboardShortcut>("General", "OpenSeidrChest", chestOpenKeyDefault, "Press this key to open your Seidr Chest. In EnderChest mode, hold this key down when opening a Personal chest to access the actual chest contents."); useStrictCost = new DelegatedConfigEntry<bool>(useServerDelegate: true); useStrictCost.ConfigEntry = _instance.Config.Bind<bool>("Cost", "StrictCost", false, "Require cost to be met before binding or opening. If Eitr and/or Stamina is less than this cost (depending on CostType setting), chest cannot be bound or open."); invertEnderKey = new DelegatedConfigEntry<bool>(); invertEnderKey.ConfigEntry = _instance.Config.Bind<bool>("General", "InvertEnderOpenKey", false, "Set True to invert Ender mode open action, i.e., open Personal Chest as default, open SeidrChest while holding the OpenSeidrChest key."); teleportRestriction = new DelegatedConfigEntry<bool>(useServerDelegate: true); teleportRestriction.ConfigEntry = _instance.Config.Bind<bool>("General", "RestrictNonTeleportable", false, "Set to true to prevent non-teleportable items in the Seidr chest."); bindCost = new DelegatedConfigEntry<int>(useServerDelegate: true); bindCost.ConfigEntry = _instance.Config.Bind<int>("Cost", "CostToBind", 50, new ConfigDescription("Sets the amount of eitr and/or stamina consumed to bind a Seidr chest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>())); openCost = new DelegatedConfigEntry<int>(useServerDelegate: true); openCost.ConfigEntry = _instance.Config.Bind<int>("Cost", "CostToOpen", 10, new ConfigDescription("Sets the amount of eitr and/or stamina consumed to use a Seidr chest.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>())); } } [BepInPlugin("neobotics.valheim_mod.seidrchest", "SeidrChest", "0.1.15")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class SeidrChest : BaseUnityPlugin { public enum ChestModes { SeidrChest, EnderChest } public enum CostModes { EitrThenStamina, EitrOnly, StaminaOnly } [HarmonyPatch(typeof(Game), "Start")] private static class Game_Start_Patch { [HarmonyPostfix] private static void Game_Start_Patch_Postfix(Game __instance) { Log.Debug(" Game_Start_Patch_Postfix"); ZRoutedRpc.instance.Register<string>("RequestSeidrZDO", (Action<long, string>)RPC_RequestSeidrZDO); ZRoutedRpc.instance.Register("CancelRequestZDO", (Action<long>)RPC_CancelRequestZDO); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] private static class InventoryGui_Hide_Patch { [HarmonyPostfix] private static void InventoryGui_Hide_Postfix(InventoryGui __instance) { if (originalAutocloseDistance >= 0f) { __instance.m_autoCloseDistance = originalAutocloseDistance; } } } [HarmonyPatch(typeof(InventoryGui), "CloseContainer")] private static class InventoryGui_CloseContainer_Patch { [HarmonyPostfix] private static void InventoryGui_CloseContainer_Postfix(InventoryGui __instance) { Log.Debug("InventoryGui_CloseContainer_Patch_Postfix"); if (originalAutocloseDistance >= 0f) { __instance.m_autoCloseDistance = originalAutocloseDistance; } } } [HarmonyPatch(typeof(ZDOMan), "FindSectorObjects")] public static class ZDOMan_FindSectorObjects1_Patch { private static void Prefix(ZDOMan __instance, Vector2i sector, int area, List<ZDO> sectorObjects) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) AddSectorObject(__instance, sector, area, sectorObjects); } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryGui_Show_Patch { private static bool Prefix(InventoryGui __instance, ref Container container, out Container __state) { //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) __state = null; if (originalAutocloseDistance == -1f) { originalAutocloseDistance = __instance.m_autoCloseDistance; } if ((Object)(object)container != (Object)null) { if (Log.LogLevel >= Logging.LogLevels.Trace) { Log.Trace("Showing container name " + container.m_name); } if (container.m_name == "$piece_chestprivate" && Cfg.chestMode.Value == ChestModes.EnderChest && ((!Cfg.chestOpenKey.IsKeyDown() && !Cfg.invertEnderKey.Value) || (Cfg.chestOpenKey.IsKeyDown() && Cfg.invertEnderKey.Value))) { if (!SetupSeidrChest()) { Log.Info("No Seidr chest is bound"); return true; } Container val = default(Container); if ((Object)(object)voidChest != (Object)null && voidChest.TryGetComponent<Container>(ref val)) { Log.Debug("Switching to Sedir chest"); container = val; } } if ((Object)(object)voidChest != (Object)null && (Object)(object)voidChest.GetComponent<Container>() == (Object)(object)container) { Log.Debug("Showing Seidr chest"); if (!HasSeidrCost(Player.m_localPlayer, Cfg.openCost.Value, binding: false)) { return false; } ApplySeidrCost(Player.m_localPlayer, Cfg.openCost.Value); container.GetInventory().m_name = "Seiðr chest"; if (Vector3.Distance(((Component)Player.m_localPlayer).transform.position, voidChest.transform.position) > 5f) { __instance.m_autoCloseDistance = float.MaxValue; Log.Debug("Reset autoclose distance"); } else { __instance.m_autoCloseDistance = originalAutocloseDistance; } } } else { Log.Debug("Not a Container"); } return true; } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class Player_OnSpawned_Patch { public static void Postfix(Player __instance) { Log.Debug("Player OnSpawned"); voidChest = null; voidZdo = null; if (!SetupSeidrChest() && !ZNet.instance.IsServer()) { Log.Debug("No local ZDO. Requesting from server"); RequestSeidrZDOFromServer(Player.m_localPlayer.GetPlayerName()); ((MonoBehaviour)_modInstance).StartCoroutine(_modInstance.Co_WaitForZDO()); } } } [HarmonyPatch(typeof(Container), "CanBeRemoved")] public static class Container_CanBeRemoved_Patch { private static void Postfix(Container __instance, ref bool __result) { if (__result && (Object)(object)voidChest != (Object)null && (Object)(object)voidChest == (Object)(object)((Component)__instance).gameObject) { Log.Trace("Setting Seidr chest removal false"); __result = false; } } } [HarmonyPatch(typeof(Container), "GetHoverText")] public static class Container_GetHoverText_Patch { private static void Postfix(Container __instance, ref string __result) { if ((Object)(object)voidChest != (Object)null && Cfg.chestMode.Value == ChestModes.EnderChest && __instance.m_name == "$piece_chestprivate" && ((!Cfg.chestOpenKey.IsKeyDown() && !Cfg.invertEnderKey.Value) || (Cfg.chestOpenKey.IsKeyDown() && Cfg.invertEnderKey.Value))) { __result += " (Seiðr chest)"; } } } [HarmonyPatch(typeof(Player), "Update")] public static class Player_Update_Patch { private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && OkToKey(__instance)) { if (Cfg.chestBindKey.IsKeyPressed()) { BindChest(); } else if (Cfg.chestMode.Value == ChestModes.SeidrChest && Cfg.chestOpenKey.IsKeyPressed()) { HandleChest(); } } } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(int), typeof(int), typeof(int) })] private static class Inventory_AddItem_ToSlot_Patch { private static bool Prefix(Inventory __instance, ItemData item, int amount, int x, int y, string ___m_name, out bool __result) { __result = true; if (Log.LogLevel >= Logging.LogLevels.Trace) { Log.Trace("AddItem_ToSlot " + item.m_shared.m_name + " to " + ___m_name); } if (!IsOkToMove(item, ___m_name)) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] private static class Inventory_AddItem_Patch { private static bool Prefix(Inventory __instance, ItemData item, string ___m_name, out bool __result) { __result = true; if (Log.LogLevel >= Logging.LogLevels.Trace) { Log.Trace("AddItem " + item.m_shared.m_name + " to " + ___m_name); } if (!IsOkToMove(item, ___m_name)) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int), typeof(int), typeof(int) })] private static class Inventory_MoveItemToThis_Slot_Patch { private static bool Prefix(Inventory __instance, Inventory fromInventory, ItemData item, int amount, int x, int y, string ___m_name) { if (Log.LogLevel >= Logging.LogLevels.Trace) { Log.Trace("MoveItemToThis_Slot " + item.m_shared.m_name + " to " + ___m_name); } ItemData itemAt = __instance.GetItemAt(x, y); if (itemAt != null && !IsOkToMove(itemAt, fromInventory.GetName())) { return false; } if (!IsOkToMove(item, ___m_name)) { return false; } return true; } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData) })] private static class Inventory_MoveItemToThis_Patch { private static bool Prefix(Inventory __instance, Inventory fromInventory, ItemData item, string ___m_name) { if (Log.LogLevel >= Logging.LogLevels.Trace) { Log.Trace("MoveItemToThis " + item.m_shared.m_name + " to " + ___m_name); } if (!IsOkToMove(item, ___m_name)) { return false; } return true; } } [HarmonyPatch(typeof(InventoryGrid), "DropItem")] private static class InventoryGrid_DropItem_Patch { private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, Inventory ___m_inventory, out bool __result) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) __result = true; string name = ___m_inventory.GetName(); if (Log.LogLevel >= Logging.LogLevels.Trace) { Log.Trace("InventoryGrid_DropItem " + item.m_shared.m_name + " to " + name); } ItemData itemAt = ___m_inventory.GetItemAt(pos.x, pos.y); if (itemAt != null && !IsOkToMove(itemAt, fromInventory.GetName())) { return false; } if (!IsOkToMove(item, name)) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(InventoryGui), "UpdateContainer")] private static class InventoryGui_UpdateContainer_Patch { private static void Prefix(InventoryGui __instance, Container ___m_currentContainer) { ZNetView val = default(ZNetView); if ((Object)(object)___m_currentContainer != (Object)null && !___m_currentContainer.IsOwner() && (Object)(object)voidChest != (Object)null && (Object)(object)((Component)___m_currentContainer).gameObject == (Object)(object)voidChest && ((Component)___m_currentContainer).gameObject.TryGetComponent<ZNetView>(ref val)) { ZDO zDO = val.GetZDO(); if (zDO != null) { zDO.SetOwner(((Character)Player.m_localPlayer).GetOwner()); } } } } [HarmonyPatch(typeof(FejdStartup), "Awake")] private static class FejidStartup_Awake_Patch { private static void Postfix(FejdStartup __instance) { GetDetectionSet(new Dictionary<string, string> { { "yay.spikehimself.xstorage.harmony", "XStorage" } }); } } private static SeidrChest _modInstance; private static string Mod = "SeidrChest"; private static string LcMod = Mod.ToLower(); public static Logging Log; private const string convertedName = "Seiðr chest"; private const string personalChestTag = "$piece_chestprivate"; private Harmony harmony; private static string worldPlayer = ""; private static string worldName = ""; private static float originalAutocloseDistance = -1f; private static GameObject voidChest = null; private static ZDO voidZdo = null; private static GameObject bindPrefab = null; private static bool cancelRequest = false; private const string CANTBIND = "You can't bind it"; public const string SEIDRPREFIX = "SeidrChest_1847_"; private const string XSTORAGESKIP = "XStorage_SkipMark"; private const string SEIDERCHEST_TEMP = "SeidrChest_Temp"; private static Dictionary<string, string> detectionSet = new Dictionary<string, string>(); private static Dictionary<string, string> unpatchMods = new Dictionary<string, string>(); public static SeidrChest GetInstance() { return _modInstance; } private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown _modInstance = this; Log = Logging.GetLogger(Logging.LogLevels.Info, Mod); harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); harmony.PatchAll(Assembly.GetExecutingAssembly()); ConfigureMod(); Log.Info("Awake"); } private void ConfigureMod() { Log = Logging.GetLogger(Logging.LogLevels.Info, Mod); ServerConfiguration.Instance.Setup(((BaseUnityPlugin)this).Config, (BaseUnityPlugin)(object)this); Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance); ServerConfiguration.Instance.CreateConfigWatcher(); } private void OnDestroy() { harmony.UnpatchSelf(); } private static bool HasSeidrCost(Player aPlayer, float amount, bool binding = true) { bool flag = true; if (Cfg.useStrictCost.Value) { float eitr = aPlayer.GetEitr(); float stamina = aPlayer.GetStamina(); switch (Cfg.costMode.Value) { case CostModes.EitrOnly: if (eitr < amount) { flag = false; } break; case CostModes.StaminaOnly: if (stamina < amount) { flag = false; } break; default: if (eitr + stamina < amount) { flag = false; } break; } if (!flag) { Log.Info("Not enough energy to " + (binding ? "bind" : "use") + " the Seidr chest"); ((Character)Player.m_localPlayer).Message((MessageType)2, "Not enough energy", 0, (Sprite)null); } } return flag; } private static void ApplySeidrCost(Player aPlayer, float amount) { float eitr = aPlayer.GetEitr(); aPlayer.GetStamina(); if ((Cfg.costMode.Value == CostModes.EitrOnly || Cfg.costMode.Value == CostModes.EitrThenStamina) && eitr > 0f) { ((Character)aPlayer).UseEitr(amount); amount -= eitr; } if ((Cfg.costMode.Value == CostModes.StaminaOnly || Cfg.costMode.Value == CostModes.EitrThenStamina) && amount > 0f) { ((Character)aPlayer).UseStamina(amount, false); } } private static void RestoreToPersonalChest() { Log.Debug("RestoreToPersonalChest"); Container val = default(Container); if ((Object)(object)voidChest != (Object)null && voidChest.TryGetComponent<Container>(ref val)) { val.GetInventory().m_name = "$piece_chestprivate"; val.m_name = "$piece_chestprivate"; } } private static bool IsOkToMove(ItemData item, string name) { if (name == "Seiðr chest" && item?.m_shared != null && Cfg.teleportRestriction.Value && !item.m_shared.m_teleportable) { Log.Info("Can't store non-teleportable items in the Seidr chest"); ((Character)Player.m_localPlayer).Message((MessageType)1, "Can't store that in the chest", 0, (Sprite)null); return false; } return true; } private static void UnbindChest(bool message = true) { //IL_006d: 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) Log.Debug("UnbindChest"); Container val = default(Container); if (!((Object)(object)voidChest != (Object)null) || !voidChest.TryGetComponent<Container>(ref val)) { return; } if (message) { CreateAura(voidChest); } RestoreToPersonalChest(); ZDO zDO = val.m_nview.GetZDO(); if (zDO.IsValid()) { zDO.Set(StringExtensionMethods.GetStableHashCode("XStorage_SkipMark"), false); if (ZDOHelper.Remove<string>(ZDOExtraData.s_strings, zDO.m_uid, StringExtensionMethods.GetStableHashCode("SeidrChest_1847_"))) { Log.Debug($"Removed player reference from chest ZDO {zDO.m_uid}"); } } voidChest = null; voidZdo = null; Log.Info("Seidr Chest is unbound"); if (message) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Seiðr chest is unbound", 0, (Sprite)null); } } private static bool HasNonTeleportableItems(Container container) { if (((container != null) ? container.GetInventory() : null) != null) { return container.GetInventory().GetAllItems().Find((ItemData x) => !x.m_shared.m_teleportable) != null; } return false; } private static void BindChest() { Player localPlayer = Player.m_localPlayer; Log.Debug("BindChest"); GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); GameObject val = ((hoverObject != null) ? ((Component)hoverObject.transform.root).gameObject : null); if ((Object)(object)val == (Object)null) { return; } if ((Object)(object)val == (Object)(object)voidChest) { Log.Debug("Unbinding hovered Seidr chest"); UnbindChest(); return; } if (((Object)val).name != "piece_chest_private(Clone)") { Log.Info("Hovered object is not a personal chest"); ((Character)localPlayer).Message((MessageType)2, "You can't bind it", 0, (Sprite)null); return; } ZNetView val2 = default(ZNetView); if (!val.TryGetComponent<ZNetView>(ref val2)) { Log.Warning("Hovering object has no view"); return; } ZDO zDO = val2.GetZDO(); Piece component = val.GetComponent<Piece>(); Container container = default(Container); if (zDO == null || (Object)(object)component == (Object)null) { Log.Warning("Invalid hover object"); } else if (!component.IsCreator()) { Log.Info("You can only bind your own Personal chest"); ((Character)localPlayer).Message((MessageType)2, "You can't bind it", 0, (Sprite)null); } else if (Cfg.teleportRestriction.Value && val.TryGetComponent<Container>(ref container) && HasNonTeleportableItems(container)) { Log.Info("You cannot bind a chest with items that can't be teleported"); ((Character)localPlayer).Message((MessageType)2, "You can't bind it", 0, (Sprite)null); } else if (HasSeidrCost(localPlayer, Cfg.bindCost.Value)) { ApplySeidrCost(localPlayer, Cfg.bindCost.Value); if ((Object)(object)voidChest != (Object)null) { Log.Debug("Unbinding existing Seidr chest"); UnbindChest(message: false); } voidChest = val; Log.Debug("Player selected own Personal chest"); SaveSeidrChestZDO(zDO); Object.DontDestroyOnLoad((Object)(object)voidChest); CreateAura(voidChest); Container val3 = default(Container); if (voidChest.TryGetComponent<Container>(ref val3)) { val3.m_name = "Seiðr chest"; zDO.Set(StringExtensionMethods.GetStableHashCode("XStorage_SkipMark"), true); } Log.Info("Seidr Chest is bound"); ((Character)localPlayer).Message((MessageType)2, "Seiðr chest is bound", 0, (Sprite)null); } } private static void CreateAura(GameObject go) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bindPrefab == (Object)null) { bindPrefab = ZNetScene.instance.GetPrefab("fx_Immobilize"); } if ((Object)(object)bindPrefab != (Object)null) { Object.Instantiate<GameObject>(bindPrefab, go.transform.position, Quaternion.identity); } } private static string GetChestWorldKey() { return "SeidrChest_1847_" + ZNet.m_world.m_name; } private static ZDO GetSeidrChestZDO(string playerName) { Log.Debug("GetSeidrChestZDO"); int stableHashCode = StringExtensionMethods.GetStableHashCode("piece_chest_private"); if (ZDOMan.instance.m_objectsByID != null) { foreach (ZDO value in ZDOMan.instance.m_objectsByID.Values) { if (value != null && value.m_prefab == stableHashCode && value.GetString("SeidrChest_1847_", "") == playerName) { return value; } } } Log.Info("No Seidr chest ZDO found."); return null; } private static void RequestSeidrZDOFromServer(string playerName) { Log.Debug("RequestSeidrZDOFromServer"); ZRoutedRpc.instance.InvokeRoutedRPC("RequestSeidrZDO", new object[1] { playerName }); } private static void CancelRequestToServer(long peer) { Log.Debug("CancelRequestToServer"); ZRoutedRpc.instance.InvokeRoutedRPC(peer, "CancelRequestZDO", Array.Empty<object>()); } private static void RPC_RequestSeidrZDO(long id, string playerName) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (ZNet.instance.IsServer()) { Log.Debug("RPC_RequestSeidrZDO"); ZNetPeer peerByPlayerName = ZNet.instance.GetPeerByPlayerName(playerName); ZDO seidrChestZDO = GetSeidrChestZDO(playerName); if (seidrChestZDO != null) { Log.Debug($"Server sending Seidr chest ZDO with ZDOID {seidrChestZDO.m_uid} to {playerName}"); seidrChestZDO.SetOwner(peerByPlayerName.m_uid); ZDOMan.instance.ForceSendZDO(peerByPlayerName.m_uid, seidrChestZDO.m_uid); } else { Log.Warning("Server can't find requested Seidr chest for " + playerName); CancelRequestToServer(id); } } } private static void RPC_CancelRequestZDO(long id) { if (!ZNet.instance.IsServer()) { Log.Debug("RPC_CancelRequestZDO"); cancelRequest = true; } } private static void SaveSeidrChestZDO(ZDO zdo) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) Log.Debug("SaveSeidrChestZDO"); zdo.Set("SeidrChest_1847_", Player.m_localPlayer.GetPlayerName()); Log.Debug($"Saved player to Seidr chest ZDO {zdo.m_uid}"); } private static bool SetupSeidrChest() { Log.Debug("SetupSeidrChest"); if ((Object)(object)voidChest != (Object)null) { Log.Debug("Chest already exists"); return true; } Log.Debug("Finding chest"); ZDO seidrChestZDO = voidZdo; if (seidrChestZDO == null) { Log.Debug("No Seidr chest ZDO. Getting from local data."); seidrChestZDO = GetSeidrChestZDO(Player.m_localPlayer.GetPlayerName()); } if (seidrChestZDO == null) { Log.Debug("No pre-existing chest"); return false; } if (!ZNetScene.instance.HaveInstance(seidrChestZDO)) { Log.Debug("No chest instance currently in scene... creating."); ZNetScene.instance.CreateObject(seidrChestZDO); } ZNetView val = ZNetScene.instance.FindInstance(seidrChestZDO); if ((Object)(object)val != (Object)null) { Log.Debug("Re-binding existing chest"); voidChest = ((Component)val).gameObject; voidZdo = seidrChestZDO; Container val2 = default(Container); if (voidChest.TryGetComponent<Container>(ref val2)) { val2.m_name = "Seiðr chest"; } Object.DontDestroyOnLoad((Object)(object)voidChest); return true; } Log.Warning("Couldn't find or create existing chest instance"); return false; } private static bool HandleChest() { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Log.Debug("HandleChest"); if (!SetupSeidrChest()) { Log.Info("No Seidr chest is bound"); return false; } if (InventoryGui.instance.IsContainerOpen()) { Container currentContainer = InventoryGui.instance.m_currentContainer; if ((Object)(object)currentContainer != (Object)null && (Object)(object)((Component)currentContainer).gameObject != (Object)(object)voidChest) { InventoryGui.instance.Hide(); } } ZNetView val = default(ZNetView); if (voidChest.TryGetComponent<ZNetView>(ref val)) { if (val.GetZDO() == null) { Log.Warning("Chest missing ZDO"); return false; } Container val2 = default(Container); if (voidChest.TryGetComponent<Container>(ref val2)) { if (val2.IsInUse()) { Log.Debug("Closing chest"); InventoryGui.instance.Hide(); return true; } Log.Debug($"Seidr chest is {Vector3.Distance(voidChest.transform.position, ((Component)localPlayer).transform.position)} meters away"); if (!HasSeidrCost(localPlayer, Cfg.openCost.Value, binding: false)) { return false; } val2.m_name = "Seiðr chest"; if (val2.Interact((Humanoid)(object)localPlayer, false, false)) { Log.Debug("Interact successful"); val2.m_inUse = false; val2.SetInUse(true); return true; } Log.Warning("Can't interact with chest"); return false; } Log.Warning("Chest missing Container"); return false; } Log.Warning("Chest missing ZNetView"); return false; } private static bool OkToKey(Player player) { if (!Chat.instance.HasFocus() && !Console.IsVisible() && (Object)(object)TextViewer.instance != (Object)null && !TextViewer.instance.IsVisible() && !GameCamera.InFreeFly() && !Minimap.IsOpen() && !TextInput.IsVisible() && !StoreGui.IsVisible() && !((Character)player).InCutscene() && !((Character)player).InBed() && !((Character)player).IsTeleporting() && !((Character)player).IsDead()) { return !((Character)player).InPlaceMode(); } return false; } public static void GetDetectionSet(Dictionary<string, string> harmonyIds) { foreach (KeyValuePair<string, string> harmonyId in harmonyIds) { if (Harmony.HasAnyPatches(harmonyId.Key)) { Log.Debug("Detected " + harmonyId.Value); if (!detectionSet.ContainsKey(harmonyId.Key)) { detectionSet.Add(harmonyId.Key, harmonyId.Value); } } } } public static void AddExclusion(string key) { if (detectionSet.ContainsKey(key)) { unpatchMods.Add(key, detectionSet[key]); } } public static void UnpatchMods() { foreach (KeyValuePair<string, string> unpatchMod in unpatchMods) { Log.Warning("Not compatible with " + unpatchMod.Value); _modInstance.harmony.UnpatchAll(unpatchMod.Key); detectionSet.Remove(unpatchMod.Key); Log.Warning("Disabled " + unpatchMod.Value); } } public static bool IsDetectedId(string key) { return detectionSet.ContainsKey(key); } private static void AddSectorObject(ZDOMan __instance, Vector2i sector, int area, List<ZDO> sectorObjects) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) ZNetView val = default(ZNetView); if (!((Object)(object)voidChest != (Object)null) || sectorObjects == null || !(ZoneSystem.instance.GetZone(voidChest.transform.position) != sector) || !voidChest.TryGetComponent<ZNetView>(ref val)) { return; } ZDO zDO = val.GetZDO(); if (zDO != null && (Object)(object)Player.m_localPlayer != (Object)null) { zDO.SetOwner(((Character)Player.m_localPlayer).GetOwner()); if (!sectorObjects.Contains(zDO)) { sectorObjects.Add(zDO); } } } private IEnumerator Co_WaitForZDO() { Log.Debug("Co_WaitForZDO"); float abortTime = Time.time + 20f; cancelRequest = false; while (!SetupSeidrChest() && !cancelRequest && Time.time < abortTime) { Log.Debug("Waiting for SeidrChest ZDO from server"); yield return (object)new WaitForSeconds(1f); } if (Time.time >= abortTime) { Log.Warning("Didn't receive SeidrChest ZDO from server."); } if (cancelRequest) { cancelRequest = false; Log.Warning("Server didn't find SeidrChest."); } } }