Decompiled source of Zen ModLib v1.1.0
plugins\Zen.ModLib.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.LowLevel; using UnityEngine.SceneManagement; using UnityEngine.UI; using Valheim.SettingsGui; using Zen.Config; using Zen.Controls; using Zen.Lib; using Zen.Logging; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ZenModLib")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ZenModLib")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("A05ACC86-586F-4121-AD53-9B75C655D77D")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Zen { [BepInPlugin("ZenDragon.Zen.ModLib", "Zen.ModLib", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class ModLib : ZenMod<ModLib> { private const string PluginName = "Zen.ModLib"; private const string PluginVersion = "1.1.0"; public const string PluginGUID = "ZenDragon.Zen.ModLib"; public static ModLibConfigs Configs { get; private set; } private ModLib() { Configs = new ModLibConfigs(((BaseUnityPlugin)this).Config); } protected override void Setup() { base.RunOnServer = true; base.RequireGamepadRemap = Configs.ForceGamepadRemap.Value; } protected override void TitleScene(bool isFirstBoot) { } protected override void WorldStart() { } protected override void Shutdown() { base.Log.Message("Shutting down", 0u); } } public class ModLibConfigs { internal readonly ConfigEntry<KeyCode> InteractAltKey; internal readonly ConfigEntry<bool> ForceGamepadRemap; internal ModLibConfigs(ConfigFile configFile) { Zen.Config.Config.File = configFile; InteractAltKey = Zen.Config.Config.Define<KeyCode>(isAdmin: false, "Input", "Alternate Interact Key", (KeyCode)113, "Key to use for alternative interaction instead of Shift + E"); InteractAltKey.SettingChanged += delegate { ZenMod<ModLib>.Instance.RefreshInputs(); }; ForceGamepadRemap = Zen.Config.Config.Define(isAdmin: false, "Input", "Force Gamepad Remap", defaultValue: false, "Normally ZenMods request gamepad remapping as needed on a per mod basis.\r\nSet this to true to force the extended gamepad remap to always be applied. [restart required]"); } } } namespace Zen.Logging { public class Log { private static readonly LogLevel LogLevels; private readonly ManualLogSource _logger; private readonly ConfigEntry<bool> _config; public static bool IsEnabled => ZenMod.CallingInstance.Log.Enabled; private bool Enabled => _config.Value; static Log() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) try { ConfigFile val = (ConfigFile)AccessTools.Property(typeof(ConfigFile), "CoreConfig").GetValue(null); ConfigEntry<LogLevel> val2 = default(ConfigEntry<LogLevel>); if (!val.TryGetEntry<LogLevel>("Logging.Disk", "LogLevels", ref val2)) { throw new Exception("Logging.Disk LogLevels config info missing"); } ConfigEntry<LogLevel> val3 = default(ConfigEntry<LogLevel>); if (!val.TryGetEntry<LogLevel>("Logging.Console", "LogLevels", ref val3)) { throw new Exception("Logging.Console LogLevels config info missing"); } LogLevels = (LogLevel)(val2.Value | val3.Value); } catch (Exception ex) { Debug.LogError((object)ex.Message); Debug.LogWarning((object)"Falling back to default log levels"); LogLevels = (LogLevel)23; } } internal Log(ManualLogSource logger) { _logger = logger; _config = Zen.Config.Config.Define(isAdmin: false, "_Debug", "Enable Logging", defaultValue: false, "Generate additional debug information in the logs"); } private static string Format(object data, uint stackDepth) { MethodBase? method = new StackTrace((int)(stackDepth + 2)).GetFrame(0).GetMethod(); string arg = method.DeclaringType?.Name; string name = method.Name; return $"{arg}.{name}: {data}"; } public static void Debug(object data, ushort stackDepth = 0) { ZenMod zenMod; try { zenMod = ZenMod.CallingInstance; } catch (MissingInstanceException) { zenMod = ZenMod.ExecInstance; } zenMod.Log.Debug(data, (uint)(stackDepth + 1)); } public void Debug(object data, uint stackDepth = 0u) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (Enabled && ((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)32)) { _logger.LogDebug((object)Format(data, stackDepth)); } } public static void Info(object data, ushort stackDepth = 0) { ZenMod zenMod; try { zenMod = ZenMod.CallingInstance; } catch (MissingInstanceException) { zenMod = ZenMod.ExecInstance; } zenMod.Log.Info(data, (uint)(stackDepth + 1)); } public void Info(object data, uint stackDepth = 0u) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (Enabled && ((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)16)) { _logger.LogInfo((object)Format(data, stackDepth)); } } public static void Message(object data, ushort stackDepth = 0) { ZenMod zenMod; try { zenMod = ZenMod.CallingInstance; } catch (MissingInstanceException) { zenMod = ZenMod.ExecInstance; } zenMod.Log.Message(data, (uint)(stackDepth + 1)); } public void Message(object data, uint stackDepth = 0u) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)8)) { _logger.LogMessage(data); } } public static void Warning(object data, ushort stackDepth = 0) { ZenMod zenMod; try { zenMod = ZenMod.CallingInstance; } catch (MissingInstanceException) { zenMod = ZenMod.ExecInstance; } zenMod.Log.Warning(data, (uint)(stackDepth + 1)); } public void Warning(object data, uint stackDepth = 0u) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (((Enum)LogLevels).HasFlag((Enum)(object)(LogLevel)4)) { _logger.LogWarning((object)Format(data, stackDepth)); } } public static void Error(object data, ushort stackDepth = 0) { ZenMod zenMod; try { zenMod = ZenMod.CallingInstance; } catch (MissingInstanceException) { zenMod = ZenMod.ExecInstance; } zenMod.Log.Error(data, (uint)(stackDepth + 1)); } public void Error(object data, uint stackDepth = 0u) { _logger.LogError((object)Format(data, stackDepth)); } public static void Fatal(object data, ushort stackDepth = 0) { ZenMod zenMod; try { zenMod = ZenMod.CallingInstance; } catch (MissingInstanceException) { zenMod = ZenMod.ExecInstance; } zenMod.Log.Fatal(data, (uint)(stackDepth + 1)); } public void Fatal(object data, uint stackDepth = 0u) { _logger.LogFatal((object)Format(data, stackDepth)); } } } namespace Zen.Lib { public static class AssetIO { public static Sprite LoadSprite(string resourceName, Assembly? assembly = null) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(val, LoadResource(resourceName, assembly ?? Assembly.GetCallingAssembly())); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } private static byte[] LoadResource(string resourceName, Assembly? assembly = null) { if ((object)assembly == null) { assembly = Assembly.GetCallingAssembly(); } Type type = ((object)ZenMod.GetInstance(assembly)).GetType(); using Stream stream = assembly.GetManifestResourceStream(type.Namespace + ".Resources." + resourceName); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } } internal static class Cleanup { public static void External(ZenMod mod) { if (mod is ModLib) { ConfigTomlTypeConverterEntries(); } JotunnConfigs(((BaseUnityPlugin)mod).Config); } private static void JotunnConfigs(ConfigFile configFile) { Log.Debug("Remove config entries from Jotunn cache", 1); Dictionary<ConfigEntryBase, object> dictionary = (Dictionary<ConfigEntryBase, object>)AccessTools.Field(typeof(SynchronizationManager), "localValues").GetValue(SynchronizationManager.Instance); foreach (ConfigDefinition key2 in configFile.Keys) { ConfigEntryBase key = configFile[key2]; dictionary.Remove(key); } } private static void ConfigTomlTypeConverterEntries() { Log.Debug("Removing TomlTypeConverter Entry: StringList", 1); ((Dictionary<Type, TypeConverter>)AccessTools.Property(typeof(TomlTypeConverter), "TypeConverters").GetValue(null)).Remove(typeof(StringList)); } } public class MissingInstanceException : Exception { [CompilerGenerated] private Assembly <assembly>P; public Assembly Assembly => <assembly>P; public MissingInstanceException(Assembly assembly) { <assembly>P = assembly; base..ctor($"Mod instance not found for assembly {<assembly>P.FullName} HashCode: {<assembly>P.GetHashCode():X}"); } } public class MissingItemException : Exception { [CompilerGenerated] private string <itemName>P; [CompilerGenerated] private Vector3 <position>P; public string ItemName => <itemName>P; public Vector3 Position => <position>P; public MissingItemException(string itemName, Vector3 position) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) <itemName>P = itemName; <position>P = position; base..ctor($"Item not found in ObjectDB. Did you remove a mod? {<position>P} {<itemName>P}"); } } public static class CharacterExt { public static HudData? GetHudData(this Character c) { if (!EnemyHud.instance.m_huds.TryGetValue(c, out var value)) { return null; } return value; } } public static class ColorExt { public static string Hex(this Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new UIColor.ZColor(color).ToString(); } } public static class FireplaceExt { public static int FuelDays(this Fireplace fireplace, float? fuel = null) { float valueOrDefault = fuel.GetValueOrDefault(); if (!fuel.HasValue) { valueOrDefault = fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f); fuel = valueOrDefault; } return UI.RealToGameTime(fuel.Value * fireplace.m_secPerFuel).Days; } public static int FuelDaysMax(this Fireplace fireplace) { return UI.RealToGameTime(fireplace.m_maxFuel * fireplace.m_secPerFuel).Days; } public static bool IsFuelDaysFull(this Fireplace fireplace, float? fuel = null) { if (fireplace.m_infiniteFuel) { return true; } int num = fireplace.FuelDays(fuel); if (num > 0) { return num >= fireplace.FuelDaysMax(); } return false; } public static bool IsFuelDaysEmpty(this Fireplace fireplace, float? fuel = null) { if (!fireplace.m_infiniteFuel) { return fireplace.FuelDays(fuel) <= 0; } return false; } public static bool IsFuelEmpty(this Fireplace fireplace) { if (!fireplace.m_infiniteFuel) { return fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f) <= 0f; } return false; } } public static class GameObjectExt { public static string GetPrefabName(this GameObject gameObject) { return Utils.GetPrefabName(((Object)gameObject).name); } } public static class HudExt { private static void SendHoverItemsMessage(Hud hud, object arg) { ((Component)hud).SendMessage("UpdateHoverIcons", arg, (SendMessageOptions)1); } public static void UpdateHoverIcons(this Hud hud, params (Sprite Icon, string Label)[] elements) { SendHoverItemsMessage(hud, elements); } public static void UpdateHoverIcons(this Hud hud, params (string prefabName, string Label)[] elements) { SendHoverItemsMessage(hud, elements); } public static void UpdateHoverIcons(this Hud hud, params Sprite[] sprites) { SendHoverItemsMessage(hud, sprites); } public static void UpdateHoverIcons(this Hud hud, params string[] prefabNames) { SendHoverItemsMessage(hud, prefabNames); } } public static class HumanoidExt { public static MonoBehaviour? GetHoverInteractable(this Humanoid self) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown GameObject hoverObject = self.GetHoverObject(); return (MonoBehaviour)(Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<Interactable>() : null); } public static bool IsUnarmed(this Humanoid self) { if (self.GetLeftItem() == null) { return self.GetRightItem() == null; } return false; } public static bool IsUsingRangedWeapon(this Humanoid self) { //IL_001c: 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) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 if (self.IsUnarmed()) { return false; } ItemData currentWeapon = self.GetCurrentWeapon(); AttackType attackType = currentWeapon.m_shared.m_attack.m_attackType; if (((int)attackType == 2 || (int)attackType == 5) ? true : false) { return true; } ItemType itemType = currentWeapon.m_shared.m_itemType; if ((int)itemType != 3 && (int)itemType != 14) { return (int)itemType != 22; } return false; } public static bool IsUsingTool(this Humanoid self, bool includeFishigRod) { if (!self.RightItem.IsItemType((ItemType)19) && !self.LeftItem.IsItemType((ItemType)19)) { if (includeFishigRod) { return self.GetCurrentWeapon()?.GetName() == "$item_fishingrod"; } return false; } return true; } public static bool IsUsingPickAxe(this Humanoid self) { if (!IsPickAxe(self.RightItem)) { return IsPickAxe(self.LeftItem); } return true; static bool IsPickAxe(ItemData? item) { if (item != null) { return item.m_shared.m_damages.m_pickaxe > 0f; } return false; } } } public static class IEnumerableExt { public static IEnumerable<(TKey Key, TValue Value)> AsTuple<TKey, TValue>(this Dictionary<TKey, TValue> self) { foreach (KeyValuePair<TKey, TValue> item in self) { yield return (item.Key, item.Value); } } public static IEnumerable<(T Item, int Index)> WithIndex<T>(this IEnumerable<T> self) { return self.Select((T obj, int index) => (obj, index)); } } public static class InputExtStr { private static readonly Dictionary<GamepadInput, string> ButtonActionStringCache = new Dictionary<GamepadInput, string>(); public static string ToActionString(this GamepadInput gamepadButton) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (ButtonActionStringCache.TryGetValue(gamepadButton, out string value)) { return value; } return ButtonActionStringCache[gamepadButton] = ZInput.instance.GetBoundActionString(gamepadButton, (FloatRange?)null); } public static string ToSpriteString(this GamepadInput gamepadButton) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) string key = gamepadButton.ToActionString(); if (ZInput.s_gamepadSpriteMap.TryGetValue(key, out var value)) { string text = value["xbox"]; return "<sprite=\"xbox\" name=\"" + text + "\">"; } return string.Empty; } public static string ToDisplayText(this KeyCode keycode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected I4, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected I4, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 string text; if ((int)keycode <= 44) { if ((int)keycode <= 13) { if ((int)keycode != 0) { if ((int)keycode != 13) { goto IL_0129; } text = "$button_return"; } else { text = "$menu_none"; } } else if ((int)keycode != 32) { if ((int)keycode != 44) { goto IL_0129; } text = ","; } else { text = "$button_space"; } } else if ((int)keycode <= 271) { if ((int)keycode != 46) { if ((int)keycode != 271) { goto IL_0129; } text = "$button_return"; } else { text = "."; } } else { switch (keycode - 303) { case 1: goto IL_00f1; case 0: goto IL_00f9; case 5: goto IL_0101; case 4: goto IL_0109; case 3: goto IL_0111; case 2: goto IL_0119; } switch (keycode - 323) { case 0: break; case 1: goto IL_00a6; case 2: goto IL_00b1; case 3: goto IL_00b9; case 4: goto IL_00c1; default: goto IL_0129; } text = "$button_mouse0"; } goto IL_0137; IL_00f1: text = "$button_lshift"; goto IL_0137; IL_0109: text = "$button_ralt"; goto IL_0137; IL_0129: text = ((object)(KeyCode)(ref keycode)).ToString(); goto IL_0137; IL_00b9: text = "Mouse-3"; goto IL_0137; IL_00c1: text = "Mouse-4"; goto IL_0137; IL_00f9: text = "$button_rshift"; goto IL_0137; IL_00b1: text = "$button_mouse2"; goto IL_0137; IL_0137: string text2 = text; return Localization.instance.Localize(text2); IL_00a6: text = "$button_mouse1"; goto IL_0137; IL_0119: text = "$button_rctrl"; goto IL_0137; IL_0101: text = "$button_lalt"; goto IL_0137; IL_0111: text = "$button_lctrl"; goto IL_0137; } } public static class InventoryGridExt { public static void ShowAmountText(this InventoryGrid grid, bool isVisible, Vector2i pos) { //IL_0002: 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) grid.ShowAmountText(isVisible, pos.x * (pos.y + 1)); } public static void ShowAmountText(this InventoryGrid grid, bool isVisible, int index = -1) { InventoryGrid grid2 = grid; if (grid2.m_elements.Count == 0) { return; } if (grid2.m_elements.Count < index) { throw new ArgumentOutOfRangeException("index"); } Timing.NextFrame(delegate { Log.Info($"Show grid element amount: {isVisible} at index: {index}", 0); if (index == -1) { CollectionExtensions.Do<Element>((IEnumerable<Element>)grid2.m_elements, (Action<Element>)delegate(Element element) { ((Component)element.m_amount).gameObject.SetActive(isVisible); }); } else { ((Component)grid2.m_elements[index].m_amount).gameObject.SetActive(isVisible); } }); } } public static class InventoryGuiExt { private static bool _isRestoringStackAllButton; public static void ShowStackAllButton(this InventoryGui self, bool show) { Log.Info($"Show StackAll button: {show}", 0); GameObject btn = ((Component)self.m_stackAllButton).gameObject; btn.SetActive(show); if (!show && !_isRestoringStackAllButton) { Timing.StartCoroutine(Restore()); } IEnumerator Restore() { _isRestoringStackAllButton = true; while (!btn.activeSelf) { Log.Info("Coroutine set to restore StackAll button visibility when inventory is closed.", 0); yield return (object)new WaitWhile((Func<bool>)InventoryGui.IsVisible); yield return (object)new WaitForSeconds(0.5f); if (!InventoryGui.IsVisible()) { btn.SetActive(true); } } _isRestoringStackAllButton = false; Log.Info("StackAll button visibility restored.", 0); } } } public static class ItemDataExt { public static bool TryGetRecipe(this ItemDrop itemDrop, out Recipe recipe) { return itemDrop.m_itemData.TryGetRecipe(out recipe); } public static bool TryGetRecipe(this ItemData item, out Recipe recipe) { return Object.op_Implicit((Object)(object)(recipe = ObjectDB.instance.GetRecipe(item))); } public static ItemType GetItemType(this ItemData? item) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return (ItemType)(((??)item?.m_shared.m_itemType) ?? 0); } public static bool IsItemType(this ItemData? item, ItemType type) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (item == null) { return false; } return item.m_shared.m_itemType == type; } public static bool IsStackable(this ItemData item) { return item.m_shared.m_maxStackSize > 1; } public static bool IsStackable(this ItemDrop item) { return item.m_itemData.m_shared.m_maxStackSize > 1; } public static string GetPrefabName(this ItemDrop itemDrop) { return Utils.GetPrefabName(((Object)itemDrop).name); } public static string GetPrefabName(this ItemData item) { if (!Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return ((Object)ObjectDB.instance.GetItemPrefab(item.m_shared)).name; } return ((Object)item.m_dropPrefab).name; } public static string GetName(this ItemData item) { return item.m_shared.m_name; } public static string GetName(this ItemDrop item) { return item.m_itemData.m_shared.m_name; } public static Sprite GetIcon(this ItemData item, int variant) { return item.m_shared.m_icons[variant]; } public static Sprite GetIcon(this ItemDrop item) { return item.m_itemData.GetIcon(); } public static Sprite GetIcon(this ItemDrop item, int variant) { return item.m_itemData.GetIcon(variant); } public static int GetStableHashCode(this ItemData item) { return StringExtensionMethods.GetStableHashCode(item.GetPrefabName()); } public static int GetStableHashCode(this ItemDrop itemDrop) { return StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(((Object)itemDrop).name)); } public static bool IsEqual(this ItemData item, ItemData other) { if (!(((Object)item.m_dropPrefab).name == ((Object)other.m_dropPrefab).name) || !(item.GetName() == other.GetName()) || item.m_variant != other.m_variant || item.m_quality != other.m_quality || !Mathf.Approximately(item.m_durability, other.m_durability)) { return false; } foreach (KeyValuePair<string, string> customDatum in item.m_customData) { if (!other.m_customData.TryGetValue(customDatum.Key, out var value)) { return false; } if (value != customDatum.Value) { return false; } } return true; } public static bool HaveItemData(this Inventory inventory, ItemData itemData) { foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.IsEqual(itemData)) { return true; } } return false; } public static void SwapItem(this Inventory thisInv, ItemData thisItem, Inventory otherInv, ItemData otherItem) { //IL_0001: 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_0008: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Vector2i gridPos = thisItem.m_gridPos; Vector2i gridPos2 = otherItem.m_gridPos; bool equipped = thisItem.m_equipped; bool equipped2 = otherItem.m_equipped; thisInv.RemoveItem(thisItem); otherInv.RemoveItem(otherItem); thisInv.AddItem(otherItem, gridPos); otherInv.AddItem(thisItem, gridPos2); Player player = Player.m_localPlayer; if (equipped) { SwitchEquipped(thisItem, otherItem); } else if (equipped2) { SwitchEquipped(otherItem, thisItem); } void SwitchEquipped(ItemData a, ItemData b) { //IL_0013: 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) ((Humanoid)player).UnequipItem(a, false); if (a.m_shared.m_itemType == b.m_shared.m_itemType || (a.IsWeapon() && b.IsWeapon())) { ((Humanoid)player).EquipItem(b, false); } } } } public static class ItemStandExt { public static bool IsBossStone(this ItemStand itemStand) { if (Object.op_Implicit((Object)(object)itemStand.m_guardianPower)) { return Object.op_Implicit((Object)(object)((Component)itemStand).GetComponentInParent<BossStone>()); } return false; } public static bool IsAutoAttach(this ItemStand itemStand) { return itemStand.m_autoAttach; } public static bool CanBeRemoved(this ItemStand itemStand) { return itemStand.m_canBeRemoved; } } public static class MaterialExt { private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor"); private static readonly int Metallic = Shader.PropertyToID("_Metallic"); private static readonly int Glossiness = Shader.PropertyToID("_Glossiness"); public static void SetMetalic(this Material mat, float range) { mat.SetFloat(Metallic, range); } public static void SetGlossiness(this Material mat, float range) { mat.SetFloat(Glossiness, range); } public static void SetGlow(this Material mat, float intensity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) mat.SetEmission(Color.white * intensity); } public static void SetEmission(this Material mat, Color color) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) mat.SetColor(EmissionColor, color); } } public static class MathExt { public static bool InRange(this GameObject self, GameObject target, float range) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(self.transform.position - target.transform.position) < range * range; } public static bool InRange(this GameObject self, Vector3 target, float range) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(self.transform.position - target) < range * range; } public static bool InRange(this MonoBehaviour self, Vector3 target, float range) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(((Component)self).transform.position - target) < range * range; } public static bool InRange(this MonoBehaviour self, MonoBehaviour target, float range) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(((Component)self).transform.position - ((Component)target).transform.position) < range * range; } public static bool InRange(this MonoBehaviour self, GameObject target, float range) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(((Component)self).transform.position - target.transform.position) < range * range; } public static float DistanceToSqr(this GameObject self, Vector3 target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(self.transform.position - target); } public static float DistanceToSqr(this MonoBehaviour self, MonoBehaviour target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(((Component)self).transform.position - ((Component)target).transform.position); } public static float DistanceToSqr(this MonoBehaviour self, Vector3 target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(((Component)self).transform.position - target); } public static float DistanceToSqr(this Vector3 source, Vector3 target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(source - target); } public static float DistanceToXZ(this GameObject self, GameObject target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return self.transform.position.DistanceToXZ(target.transform.position); } public static float DistanceToXZ(this MonoBehaviour self, MonoBehaviour target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return ((Component)self).transform.position.DistanceToXZ(((Component)target).transform.position); } public static float DistanceToXZ(this MonoBehaviour self, Vector3 target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return ((Component)self).transform.position.DistanceToXZ(target); } public static float DistanceToXZ(this Vector3 source, Vector3 target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = source; val.y = 0f; Vector3 val2 = val; val = target; val.y = 0f; return Vector3.Distance(val2, val); } public static float DistanceTo(this GameObject self, GameObject target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return self.transform.position.DistanceTo(target.transform.position); } public static float DistanceTo(this MonoBehaviour self, MonoBehaviour target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return ((Component)self).transform.position.DistanceTo(((Component)target).transform.position); } public static float DistanceTo(this MonoBehaviour self, Vector3 target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return ((Component)self).transform.position.DistanceTo(target); } public static float DistanceTo(this Vector3 source, Vector3 target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(source, target); } public static bool Approximately(this Vector3 self, Vector3 other) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(self - other) < 0.0001f; } public static Vector3 XZY(this Vector3 self) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(self.x, self.z, self.y); } public static float DistanceToPlayer(this Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return position.DistanceToCharacter((Character)(object)Player.m_localPlayer); } public static float DistanceToCharacter(this Vector3 position, Character c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return Mathf.Sqrt(position.DistanceToCharacterSqr(c)); } public static float DistanceToCharacterSqr(this Vector3 position, Character c) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return Vector3.SqrMagnitude(((Component)c).transform.position - position); } public static float AngleFromPlayer(this Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return position.AngleFromCharacter((Character)(object)Player.m_localPlayer); } public static float AngleFromCharacter(this Vector3 position, Character c) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_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_001d: 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_0023: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)c).transform; Vector3 val = position - transform.position; Vector3 normalized = ((Vector3)(ref val)).normalized; return Vector3.SignedAngle(transform.forward, normalized, Vector3.up); } public static float AngleFromCamera(this Vector3 position) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)GameCamera.instance.m_camera).transform; Vector3 val = position - transform.position; Vector3 normalized = ((Vector3)(ref val)).normalized; return Vector3.SignedAngle(transform.forward, normalized, Vector3.up); } public static float AlignmentRatioTo(this Transform transform, Vector3 destPosition) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //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) Vector3 val = destPosition - transform.position; Vector3 normalized = ((Vector3)(ref val)).normalized; return Vector3.Dot(transform.forward, normalized); } } public static class MessageHudExt { public static void ShowMessage(this MessageHud msgHud, long targetPeerID, MessageType type, string text) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected I4, but got Unknown ZRoutedRpc.instance.InvokeRoutedRPC(targetPeerID, "ShowMessage", new object[2] { (int)type, text }); } } public static class PlayerExt { public static bool IsReady(this Player? player) { if (Object.op_Implicit((Object)(object)player) && !((Character)player).IsDead()) { return !((Character)player).IsTeleporting(); } return false; } public static bool Is(this Player? player, Character other) { if (player.IsReady()) { return (Object)(object)player == (Object)(object)other; } return false; } public static void SelectRepairTool(this Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) player.SetSelectedPiece(Vector2Int.zero); } public static void RemoveGuardianPower(this Player player) { player.m_guardianPower = string.Empty; player.m_guardianPowerHash = 0; player.m_guardianSE = null; } } public static class PrefabManagerExt { public static CraftingStation? GetCraftingStation(this PrefabManager prefabManager, string stationName) { string internalName = CraftingStations.GetInternalName(stationName); GameObject prefab = prefabManager.GetPrefab(internalName); if (!Object.op_Implicit((Object)(object)prefab)) { return null; } return prefab.GetComponent<CraftingStation>(); } } public static class StringExt { public static string ToHumanString(this int num) { if (num >= 1000000) { if (num >= 1000000000) { return "∞"; } return $"{Mathf.Round((float)num / 1000000f):0}M"; } if (num >= 10000) { return $"{Mathf.Round((float)num / 1000f):0}K"; } return num.ToString(); } public static string Localize(this string? s) { return Localization.instance.Localize(s); } public static string ToProperCase(this string? str) { return str?[0].ToString().ToUpper() + str?.Substring(1).ToLower(); } public static string RegexPattern(this string? pattern, bool localize = true) { return pattern.RegexPattern((string s) => s, localize); } public static string RegexPattern(this string? pattern, Func<string, string> func, bool localize = true) { return Regex.Escape(func(localize ? pattern.Localize() : (pattern ?? string.Empty))); } public static string GlyphFix(this string s, bool onlyIfGamepad = true) { if (!ZInput.IsGamepadActive() && onlyIfGamepad) { return s; } return s.Replace("[<color=yellow><b><sprite=", "<sprite=").Replace("\"></b></color>]", "\">"); } } public static class WardAccessExt { public static bool CanAccessWard(this GameObject self, bool flash) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return self.transform.position.CanAccessWard(flash); } public static bool CanAccessWard(this MonoBehaviour self, bool flash) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ((Component)self).transform.position.CanAccessWard(flash); } public static bool CanAccessWard(this Vector3 self, bool flash) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return PrivateArea.CheckAccess(self, 0f, flash, false); } } public static class ZdoExt { private static readonly int ZdoKeyEpochStart = StringExtensionMethods.GetStableHashCode("Zen_EpochStart"); public static bool IsPlayerCreated(this ZDO zdo) { if (zdo.IsValid()) { return zdo.GetLong(ZDOVars.s_creator, 0L) != 0; } return false; } private static bool HasEpoch(this ZDO zdo) { return zdo.GetEpoch() != 0.0; } private static double GetEpoch(this ZDO zdo) { return zdo.GetDouble(ZdoKeyEpochStart); } public static float GetAgeSeconds(this ZDO zdo) { return (float)(ZNet.instance.GetTimeSeconds() - zdo.GetEpoch()); } public static void AccelerateAge(this ZDO zdo, float seconds) { if (!zdo.IsOwner()) { Log.Error("Cannot age this ZDO, not owner.", 0); return; } double value = Math.Max(zdo.GetEpoch() - (double)seconds, 0.0); zdo.Set(ZdoKeyEpochStart, value); } public static void RemoveEpoch(this ZDO zdo) { if (!zdo.IsOwner()) { Log.Error("Cannot remove epoch time because not owner of this ZDO.", 0); } else { zdo.Set(ZdoKeyEpochStart, 0.0); } } public static void InitEpoch(this ZDO zdo) { if (!zdo.IsOwner()) { Log.Error("Cannot init epoch time because not owner of this ZDO.", 0); } else if (!zdo.HasEpoch()) { zdo.Set(ZdoKeyEpochStart, ZNet.instance.GetTimeSeconds()); } } public static string GetPrefabName(this ZDO zdo) { return ((Object)ZNetScene.instance.GetPrefab(zdo.GetPrefab())).name; } public static double GetDouble(this ZDO zdo, string name, double defaultValue = 0.0) { return zdo.GetDouble(StringExtensionMethods.GetStableHashCode(name), defaultValue); } public static double GetDouble(this ZDO zdo, int hash, double defaultValue = 0.0) { long num = BitConverter.DoubleToInt64Bits(defaultValue); return BitConverter.Int64BitsToDouble(zdo.GetLong(hash, num)); } public static void Set(this ZDO zdo, string name, double value) { zdo.Set(StringExtensionMethods.GetStableHashCode(name), value); } public static void Set(this ZDO zdo, int hash, double value) { long num = BitConverter.DoubleToInt64Bits(value); zdo.Set(hash, num); } public static ItemData? GetItemData(this ZDO zdo, string itemPrefabName, int index = -1) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (Utility.IsNullOrWhiteSpace(itemPrefabName)) { return null; } ItemData val = new ItemData(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemPrefabName); if (!Object.op_Implicit((Object)(object)itemPrefab)) { throw new MissingItemException(itemPrefabName, zdo.GetPosition()); } val.m_dropPrefab = itemPrefab; val.m_shared = itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared; if (index > -1) { ItemDrop.LoadFromZDO(index, val, zdo); } else { ItemDrop.LoadFromZDO(val, zdo); } return val; } } public static class ZInputExt { public static string Path(this GamepadInput g) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return ZInput.s_gamepadInputPathMap[g]; } public static string Path(this MouseButton m) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ZInput.MouseButtonToPath(m, true); } public static string Path(this KeyCode k) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ZInput.KeyCodeToPath(k, false); } public static string Path(this Key k) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ZInput.KeyToPath(k); } public static ButtonDef GetButtonDef(this ZInput self, ActionString actionString) { return self.GetButtonDef(actionString.Name); } public static bool RemoveButton(this ZInput self, string name) { if (!self.m_buttons.TryGetValue(name, out var value)) { return false; } Log.Info("Remove Button: " + name, 1); self.UnsubscribeButton(value); self.m_buttons.Remove(value.Name); return true; } private static bool RemapToPath(this ButtonDef self, string newPath, bool? altKey = null, bool? showHints = null, bool? rebindable = null, float? repeatDelay = null, float? repeatInterval = null) { if (self.GetActionPath(true) == newPath && (!altKey.HasValue || altKey == self.AltKey) && (!showHints.HasValue || showHints == self.ShowHints) && (!rebindable.HasValue || rebindable == self.Rebindable) && (!repeatDelay.HasValue || Mathf.Approximately(repeatDelay.Value, self.m_repeatDelay)) && (!repeatInterval.HasValue || Mathf.Approximately(repeatInterval.Value, self.m_repeatInterval))) { return false; } self.Rebind(newPath); if (altKey.HasValue) { self.AltKey = altKey.Value; } if (showHints.HasValue) { self.ShowHints = showHints.Value; } if (rebindable.HasValue) { self.Rebindable = rebindable.Value; } if (repeatDelay.HasValue) { self.m_repeatDelay = repeatDelay.Value; } if (repeatInterval.HasValue) { self.m_repeatInterval = repeatInterval.Value; } return true; } public static bool RemapTo(this ButtonDef self, KeyCode newInput, bool? altKey = null, bool? showHints = null, bool? rebindable = null, float? repeatDelay = null, float? repeatInterval = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return self.RemapToPath(newInput.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval); } public static bool RemapTo(this ButtonDef self, GamepadInput newInput, bool? altKey = null, bool? showHints = null, bool? rebindable = null, float? repeatDelay = null, float? repeatInterval = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return self.RemapToPath(newInput.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval); } public static string GetGamepadPlatform(this ZInput zi) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0018: Expected I4, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 GamepadGlyphs currentGlyph = ZInput.CurrentGlyph; switch ((int)currentGlyph) { case 0: { GamepadType connectedGamepadType = ZInput.ConnectedGamepadType; return ((int)connectedGamepadType == 3) ? "xbox" : ((connectedGamepadType - 4 > 1) ? "xbox" : "ps5"); } case 1: return "xbox"; case 2: return "ps5"; default: return "xbox"; } } public static string GetGamepadSpriteName(this ZInput zi, GamepadInput gamepadInput, string platform) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) string key = zi.MapKeyFromPath(ZInput.s_gamepadInputPathMap[gamepadInput]); return ZInput.s_gamepadSpriteMap[key][platform]; } public static string GetSpriteTag(this ZInput zi, GamepadInput gamepadInput) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) string gamepadPlatform = zi.GetGamepadPlatform(); string gamepadSpriteName = zi.GetGamepadSpriteName(gamepadInput, gamepadPlatform); return "<sprite=\"" + gamepadPlatform + "\" name=\"" + gamepadSpriteName + "\">"; } } public static class ZNetViewExt { } public static class ZRoutedRpcExt { public static void Unregister(this ZRoutedRpc? zrpc, string name) { if (zrpc != null && zrpc.m_functions.Remove(StringExtensionMethods.GetStableHashCode(name))) { Log.Info("Unregistered RPC: " + name, 0); } } } public interface IRedecorate { void OnRedecorateBefore(); void OnRedecorateAfter((Vector3 Position, Quaternion Rotation) before); } public enum HintType { Build, Combat, Bow, Inventory, Barber, Fishing, Radial } [HarmonyPatch] public class KeyHint { private static HintType _activeType; private readonly Dictionary<string, (GameObject Keyboard, GameObject Gamepad)> _allHints = new Dictionary<string, (GameObject, GameObject)>(); private const string Section = "_SECTION_"; private static readonly string[] ControlPaths = new string[2] { "Keyboard/_SECTION_/Text", "Gamepad/Text - _SECTION_" }; private const float UpdateDelay = 0.1f; private static float _lastUpdateTime; private event Action? UpdateBuildHints; private event Action? UpdateCombatHints; private event Action? UpdateBowHints; private event Action? UpdateInventoryHints; private event Action? UpdateBarberHints; private event Action? UpdateFishingHints; private event Action? UpdateRadialHints; internal void RemoveAll() { foreach (var value in _allHints.Values) { Object.Destroy((Object)(object)value.Keyboard); Object.Destroy((Object)(object)value.Gamepad); } _allHints.Clear(); this.UpdateBuildHints = null; this.UpdateCombatHints = null; this.UpdateBowHints = null; this.UpdateInventoryHints = null; this.UpdateBarberHints = null; this.UpdateFishingHints = null; this.UpdateRadialHints = null; } private static GameObject GetHintRoot(HintType hintType) { return (GameObject)(hintType switch { HintType.Build => KeyHints.instance.m_buildHints, HintType.Combat => KeyHints.instance.m_combatHints, HintType.Bow => KeyHints.instance.m_combatHints, HintType.Inventory => KeyHints.instance.m_inventoryHints, HintType.Barber => KeyHints.instance.m_barberHints, HintType.Fishing => KeyHints.instance.m_fishingHints, HintType.Radial => KeyHints.instance.m_radialHints, _ => throw new ArgumentOutOfRangeException("hintType", hintType, null), }); } public static void Create(HintType hintType, ActionString action, int index = -1, bool startVisible = false) { Create(ZenMod.CallingInstance, hintType, action.Name, index, startVisible); } public static void Create(HintType hintType, string hintName, int index = -1, bool startVisible = false) { Create(ZenMod.CallingInstance, hintType, hintName, index, startVisible); } private static void Create(ZenMod mod, HintType hintType, string hintName, int index = -1, bool startVisible = false) { //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) GameObject hintRoot = GetHintRoot(hintType); (GameObject, GameObject) value = default((GameObject, GameObject)); Transform val = hintRoot.transform.Find("Keyboard"); GameObject val2 = Object.Instantiate<GameObject>(((Component)val.GetChild(0)).gameObject, val); if (index >= 0) { val2.transform.SetSiblingIndex(index); } ((Object)val2).name = hintName; ((Component)val2.transform.Find("Text")).GetComponent<TMP_Text>().text = "$" + hintName; ((Component)val2.transform.Find("key_bkg/Key")).GetComponent<TMP_Text>().text = "$KEY_" + hintName; value.Item1 = val2; val2.SetActive(startVisible); Transform val3 = hintRoot.transform.Find("Gamepad"); GameObject val4 = Object.Instantiate<GameObject>(((Component)val3.GetChild(0)).gameObject, val3); if (index >= 0) { val4.transform.SetSiblingIndex(index); } ((Object)val4).name = "Text - " + hintName; val4.GetComponent<TMP_Text>().text = "$" + hintName + " <mspace=0.6em>$KEY_Joy" + hintName + "</mspace>"; value.Item2 = val4; foreach (Transform item in val3) { ((Object)item).name = ((Object)item).name.Replace("/", "-"); } val4.SetActive(startVisible); mod.KeyHint._allHints.Add(hintName, value); Localization.instance.Localize(hintRoot.transform); } public static void SetEvent(HintType hintType, Action action) { KeyHint keyHint = ZenMod.CallingInstance.KeyHint; switch (hintType) { case HintType.Build: keyHint.UpdateBuildHints += action; break; case HintType.Combat: keyHint.UpdateCombatHints += action; break; case HintType.Bow: keyHint.UpdateBowHints += action; break; case HintType.Inventory: keyHint.UpdateInventoryHints += action; break; case HintType.Barber: keyHint.UpdateBarberHints += action; break; case HintType.Fishing: keyHint.UpdateFishingHints += action; break; case HintType.Radial: keyHint.UpdateRadialHints += action; break; default: throw new ArgumentOutOfRangeException("hintType", hintType, "Unknown hint type."); } } public static void SetVisible(ActionString action, bool isVisible) { SetVisible(_activeType, action.Name, isVisible); } public static void SetVisible(string hintName, bool isVisible) { SetVisible(_activeType, hintName, isVisible); } private static void SetVisible(HintType hintType, string hintName, bool isVisible, string[]? searchPaths = null) { string[] array = searchPaths ?? ControlPaths; foreach (string text in array) { bool flag = text.StartsWith("Gamepad"); if (flag && hintName == "Copy") { SetVisible(hintType, "Copy Alt1-2", isVisible && ZInput.IsNonClassicFunctionality(), new string[1] { text }); SetVisible(hintType, "Copy Default", isVisible && !ZInput.IsNonClassicFunctionality(), new string[1] { text }); break; } string text2 = text.Replace("_SECTION_", hintName); Transform val = GetHintRoot(hintType).transform.Find(text2); if (!Object.op_Implicit((Object)(object)val)) { Log.Error("Node not found: " + text2, 0); break; } if (flag) { ((Component)val).gameObject.SetActive(isVisible); } else { ((Component)val.parent).gameObject.SetActive(isVisible); } } } [HarmonyPostfix] [HarmonyPatch(typeof(KeyHints), "UpdateHints")] private static void KeyHints_UpdateHints(KeyHints __instance) { if (!__instance.m_keyHintsEnabled || (!UI.IsOpen && Time.time < _lastUpdateTime + 0.1f)) { return; } _lastUpdateTime = Time.time; if (__instance.m_buildHints.activeSelf) { InvokeHint(HintType.Build, (KeyHint hint) => hint.UpdateBuildHints); } if (__instance.m_inventoryHints.activeSelf) { InvokeHint(HintType.Inventory, (KeyHint hint) => hint.UpdateInventoryHints); } if (__instance.m_combatHints.activeSelf) { InvokeHint(HintType.Combat, (KeyHint hint) => hint.UpdateCombatHints); } if (__instance.m_combatHints.activeSelf && ((Humanoid)(object)Player.m_localPlayer).IsUsingRangedWeapon()) { InvokeHint(HintType.Bow, (KeyHint hint) => hint.UpdateBowHints); } if (__instance.m_fishingHints.activeSelf) { InvokeHint(HintType.Fishing, (KeyHint hint) => hint.UpdateFishingHints); } if (__instance.m_barberHints.activeSelf) { InvokeHint(HintType.Barber, (KeyHint hint) => hint.UpdateBarberHints); } if (__instance.m_radialHints.activeSelf) { InvokeHint(HintType.Radial, (KeyHint hint) => hint.UpdateRadialHints); } } private static void InvokeHint(HintType hintType, Func<KeyHint, Action?> eventSelector) { Func<KeyHint, Action?> eventSelector2 = eventSelector; _activeType = hintType; foreach (Action item in ZenMod.Instances.Values.Select((ZenMod mod) => eventSelector2(mod.KeyHint))) { item?.Invoke(); } } } public class Hotload { private readonly HashSet<Object> _hotloadObjects = new HashSet<Object>(); internal bool IsPrefabInitInvoked { get; private set; } public event Func<IEnumerable<Object>>? PrefabInit; internal Hotload() { } public void Track(Object obj) { Log.Info($"Track: {obj.name} << {((object)obj).GetType()}", 0); _hotloadObjects.Add(obj); } public void Untrack(Object obj) { if (_hotloadObjects.Contains(obj)) { Log.Debug($"Untrack: {obj.name} @ {((object)obj).GetType()}", 0); _hotloadObjects.Remove(obj); } } internal void RestoreAll() { Log.Info("Restoring all hot-tracked modded objects to their original state", 0); foreach (Object hotloadObject in _hotloadObjects) { Log.Info($"Remove: {hotloadObject.name} >> {((object)hotloadObject).GetType()}", 0); Object.Destroy(hotloadObject); } } internal void PrefabInitInvoke() { if (IsPrefabInitInvoked) { throw new Exception("PrefabInitInvoke already invoked"); } Log.Info("Prefab Init", 0); foreach (Object item in this.PrefabInit?.Invoke() ?? Array.Empty<Object>()) { Track(item); } IsPrefabInitInvoked = true; } } internal static class Secure { public static string Encrypt(string plainText, byte[] key, Encoding? encoding = null) { return Convert.ToBase64String(Encrypt((encoding ?? Encoding.UTF8).GetBytes(plainText), key).ToArray()); } public static byte[] Encrypt(byte[] input, byte[] key) { using Aes aes = Aes.Create(); aes.Key = key; using ICryptoTransform cryptoTransform = aes.CreateEncryptor(); byte[] collection = cryptoTransform.TransformFinalBlock(input, 0, input.Length); List<byte> list = new List<byte>(); list.AddRange(aes.IV); list.AddRange(collection); aes.Clear(); return list.ToArray(); } public static string Decrypt(string cipherBase64, byte[] key, Encoding? encoding = null) { byte[] bytes = Decrypt(Convert.FromBase64String(cipherBase64), key); return (encoding ?? Encoding.UTF8).GetString(bytes); } public static byte[] Decrypt(byte[] input, byte[] key) { try { using Aes aes = Aes.Create(); aes.Key = key; aes.IV = input.Take(aes.BlockSize / 8).ToArray(); byte[] array = input.Skip(aes.IV.Length).ToArray(); using ICryptoTransform cryptoTransform = aes.CreateDecryptor(); byte[] result = cryptoTransform.TransformFinalBlock(array, 0, array.Length); aes.Clear(); return result; } catch { return Array.Empty<byte>(); } } public static byte[] GenerateAesKey() { using Aes aes = Aes.Create(); return aes.Key; } public static byte[] DeriveKey(string password, byte[] salt, int iterations = 10000, int keyLength = 32) { using Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, iterations); return rfc2898DeriveBytes.GetBytes(keyLength); } public static byte[] GenerateSalt(int saltLength = 32) { using RNGCryptoServiceProvider rNGCryptoServiceProvider = new RNGCryptoServiceProvider(); byte[] array = new byte[saltLength]; rNGCryptoServiceProvider.GetBytes(array); return array; } public static byte[] FromHexStringToBytes(this string hexString) { try { byte[] array = new byte[hexString.Length / 2]; for (int i = 0; i < array.Length; i++) { array[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); } return array; } catch { throw new InvalidDataException("HexString is not valid for conversion to bytes"); } } } public class Tally : Tally<string> { } public class Tally<T> : Dictionary<T, int> { public new int this[T key] { get { if (!TryGetValue(key, out var value)) { return 0; } return value; } set { base[key] = value; } } public HashSet<T> Diff(Tally<T>? other, IEqualityComparer<KeyValuePair<T, int>>? comparer = null) { HashSet<T> hashSet; if (other == null) { hashSet = new HashSet<T>(); { foreach (T key in base.Keys) { hashSet.Add(key); } return hashSet; } } IEnumerable<KeyValuePair<T, int>> first = this.Except<KeyValuePair<T, int>>(other, comparer); IEnumerable<KeyValuePair<T, int>> second = other.Except<KeyValuePair<T, int>>(this, comparer); hashSet = new HashSet<T>(); foreach (T item in from item in first.Union<KeyValuePair<T, int>>(second, comparer) select item.Key) { hashSet.Add(item); } return hashSet; } public IEnumerable<(T Key, int Amount)> Sorted() { return this.OrderByDescending(delegate(KeyValuePair<T, int> pair) { KeyValuePair<T, int> keyValuePair2 = pair; return keyValuePair2.Value; }).Select(delegate(KeyValuePair<T, int> pair) { KeyValuePair<T, int> keyValuePair = pair; T key = keyValuePair.Key; keyValuePair = pair; return (key, keyValuePair.Value); }); } } public class TerminalCtrl { private readonly List<string> _commands = new List<string>(); private readonly string _prefix; internal TerminalCtrl(string prefix) { _prefix = prefix; } public ConsoleCommand CreateCommand(string name, string description, bool isCheat, Action<string[]> action) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown Action<string[]> action2 = action; string text = _prefix + "_" + name; _commands.Add(text); Log.Info("Terminal command added: " + text, 0); return new ConsoleCommand(text, description, (ConsoleEvent)delegate(ConsoleEventArgs args) { action2(args.Args); }, isCheat, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } internal void Shutdown() { foreach (string command in _commands) { Terminal.commands.Remove(command.ToLower()); } _commands.Clear(); } } public static class Timing { public static Coroutine StartCoroutine(IEnumerator coroutine) { return ((MonoBehaviour)ZenMod.CallingInstance).StartCoroutine(coroutine); } public static void StopCoroutine(Coroutine? coroutine) { if (coroutine != null) { ((MonoBehaviour)ZenMod.CallingInstance).StopCoroutine(coroutine); } } public static Coroutine SkipFrames(this MonoBehaviour component, int frames, Action action) { return component.StartCoroutine(_SkipFrames(frames, action)); } public static Coroutine SkipFrames(int frames, Action action) { return ((MonoBehaviour)(object)ZenMod.CallingInstance).SkipFrames(frames, action); } public static Coroutine NextFrame(this MonoBehaviour component, Action action) { return component.StartCoroutine(_SkipFrames(1, action)); } public static Coroutine NextFrame(Action action) { return ((MonoBehaviour)(object)ZenMod.CallingInstance).NextFrame(action); } public static Coroutine EndOfFrame(this MonoBehaviour component, Action action) { return component.StartCoroutine(_EndOfFrame(action)); } public static Coroutine EndOfFrame(Action action) { return ((MonoBehaviour)(object)ZenMod.CallingInstance).EndOfFrame(action); } public static Coroutine Delay(this MonoBehaviour component, float seconds, Action action) { return component.StartCoroutine(_Delay(seconds, action)); } public static Coroutine Delay(float seconds, Action action) { return ((MonoBehaviour)(object)ZenMod.CallingInstance).Delay(seconds, action); } public static Coroutine When(this MonoBehaviour component, Func<bool> condition, Action action) { return component.StartCoroutine(_When(condition, action)); } public static Coroutine When(Func<bool> condition, Action action) { return ((MonoBehaviour)(object)ZenMod.CallingInstance).When(condition, action); } public static Coroutine WhenNot(this MonoBehaviour component, Func<bool> condition, Action action) { Func<bool> condition2 = condition; return component.StartCoroutine(_When(() => !condition2(), action)); } public static Coroutine WhenNot(Func<bool> condition, Action action) { return ((MonoBehaviour)(object)ZenMod.CallingInstance).WhenNot(condition, action); } private static IEnumerator _When(Func<bool> condition, Action action) { yield return (object)new WaitUntil(condition); action(); } private static IEnumerator _Delay(float delay, Action action) { yield return (object)new WaitForSeconds(delay); action(); } private static IEnumerator _SkipFrames(int frames, Action action) { for (int i = 0; i < frames; i++) { yield return null; } action(); } private static IEnumerator _EndOfFrame(Action action) { yield return (object)new WaitForEndOfFrame(); action(); } } public static class UI { public static string PromptUseItem => Prompt("1-8"); public static string PromptInteract => Prompt("$KEY_Use"); public static string PromptInteractAlt => Prompt($"$KEY_{ControlInputs.InteractAlt}"); public static bool IsBuildModeActive { get { if (!Hud.IsPieceSelectionVisible()) { if (Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Hud.instance.m_buildHud)) { return Hud.instance.m_buildHud.activeSelf; } return false; } return true; } } internal static CanvasScaler? CanvasScaler { get; set; } public static float ScaleFactor { get { if (!Object.op_Implicit((Object)(object)CanvasScaler)) { return 1f; } return CanvasScaler.scaleFactor; } } public static bool IsOpen { get { if (!Object.op_Implicit((Object)(object)Game.instance) || !Object.op_Implicit((Object)(object)GameCamera.instance) || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return true; } if (((Character)Player.m_localPlayer).TakeInput()) { return IsBuildModeActive; } return true; } } public static string Prompt(string text) { return "[<color=yellow><b>" + text + "</b></color>]"; } public static TimeSpan RealToGameTime(float seconds) { float num = seconds / (float)EnvMan.instance.m_dayLengthSec; return TimeSpan.FromDays((num <= 0f) ? 0f : (num + 0.51f)); } public static string RemainingTimeText(float seconds, float secPerFuel = -1f) { bool num = secPerFuel > (float)EnvMan.instance.m_dayLengthSec; TimeSpan timeSpan = (num ? RealToGameTime(seconds) : TimeSpan.FromSeconds(seconds)); string result = "None"; if (num) { if (timeSpan.Days > 0) { result = $"{timeSpan.Days} day" + ((timeSpan.Days > 1) ? "s" : ""); } else if (timeSpan.TotalSeconds > 0.0) { result = "Less than a day"; } } else { double totalMinutes = timeSpan.TotalMinutes; if (totalMinutes > 0.0 && totalMinutes <= 1.0) { result = "Less than a minute"; } else { totalMinutes = timeSpan.TotalMinutes; if (totalMinutes > 1.0 && totalMinutes < 60.0) { result = $"{timeSpan.Minutes + 1} minutes"; } } } return result; } public static Material AddValheimIconShadow(this Image image) { return ((Graphic)image).material = ((Graphic)Hud.instance.m_buildIcon).material; } public static Outline AddOutline(this GameObject gameObject) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return gameObject.AddOutline(1f, Color.black); } public static Outline AddOutline(this GameObject gameObject, float thickness, Color effectColor = default(Color)) { //IL_0007: 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_0018: 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) //IL_002c: 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) Outline orAddComponent = ExposedGameObjectExtension.GetOrAddComponent<Outline>(gameObject); ((Shadow)orAddComponent).effectDistance = Vector2.one * thickness; ((Shadow)orAddComponent).effectColor = ((effectColor == default(Color)) ? Color.black : effectColor); return orAddComponent; } } public static class UIColor { public readonly struct ZColor : IEquatable<ZColor> { public readonly string Hex; public readonly Color Color; public ZColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Color = color; Hex = ColorUtility.ToHtmlStringRGBA(Color); } public static implicit operator Color(ZColor color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return color.Color; } public static implicit operator ZColor(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new ZColor(color); } public static implicit operator ZColor(Color32 color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new ZColor(Color32.op_Implicit(color)); } public override string ToString() { return "#" + Hex; } public bool Equals(ZColor other) { //IL_0001: 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_000a: Unknown result type (might be due to invalid IL or missing references) Color color = Color; return ((Color)(ref color)).Equals(other.Color); } public override bool Equals(object? obj) { if (obj is ZColor other) { return Equals(other); } return false; } public override int GetHashCode() { //IL_0001: 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) Color color = Color; return ((object)(Color)(ref color)).GetHashCode(); } } public static readonly ZColor ValheimOrange = (ZColor)new Color(1f, 0.631f, 0.235f, 1f); public static readonly ZColor ValheimYellow = (ZColor)new Color(1f, 0.889f, 0f, 1f); public static readonly ZColor ValheimBeige = (ZColor)new Color(0.8529f, 0.725f, 0.5331f, 1f); public static readonly ZColor White = Color.white; public static readonly ZColor Black = Color.black; public static readonly ZColor Gray = (ZColor)new Color32((byte)170, (byte)170, (byte)170, byte.MaxValue); public static readonly ZColor Teal = (ZColor)new Color32((byte)170, byte.MaxValue, (byte)170, byte.MaxValue); public static readonly ZColor Orange = (ZColor)new Color(1f, 0.5f, 0f, 1f); public static readonly ZColor Yellow = (ZColor)new Color(1f, 1f, 0f); public static readonly ZColor Red = (ZColor)new Color32((byte)204, (byte)0, (byte)0, byte.MaxValue); public static readonly ZColor Blue = (ZColor)new Color32((byte)0, (byte)0, byte.MaxValue, byte.MaxValue); public static readonly ZColor Green = (ZColor)new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue); public static readonly ZColor Purple = (ZColor)new Color32((byte)147, (byte)49, (byte)189, byte.MaxValue); public static readonly ZColor LightOrange = (ZColor)new Color32(byte.MaxValue, (byte)153, (byte)0, byte.MaxValue); public static readonly ZColor LightYellow = (ZColor)new Color32(byte.MaxValue, byte.MaxValue, (byte)170, byte.MaxValue); public static readonly ZColor LightRed = (ZColor)new Color32(byte.MaxValue, (byte)102, (byte)102, byte.MaxValue); public static readonly ZColor LightBlue = (ZColor)new Color(0f, 0.5f, 1f); public static readonly ZColor LightGreen = (ZColor)new Color32((byte)102, byte.MaxValue, (byte)102, byte.MaxValue); public static readonly ZColor LightPurple = (ZColor)new Color32((byte)221, (byte)136, byte.MaxValue, byte.MaxValue); public static readonly ZColor MinorInfo = Gray; public static readonly ZColor MajorInfo = ValheimOrange; } public abstract class ZenMod<T> : ZenMod where T : ZenMod<T> { public static T Instance { get; private set; } public static bool Initialized { get { if (Object.op_Implicit((Object)(object)Instance)) { return Instance.IsInitialized; } return false; } } public static TerminalCtrl Terminal => Instance.TerminalCtrl; public static Hotload Hotload => Instance._hotload; public static bool IsOnServerAlso => ModCompatibility.IsModuleOnServer((BaseUnityPlugin)(object)Instance); public static bool IsOnServerAndAllClients { get { //IL_001d: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if (!IsOnServerAlso) { return false; } CompatibilityLevel enforceModOnClients = ((MemberInfo)((object)Instance).GetType()).GetCustomAttribute<NetworkCompatibilityAttribute>().EnforceModOnClients; if (enforceModOnClients - 2 <= 1) { return true; } return false; } } protected ZenMod() { if (Object.op_Implicit((Object)(object)Instance)) { throw new Exception($"Instance {typeof(T)} is already loaded. There can be only one!"); } Instance = (T)this; } } public abstract class ZenMod : BaseUnityPlugin { public const string AuthorName = "ZenDragon"; public const string HomeURL = "https://github.com/ZenDragonX/ZenMods_Valheim/wiki"; private static bool _requireGamepadRemap; private bool _loadedOnce; private readonly Assembly _assembly; private readonly Harmony _harmony; private protected readonly Hotload _hotload = new Hotload(); internal static readonly Dictionary<Assembly, ZenMod> Instances = new Dictionary<Assembly, ZenMod>(); private readonly List<Action> _craftingSyncConfigs = new List<Action>(); private readonly List<Action> _prefabSyncConfigs = new List<Action>(); protected virtual GameVersion? RequiredValheimVersion => null; internal TerminalCtrl TerminalCtrl { get; } internal KeyHint KeyHint { get; } = new KeyHint(); internal HashSet<ActionString> RegisteredActionStrings { get; } = new HashSet<ActionString>(); internal Log Log { get; } protected bool RunOnServer { get; set; } protected internal bool RequireGamepadRemap { get { return _requireGamepadRemap; } protected set { if (value) { if (!GUIManager.IsHeadless()) { Log.Message("Requires extended controls. Gamepad remap will be applied.", 0u); } _requireGamepadRemap = value; } } } public bool IsScriptEngine { get { if (!Utility.IsNullOrWhiteSpace(((BaseUnityPlugin)this).Info.Location)) { return ((BaseUnityPlugin)this).Info.Location.Contains("scripts"); } return true; } } protected bool IsInitialized { get; private set; } internal static ZenMod ExecInstance { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return GetInstance(Assembly.GetExecutingAssembly()); } } internal static ZenMod CallingInstance { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return GetInstance(Assembly.GetCallingAssembly()); } } public event Action? RegisterInputs; public event Func<Action?>? RegisterCraftingItems; public event Func<Action?>? PrefabsRegistered; public event Action<string>? LanguageChanged; public event Action? ConfigSync; public static T GetInstance<T>() where T : ZenMod { return (T)GetInstance(typeof(T).Assembly); } internal static ZenMod GetInstance(Assembly assembly) { if (!Instances.TryGetValue(assembly, out ZenMod value)) { throw new MissingInstanceException(assembly); } return value; } protected abstract void Setup(); protected abstract void TitleScene(bool isFirstBoot); protected abstract void WorldStart(); protected abstract void Shutdown(); protected virtual void HotRestore() { } protected ZenMod() { Game.isModded = true; _assembly = ((object)this).GetType().Assembly; if (Instances.ContainsKey(_assembly)) { throw new Exception($"Mod instance {((object)this).GetType()} already exists, there can be only one."); } Instances.Add(_assembly, this); _harmony = Harmony.CreateAndPatchAll(_assembly, (string)null); Zen.Config.Config.File = ((BaseUnityPlugin)this).Config; Log = new Log(((BaseUnityPlugin)this).Logger); if (IsScriptEngine) { Log.Warning("------------------------------", 0u); Log.Warning($"Type: {((object)this).GetType()}", 0u); Log.Warning("Assembly: " + _assembly.GetName().Name, 0u); Log.Warning($"Assembly Hash: {_assembly.GetHashCode():X}", 0u); Log.Warning("------------------------------", 0u); } TerminalCtrl = new TerminalCtrl(((BaseUnityPlugin)this).Info.Metadata.Name); Zen.Config.Config.Define(isAdmin: false, "_Author", "Website", "https://github.com/ZenDragonX/ZenMods_Valheim/wiki", "ZenDragon\nLike my mods?"); } protected void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (RequiredValheimVersion.HasValue) { GameVersion? requiredValheimVersion = RequiredValheimVersion; GameVersion currentVersion = Version.CurrentVersion; if (!requiredValheimVersion.HasValue || requiredValheimVersion.GetValueOrDefault() != currentVersion) { Log.Error($"Valheim version mismatch. Required: {RequiredValheimVersion} Current: {Version.CurrentVersion}", 0u); AbortInit(); return; } } RegisterEventHandlers(); InitConfigs(); Setup(); PreInit(); if (IsScriptEngine) { DebugAddTranslations(); } } private void PreInit() { IsInitialized = false; ((MonoBehaviour)this).StopAllCoroutines(); ((MonoBehaviour)this).CancelInvoke("CheckInit"); ((MonoBehaviour)this).InvokeRepeating("CheckInit", 1f, 1f); } protected virtual bool IsSysReady() { bool flag = Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer); bool flag2 = Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsDedicated(); if (Object.op_Implicit((Object)(object)ZoneSystem.instance) && Object.op_Implicit((Object)(object)ZNet.instance)) { return flag2 || flag; } return false; } private void CheckInit() { Log.Debug("CheckInit", 0u); if (!IsSysReady()) { return; } if (ZNet.instance.IsDedicated()) { if (!RunOnServer) { Log.Message("Server mode: ConfigSync", 0u); AbortInit(); return; } Log.Message("Server mode: Active", 0u); } ((MonoBehaviour)this).CancelInvoke("CheckInit"); if (!_loadedOnce) { OnLanguageChange(); OnInputLayoutChanged(); } UI.CanvasScaler = ((Component)Hud.instance).GetComponent<GuiScaler>().m_canvasScaler; Log.Info("Reload Configs", 0u); ((BaseUnityPlugin)this).Config.Reload(); if (!_hotload.IsPrefabInitInvoked && IsScriptEngine) { _hotload.PrefabInitInvoke(); Log.Warning("Hot restoring existing objects", 0u); HotRestore(); } Log.Info("World Start", 0u); WorldStart(); IsInitialized = true; _loadedOnce = true; } private void AbortInit() { ((MonoBehaviour)this).CancelInvoke("CheckInit"); _harmony.UnpatchSelf(); } private void DebugAddTranslations() { if (!IsScriptEngine) { Log.Warning("Not running as script! Skipping debug add translations", 0u); return; } Timing.EndOfFrame(delegate { Log.Debug("Assembly: " + ((object)this).GetType().Assembly.GetName().Name, 0u); Log.Debug("Assembly Location: " + ((object)this).GetType().Assembly.Location, 0u); Log.Debug("Type: " + ((object)this).GetType(), 0u); Log.Debug("Name: " + ((BaseUnityPlugin)this).Info.Metadata.Name, 0u); Log.Debug("Instance: " + (object)((BaseUnityPlugin)this).Info.Instance, 0u); Log.Debug("Location: " + ((BaseUnityPlugin)this).Info.Location, 0u); string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); if (!Directory.Exists(directoryName)) { throw new DirectoryNotFoundException(directoryName); } Log.Info("Search: " + directoryName, 0u); string[] files = Directory.GetFiles(directoryName, "*.json", SearchOption.AllDirectories); foreach (string text in files) { LocalizationManager.Instance.GetLocalization().AddFileByPath(text, true); } }); } private void InitConfigs() { Log.Info("Initialize Configs", 0u); Zen.Config.Config.File = ((BaseUnityPlugin)this).Config; Log.Info("Config file: " + Zen.Config.Config.File.ConfigFilePath, 0u); Func<Type, bool> predicate = (Type t) => (object)t != null && t.IsClass && t.IsAbstract && t.IsSealed; foreach (Type item in _assembly.GetTypes().Where(predicate)) { if (item.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo field) => field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(ConfigEntry<>)) != null) { RuntimeHelpers.RunClassConstructor(item.TypeHandle); } } Zen.Config.Config.File = null; } private void OnDestroy() { Log.Info("OnDestroy: " + _assembly.GetName().Name, 0u); GUIManager.BlockInput(false); UnregisterEventHandlers(); Shutdown(); _hotload.RestoreAll(); ((MonoBehaviour)this).StopAllCoroutines(); RemoveAllActionStrings(); KeyHint.RemoveAll(); TerminalCtrl.Shutdown(); Cleanup.External(this); _harmony.UnpatchSelf(); if (!(this is ModLib) && Object.op_Implicit((Object)(object)Game.instance)) { ((MonoBehaviour)(object)Game.instance).NextFrame(delegate { Instances.Remove(_assembly); }); } } private void RemoveAllActionStrings() { foreach (ActionString registeredActionString in RegisteredActionStrings) { Log.Info("Remove ActionString: " + registeredActionString.Name, 0u); registeredActionString.RemoveButtons(); } } private void RegisterEventHandlers() { ZInput.OnInputLayoutChanged += OnInputLayoutChanged; SceneManager.sceneLoaded += OnSceneLoaded; PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailableOnce; PrefabManager.OnPrefabsRegistered += OnPrefabsRegisteredOnce; PrefabManager.OnPrefabsRegistered += OnLocalPlayerConfigSync; SynchronizationManager.OnConfigurationSynchronized += OnConfigSync; Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(OnLanguageChange)); } private void UnregisterEventHandlers() { ZInput.OnInputLayoutChanged -= OnInputLayoutChanged; SceneManager.sceneLoaded -= OnSceneLoaded; PrefabManager.OnPrefabsRegistered -= OnLocalPlayerConfigSync; SynchronizationManager.OnConfigurationSynchronized -= OnConfigSync; Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(OnLanguageChange)); } private static IEnumerable<Action> InvokeGetSyncConfigs(Func<Action?>? @event) { Delegate[] array = @event?.GetInvocationList() ?? Array.Empty<Delegate>(); for (int i = 0; i < array.Length; i++) { Action action = ((Func<Action>)array[i])(); if (action != null) { yield return action; } } } private void OnVanillaPrefabsAvailableOnce() { _craftingSyncConfigs.AddRange(InvokeGetSyncConfigs(this.RegisterCraftingItems)); PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailableOnce; } private void OnPrefabsRegisteredOnce() { _hotload.PrefabInitInvoke(); _prefabSyncConfigs.AddRange(InvokeGetSyncConfigs(this.PrefabsRegistered)); PrefabManager.OnPrefabsRegistered -= OnPrefabsRegisteredOnce; } private void OnLocalPlayerConfigSync() { if (ZNetExtension.IsLocalInstance(ZNet.instance)) { Log.Info("Local mode: single player or player is server, apply ConfigSync now.", 0u); OnConfigSync(); } } private void OnConfigSync(object sender, EventArgs e) { OnConfigSync(); } private void OnConfigSync() { Log.Info("Config sync", 0u); this.ConfigSync?.Invoke(); InvokeSyncCallbacks(); } private void InvokeSyncCallbacks() { Log.Info($"Invoking RegisterCraftingItems callbacks: {_craftingSyncConfigs.Count}", 0u); CollectionExtensions.Do<Action>((IEnumerable<Action>)_craftingSyncConfigs, (Action<Action>)delegate(Action callback) { callback(); }); Log.Info($"Invoking PrefabsRegistered callbacks: {_prefabSyncConfigs.Count}", 0u); CollectionExtensions.Do<Action>((IEnumerable<Action>)_prefabSyncConfigs, (Action<Action>)delegate(Action callback) { callback(); }); } private void OnLanguageChange() { string @string = PlayerPrefs.GetString("language", "English"); this.LanguageChanged?.Invoke(@string); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name == "start") { StringList.AccessCount.Clear(); KeyHint.RemoveAll(); TitleScene(!IsInitialized); PreInit(); } } private void OnInputLayoutChanged() { if (GUIManager.IsHeadless()) { Log.Info("Running headless, input layout change doesn't apply", 0u); return; } if (this is ModLib) { InteractAlt.Register(); if (RequireGamepadRemap) { GamepadRemap.SetupControls(); } } this.RegisterInputs?.Invoke(); } public void RefreshInputs() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ZInput.instance.ChangeLayout(ZInput.InputLayout); } } public static class InventoryExt { public static Tally SumItems(this Inventory inv, Func<ItemData, string> callback) { Tally tally = new Tally(); foreach (ItemData allItem in inv.GetAllItems()) { tally[callback(allItem)] += allItem.m_stack; } return tally; } public static Tally SumItemsByName(this Inventory inv) { return inv.SumItems((ItemData item) => item.GetName()); } public static Tally SumItemsByPrefabName(this Inventory inv) { return inv.SumItems((ItemData item) => item.GetPrefabName()); } } } namespace Zen.FixVanilla { [HarmonyPatch] internal static class FixBlankPlayerKey { [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "AddUniqueKey")] private static IEnumerable<CodeInstruction> Player_AddUniqueKey_Transpiler(IEnumerable<CodeInstruction> codes) { MethodInfo methodInfo = AccessTools.Method(typeof(HashSet<string>), "Contains", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(FixBlankPlayerKey), "HashSet_Contains_Intercept", (Type[])null, (Type[])null); return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2); } private static bool HashSet_Contains_Intercept(HashSet<string> self, string? item) { Log.Info("Fixed: Player key can not be blank", 0); self.Remove(string.Empty); self.Remove(null); if (!Utility.IsNullOrWhiteSpace(item)) { return self.Contains(item); } return true; } } } namespace Zen.Controls { public class ActionString { public string NameShort { get; private set; } public string Name { get; } public string Label { get; } public ButtonDef? AliasKBM { get; private set; } public ButtonDef? AliasJoy { get; private set; } public static implicit operator string(ActionString input) { return input.ToString(); } public ActionString(string actionName, string label, bool safeNamespace = true) { if (Utility.IsNullOrWhiteSpace(actionName)) { throw new Exception("ActionString can not be empty or null."); } NameShort = actionName; string name = ((BaseUnityPlugin)ZenMod.CallingInstance).Info.Metadata.Name; Name = (safeNamespace ? (Regex.Replace(name, "[^\\w]", "_") + "_" + actionName) : actionName); Label = Localization.instance.Localize(label); UpdateTranslationLabels(); ZenMod.CallingInstance.RegisteredActionStrings.Add(this); } private void UpdateTranslationLabels() { if (!Utility.IsNullOrWhiteSpace(Label)) { Localization.instance.AddWord(Name, Label); Localization.instance.AddWord("settings_" + Name.ToLower(), Label); } } private static void AddButton(string name, string path, bool altKey, bool showHints, bool rebindable, float repeatDelay, float repeatInterval) { if (ZInput.instance.m_buttons.TryGetValue(name, out var value)) { Log.Info("Skip existing button: " + value.GetActionPath(true) + "\t" + value.Name, 0); return; } if (rebindable && (path.StartsWith("<Keyboard>") || path.StartsWith("<Mouse>"))) { string @string = PlayerPrefs.GetString("kbmBinding_" + name); if (!Utility.IsNullOrWhiteSpace(@string)) { path = @string; } } Log.Info("Add Button: " + path + "\t" + name, 0); ZInput.instance.AddButton(name, path, altKey, showHints, rebindable, repeatDelay, repeatInterval); } public void AddButton(GamepadInput input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) AddButton("Joy" + Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval); } public void AddButton(MouseButton input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) AddButton(Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval); } public void AddButton(KeyCode input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) AddButton(Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval); } public void AddButton(Key input, bool altKey = false, bool showHints = false, bool rebindable = false, float repeatDelay = 0f, float repeatInterval = 0f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) AddButton(Name, input.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval); } public void Alias(string existingName) { ButtonDef buttonDef = ZInput.instance.GetButtonDef(existingName); string actionPath = buttonDef.GetActionPath(true); if (actionPath.StartsWith("<Gamepad>")) { AliasJoy = buttonDef; } else if (actionPath.StartsWith("<Keyboard>") || actionPath.StartsWith("<Mouse>")) { AliasKBM = buttonDef; } Log.Info("Alias: " + buttonDef.GetActionPath(true) + "\t" + existingName + " -> " + Name, 0); } public override string ToString() { if (ZInput.IsGamepadActive()) { if (AliasJoy == null) { return "Joy" + Name; } return AliasJoy.Name; } if (AliasKBM == null) { return Name; } return AliasKBM.Name; } public void RemoveButtons() { ZInput.instance.RemoveButton(Name); ZInput.instance.RemoveButton("Joy" + Name); } } public static class ControlInputs { public static readonly ActionString InteractAlt = new ActionString("Zen_ModLib_InteractAlt", "Alt interact", safeNamespace: false); public static string JoyAlt { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)ZInput.InputLayout != 1) { return JoyTrigger; } return JoyBumper; } } public static string JoyTrigger { get { if (!ZInput.SwapTriggers) { return "JoyLTrigger"; } return "JoyRTrigger"; } } public static string JoyBumper { get { if (!ZInput.SwapTriggers) { return "JoyLBumper"; } return "JoyRBumper"; } } public static GamepadInput TriggerSwappedL { get { if (ZInput.SwapTriggers) { return (GamepadInput)18; } return (GamepadInput)17; } } public static GamepadInput BumperSwappedL { get { if (ZInput.SwapTriggers) { return (GamepadInput)16; } return (GamepadInput)15; } } public static GamepadInput TriggerSwappedR { get { if (ZInput.SwapTriggers) { return (GamepadInput)17; } return (GamepadInput)18; } } public static GamepadInput BumperSwappedR { get { if (ZInput.SwapTriggers) { return (GamepadInput)15; } return (GamepadInput)16; } } } [HarmonyPatch] internal static class GamepadRemap { internal static bool SetupControls() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Invalid comparison between Unknown and I4 //IL_00c4: Unknown result type (might be due to inval