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;
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.");
}
}
}