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.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; 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.Commands; using Zen.Compatibility; using Zen.Components; using Zen.FixVanilla; using Zen.Lib; using Zen.Lib.Config; using Zen.Lib.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Zen.ModLib")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("ZenDragon")] [assembly: AssemblyProduct("Zen.ModLib")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("A05ACC86-586F-4121-AD53-9B75C655D77D")] [assembly: AssemblyFileVersion("1.10.4")] [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; } } internal static class IsExternalInit { } } namespace Zen { public abstract class LoggingBase { protected static readonly LogLevel LogLevels; static LoggingBase() { //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 val2 = default(ConfigEntry); if (!val.TryGetEntry("Logging.Disk", "LogLevels", ref val2)) { throw new Exception("Logging.Disk LogLevels config info missing"); } ConfigEntry val3 = default(ConfigEntry); if (!val.TryGetEntry("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; } } protected static string Format(object data, int stackDepth) { MethodBase? method = new StackTrace(stackDepth + 2).GetFrame(0).GetMethod(); string arg = method.DeclaringType?.Name; string name = method.Name; return $"{arg}.{name}: {data}"; } } public class Logging : LoggingBase where TPlugin : ZenMod { private readonly ConfigEntry _enabled = Config.Define(isAdmin: false, "_Debug", "Enable Logging", defaultValue: false, "Generate additional debug information in the logs for this mod.\r\nThis will cause a performance hit and should only be used for debugging."); public static bool IsEnabled { get { if (!Object.op_Implicit((Object)(object)ZNet.instance) || ZNet.instance.IsServer() || ModLib.Configs.AllowDebugLogs.Value) { if (!ZenMod.Instance.Logging._enabled.Value) { return ModLib.Configs.DebugAll.Value; } return true; } return false; } } private static ManualLogSource Logger => ZenMod.Instance.GetLogger(); public static void Debug(object data, int stackDepth = 0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (IsEnabled && ((Enum)LoggingBase.LogLevels).HasFlag((Enum)(object)(LogLevel)32)) { Logger.LogDebug((object)LoggingBase.Format(data, stackDepth)); } } public static void Info(object data, int stackDepth = 0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (IsEnabled && ((Enum)LoggingBase.LogLevels).HasFlag((Enum)(object)(LogLevel)16)) { Logger.LogInfo((object)LoggingBase.Format(data, stackDepth)); } } public static void Message(object data, int stackDepth = 0) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (((Enum)LoggingBase.LogLevels).HasFlag((Enum)(object)(LogLevel)8)) { Logger.LogMessage(data); } } public static void Warning(object data, int stackDepth = 0) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (((Enum)LoggingBase.LogLevels).HasFlag((Enum)(object)(LogLevel)4)) { Logger.LogWarning((object)LoggingBase.Format(data, stackDepth)); } } public static void Error(object data, ushort stackDepth = 0) { Logger.LogError((object)LoggingBase.Format(data, stackDepth)); } public static void Fatal(object data, ushort stackDepth = 0) { Logger.LogFatal((object)LoggingBase.Format(data, stackDepth)); } } [BepInPlugin("ZenDragon.Zen.ModLib", "Zen.ModLib", "1.10.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class ModLib : ZenMod { public static class Inputs { public static readonly ActionString InteractAlt = Zen.Lib.Controls.InteractAlt.Create(); } public static class Configs { internal static readonly ConfigEntry AllowDebugLogs; internal static readonly ConfigEntry DebugAll; internal static readonly ConfigEntry EnableMessageCache; internal static readonly ConfigEntry EnablePrefabLookupCache; internal static readonly ConfigEntry EnableValheimVersionCheck; internal static readonly ConfigEntry ConfigThrashWarningLimit; internal static readonly ConfigEntry SanitizeData; internal static readonly ConfigEntry SanitizeDataAfterSync; internal static readonly ConfigEntry FixApplyPlayerKeyOnBossDeath; internal static readonly ConfigEntry FixApplyPlayerKeyOnBossDeathDistance; internal static readonly ConfigEntry FixFireIsLit; internal static readonly ConfigEntry FixRunAttackStaminaDrain; internal static readonly ConfigEntry FixExploitChairBypass; internal static readonly ConfigEntry FixExploitTooHardMsg; internal static readonly ConfigEntry FixWolfEatMeats; internal static readonly ConfigEntry FixFuelLeak; internal static readonly ConfigEntry UseModSeasonsFuelBurnRate; internal static readonly ConfigEntry SwapMouse3Mouse4; internal static readonly ConfigEntry InteractAltKey; internal static readonly ConfigEntry InteractAltUseShiftE; internal static readonly ConfigEntry GamepadForceRemap; internal static readonly ConfigEntry GamepadEmoteWheel; internal static readonly ConfigEntry GamepadEmoteWheelDuration; internal static readonly ConfigEntry DefaultHighlightColor; internal static readonly ConfigEntry RemoveRichTextFromTranslations; internal static readonly ConfigEntry ShowHelpInfo; internal static readonly ConfigEntry ShowHelpInfoIndex; internal static readonly ConfigEntry ShowHelpInfoPrefix; internal static readonly ConfigEntry ConsoleAllowed; internal static readonly ConfigEntry CommandsRequireAdmin; internal static readonly ConfigEntry CommandRelayEnabled; static Configs() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) AllowDebugLogs = Config.Define(isAdmin: true, "_Debug", "Allow Debug Logs", defaultValue: false, "Must be enabled by admin for any ZenMods to generate debug logs.\r\nIf disabled prevents ZenMods from generating debug logs while connected to live servers.\r\nSingle-player, multiplayer hosts, and dedicated servers ignore this config."); DebugAll = Config.Define(isAdmin: false, "_Debug", "Enable All Logs", defaultValue: false, "Enable all debug flags for all ZenMods. Caution this will reduce performance! Useful only for internal testing."); EnableMessageCache = Config.Define(isAdmin: false, "_Debug", "Enable Message Cache", defaultValue: true, "Cache the results of Interop SendMessage calls to improve performance.\r\nThis is primarily a developer debug option, end users probably never need to disable this."); EnablePrefabLookupCache = Config.Define(isAdmin: false, "_Debug", "Enable Prefab Lookup Cache", defaultValue: true, "Cache the results of prefab lookups that are not found in the JVL cache.\r\nThis is primarily a developer debug option, end users probably never need to disable this."); EnableValheimVersionCheck = Config.Define(isAdmin: false, "_Debug", "Enable Valheim Version Check", defaultValue: true, $"Verify the Valheim version is compatible with this mod.\r\nExpected Valheim version: {ZenMod.ValheimVersionRequired}\r\nDisabling this is not recommended and can lead to unpredictable runtime errors."); ConfigThrashWarningLimit = Config.Define(isAdmin: false, "Diagnostics", "Config Thrashing Warning Limit", 100, Config.AcceptRange(0, 1000), "Upper limit before triggering a warning in the logs that config files are being thrashed. \r\nThis happens when mods like ConfigWatcher are spamming IO operations and constantly reloading config files.\r\nYou really should investigate the cause of any thrashing alerts triggered by this.\r\nIt means your config files are being reloaded constantly in the background, that can hurt performance.\r\nA few times is no big deal, but if it's happening constantly, you should investigate the cause.\r\nSet to 0 to disable the alert if you don't care about the performance impact from mods that are repeatedly hammering IO."); SanitizeData = Config.Define(isAdmin: false, "Diagnostics", "Sanitize Data", defaultValue: true, "Sanitize item and recipe data to ensure they are properly indexed."); SanitizeDataAfterSync = Config.Define(isAdmin: true, "Diagnostics", "Sanitize Data After Sync", defaultValue: false, "Run data sanitization again after sync to compensate for some mods not registering items correctly.\r\nEnable this if you see errors that say: \"Exception: Unable to locate item prefab. Missing dropPrefab and sharedData index\""); UseModSeasonsFuelBurnRate = Config.Define(isAdmin: true, "Compatibility", "Use Mod Seasons Fuel Burn Rates", defaultValue: true, "Enable fireplace burn rate calculations from the Seasons mod if it is installed.\r\nIf unsure just leave this enabled, it has no effect if Seasons is not installed."); ConsoleAllowed = Config.Define(isAdmin: true, "Console", "Allow Console", defaultValue: false, "Toggle for server-wide access to the console for all players connected to the server.\r\nNOTE: Admin can always access the console."); CommandRelayEnabled = Config.Define(isAdmin: true, "Console", "Command Relay", defaultValue: false, "Maintenance: Allow server admins to run console commands as another player.\r\nUseful for admins to update or fix problems with player characters.\r\nCan be changed while the game is running via Configuration Manager.\r\nIf this mod is installed on the server then the admin can toggle this for everyone.\r\nIf not installed on the server then the receiver must manually enable this to allow access.\r\nDisable this when not in use to prevent griefing.\r\nMust be admin to use this command and in the devcommands context.\r\nSyntax: " + Relay.Syntax); CommandsRequireAdmin = Config.Define(isAdmin: true, "Console", "Require Admin", new StringList { "seed", "printseeds", "nextseed" }, "Comma separated list of commands that are forced to be admin-only devcommands context."); FixFireIsLit = Config.Define(isAdmin: true, "BugFix", "Verify Fire Is Lit", defaultValue: true, "As of Valheim Version: 0.220.5 (n-34) vanilla code is wrong.\r\nIt is not checking if the fire is lit under a cauldron, just that it's a burning area.\r\nThis fix verifies that the fire is actually lit."); FixRunAttackStaminaDrain = Config.Define(isAdmin: true, "BugFix", "Fix Run Attack Stamina Drain", defaultValue: true, "Prevent excess stamina drain when running and then attacking without releasing the move button.\r\nIn vanilla, it will keep draining your stamina as if you are running even though you are no longer running when you attack."); FixApplyPlayerKeyOnBossDeath = Config.Define(isAdmin: true, "BugFix", "Apply Player Key", defaultValue: true, "Vanilla has a bug where it does not apply the player key on boss death.\r\nThis mostly affects Hildir's Quest when PlayerEvents is enabled.\r\nThis option is here to turn this fix off if IG later fixes the bug."); FixApplyPlayerKeyOnBossDeathDistance = Config.Define(isAdmin: true, "BugFix", "Apply Player Key Distance", 300f, Config.AcceptRange(0f, 1000f), "The max distance that other players can be from the boss when it dies to still get the key applied."); FixFuelLeak = Config.Define(isAdmin: true, "BugFix", "Fix Fuel Leak", defaultValue: true, "Prevent loss of resources when ZDO owner lags while another player adds fuel/ore to piece.\r\nForce claim ownership of the ZDO. The resource has already been removed from inventory."); FixWolfEatMeats = Config.Define(isAdmin: true, "BugFix", "Fix Wolf Eat Meats", new StringList { "BjornMeat", "SerpentMeat", "BoneMawSerpentMeat" }, "List of additional meats that wolves will eat. Default includes Bear and Serpent, add others if desired."); FixExploitChairBypass = Config.Define(isAdmin: true, "BugFix", "Fix Exploit - Chair Bypass", defaultValue: true, "Prevent players from clipping through doors and walls with chairs."); FixExploitTooHardMsg = Config.Define(isAdmin: true, "BugFix", "Fix Exploit - Too Hard Msg", defaultValue: true, "Suppress the Too Hard message when slamming the ground to find silver."); ShowHelpInfo = Config.Define(isAdmin: true, "Compendium", "Enable Help Info", defaultValue: true, "Populate the Compendium (aka Raven Menu) with help info for installed Zen Mods."); ShowHelpInfoIndex = Config.Define(isAdmin: true, "Compendium", "Insertion Index", 2, "Index position in the Compendium to insert help info entries.\r\n-1 will add to the end of the list.\r\n0 will add to the top of the list.\r\n2 will add after the \"Message log\" entry."); ShowHelpInfoPrefix = Config.Define(isAdmin: true, "Compendium", "Label Prefix", "Zen:", "Prefix each help info entry in the Compendium with this string."); DefaultHighlightColor = Config.Define(isAdmin: false, "General", "Default Highlight Color", new Color(1f, 0.5f, 0f, 1f), "Default highlight color when outlining pieces."); RemoveRichTextFromTranslations = Config.Define(isAdmin: true, "General", "Remove Rich Text From Translations", new StringList { "_RtD$" }, "Comma separated list of regex patterns matched against the translation keys. \r\nMatched keys have their translations stripped of rich text tags.\r\nSome mods add rich text tags like to their translations.\r\nIn order to provide a consistent UI theme you can remove those tags from the translations of matched keys.\r\nIf you don't want to remove any tags then leave the list empty. (Default is to remove the rich text on RtD mods)\r\nIf you need help with regex patterns then check out https://regex101.com/ or ask an AI."); InteractAltKey = Config.Define(isAdmin: false, "Input", "Alternate Interact Key", (KeyCode)113, "Key to use for alternative interaction instead of Shift + E"); InteractAltKey.SettingChanged += delegate { ZenMod.Instance.RefreshInputs(); }; InteractAltUseShiftE = Config.Define(isAdmin: false, "Input", "Alternate Interact Use Shift+E", defaultValue: true, "Disabling this can be useful when trying to run and press E at the same time.\r\nNOTE: If you use other mods and disable this they won't detect the Shift input key.\r\nInstead you will need to use the " + ((ConfigEntryBase)InteractAltKey).Definition.Key); GamepadForceRemap = Config.Define(isAdmin: false, "Input", "Gamepad Force 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]"); GamepadEmoteWheel = Config.Define(isAdmin: false, "Input", "Gamepad Emote Wheel", defaultValue: true, "Enable or disable the emote wheel activation when using a gamepad. \r\nIf this is disabled the emote wheel can only be activated via keyboard.\r\nSome players only play single player and do not need or want the wheel."); GamepadEmoteWheelDuration = Config.Define(isAdmin: false, "Input", "Gamepad Emote Wheel Duration", 1f, Config.AcceptRange(0.33f, 2f), "How long to hold the button before activating the emote wheel on gamepad. (Vanilla: 0.33)"); SwapMouse3Mouse4 = Config.Define(isAdmin: false, "Input", "Swap Mouse3 Mouse4", defaultValue: false, "Swap the Mouse3 and Mouse4 buttons. (Vanilla: false)"); } } public const string PluginName = "Zen.ModLib"; public const string PluginVersion = "1.10.4"; public const string PluginGUID = "ZenDragon.Zen.ModLib"; public static bool IsApplicationQuit { get; private set; } private void OnApplicationQuit() { IsApplicationQuit = true; } protected override void Setup() { base.RunOnServer = true; ZenMod.RequireGamepadRemap = Configs.GamepadForceRemap.Value; QuickOutline.InitMaterials(); Relay.InitTerminal(); base.LanguageChanged += OnLanguageChanged; } protected override void TitleScene(bool isFirstBoot) { } internal void BeforeWorldStart() { if (Configs.SanitizeDataAfterSync.Value) { SanitizeData.SanitizeItemsAndRecipes("After Sync - World Start"); } } protected override void WorldStart() { Relay.RegisterRPC(); SetAdminOnlyCommands(); } protected override void Shutdown() { Logging.Message("Shutting down"); QuickOutline.DisableAll(); Relay.Shutdown(); FixAddPlayerKeyOnBossDeath.Shutdown(); } private static void OnLanguageChanged(string language) { if (Configs.RemoveRichTextFromTranslations.Value.Any()) { Localization.instance.RemoveRichTextTags(); } } private static void SetAdminOnlyCommands() { if (ZNet.instance.IsDedicated()) { return; } foreach (string item in Configs.CommandsRequireAdmin.Value) { if (Terminal.commands.TryGetValue(item.ToLower(), out var value)) { value.IsCheat = true; } } } } } namespace Zen.Lib { public static class AssetIO { public static Sprite LoadSpriteFromResource(this BaseUnityPlugin plugin, string resourceName) { Texture2D val = AssetUtils.LoadImage(LoadResourceToMemory(plugin, resourceName)); if (!Object.op_Implicit((Object)(object)val)) { throw new Exception("Unable to load as texture: " + resourceName); } return val.CreateSprite(); } public static Sprite CreateSprite(this Texture2D texture) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); return Sprite.Create(texture, val, val2); } private static byte[] LoadResourceToMemory(BaseUnityPlugin plugin, string resourceName) { Type type = ((object)plugin).GetType(); Assembly assembly = type.Assembly; string text = type.Namespace + ".Resources." + resourceName; Logging.Info(text); using Stream stream = assembly.GetManifestResourceStream(text); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } } internal static class Cleanup { public static void External(BaseUnityPlugin plugin) { if (plugin is ModLib) { ConfigTomlTypeConverterEntries(); } JotunnConfigs(plugin.Config); } private static void JotunnConfigs(ConfigFile configFile) { Logging.Debug("Remove config entries from Jotunn cache", 1); Dictionary dictionary = (Dictionary)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() { Logging.Debug("Removing TomlTypeConverter Entry: StringList", 1); ((Dictionary)AccessTools.Property(typeof(TomlTypeConverter), "TypeConverters").GetValue(null)).Remove(typeof(StringList)); } } [HarmonyPatch] internal static class ConsoleAccess { [HarmonyPostfix] [HarmonyPatch(typeof(Console), "IsConsoleEnabled")] private static void Console_IsConsoleEnabled(ref bool __result) { if (Object.op_Implicit((Object)(object)ZNet.instance) && !SynchronizationManager.Instance.PlayerIsAdmin) { __result = __result && ModLib.Configs.ConsoleAllowed.Value; } } } public class MissingItemException : Exception { [CompilerGenerated] private string P; [CompilerGenerated] private Vector3 P; public string ItemName => P; public Vector3 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) //IL_001a: Unknown result type (might be due to invalid IL or missing references) P = itemName; P = position; base..ctor($"Item not found in ObjectDB. Did you remove a mod? {P.XZY()} {P}"); } } public static class BiomeExt { public static string Localize(this Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (((int)biome != 0 && (int)biome != 895) || 1 == 0) { return $"$biome_{biome}".ToLowerInvariant().Localize(); } return string.Empty; } } 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 ToStringRGB(this Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new UIColor(color).ToString(); } } public static class CustomItemExt { public static SharedData ApplyTextureToPrefab(this CustomItem item, Texture2D texture, float scale3D, Vector2 textureScale, Vector2 offset, string attachName = "", bool initShared = true, Color? color = null) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) ((Object)item.ItemPrefab.transform.GetChild(0)).name = attachName; MeshRenderer componentInChildren = item.ItemPrefab.GetComponentInChildren(); Material material = ((Renderer)componentInChildren).material; material.mainTexture = (Texture)(object)texture; material.mainTextureScale = textureScale; material.mainTextureOffset = offset; material.color = (Color)(((??)color) ?? Color.white); Transform transform = ((Component)componentInChildren).transform; transform.localScale *= scale3D; SharedData shared = item.ItemDrop.m_itemData.m_shared; if (initShared) { shared.m_movementModifier = 0f; shared.m_useDurability = false; shared.m_canBeReparied = false; shared.m_maxQuality = 1; shared.m_value = 0; shared.m_itemType = (ItemType)16; } return shared; } } public static class FireplaceExt { public static double FuelTimeRemaining(this Fireplace fireplace, out float fuel) { if (!fireplace.m_nview.IsValid()) { fuel = 0f; return 0.0; } fuel = fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f); double timeRemaining = Seasons.GetTimeRemaining(fireplace); if (!(timeRemaining >= 0.0)) { return fuel * fireplace.m_secPerFuel; } return timeRemaining; } public static double FuelTimeRemaining(this Fireplace fireplace) { float fuel; return fireplace.FuelTimeRemaining(out fuel); } 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.RealToGameTimeFuel(fuel.Value * fireplace.m_secPerFuel).Days; } public static int FuelDaysMax(this Fireplace fireplace) { return UI.RealToGameTimeFuel(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 { [StructLayout(LayoutKind.Auto)] [CompilerGenerated] private struct <>c__DisplayClass4_0 { public bool isOnlyXZ; public GameObject self; } [CompilerGenerated] private sealed class d__7 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator where T : notnull, Component { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; private GameObject self; public GameObject <>3__self; private float range; public float <>3__range; private LayerMask layerMask; public LayerMask <>3__layerMask; private int 5__2; private T 5__3; private int 5__4; T IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { 5__3 = default(T); <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_00c5; } <>1__state = -1; 5__2 = Physics.OverlapSphereNonAlloc(self.transform.position, range, HitDataBuffer, LayerMask.op_Implicit(layerMask)); 5__3 = self.GetComponentInParent(); 5__4 = 0; goto IL_00d5; IL_00c5: 5__4++; goto IL_00d5; IL_00d5: if (5__4 < 5__2) { T componentInParent = ((Component)HitDataBuffer[5__4]).GetComponentInParent(); if (Object.op_Implicit((Object)(object)componentInParent) && (!Object.op_Implicit((Object)(object)5__3) || !((Object)(object)5__3 == (Object)(object)componentInParent))) { <>2__current = componentInParent; <>1__state = 1; return true; } goto IL_00c5; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) d__7 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__7(0); } d__.self = <>3__self; d__.range = <>3__range; d__.layerMask = <>3__layerMask; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__4 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private Piece <>2__current; private int <>l__initialThreadId; private bool isOnlyXZ; public bool <>3__isOnlyXZ; private GameObject self; public GameObject <>3__self; private <>c__DisplayClass4_0 <>8__1; private float range; public float <>3__range; private Piece 5__2; private List.Enumerator <>7__wrap2; Piece IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>8__1 = default(<>c__DisplayClass4_0); 5__2 = null; <>7__wrap2 = default(List.Enumerator); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1.isOnlyXZ = isOnlyXZ; <>8__1.self = self; 5__2 = <>8__1.self.GetComponentInParent(); <>7__wrap2 = Piece.s_allPieces.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap2.MoveNext()) { Piece current = <>7__wrap2.Current; if (((Component)current).gameObject.layer != Piece.s_ghostLayer && g__GetDistance|4_0(current, ref <>8__1) < range && !((Object)(object)current == (Object)(object)5__2) && Object.op_Implicit((Object)(object)current)) { <>2__current = current; <>1__state = 1; return true; } } <>m__Finally1(); <>7__wrap2 = default(List.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap2).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__4 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__4(0); } d__.self = <>3__self; d__.range = <>3__range; d__.isOnlyXZ = <>3__isOnlyXZ; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static readonly Collider[] HitDataBuffer = (Collider[])(object)new Collider[1000]; public static string GetPrefabName(this GameObject gameObject) { return Utils.GetPrefabName(((Object)gameObject).name); } public static T? GetClosest(this GameObject self, float range, Func? filter = null) where T : MonoBehaviour { //IL_0031: Unknown result type (might be due to invalid IL or missing references) T result = default(T); float num = float.MaxValue; foreach (T nearbyPiece in self.GetNearbyPieces(range, isOnlyXZ: false)) { float num2 = ((MonoBehaviour)(object)nearbyPiece).DistanceToSqr(self.transform.position); if (!(num2 > num) && (filter == null || filter(nearbyPiece))) { num = num2; result = nearbyPiece; } } return result; } public static IEnumerable GetNearbyPiecesXZ(this GameObject self, float range) { return self.GetNearbyPieces(range, isOnlyXZ: true); } [IteratorStateMachine(typeof(d__4))] public static IEnumerable GetNearbyPieces(this GameObject self, float range, bool isOnlyXZ = false) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(-2) { <>3__self = self, <>3__range = range, <>3__isOnlyXZ = isOnlyXZ }; } public static IEnumerable GetNearbyPiecesXZ(this GameObject self, float range) where T : Component { return self.GetNearbyPieces(range, isOnlyXZ: true); } public static IEnumerable GetNearbyPieces(this GameObject self, float range, bool isOnlyXZ = false) where T : Component { T selfComponent = self.GetComponentInChildren(); return from piece in self.GetNearbyPieces(range, isOnlyXZ) select ((Component)piece).GetComponentInChildren() into c where Object.op_Implicit((Object)(object)c) && (Object)(object)c != (Object)(object)selfComponent select c; } [IteratorStateMachine(typeof(d__7<>))] public static IEnumerable GetNearbyFromOverlapSphere(this GameObject self, float range, LayerMask layerMask) where T : Component { //IL_0016: 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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(-2) { <>3__self = self, <>3__range = range, <>3__layerMask = layerMask }; } [CompilerGenerated] internal static float g__GetDistance|4_0(Piece p, ref <>c__DisplayClass4_0 P_1) { if (!P_1.isOnlyXZ) { return P_1.self.DistanceToXZ(((Component)p).gameObject); } return P_1.self.DistanceTo(((Component)p).gameObject); } } public static class HarmonyExt { public static bool IsLdloc(this CodeInstruction code, int index) { if (CodeInstructionExtensions.IsLdloc(code, (LocalBuilder)null)) { return code.IsLocal(index); } return false; } public static bool IsStloc(this CodeInstruction code, int index) { if (CodeInstructionExtensions.IsStloc(code, (LocalBuilder)null)) { return code.IsLocal(index); } return false; } public static bool IsLocal(this CodeInstruction code, int index) { if (code.operand != null) { if ((!(code.operand is LocalBuilder localBuilder) || localBuilder.LocalIndex != index) && (!(code.operand is byte b) || b != index) && (!(code.operand is short num) || num != index)) { if (code.operand is int num2) { return num2 == index; } return false; } return true; } return false; } } 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() : 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 includeFishingRod) { if (!self.RightItem.IsItemType((ItemType)19) && !self.LeftItem.IsItemType((ItemType)19)) { if (includeFishingRod) { 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 bool IsUsing(this Humanoid? self, ItemData item, bool rightOnly = false) { return self.IsUsing(item.GetPrefabName(), rightOnly); } public static bool IsUsing(this Humanoid? self, string itemPrefab, bool rightOnly = false) { if (!(itemPrefab == ((self == null) ? null : self.RightItem?.GetPrefabName()))) { if (itemPrefab == ((self == null) ? null : self.LeftItem?.GetPrefabName())) { return !rightOnly; } return false; } return true; } } public static class IDictionaryExt { public static void AddToList(this IDictionary dict, TKey key, TValue value) where TList : ICollection, new() { if (!dict.TryGetValue(key, out TList value2)) { value2 = (dict[key] = new TList()); } value2.Add(value); } } public static class IEnumerableExt { public static IEnumerable<(TKey Key, TValue Value)> AsTuple(this Dictionary self) where TKey : notnull { return self.Select, (TKey, TValue)>((KeyValuePair kvp) => (kvp.Key, kvp.Value)); } public static IEnumerable<(T Item, int Index)> WithIndex(this IEnumerable self) { return self.Select((T obj, int index) => (obj, index)); } public static IEnumerable InRangeXZ(this IEnumerable list, Vector3 position, float range) where T : Component { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return list.Where((T p) => position.DistanceToXZ(((Component)p).transform.position) < range); } public static IEnumerable InRange(this IEnumerable list, Vector3 position, float range) where T : Component { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return list.Where((T p) => position.DistanceToSqr(((Component)p).transform.position) < range * range); } public static IEnumerable WhereNot(this IEnumerable source, Func predicate) { Func predicate2 = predicate; return source.Where((T x) => !predicate2(x)); } } public static class InputExtStr { private static readonly Dictionary ButtonActionStringCache = new Dictionary(); 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 ""; } 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 InventoryExt { public static Tally SumItems(this Inventory inv, Func 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()); } 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 bool ContainsItemByPrefab(this Inventory inventory, string prefabName) { string prefabName2 = prefabName; return inventory.GetAllItems().Any((ItemData item) => item.GetPrefabName() == prefabName2); } public static bool ContainsItemByPrefab(this Inventory inventory, GameObject prefab) { return inventory.ContainsItemByPrefab(Utils.GetPrefabName(((Object)prefab).name)); } public static bool TryAddItem(this Inventory inventory, GameObject prefab, int amount, out ItemData item) { item = prefab.GetComponent().m_itemData.Clone(); item.m_dropPrefab = prefab; item.m_stack = Mathf.Min(amount, item.m_shared.m_maxStackSize); item.m_worldLevel = Game.m_worldLevel; return inventory.AddItem(item); } } 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 { Logging.Info($"Show grid element amount: {isVisible} at index: {index}"); if (index == -1) { CollectionExtensions.Do((IEnumerable)grid2.m_elements, (Action)delegate(Element element) { ((Component)element.m_amount).gameObject.SetActive(isVisible); }); } else { ((Component)grid2.m_elements[index].m_amount).gameObject.SetActive(isVisible); } }); } public static void DisableElement(this InventoryGrid grid, Element element) { element.m_used = false; if (Object.op_Implicit((Object)(object)element.m_durability)) { ((Component)element.m_durability).gameObject.SetActive(false); } if (Object.op_Implicit((Object)(object)element.m_icon)) { ((Behaviour)element.m_icon).enabled = false; } if (Object.op_Implicit((Object)(object)element.m_amount)) { ((Behaviour)element.m_amount).enabled = false; } if (Object.op_Implicit((Object)(object)element.m_quality)) { ((Behaviour)element.m_quality).enabled = false; } if (Object.op_Implicit((Object)(object)element.m_equiped)) { ((Behaviour)element.m_equiped).enabled = false; } if (Object.op_Implicit((Object)(object)element.m_queued)) { ((Behaviour)element.m_queued).enabled = false; } if (Object.op_Implicit((Object)(object)element.m_noteleport)) { ((Behaviour)element.m_noteleport).enabled = false; } if (Object.op_Implicit((Object)(object)element.m_food)) { ((Behaviour)element.m_food).enabled = false; } if (Object.op_Implicit((Object)(object)element.m_tooltip)) { element.m_tooltip.m_text = string.Empty; element.m_tooltip.m_topic = string.Empty; } } public static ItemData? GetHoveredItem(this InventoryGrid grid) { if (grid.m_uiGroup.IsActive && ZInput.GamepadActive) { return grid.GetGamepadSelectedItem(); } Element hoveredElement = grid.GetHoveredElement(); if (hoveredElement != null) { return grid.m_inventory.GetItemAt(hoveredElement.m_pos.x, hoveredElement.m_pos.y); } return null; } public static bool IsFocusedElement(this InventoryGrid grid, Element element) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (grid.m_uiGroup.IsActive && ZInput.IsGamepadActive()) { return element == grid.GetElement(grid.m_selected.x, grid.m_selected.y, grid.m_width); } RectTransform val = (RectTransform)element.m_go.transform; Rect rect = val.rect; return ((Rect)(ref rect)).Contains(((Transform)val).InverseTransformPoint(ZInput.mousePosition)); } } public static class InventoryGuiExt { [CompilerGenerated] private sealed class <>c__DisplayClass1_0 { public GameObject btn; } private static bool _isRestoringStackAllButton; public static void ShowStackAllButton(this InventoryGui self, bool show) { <>c__DisplayClass1_0 CS$<>8__locals0 = new <>c__DisplayClass1_0(); Logging.Info($"Show StackAll button: {show}"); CS$<>8__locals0.btn = ((Component)self.m_stackAllButton).gameObject; CS$<>8__locals0.btn.SetActive(show); if (!show && !_isRestoringStackAllButton) { ((MonoBehaviour)self).StartCoroutine(Restore()); } [IteratorStateMachine(typeof(<>c__DisplayClass1_0.<g__Restore|0>d))] IEnumerator Restore() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass1_0.<g__Restore|0>d(0) { <>4__this = CS$<>8__locals0 }; } } } public static class ItemDataExt { private const string KeyTooltipExtra = "Zen_Tooltip"; 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 IsTowerShield(this ItemData? item) { if (item != null && item.IsShield()) { return item.m_shared.m_timedBlockBonus <= 0f; } return false; } public static bool IsShield(this ItemData? item) { return item?.IsItemType((ItemType)5) ?? false; } public static bool IsArmor(this ItemData? item, bool includeTrinket = false) { if ((item == null || !item.IsItemType((ItemType)7)) && !item.IsItemType((ItemType)6) && !item.IsItemType((ItemType)11) && !item.IsItemType((ItemType)17)) { if (includeTrinket) { return item.IsItemType((ItemType)24); } return false; } return true; } 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)item.m_dropPrefab).name; } GameObject val = default(GameObject); if (ObjectDB.instance.TryGetItemPrefab(item.m_shared, ref val)) { return ((Object)val).name; } Logging.Info("Item does not have dropPrefab or sharedData index, fallback to using the item name to locate the prefab: " + item.GetName()); if (SanitizeData.TryGetItemDropFromItemName(item.GetName(), out ItemDrop itemDrop)) { return itemDrop.GetPrefabName(); } throw new Exception("Unable to locate item prefab. Missing dropPrefab and sharedData index for " + item.GetName()); } public static GameObject GetPrefab(this ItemData item) { return GlobalStatic.GetPrefab(item.GetPrefabName()); } public static ItemDrop GetPrefabItemDrop(this ItemData item) { return GlobalStatic.GetPrefab(item.GetPrefabName(), useCache: true); } public static string GetName(this ItemData item) { return item.m_shared.m_name ?? string.Empty; } public static string GetName(this ItemDrop item) { return item.m_itemData.m_shared.m_name ?? string.Empty; } 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 (!(item.GetPrefabName() == other.GetPrefabName()) || !(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 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 void SetTooltipExtra(this ItemData item, string? text) { if (string.IsNullOrEmpty(text)) { item.m_customData.Remove("Zen_Tooltip"); } else { item.m_customData["Zen_Tooltip"] = text; } } public static string GetTooltipExtra(this ItemData item) { if (!item.m_customData.TryGetValue("Zen_Tooltip", out var value)) { return string.Empty; } return value; } } 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()); } 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 LocalizationExt { internal static void RemoveRichTextTags(this Localization instance) { Logging.Info("Applying configs to remove rich text tags from translations"); List list = new List(); Dictionary translations = instance.m_translations; foreach (var (text2, text3) in translations.AsTuple()) { if (IsMatch(text2) && text3.Contains("<") && text3.Contains(">")) { list.Add(text2); } } foreach (string item in list) { Logging.Info("Tags removed from " + item); translations[item] = StringExtensionMethods.RemoveRichTextTags(translations[item]); } static bool IsMatch(string text) { string text4 = text; return ModLib.Configs.RemoveRichTextFromTranslations.Value.Any((string key) => Regex.Match(text4, key).Success); } } } 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 Vector3 Abs(this Vector3 self) { //IL_0000: 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_0016: 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) return new Vector3(Mathf.Abs(self.x), Mathf.Abs(self.y), Mathf.Abs(self.z)); } public static float Max(this Vector3 self) { //IL_0008: 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_001a: Unknown result type (might be due to invalid IL or missing references) return Mathf.Max(new float[3] { self.x, self.y, self.z }); } public static float Min(this Vector3 self) { //IL_0008: 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_001a: Unknown result type (might be due to invalid IL or missing references) return Mathf.Min(new float[3] { self.x, self.y, self.z }); } public static ulong GetCantorID(this Vector2i coord) { //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) return MathLib.GetCantorID(coord.x, coord.y); } public static Vector2i FromCantorID(this ulong id) { //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_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_0013: Unknown result type (might be due to invalid IL or missing references) Vector2i val = MathLib.FromCantorID(id); return new Vector2i(val.x, val.y); } } 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 ObjectDBExt { public static Recipe? GetRecipe(this ObjectDB self, ItemDrop itemDrop) { ItemDrop itemDrop2 = itemDrop; return ((IEnumerable)self.m_recipes).FirstOrDefault((Func)((Recipe r) => (Object)(object)r.m_item == (Object)(object)itemDrop2)); } } 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 bool IsGodMode(this Player? player) { if (Object.op_Implicit((Object)(object)player)) { return ((Character)player).InGodMode(); } return false; } public static bool IsNot(this Player? player, Character other) { return !player.Is(other); } 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 bool IsShipCaptain(this Player player) { return Object.op_Implicit((Object)(object)player.GetControlledShip()); } public static T? GetControlled(this Player player) where T : MonoBehaviour { IDoodadController doodadController = player.GetDoodadController(); if (doodadController == null || !doodadController.IsValid()) { return default(T); } return ((T)(object)((doodadController is T) ? doodadController : null)) ?? ((T)(object)/*isinst with value type is only supported in some contexts*/); } } 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(); } } 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 Truncate(this string? s, int length) { return ((s != null && s.Length > length) ? s.Substring(0, length) : s) ?? string.Empty; } public static string Localize(this string? s, params string[] words) { return Localization.instance.Localize(s, words); } public static string Localize(this string? s) { return Localization.instance.Localize(s); } public static string ToProperCase(this string? str, bool forceLower = true) { if (str == null || Utility.IsNullOrWhiteSpace(str)) { return ""; } string text = str[0].ToString().ToUpper(); string text2 = str.Substring(1); return text + (forceLower ? text2.ToLower() : text2); } 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 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("[]", "\">"); } public static string Repeat(this string s, int n) { return new StringBuilder(s.Length * n).Insert(0, s, n).ToString(); } } 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 Container self, bool flash) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (self.m_checkGuardStone) { return ((Component)self).transform.position.CanAccessWard(flash); } return true; } 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 double GetAgeSeconds(this ZDO zdo) { return ZNet.instance.GetTimeSeconds() - zdo.GetEpoch(); } public static void AccelerateAge(this ZDO zdo, double seconds) { if (!zdo.IsOwner()) { Logging.Error("Cannot age this ZDO, not owner.", 0); return; } double value = Math.Max(zdo.GetEpoch() - seconds, 0.0); zdo.Set(ZdoKeyEpochStart, value); } public static void RemoveEpoch(this ZDO zdo) { if (!zdo.IsOwner()) { Logging.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()) { Logging.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) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!GlobalStatic.TryGetPrefab(zdo.GetPrefab(), out GameObject prefab)) { throw new Exception($"ZDO is missing prefab for hash at location: {zdo.GetPosition().XZY()}"); } return ((Object)prefab).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) { return BitConverter.Int64BitsToDouble(zdo.GetLong(hash, (defaultValue == 0.0) ? 0 : BitConverter.DoubleToInt64Bits(defaultValue))); } 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) { zdo.Set(hash, BitConverter.DoubleToInt64Bits(value)); } 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().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; } Logging.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 IsMappedTo(this ButtonDef def, KeyCode input) { return def.GetActionPath(true).ToUpper().EndsWith(((object)(KeyCode)(ref input)).ToString()); } public static bool RemapTo(this ButtonDef def, 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 def.RemapToPath(newInput.Path(), altKey, showHints, rebindable, repeatDelay, repeatInterval); } public static bool RemapTo(this ButtonDef def, 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 def.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 ""; } } public static class ZNetExt { public static long GetPlayerUID(this ZNet instance, string playerName) { //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) ZDOID playerZDOID = instance.GetPlayerZDOID(playerName); return ((ZDOID)(ref playerZDOID)).UserID; } public static ZDOID GetPlayerZDOID(this ZNet instance, string playerName) { //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) string playerName2 = playerName; return ((IEnumerable)instance.GetPlayerList()).FirstOrDefault((Func)((PlayerInfo p) => string.Equals(p.m_name, playerName2, StringComparison.OrdinalIgnoreCase))).m_characterID; } } 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))) { Logging.Info("Unregistered RPC: " + name); } } } public static class FX { public static GameObject? PlayFX(this MonoBehaviour target, string fxPrefabName) { return Play(fxPrefabName, target); } public static GameObject? Play(string fxPrefabName, MonoBehaviour target) { //IL_0009: 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) Transform transform = ((Component)target).transform; return Play(fxPrefabName, transform.position, transform.rotation); } public static GameObject? Play(string fxPrefabName, Vector3 position, Quaternion rotation) { //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) if (!GlobalStatic.TryGetPrefab(fxPrefabName, out GameObject prefab)) { Logging.Error("fx prefab missing: " + fxPrefabName, 0); return null; } return Object.Instantiate(prefab, position, rotation); } } public static class GlobalStatic { private static readonly Dictionary<(string PrefabName, Type Type), Object> PrefabLookupCache = new Dictionary<(string, Type), Object>(); public static bool TryGetPrefab(string prefabName, out GameObject prefab, bool useCache = true) { return GlobalStatic.TryGetPrefab(prefabName, out prefab, useCache); } public static bool TryGetPrefab(string prefabName, out T prefab, bool useCache = true) where T : Object { return Object.op_Implicit((Object)(object)(prefab = GetPrefab(prefabName, useCache))); } public static bool TryGetPrefab(int prefabHash, out GameObject prefab) { return Object.op_Implicit((Object)(object)(prefab = GetPrefab(prefabHash))); } public static GameObject? GetPrefab(int prefabHash) { return ZNetScene.instance.GetPrefab(prefabHash); } public static GameObject? GetPrefab(string prefabName, bool useCache = true) { return GlobalStatic.GetPrefab(prefabName, useCache); } [Obsolete("Use TryGetPrefab(prefabName, out item, useCache) instead.")] public static bool TryGetPrefabItem(string prefabName, out ItemDrop item, bool useCache = true) { return GlobalStatic.TryGetPrefab(prefabName, out item, useCache); } [Obsolete("Use TryGetPrefab(prefabName, out piece, useCache) instead.")] public static bool TryGetPrefabPiece(string prefabName, out Piece piece, bool useCache = true) { return GlobalStatic.TryGetPrefab(prefabName, out piece, useCache); } [Obsolete("Use GetPrefab(prefabName, useCache) instead.")] public static ItemDrop? GetPrefabItem(string prefabName, bool useCache = true) { return GlobalStatic.GetPrefab(prefabName, useCache); } [Obsolete("Use GetPrefab(prefabName, useCache) instead.")] public static Piece? GetPrefabPiece(string prefabName, bool useCache = true) { return GlobalStatic.GetPrefab(prefabName, useCache); } internal static void ResetPrefabLookupCache() { if (PrefabLookupCache.Count == 0) { return; } if (Logging.IsEnabled) { Logging.Message($"Clearing prefab lookup cache: {PrefabLookupCache.Count} entities"); foreach (Object value in PrefabLookupCache.Values) { if (Object.op_Implicit(value)) { Logging.Info("- Cached: " + value.name); } } } PrefabLookupCache.Clear(); } public static T? GetPrefab(string prefabName, bool useCache = true) where T : Object { string prefabName2 = prefabName; if (Utility.IsNullOrWhiteSpace(prefabName2)) { return default(T); } prefabName2 = Utils.GetPrefabName(prefabName2); if (useCache) { T prefab = Cache.GetPrefab(prefabName2); if (Object.op_Implicit((Object)(object)prefab)) { return prefab; } if (ModLib.Configs.EnablePrefabLookupCache.Value && PrefabLookupCache.TryGetValue((prefabName2, typeof(T)), out Object value)) { return (T)(object)value; } if (Logging.IsEnabled) { Logging.Message($"Prefab not found in {typeof(T)} cache: {prefabName2}, fallback to component lookup"); } } GameObject prefab2 = PrefabManager.Instance.GetPrefab(prefabName2); if (!Object.op_Implicit((Object)(object)prefab2)) { if (Logging.IsEnabled) { Logging.Warning("Prefab is missing: " + prefabName2); } return default(T); } if (typeof(T) == typeof(GameObject)) { return Cache((T)(object)prefab2); } T obj2 = default(T); if (prefab2.TryGetComponent(ref obj2)) { return Cache(obj2); } if (Logging.IsEnabled) { Logging.Warning($"Component {typeof(T)} is missing for prefab: {prefabName2}"); } return default(T); T Cache(T obj) { if (useCache && ModLib.Configs.EnablePrefabLookupCache.Value) { PrefabLookupCache[(prefabName2, typeof(T))] = (Object)(object)obj; } return obj; } } } [HarmonyPatch] public class HelpInfo { private readonly string _topic; private readonly string _text; public HelpInfo(string topic, string text) { _topic = topic; _text = text; base..ctor(); } public static string Format(string heading, string text, string? displayValue = null, bool stripParens = true, bool stripNewLine = true) { heading = Regex.Replace(heading, "\\s*- Enabled?$", string.Empty, RegexOptions.IgnoreCase); heading = Regex.Replace(heading, "\\s*- Disabled?$", string.Empty, RegexOptions.IgnoreCase); if (stripParens) { text = Regex.Replace(text, "\\s*(\\([^)]*\\)|\\[[^\\]]*\\])", string.Empty); } if (stripNewLine) { text = text.Replace(text.Contains("\r") ? "\r\n" : "\n", " "); } heading = heading.Trim(); text = text.Trim(); string text2 = string.Empty; string text3 = string.Empty; if (displayValue != null && !Utility.IsNullOrWhiteSpace(displayValue)) { if (StringExtensionMethods.RemoveRichTextTags(displayValue).Length < 20) { text2 = " = " + displayValue; } else { text3 = "\n- " + displayValue; } } return $"\r\n{heading}{text2}\r\n{text}{text3}"; } public static string Format(ConfigEntry config, bool showValue = false, bool stripParens = true, bool stripNewLine = true) { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Invalid comparison between Unknown and I4 //IL_0166: Unknown result type (might be due to invalid IL or missing references) ConfigEntry config2 = config; string heading = ((((ConfigEntryBase)config2).Definition.Section != "General") ? (((ConfigEntryBase)config2).Definition.Section + ": " + ((ConfigEntryBase)config2).Definition.Key) : ((ConfigEntryBase)config2).Definition.Key); string description = ((ConfigEntryBase)config2).Description.Description; string displayValue = null; KeyCode val = default(KeyCode); bool flag; if (showValue) { T value = config2.Value; if (value is float) { object obj = value; float num = (float)((obj is float) ? obj : null); if (MentionsPercent()) { displayValue = (num * 100f).ToString("N0") + "%"; goto IL_01ab; } } value = config2.Value; if (!(value is Color)) { value = config2.Value; if (value is KeyCode) { object obj2 = value; val = (KeyCode)((obj2 is KeyCode) ? obj2 : null); if (val - 323 <= 2) { flag = true; goto IL_015d; } } flag = false; goto IL_015d; } object obj3 = value; Color color = (Color)((obj3 is Color) ? obj3 : null); displayValue = $"\ud83d\udd33"; } goto IL_01ab; IL_01ab: return Format(heading, description, displayValue, stripParens, stripNewLine); IL_015d: if (flag) { displayValue = $"$button_{val}".ToLowerInvariant().Localize(); } else { T value = config2.Value; displayValue = ((value != null) ? value.ToString() : null); } goto IL_01ab; bool MentionsPercent() { if (!((ConfigEntryBase)config2).Definition.Key.ToLowerInvariant().Contains("percent")) { return ((ConfigEntryBase)config2).Description.Description.ToLowerInvariant().Contains("percent"); } return true; } } [HarmonyPostfix] [HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")] [HarmonyPriority(0)] private static void TextsDialog_UpdateTextsList(TextsDialog __instance) { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown if (!ModLib.Configs.ShowHelpInfo.Value) { return; } List list = new List(); foreach (ZenMod value2 in ZenMod.Instances.Values) { HelpInfo helpInfo = value2.GetHelpInfo(); if (helpInfo != null && !Utility.IsNullOrWhiteSpace(helpInfo._topic) && !Utility.IsNullOrWhiteSpace(helpInfo._text)) { list.Add(helpInfo); } } int value = ModLib.Configs.ShowHelpInfoIndex.Value; string text = ModLib.Configs.ShowHelpInfoPrefix.Value.Trim(); if (text.Length > 0) { text += " "; } Func keySelector = (HelpInfo h) => h._topic; bool flag = value < 0 || value > __instance.m_texts.Count - 1; foreach (HelpInfo item2 in flag ? list.OrderBy(keySelector) : list.OrderByDescending(keySelector)) { TextInfo item = new TextInfo(text + item2._topic, item2._text); if (flag) { __instance.m_texts.Add(item); } else { __instance.m_texts.Insert(value, item); } } } } [HarmonyPatch] public static class Highlight { [CompilerGenerated] private sealed class d__11 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float duration; public bool blink; public Piece piece; public Action onFinish; private bool 5__2; private float 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (duration < 0f && !blink) { <>2__current = null; <>1__state = 1; return true; } goto IL_004e; case 1: <>1__state = -1; goto IL_004e; case 2: { <>1__state = -1; break; } IL_004e: Logging.Info($"Applying FX to {piece.m_name} @ {((Component)piece).transform.position.XZY()}"); 5__2 = false; 5__3 = Time.time; break; } if (duration < 0f || Time.time < 5__3 + duration) { if (blink) { Logging.Info($"Blink? {5__2}"); } ((Behaviour)piece.GetOutline()).enabled = !blink || (5__2 = !5__2); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } Unselect(piece); onFinish?.Invoke(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Dictionary FxCoroutines = new Dictionary(); public static Color DefaultColor => ModLib.Configs.DefaultHighlightColor.Value; public static int Count => FxCoroutines.Count; private static QuickOutline GetOutline(this Piece piece) { QuickOutline quickOutline = default(QuickOutline); if (!((Component)piece).gameObject.TryGetComponent(ref quickOutline)) { quickOutline = ((Component)piece).gameObject.AddComponent(); quickOutline.OutlineMode = QuickOutline.Mode.OutlineAll; quickOutline.OutlineWidth = 3f; ((Behaviour)quickOutline).enabled = false; } return quickOutline; } public static void Unselect(Piece? piece) { //IL_0026: 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) Logging.Info("Unhighlight: " + piece?.m_name); Select(piece, isActive: false, 0f, blink: false, default(Color), null); } public static void Select(Piece piece, bool blink, Color color = default(Color)) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) Select(piece, -1f, blink, color); } public static void Select(Piece? piece, float duration, bool blink, Color color = default(Color), Action? onFinish = null) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) Logging.Info("Highlight: " + piece?.m_name); Select(piece, isActive: true, duration, blink, color, onFinish); } private static void Select(Piece? piece, bool isActive, float duration, bool blink, Color color, Action? onFinish) { //IL_0010: 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_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)piece)) { QuickOutline outline = piece.GetOutline(); outline.OutlineColor = ((color == default(Color)) ? DefaultColor : color); ((Behaviour)outline).enabled = isActive; if (isActive) { piece.StartFX(duration, blink, onFinish); } else { StopFX(piece); } } } private static void StartFX(this Piece piece, float duration, bool blink, Action? onFinish) { if (FxCoroutines.TryGetValue(piece, out Coroutine value)) { ((MonoBehaviour)piece).StopCoroutine(value); } FxCoroutines[piece] = ((MonoBehaviour)piece).StartCoroutine(ApplyFx(piece, duration, blink, onFinish)); } [IteratorStateMachine(typeof(d__11))] private static IEnumerator ApplyFx(Piece piece, float duration, bool blink, Action? onFinish) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__11(0) { piece = piece, duration = duration, blink = blink, onFinish = onFinish }; } private static void StopFX(Piece piece) { //IL_0021: 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) if (FxCoroutines.TryGetValue(piece, out Coroutine value)) { Logging.Info($"Stopping FX for {piece.m_name} @ {((Component)piece).transform.position.XZY()}"); if (value != null) { ((MonoBehaviour)piece).StopCoroutine(value); } FxCoroutines.Remove(piece); Unselect(piece); } } public static void None() { Logging.Info("Stop all FX coroutines", 1); Piece[] array = FxCoroutines.Keys.ToArray(); for (int i = 0; i < array.Length; i++) { Unselect(array[i]); } } [HarmonyPrefix] [HarmonyPatch(typeof(Piece), "OnDestroy")] private static void Piece_OnDestroy(Piece __instance) { StopFX(__instance); } } public class HotLoad { private readonly HashSet _hotloadObjects = new HashSet(); internal bool IsPrefabInitInvoked { get; private set; } public event Func>? PrefabInit; internal HotLoad() { } public void Track(Object obj) { Logging.Info($"Track: {obj.name} << {((object)obj).GetType()}"); _hotloadObjects.Add(obj); } public void Untrack(Object obj) { if (_hotloadObjects.Contains(obj)) { Logging.Debug($"Untrack: {obj.name} @ {((object)obj).GetType()}"); _hotloadObjects.Remove(obj); } } internal void RestoreAll() { Logging.Info("Restoring all hot-tracked modded objects to their original state"); foreach (Object hotloadObject in _hotloadObjects) { Logging.Info($"Remove: {hotloadObject.name} >> {((object)hotloadObject).GetType()}"); Object.Destroy(hotloadObject); } } internal void PrefabInitInvoke() { if (IsPrefabInitInvoked) { throw new Exception("PrefabInitInvoke already invoked"); } Logging.Info("Prefab Init"); foreach (Object item in this.PrefabInit?.Invoke() ?? Array.Empty()) { Track(item); } IsPrefabInitInvoked = true; } } public interface IRedecorate { void OnRedecorateBefore(); void OnRedecorateAfter((Vector3 Position, Quaternion Rotation) before); } public enum HintType { None, Build, Combat, Bow, Inventory, Container, Barber, Fishing, Radial } public enum HintName { Place, CloseBuildMenu, Remove, BuildMenu, AltPlace, Snap, Copy, PrimaryAttack, BowDraw, SecondaryAttack, Block, Dodge, Move, ExitMenu, Use, Split, Drop, Multicraft, Transfer, Look } [HarmonyPatch] public static class KeyHint { private class KeyHintInstance { public readonly Dictionary<(string Name, HintType Type), (GameObject Keyboard, GameObject Gamepad)> HintUI = new Dictionary<(string, HintType), (GameObject, GameObject)>(); public event Action? UpdateBuildHints; public event Action? UpdateCombatHints; public event Action? UpdateBowHints; public event Action? UpdateInventoryHints; public event Action? UpdateContainerHints; public event Action? UpdateBarberHints; public event Action? UpdateFishingHints; public event Action? UpdateRadialHints; public static void InvokeEvents() { foreach (KeyHintInstance value in Instances.Values) { ((Action)(ActiveType switch { HintType.None => null, HintType.Build => value.UpdateBuildHints, HintType.Inventory => value.UpdateInventoryHints, HintType.Container => value.UpdateContainerHints, HintType.Combat => value.UpdateCombatHints, HintType.Bow => value.UpdateBowHints, HintType.Barber => value.UpdateBarberHints, HintType.Fishing => value.UpdateFishingHints, HintType.Radial => value.UpdateRadialHints, _ => throw new ArgumentOutOfRangeException(), }))?.Invoke(); } } } private static readonly Dictionary HintNodeNames = new Dictionary { [HintName.Place] = "Place", [HintName.CloseBuildMenu] = "Close Build Menu", [HintName.Remove] = "Remove", [HintName.BuildMenu] = "Build Menu", [HintName.AltPlace] = "Alt Place", [HintName.Snap] = "Snap", [HintName.Copy] = "Copy", [HintName.PrimaryAttack] = "PrimaryAttack", [HintName.BowDraw] = "BowDraw", [HintName.SecondaryAttack] = "Secondary attack", [HintName.Block] = "Block", [HintName.Dodge] = "Dodge", [HintName.Move] = "Move", [HintName.ExitMenu] = "ExitMenu", [HintName.Use] = "Use", [HintName.Split] = "Split", [HintName.Drop] = "Drop", [HintName.Multicraft] = "Multicraft", [HintName.Transfer] = "Transfer", [HintName.Look] = "Look" }; 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 static bool _isLabelOneFrameDirty; private static readonly Dictionary Instances = new Dictionary(); public static HintType ActiveType { get; private set; } private static event Action? LabelOneFrame; private static KeyHintInstance GetInstance(Assembly assembly) { if (!Instances.TryGetValue(assembly, out KeyHintInstance value)) { return Instances[assembly] = new KeyHintInstance(); } return value; } public static void Create(HintType hintType, ActionString action, int index = -1, bool startVisible = false) { Create(Assembly.GetCallingAssembly(), hintType, action.Name, index, startVisible); } public static void Create(HintType hintType, HintName hintName, int index = -1, bool startVisible = false) { Create(hintType, HintNodeNames[hintName], index, startVisible); } public static void Create(HintType hintType, string hintName, int index = -1, bool startVisible = false) { Create(Assembly.GetCallingAssembly(), hintType, hintName, index, startVisible); } private static void Create(Assembly assembly, HintType hintType, string hintName, int index = -1, bool startVisible = false) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) Logging.Info($"Create KeyHint for {hintType}/{hintName}"); GameObject hintRoot = GetHintRoot(hintType); (GameObject, GameObject) value = default((GameObject, GameObject)); Transform val = hintRoot.transform.Find("Keyboard"); GameObject val2 = Object.Instantiate(((Component)val.GetChild(0)).gameObject, val); if (index >= 0) { val2.transform.SetSiblingIndex(index); } ((Object)val2).name = hintName; ((Component)val2.transform.Find("Text")).GetComponent().text = "$" + hintName; ((Component)val2.transform.Find("key_bkg/Key")).GetComponent().text = "$KEY_" + hintName; value.Item1 = val2; val2.SetActive(startVisible); Transform val3 = hintRoot.transform.Find("Gamepad"); GameObject val4 = Object.Instantiate(((Component)val3.GetChild(0)).gameObject, val3); if (index >= 0) { val4.transform.SetSiblingIndex(index); } ((Object)val4).name = "Text - " + hintName; val4.GetComponent().text = "$" + hintName + " $KEY_Joy" + hintName + ""; value.Item2 = val4; foreach (Transform item in val3) { ((Object)item).name = ((Object)item).name.Replace("/", "-"); } val4.SetActive(startVisible); GetInstance(assembly).HintUI.Add((hintName, hintType), value); Localization.instance.Localize(hintRoot.transform); } 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.Container => KeyHints.instance.m_inventoryWithContainerHints, 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 SetEvent(HintType hintType, Action action) { KeyHintInstance instance = GetInstance(Assembly.GetCallingAssembly()); switch (hintType) { case HintType.Build: instance.UpdateBuildHints += action; break; case HintType.Combat: instance.UpdateCombatHints += action; break; case HintType.Bow: instance.UpdateBowHints += action; break; case HintType.Inventory: instance.UpdateInventoryHints += action; break; case HintType.Container: instance.UpdateContainerHints += action; break; case HintType.Barber: instance.UpdateBarberHints += action; break; case HintType.Fishing: instance.UpdateFishingHints += action; break; case HintType.Radial: instance.UpdateRadialHints += action; break; case HintType.None: throw new ArgumentOutOfRangeException("hintType", hintType, "Cannot set event for None hint type."); 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(HintName hintName, bool isVisible) { SetVisible(HintNodeNames[hintName], isVisible); } public static void SetVisible(string hintName, bool isVisible) { SetVisible(ActiveType, hintName, isVisible); } public static void SetVisible(HintType hintType, HintName hintName, bool isVisible) { SetVisible(hintType, HintNodeNames[hintName], isVisible); } public static void SetVisible(HintType hintType, string hintName, bool isVisible) { Set(hintType, hintName, isVisible, null); } public static void SetLabel(ActionString action, string label) { SetLabel(ActiveType, action.Name, label); } public static void SetLabel(HintName hintName, string label) { SetLabel(HintNodeNames[hintName], label); } public static void SetLabel(string hintName, string label) { SetLabel(ActiveType, hintName, label); } public static void SetLabel(HintType hintType, HintName hintName, string label) { SetLabel(hintType, HintNodeNames[hintName], label); } public static void SetLabel(HintType hintType, string hintName, string label) { Set(hintType, hintName, isVisible: true, label); } public static void SetLabelOneFrame(HintName hintName, string label) { SetLabelOneFrame(HintNodeNames[hintName], label); } public static void SetLabelOneFrame(string hintName, string label) { string hintName2 = hintName; string label2 = label; LabelOneFrame += delegate { SetLabel(hintName2, label2); _isLabelOneFrameDirty = true; }; } private static void Set(HintType hintType, string hintName, bool isVisible, string? label, string[]? searchPaths = null) { string[] array = searchPaths ?? ControlPaths; foreach (string text in array) { bool flag = text.StartsWith("Gamepad"); if (flag && hintName == "Copy") { Set(hintType, "Copy Alt1-2", isVisible && ZInput.IsNonClassicFunctionality(), label, new string[1] { text }); Set(hintType, "Copy Default", isVisible && !ZInput.IsNonClassicFunctionality(), label, 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)) { Logging.Warning(hintName + " node not found: " + text2); break; } if (flag) { if (label != null) { Regex regex = new Regex("[^>]+$"); Regex regex2 = new Regex("^[^<]+"); Regex regex3 = ((ActiveType == HintType.Container) ? regex : regex2); TMP_Text component = ((Component)val).GetComponent(); component.text = regex3.Replace(component.text, label); } ((Component)val).gameObject.SetActive(isVisible); } else { if (label != null) { ((Component)val.parent.Find("Text")).GetComponent().text = label; } ((Component)val.parent).gameObject.SetActive(isVisible); } } } internal static void RemoveAll(Assembly assembly) { KeyHintInstance instance = GetInstance(assembly); foreach (var item in instance.HintUI.Keys.Select<(string, HintType), (GameObject, GameObject)>(((string Name, HintType Type) k) => instance.HintUI[k])) { Object.Destroy((Object)(object)item.Item1); Object.Destroy((Object)(object)item.Item2); } instance.HintUI.Clear(); Instances.Remove(assembly); } private static HintType GetActiveType() { if (KeyHints.instance.m_buildHints.activeSelf) { return HintType.Build; } if (KeyHints.instance.m_inventoryHints.activeSelf) { return HintType.Inventory; } if (KeyHints.instance.m_inventoryWithContainerHints.activeSelf) { return HintType.Container; } if (KeyHints.instance.m_combatHints.activeSelf) { return HintType.Combat; } if (KeyHints.instance.m_combatHints.activeSelf && ((Humanoid)(object)Player.m_localPlayer).IsUsingRangedWeapon()) { return HintType.Bow; } if (KeyHints.instance.m_fishingHints.activeSelf) { return HintType.Fishing; } if (KeyHints.instance.m_barberHints.activeSelf) { return HintType.Barber; } if (KeyHints.instance.m_radialHints.activeSelf) { return HintType.Radial; } return HintType.None; } [HarmonyPostfix] [HarmonyPatch(typeof(KeyHints), "UpdateHints")] private static void KeyHints_UpdateHints() { ActiveType = HintType.None; if (KeyHints.instance.m_keyHintsEnabled && (UI.IsOpen || !(Time.time < _lastUpdateTime + 0.1f))) { _lastUpdateTime = Time.time; ActiveType = GetActiveType(); if (_isLabelOneFrameDirty && ActiveType != 0) { GameObject hintRoot = GetHintRoot(ActiveType); Localization.instance.ReLocalizeVisible(hintRoot.transform); _isLabelOneFrameDirty = false; } KeyHintInstance.InvokeEvents(); KeyHint.LabelOneFrame?.Invoke(); KeyHint.LabelOneFrame = null; } } } internal static class MathLib { public static ulong GetCantorID(Vector2i v) { //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) return GetCantorID(v.x, v.y); } public static ulong GetCantorID(int x, int y) { ulong num = ToUnsigned(x); ulong num2 = ToUnsigned(y); return (num + num2) * (num + num2 + 1) / 2 + num2; static ulong ToUnsigned(int n) { if (n < 0) { return (ulong)((long)n * -2L - 1); } return (ulong)n * 2uL; } } public static Vector2i FromCantorID(ulong id) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) ulong num = (ulong)Math.Floor((Math.Sqrt(8 * id + 1) - 1.0) / 2.0); ulong num2 = (num * num + num) / 2; uint num3 = (uint)(id - num2); int num4 = FromUnsigned((uint)(num - num3)); int num5 = FromUnsigned(num3); return new Vector2i(num4, num5); static int FromUnsigned(uint n) { return (int)((n % 2 == 0) ? (n / 2) : ((n + 1) / -2)); } } } public class Tally : Tally { } public class Tally : Dictionary where T : notnull { public new int this[T key] { get { if (!TryGetValue(key, out var value)) { return 0; } return value; } set { base[key] = value; } } public HashSet Diff(Tally? other, IEqualityComparer>? comparer = null) { HashSet hashSet; if (other == null) { hashSet = new HashSet(); { foreach (T key in base.Keys) { hashSet.Add(key); } return hashSet; } } IEnumerable> first = this.Except>(other, comparer); IEnumerable> second = other.Except>(this, comparer); hashSet = new HashSet(); foreach (T item in from item in first.Union>(second, comparer) select item.Key) { hashSet.Add(item); } return hashSet; } public IEnumerable<(T Key, int Amount)> Sorted() { return this.OrderByDescending(delegate(KeyValuePair pair) { KeyValuePair keyValuePair2 = pair; return keyValuePair2.Value; }).Select(delegate(KeyValuePair pair) { KeyValuePair keyValuePair = pair; T key = keyValuePair.Key; keyValuePair = pair; return (key, keyValuePair.Value); }); } } public class TerminalCtrl { public abstract class TerminalCommand { public abstract string Name { get; } public abstract string Description { get; } public string SyntaxName { get { if (!UsePrefix) { return Name; } return "zen_" + Name; } } public abstract string Syntax { get; } public abstract bool IsCheat { get; } public virtual bool UsePrefix => true; public abstract void Exec(string[] args); } public const string Prefix = "zen_"; private readonly string _modName; private readonly List _commands = new List(); internal TerminalCtrl(string modName) { _modName = modName; } public ConsoleCommand CreateCommand(TerminalCommand cmd) { return CreateCommand(cmd.Name, cmd.Description, cmd.IsCheat, cmd.UsePrefix, cmd.Exec); } public ConsoleCommand CreateCommand(string name, string description, bool isCheat, bool usePrefix, Action action) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown Action action2 = action; string text = (usePrefix ? ("zen_" + name) : name); ConsoleCommand val = new ConsoleCommand(text, "(" + _modName + ") " + description, (ConsoleEvent)delegate(ConsoleEventArgs args) { action2(args.Args); }, isCheat, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); Logging.Info("Terminal command added: " + text); _commands.Add(val); return val; } public ConsoleCommand CreateCommand(string name, string description, bool isCheat, Action action) { return CreateCommand(name, description, isCheat, usePrefix: true, action); } internal void Shutdown() { foreach (ConsoleCommand command in _commands) { Terminal.commands.Remove(command.Command.ToLower()); } _commands.Clear(); } } public static class TextPrompt { private class Handler : TextReceiver { public string Text = string.Empty; public Action? OnSuccess; public string GetText() { return Text; } public void SetText(string text) { Text = text; OnSuccess?.Invoke(text); OnSuccess = null; PlayerController.SetTakeInputDelay(0.5f); } } private static readonly Handler Receiver = new Handler(); public static void Show(string topic, string defaultText, Action onSuccess, int charLimit = 50) { Receiver.Text = defaultText; Receiver.OnSuccess = onSuccess; TextInput.instance.RequestText((TextReceiver)(object)Receiver, topic, charLimit); } } public static class Timing { [CompilerGenerated] private sealed class <_Delay>d__15 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public Action action; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <_Delay>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; action(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <_EndOfFrame>d__17 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Action action; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <_EndOfFrame>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 1; return true; case 1: <>1__state = -1; action(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <_SkipFrames>d__16 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public int frames; public Action action; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <_SkipFrames>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = 0; break; case 1: <>1__state = -1; 5__2++; break; } if (5__2 < frames) { <>2__current = null; <>1__state = 1; return true; } action(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <_When>d__14 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Func condition; public Action action; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <_When>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil(condition); <>1__state = 1; return true; case 1: <>1__state = -1; action(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static Coroutine StartCoroutine(IEnumerator coroutine) { return ((MonoBehaviour)ZenMod.Instance).StartCoroutine(coroutine); } public static void StopCoroutine(Coroutine? coroutine) { if (coroutine != null) { ((MonoBehaviour)ZenMod.Instance).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.Instance).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.Instance).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.Instance).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.Instance).Delay(seconds, action); } public static Coroutine When(this MonoBehaviour component, Func condition, Action action) { return component.StartCoroutine(_When(condition, action)); } public static Coroutine When(Func condition, Action action) { return ((MonoBehaviour)(object)ZenMod.Instance).When(condition, action); } public static Coroutine WhenNot(this MonoBehaviour component, Func condition, Action action) { Func condition2 = condition; return component.StartCoroutine(_When(() => !condition2(), action)); } public static Coroutine WhenNot(Func condition, Action action) { return ((MonoBehaviour)(object)ZenMod.Instance).WhenNot(condition, action); } [IteratorStateMachine(typeof(<_When>d__14))] private static IEnumerator _When(Func condition, Action action) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <_When>d__14(0) { condition = condition, action = action }; } [IteratorStateMachine(typeof(<_Delay>d__15))] private static IEnumerator _Delay(float delay, Action action) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <_Delay>d__15(0) { delay = delay, action = action }; } [IteratorStateMachine(typeof(<_SkipFrames>d__16))] private static IEnumerator _SkipFrames(int frames, Action action) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <_SkipFrames>d__16(0) { frames = frames, action = action }; } [IteratorStateMachine(typeof(<_EndOfFrame>d__17))] private static IEnumerator _EndOfFrame(Action action) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <_EndOfFrame>d__17(0) { action = action }; } } public static class UI { public static class Materials { private static Material? _iconDropShadowCache; public static Material LitPanel => GlobalStatic.GetPrefab("litpanel", useCache: true); public static Material IconCleanTransparency => ((Graphic)Minimap.instance.m_pingImageObject).material; public static Material IconDropShadow { get { if (!Object.op_Implicit((Object)(object)_iconDropShadowCache)) { return _iconDropShadowCache = ((Graphic)((Component)InventoryGui.instance.m_playerGrid.m_elementPrefab.transform.Find("icon")).GetComponent()).material; } return _iconDropShadowCache; } } } public static string PromptUseItem => Prompt("1-8"); public static string PromptInteract => Prompt("$KEY_Use"); public static string PromptInteractAlt => Prompt($"$KEY_{ModLib.Inputs.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 "[" + text + "]"; } public static TimeSpan RealToGameTime(double seconds, float dayMin = 0f) { double num = seconds / (double)EnvMan.instance.m_dayLengthSec; return TimeSpan.FromDays((num <= 0.0) ? 0.0 : (num + (double)dayMin)); } public static TimeSpan RealToGameTimeFuel(double seconds) { return RealToGameTime(seconds, 0.51f); } public static string RemainingTimeText(double seconds, float secPerFuel = -1f) { bool num = secPerFuel > (float)EnvMan.instance.m_dayLengthSec; TimeSpan timeSpan = (num ? RealToGameTimeFuel(seconds) : TimeSpan.FromSeconds(seconds)); string result = "None"; if (num) { if (timeSpan.Days > 0) { result = $"{timeSpan.Days} " + ((timeSpan.Days > 1) ? "$time_dayN" : "$time_day1"); } else if (timeSpan.TotalSeconds > 0.0) { result = "$time_day0"; } } else { double totalMinutes = timeSpan.TotalMinutes; if (totalMinutes > 0.0 && totalMinutes <= 1.0) { result = "$time_minute0"; } else { totalMinutes = timeSpan.TotalMinutes; result = ((!(totalMinutes > 1.0) || !(totalMinutes < 60.0)) ? ($"{timeSpan.TotalHours:N1} " + ((timeSpan.TotalHours > 1.0) ? "$time_hourN" : "$time_hour1")) : ($"{timeSpan.Minutes + 1} " + ((timeSpan.TotalMinutes > 1.0) ? "$time_minuteN" : "$time_minute1"))); } } 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(gameObject); ((Shadow)orAddComponent).effectDistance = Vector2.one * thickness; ((Shadow)orAddComponent).effectColor = ((effectColor == default(Color)) ? Color.black : effectColor); return orAddComponent; } public static string InsertInteractAlt(string hoverText, string label) { string pattern = "^(" + PromptInteract.RegexPattern() + ".*)$"; string text = PromptInteractAlt + " " + label; return Regex.Replace(hoverText, pattern, "$1\n" + text, RegexOptions.Multiline); } public static string CreateMeter(float value, float max, int length = 10) { //IL_0005: 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) //IL_000b: 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) //IL_0023: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Color color = UIColor.MinorInfo.Color; Color val = color * 0.5f; val.a = 1f; Color val2 = val; return "\n" + CreateMeter("▄", "▄", color, val2, value, max, length) + "\n"; } public static string CreateMeter(string active, string disabled, UIColor light, UIColor dark, float value, float max, int length) { if (length <= 0 || max <= 0f) { return string.Empty; } int num; if (Mathf.Approximately(max, (float)length)) { num = Mathf.CeilToInt(value); } else { num = Mathf.RoundToInt(Mathf.Clamp01(value / max) * (float)length); if (value > 0f) { num = Mathf.Max(num, 1); } } num = Mathf.Clamp(num, 0, length); int num2 = length - num; string text = $"{active.Repeat(num)}"; if (num2 > 0) { text += $"{disabled.Repeat(num2)}"; } return text; } } public class UIColor : IEquatable { private readonly string _hex; public readonly Color Color; public static readonly UIColor ValheimOrange = (UIColor)new Color(1f, 0.631f, 0.235f, 1f); public static readonly UIColor ValheimYellow = (UIColor)new Color(1f, 0.889f, 0f, 1f); public static readonly UIColor ValheimBeige = (UIColor)new Color(0.8529f, 0.725f, 0.5331f, 1f); public static readonly UIColor ValheimTooltipTitle = (UIColor)new Color(1f, 0.718f, 0.36f, 1f); public static readonly UIColor VanillaSelectGridActivatedColorBlue = (UIColor)new Color(0.376f, 0.66f, 0.897f, 0.761f); public static readonly UIColor VanillaSelectMenuActivatedColorOrange = (UIColor)new Color(0.7574f, 0.5042f, 0.1838f, 1f); public static readonly UIColor Clear = Color.clear; public static readonly UIColor White = Color.white; public static readonly UIColor Black = Color.black; public static readonly UIColor Gray = (UIColor)new Color32((byte)170, (byte)170, (byte)170, byte.MaxValue); public static readonly UIColor Orange = (UIColor)new Color(1f, 0.5f, 0f, 1f); public static readonly UIColor Yellow = (UIColor)new Color(1f, 1f, 0f); public static readonly UIColor Beige = (UIColor)new Color(0.9f, 0.9f, 0.8f); public static readonly UIColor BrightRed = (UIColor)new Color(1f, 0f, 0f); public static readonly UIColor Red = (UIColor)new Color32((byte)204, (byte)0, (byte)0, byte.MaxValue); public static readonly UIColor Blue = (UIColor)new Color32((byte)0, (byte)0, byte.MaxValue, byte.MaxValue); public static readonly UIColor Green = (UIColor)new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue); public static readonly UIColor Teal = (UIColor)new Color32((byte)170, byte.MaxValue, (byte)170, byte.MaxValue); public static readonly UIColor Cyan = (UIColor)new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue); public static readonly UIColor Purple = (UIColor)new Color32((byte)147, (byte)49, (byte)189, byte.MaxValue); public static readonly UIColor Pink = (UIColor)new Color32(byte.MaxValue, (byte)0, byte.MaxValue, byte.MaxValue); public static readonly UIColor LightOrange = (UIColor)new Color32(byte.MaxValue, (byte)153, (byte)0, byte.MaxValue); public static readonly UIColor LightYellow = (UIColor)new Color32(byte.MaxValue, byte.MaxValue, (byte)170, byte.MaxValue); public static readonly UIColor LightRed = (UIColor)new Color32(byte.MaxValue, (byte)102, (byte)102, byte.MaxValue); public static readonly UIColor LightBlue = (UIColor)new Color(0f, 0.5f, 1f); public static readonly UIColor LightGreen = (UIColor)new Color32((byte)102, byte.MaxValue, (byte)102, byte.MaxValue); public static readonly UIColor LightPurple = (UIColor)new Color32((byte)221, (byte)136, byte.MaxValue, byte.MaxValue); public static readonly UIColor DarkGray = (UIColor)new Color32((byte)79, (byte)79, (byte)79, byte.MaxValue); public static readonly UIColor DarkCyan = (UIColor)new Color32((byte)0, (byte)153, (byte)153, byte.MaxValue); public static readonly UIColor DarkPurple = (UIColor)new Color32((byte)153, (byte)51, (byte)153, byte.MaxValue); public static readonly UIColor DarkRed = (UIColor)new Color32((byte)153, (byte)0, (byte)0, byte.MaxValue); public static readonly UIColor DarkBlue = (UIColor)new Color32((byte)0, (byte)0, (byte)153, byte.MaxValue); public static readonly UIColor DarkGreen = (UIColor)new Color32((byte)0, (byte)153, (byte)0, byte.MaxValue); public static readonly UIColor DarkYellow = (UIColor)new Color32((byte)153, (byte)153, (byte)0, byte.MaxValue); public static readonly UIColor DarkOrange = (UIColor)new Color32((byte)153, (byte)102, (byte)0, byte.MaxValue); public static readonly UIColor MinorInfo = Gray; public static readonly UIColor MajorInfo = ValheimOrange; public static readonly UIColor FrostBlue = (UIColor)new Color(0f, 0.8f, 1f); public static readonly UIColor FireRed = (UIColor)new Color(1f, 0.2f, 0.2f); public static readonly UIColor ForestGreen = (UIColor)new Color(0.2f, 0.8f, 0.2f); public static readonly UIColor Gold = (UIColor)new Color(1f, 0.8f, 0f); public static readonly UIColor Silver = (UIColor)new Color(0.7f, 0.7f, 0.7f); public static readonly UIColor SoftWhite = (UIColor)new Color32((byte)221, (byte)221, (byte)221, byte.MaxValue); public static readonly UIColor DeepGray = (UIColor)new Color32((byte)153, (byte)153, (byte)153, byte.MaxValue); public string Hex => _hex.Substring(1); public UIColor(Color color) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Color = color; _hex = "#" + ColorUtility.ToHtmlStringRGBA(Color); } public UIColor(string hexRGB, bool parseFailError = true) { //IL_0024: 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_0032: Unknown result type (might be due to invalid IL or missing references) Color color = default(Color); if (!ColorUtility.TryParseHtmlString(hexRGB, ref color) && parseFailError) { throw new ArgumentException("Unable to parse color string: " + hexRGB); } UIColor uIColor = new UIColor(color); Color = uIColor.Color; _hex = uIColor._hex; } public override string ToString() { return _hex; } public bool Equals(UIColor other) { //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) return Color == other.Color; } public override bool Equals(object? obj) { if (obj is UIColor 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 implicit operator Color(UIColor uic) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return uic.Color; } public static implicit operator UIColor(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return new UIColor(color); } public static implicit operator UIColor(Color32 color32) { //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 UIColor(Color32.op_Implicit(color32)); } } public static class ZenDebug { private static readonly StringBuilder Sb = new StringBuilder(); public static string GetCallStack() { Sb.Clear(); Sb.Append("Call Stack:\n"); StackTrace stackTrace = new StackTrace(); for (int i = 1; i < stackTrace.FrameCount; i++) { MethodBase method = stackTrace.GetFrame(i).GetMethod(); Type declaringType = method.DeclaringType; string value = ((declaringType != null) ? (declaringType.Name + "." + method.Name) : method.Name); Sb.Append(value); if (i != stackTrace.FrameCount - 1) { Sb.Append("\n"); } } return Sb.ToString(); } } public abstract class ZenMod : BaseUnityPlugin { public const string AuthorName = "ZenDragon"; public const string HomeURL = "https://github.com/ZenDragonX/ZenMods_Valheim/wiki"; protected static readonly GameVersion ValheimVersionRequired = new GameVersion(0, 221, 12); internal static readonly Dictionary Instances = new Dictionary(); private static bool _requireGamepadRemap; protected static bool IsValheimVersionOK { get { //IL_000c: 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) if (ModLib.Configs.EnableValheimVersionCheck.Value) { return Version.CurrentVersion == ValheimVersionRequired; } return true; } } protected bool RunOnServer { get; set; } protected static bool IsHeadless => (int)SystemInfo.graphicsDeviceType == 4; protected bool IsScriptEngine { get { if (!Utility.IsNullOrWhiteSpace(((BaseUnityPlugin)this).Info.Location)) { return ((BaseUnityPlugin)this).Info.Location.Contains("scripts"); } return true; } } public static bool RequireGamepadRemap { get { return _requireGamepadRemap; } protected set { if (value) { if (!IsHeadless) { Logging.Message(Assembly.GetCallingAssembly().GetName().Name + " requires extended controls. Gamepad remap will be applied."); } _requireGamepadRemap = value; } } } protected internal virtual HelpInfo? GetHelpInfo() { return null; } } public abstract class ZenMod : ZenMod where TPlugin : ZenMod { [CompilerGenerated] private sealed class d__58 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private Action <>2__current; private int <>l__initialThreadId; private Func @event; public Func <>3__event; private Delegate[] <>7__wrap1; private int <>7__wrap2; Action IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__58(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_0073; } <>1__state = -1; <>7__wrap1 = @event?.GetInvocationList() ?? Array.Empty(); <>7__wrap2 = 0; goto IL_0081; IL_0081: if (<>7__wrap2 < <>7__wrap1.Length) { Action action = ((Func)<>7__wrap1[<>7__wrap2])(); if (action != null) { <>2__current = action; <>1__state = 1; return true; } goto IL_0073; } <>7__wrap1 = null; return false; IL_0073: <>7__wrap2++; goto IL_0081; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__58 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__58(0); } d__.@event = <>3__event; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private bool _loadedOnce; private bool _isInitialized; private readonly TerminalCtrl _terminal; private readonly Assembly _assembly; private readonly Harmony _harmony; internal readonly Logging Logging; private readonly List _craftingSyncConfigs = new List(); private readonly List _prefabSyncConfigs = new List(); private readonly object _configSyncLock = new object(); public static TPlugin 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._terminal; public static bool IsOnServerAlso => ModCompatibility.IsModuleOnServer((BaseUnityPlugin)(object)Instance); public HotLoad HotLoad { get; } = new HotLoad(); 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().EnforceModOnClients; if (enforceModOnClients - 2 <= 1) { return true; } return false; } } public event Action? RegisterInputs; public event Func? RegisterCraftingItems; public event Func? PrefabsRegistered; public event Action? LanguageChanged; public event Action? ConfigSync; internal ManualLogSource GetLogger() { return ((BaseUnityPlugin)this).Logger; } protected ZenMod() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)Instance)) { throw new Exception($"Instance {typeof(TPlugin)} is already loaded. There can be only one!"); } Instance = (TPlugin)this; _assembly = ((object)this).GetType().Assembly; _harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); _terminal = new TerminalCtrl(((BaseUnityPlugin)this).Info.Metadata.Name); ZenMod.Instances.Add(_assembly, this); Zen.Lib.Config.Config.File = ((BaseUnityPlugin)this).Config; Logging = new Logging(); Zen.Lib.Config.Config.Define(isAdmin: false, "_Author", "Website", "https://github.com/ZenDragonX/ZenMods_Valheim/wiki", "ZenDragon\nLike my mods?"); if (base.IsScriptEngine) { Logging.Warning("------------------------------"); Logging.Warning($"Type: {((object)this).GetType()}"); Logging.Warning("Assembly: " + _assembly.GetName().Name); Logging.Warning($"Assembly Hash: {_assembly.GetHashCode():X}"); Logging.Warning("------------------------------"); } if (this is ModLib && !ModLib.Configs.EnableValheimVersionCheck.Value) { Logging.Warning("Valheim version check is disabled!"); } if (!ZenMod.IsValheimVersionOK) { Logging.Fatal(string.Format("\r\n================================================================================\r\n{0}\r\nABORT: Valheim version mismatch.\r\nValheim installed: {1}, required: {2}. \r\nChange your installed Valheim version to match.\r\nSee {3} configs for more info.\r\n================================================================================\r\n", ((BaseUnityPlugin)this).Info.Metadata.GUID, Version.CurrentVersion, ZenMod.ValheimVersionRequired, "Zen.ModLib"), 0); } else { _harmony.PatchAll(_assembly); Game.isModded = true; } } protected abstract void Setup(); protected abstract void TitleScene(bool isFirstBoot); protected abstract void WorldStart(); protected abstract void Shutdown(); protected virtual void HotRestore() { } private void Awake() { if (!ZenMod.IsValheimVersionOK) { Object.Destroy((Object)(object)this); return; } RegisterEventHandlers(); InitConfigs(); Setup(); PreInit(); InitInputs(); if (base.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) && Player.m_localPlayer.IsReady(); 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() { Logging.Debug("CheckInit"); if (!IsSysReady()) { return; } if (ZNet.instance.IsDedicated()) { if (!base.RunOnServer) { Logging.Message(((BaseUnityPlugin)this).Info.Metadata.Name + " server mode: ConfigSync"); AbortInit(); return; } Logging.Message(((BaseUnityPlugin)this).Info.Metadata.Name + " server mode: Active"); } ((MonoBehaviour)this).CancelInvoke("CheckInit"); if (!_loadedOnce) { OnLanguageChange(); OnInputLayoutChanged(); } UI.CanvasScaler = ((Component)Hud.instance).GetComponent().m_canvasScaler; Logging.Info("Reload Configs"); ((BaseUnityPlugin)this).Config.Reload(); if (!HotLoad.IsPrefabInitInvoked && base.IsScriptEngine) { Logging.Warning("Hot restoring existing objects"); HotLoad.PrefabInitInvoke(); HotRestore(); GUIManager.BlockInput(false); } if (this is ModLib modLib) { modLib.BeforeWorldStart(); } Logging.Info("World Start"); WorldStart(); _isInitialized = true; _loadedOnce = true; } private void AbortInit() { ((MonoBehaviour)this).CancelInvoke("CheckInit"); _harmony.UnpatchSelf(); } private void InitConfigs() { Logging.Info(((BaseUnityPlugin)this).Info.Metadata.Name + " Initialize Configs"); Zen.Lib.Config.Config.File = ((BaseUnityPlugin)this).Config; Logging.Info("Config file: " + Zen.Lib.Config.Config.File.ConfigFilePath); InvokeStaticConstructorForFields(typeof(ConfigEntry<>)); Zen.Lib.Config.Config.File = null; } private void InitInputs() { InvokeStaticConstructorForFields(typeof(ActionString)); } private void InvokeStaticConstructorForFields(Type searchFieldType) { Type searchFieldType2 = searchFieldType; Func 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).Any(delegate(FieldInfo field) { if (!searchFieldType2.IsGenericType) { if (!field.FieldType.IsGenericType) { return field.FieldType == searchFieldType2; } return false; } return field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == searchFieldType2; })) { RuntimeHelpers.RunClassConstructor(item.TypeHandle); } } } private void DebugAddTranslations() { if (!base.IsScriptEngine) { Logging.Warning("Not running as script! Skipping debug add translations"); return; } ((MonoBehaviour)(object)Instance).EndOfFrame(delegate { Logging.Debug("Assembly: " + ((object)this).GetType().Assembly.GetName().Name); Logging.Debug("Assembly Location: " + ((object)this).GetType().Assembly.Location); Logging.Debug("Type: " + ((object)this).GetType()); Logging.Debug("Name: " + ((BaseUnityPlugin)this).Info.Metadata.Name); Logging.Debug("Instance: " + (object)((BaseUnityPlugin)this).Info.Instance); Logging.Debug("Location: " + ((BaseUnityPlugin)this).Info.Location); string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); if (!Directory.Exists(directoryName)) { throw new DirectoryNotFoundException(directoryName); } Logging.Info("Search: " + directoryName); string[] files = Directory.GetFiles(directoryName, "*.json", SearchOption.AllDirectories); foreach (string text in files) { LocalizationManager.Instance.GetLocalization().AddFileByPath(text, true); } }); } private void OnDestroy() { string name = _assembly.GetName().Name; Logging.Info("Destroy: " + name); ZenMod.Instances.Remove(_assembly); if (ZenMod.IsValheimVersionOK) { UnregisterEventHandlers(); Shutdown(); if (ModLib.IsApplicationQuit) { Logging.Info("Quit: " + name); return; } Logging.Info("Cleanup: " + name); HotLoad.RestoreAll(); ((MonoBehaviour)this).StopAllCoroutines(); Cleanup.External((BaseUnityPlugin)(object)this); ActionString.Shutdown(_assembly); KeyHint.RemoveAll(_assembly); _terminal.Shutdown(); Logging.Info("Unpatching " + name); _harmony.UnpatchSelf(); } } 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)); } [IteratorStateMachine(typeof(ZenMod<>.d__58))] private static IEnumerable InvokeGetSyncConfigs(Func? @event) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__58(-2) { <>3__event = @event }; } 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)) { Logging.Info("Local mode: single player or player is server, apply ConfigSync now."); OnConfigSync(); } } private void OnConfigSync(object sender, EventArgs e) { OnConfigSync(); } private void OnConfigSync() { lock (_configSyncLock) { Logging.Info("Config sync"); this.ConfigSync?.Invoke(); InvokeSyncCallbacks(); } } private void InvokeSyncCallbacks() { Logging.Info($"Invoking RegisterCraftingItems callbacks: {_craftingSyncConfigs.Count}"); CollectionExtensions.Do((IEnumerable)_craftingSyncConfigs, (Action)delegate(Action callback) { callback(); }); Logging.Info($"Invoking PrefabsRegistered callbacks: {_prefabSyncConfigs.Count}"); CollectionExtensions.Do((IEnumerable)_prefabSyncConfigs, (Action)delegate(Action callback) { callback(); }); } private void OnLanguageChange() { ActionString.TranslateAll(_assembly); this.LanguageChanged?.Invoke(PlayerPrefs.GetString("language", "English")); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (this is ModLib) { GlobalStatic.ResetPrefabLookupCache(); } if (((Scene)(ref scene)).name == "start") { StringList.AccessCount.Clear(); KeyHint.RemoveAll(_assembly); TitleScene(!_isInitialized); PreInit(); } } private void OnInputLayoutChanged() { if (ZenMod.IsHeadless) { Logging.Info("Running headless, input layout change doesn't apply"); return; } if (this is ModLib) { InteractAlt.Register(); if (ZenMod.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); } } } namespace Zen.Lib.Controls { public class ActionString { private static readonly Dictionary> Instances = new Dictionary>(); private string _label = string.Empty; private ButtonDef? _kbmAlias; private ButtonDef? _joyAlias; public string Name { get; } public string Label { get { return _label.Localize(); } set { _label = value; } } public static implicit operator string(ActionString input) { return input.ToString(); } internal ActionString(Assembly assembly, string? label = null, string? nameOverride = null) { Regex regex = new Regex("[^\\w]"); string arg = regex.Replace(assembly.GetName().Name, "_"); string arg2 = regex.Replace(label ?? string.Empty, "").Truncate(20); if (!Instances.TryGetValue(assembly, out List value)) { value = (Instances[assembly] = new List()); } value.Add(this); if (nameOverride != null) { Logging.Info("Using name override: " + nameOverride); } Name = nameOverride ?? $"{arg}_{arg2}_{value.Count - 1:0000}"; Label = label ?? string.Empty; } private void UpdateLabelTranslations() { if (!Utility.IsNullOrWhiteSpace(Label)) { Logging.Info("Update translation: " + Name + " " + 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)) { Logging.Info("Skip existing button: " + value.GetActionPath(true) + "\t" + value.Name); return; } if (rebindable && (path.StartsWith("") || path.StartsWith(""))) { string @string = PlayerPrefs.GetString("kbmBinding_" + name); if (!Utility.IsNullOrWhiteSpace(@string)) { path = @string; } } Logging.Info("Add Button: " + path + "\t" + name); 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("")) { _joyAlias = buttonDef; } else if (actionPath.StartsWith("") || actionPath.StartsWith("")) { _kbmAlias = buttonDef; } Logging.Info("Alias: " + buttonDef.GetActionPath(true) + "\t" + existingName + " -> " + Name); } public override string ToString() { if (ZInput.IsGamepadActive()) { if (_joyAlias == null) { return "Joy" + Name; } return _joyAlias.Name; } if (_kbmAlias == null) { return Name; } return _kbmAlias.Name; } public void RemoveButtons() { Logging.Info("Remove ActionString Buttons: " + Name); ZInput.instance.RemoveButton(Name); ZInput.instance.RemoveButton("Joy" + Name); } private static void RemoveAll(Assembly assembly) { if (!Instances.TryGetValue(assembly, out List value)) { return; } foreach (ActionString item in value) { item.RemoveButtons(); } value.Clear(); } internal static void Shutdown(Assembly assembly) { RemoveAll(assembly); Instances.Remove(assembly); } internal static void TranslateAll(Assembly assembly) { if (!Instances.TryGetValue(assembly, out List value)) { return; } foreach (ActionString item in value) { item.UpdateLabelTranslations(); } } } public static class ControlInputs { 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 JoyLTriggerSwapped; } return JoyLBumperSwapped; } } private static string JoyLTriggerSwapped { get { if (!ZInput.SwapTriggers) { return "JoyLTrigger"; } return "JoyRTrigger"; } } private static string JoyLBumperSwapped { 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; } } public static ActionString Create(string? label = null) { return new ActionString(Assembly.GetCallingAssembly(), label); } internal static ActionString Create(string? label, string? nameOverride) { return new ActionString(Assembly.GetCallingAssembly(), label, nameOverride); } } [HarmonyPatch] internal static class GamepadRemap { internal static void SetupControls() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_006f: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) Logging.Message("Using gamepad extended remap"); if ((int)ZInput.InputLayout == 0) { if (ZInput.instance.GetButtonDef("JoyGP").RemapTo((GamepadInput)8, true)) { Logging.Message("> Remap 'Guardian Power' to Y+Alt button"); } } else { GamepadInput val = (((int)ZInput.InputLayout == 1) ? ControlInputs.TriggerSwappedL : ControlInputs.BumperSwappedL); if (ZInput.instance.GetButtonDef("JoyCrouch").RemapTo(val, false)) { Logging.Message($"> Remap 'Crouch' to {val}"); } } ZInput.instance.GetButtonDef("JoyAltPlace").ShowHints = false; if (ZInput.instance.GetButtonDef("JoyHide").RemapTo((GamepadInput)3)) { Logging.Message("> Remap 'Show/Hide' to D-Pad Down"); } if (ZInput.instance.GetButtonDef("JoySit").RemapTo((GamepadInput)19, true)) { Logging.Message("> Remap 'Sit' to Select button with alt press"); } ButtonDef buttonDef = ZInput.instance.GetButtonDef("JoyChat"); bool? showHints = false; if (buttonDef.RemapTo((GamepadInput)0, null, showHints)) { Logging.Message("> Remap 'Chat' to None. Use a keyboard or mic to chat."); } Logging.Info("Gamepad remap success"); } [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "Update")] private static IEnumerable JoyAltHide_Player_Update(IEnumerable codes) { MethodInfo methodInfo = AccessTools.Method(typeof(Character), "InPlaceMode", (Type[])null, (Type[])null); Func func = InPlaceModeIntercept; return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)func.Method); static bool InPlaceModeIntercept(Character character) { if (!ZenMod.RequireGamepadRemap) { return character.InPlaceMode(); } if (((IEnumerable)new string[4] { "JoyLBumper", "JoyLTrigger", "JoyRBumper", "JoyRTrigger" }).Any((Func)ZInput.GetButton)) { return character.InPlaceMode(); } if (!Hud.IsPieceSelectionVisible() && !InventoryGui.IsVisible()) { return Minimap.IsOpen(); } return true; } } [HarmonyTranspiler] [HarmonyPatch(typeof(InventoryGui), "Update")] [HarmonyPriority(100)] private static IEnumerable InventoryGui_Update(IEnumerable codes) { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(InventoryGui), "Show", (Type[])null, (Type[])null); Action action = InterceptInventoryGuiShow; return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)action.Method); static void InterceptInventoryGuiShow(InventoryGui gui, Container container, int activeGroup) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) bool flag = false; if (ZInput.IsGamepadActive() && (int)ZInput.InputLayout == 0 && ZenMod.RequireGamepadRemap) { bool button = ZInput.GetButton(ControlInputs.JoyAlt); bool button2 = ZInput.GetButton("JoyGP"); if (button && button2) { flag = true; } } if (flag) { Player.m_localPlayer.StartGuardianPower(); } else { gui.Show(container, activeGroup); } } } [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "HandleRadialInput")] private static IEnumerable Player_HandleRadialInput_Transpile(IEnumerable codes) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown Func func = InterceptJoySit; Func func2 = InterceptJoyAltKeys; return new CodeMatcher(codes, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[5] { new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"JoyAltKeys", (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(ZInput), "GetButton", (Type[])null, (Type[])null), (string)null), new CodeMatch((OpCode?)OpCodes.Brtrue, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"JoySit", (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(ZInput), "GetButtonUp", (Type[])null, (Type[])null), (string)null) }).ThrowIfInvalid("Could not match IL").Advance(1) .SetOperandAndAdvance((object)func2.Method) .Advance(2) .SetOperandAndAdvance((object)func.Method) .InstructionEnumeration(); static bool InterceptJoyAltKeys(string input) { if (!ZenMod.RequireGamepadRemap) { return ZInput.GetButton(input); } return false; } static bool InterceptJoySit(string input) { if (ZenMod.RequireGamepadRemap) { int num; if (ZInput.GetButtonUp(input)) { num = (ZInput.GetButton(ControlInputs.JoyAlt) ? 1 : 0); if (num != 0) { PlayerController.SetTakeInputDelay(0.8f); } } else { num = 0; } return (byte)num != 0; } return ZInput.GetButtonUp(input); } } [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "HandleRadialInput")] private static IEnumerable Player_HandleRadialInput(IEnumerable codes) { return codes.SetRadialPressDuration().ToggleRadialButton(); } private static IEnumerable SetRadialPressDuration(this IEnumerable codes) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"JoyRadial", (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(ZInput), "GetButtonPressedTimer", (Type[])null, (Type[])null), (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null) }; Func func = GetDuration; return new CodeMatcher(codes, (ILGenerator)null).MatchEndForward(array).ThrowIfInvalid("Unable to match IL").Set(OpCodes.Call, (object)func.Method) .InstructionEnumeration(); static float GetDuration() { return ModLib.Configs.GamepadEmoteWheelDuration.Value; } } private static IEnumerable ToggleRadialButton(this IEnumerable codes) { Func intercept = InterceptJoyRadial; return Transpilers.Manipulator(codes, (Func)((CodeInstruction c) => CodeInstructionExtensions.Is(c, OpCodes.Ldstr, (object)"JoyRadial")), (Action)delegate(CodeInstruction c) { c.opcode = OpCodes.Call; c.operand = intercept.Method; }); static string InterceptJoyRadial() { if (!ModLib.Configs.GamepadEmoteWheel.Value) { return "JoyRadial_DISABLED"; } return "JoyRadial"; } } } [HarmonyPatch] internal static class InteractAlt { internal const string ExplicitName = "Zen_ModLib_InteractAlt"; private static readonly string[] VanillaInteractAltPrompts = new string[2] { "[$KEY_AltKeys + $KEY_Use]", "[$KEY_AltPlace + $KEY_Use]" }; private static bool _isRegistered; private static string InteractAltPattern => UI.PromptInteractAlt.Localize().GlyphFix(); internal static ActionString Create() { return ControlInputs.Create("$input_interact_alt", "Zen_ModLib_InteractAlt"); } internal static void Register() { if (_isRegistered) { Logging.Info("Already registered InteractAlt button."); return; } ZenMod.Instance.RegisterInputs += AddInteractAltButton; _isRegistered = true; } private static void AddInteractAltButton() { //IL_0015: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_0079: Invalid comparison between Unknown and I4 //IL_00bb: Unknown result type (might be due to invalid IL or missing references) Logging.Info("Register Inputs: InteractAlt", 1); ModLib.Inputs.InteractAlt.RemoveButtons(); GamepadInput val = (GamepadInput)(((int)ZInput.InputLayout == 0) ? 15 : 11); Logging.Info($"Add InteractAlt Gamepad: {val}"); ModLib.Inputs.InteractAlt.AddButton(val, altKey: false, showHints: true); KeyCode value = ModLib.Configs.InteractAltKey.Value; ButtonDef buttonDef = ZInput.instance.GetButtonDef("AutoRun"); if (buttonDef.IsMappedTo(value)) { buttonDef.RemapTo((KeyCode)(((int)value == 113) ? 92 : 113)); Logging.Message($"> Remapped 'AutoRun' to avoid conflict with Interact Alt: {value}"); } Logging.Info($"Add InteractAlt Key: {value}"); ModLib.Inputs.InteractAlt.AddButton(value); } [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "Update")] private static IEnumerable Player_Update_Transpiler(IEnumerable codes) { Func configShiftE = ConfigShiftE; return Transpilers.Manipulator(codes, (Func)IsMatch, (Action)delegate(CodeInstruction c) { c.opcode = OpCodes.Call; c.operand = configShiftE.Method; }); static bool IsMatch(CodeInstruction c) { if (c.opcode == OpCodes.Ldstr) { return (string)c.operand == "AltPlace"; } return false; } } private static string ConfigShiftE() { if (!ModLib.Configs.InteractAltUseShiftE.Value) { return "AltPlace_DISABLED"; } return "AltPlace"; } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "Update")] private static void Player_Update(Player __instance) { CheckForInteraction(__instance); } private static void CheckForInteraction(Player player) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!UI.IsOpen && !Hud.InRadial() && !((Character)player).IsTeleporting() && !((Character)player).IsDead() && !((Character)player).InDodge() && !((Character)player).IsRunning() && !(((Character)player).GetMoveDir() != Vector3.zero) && player.IsHoveringInteractAlt()) { if (ZInput.GetButtonDown((string)ModLib.Inputs.InteractAlt)) { player.Interact(player.m_hovering, false, true); } else if (ZInput.GetButton((string)ModLib.Inputs.InteractAlt) && ZInput.GetButtonPressedTimer((string)ModLib.Inputs.InteractAlt) > 0.3f) { player.Interact(player.m_hovering, true, true); } } } private static bool HasHoverText(this Player player, out TMP_Text hover) { hover = (TMP_Text)(object)Hud.instance.m_hoverName; if (Object.op_Implicit((Object)(object)player.m_hovering) && Object.op_Implicit((Object)(object)hover)) { return !Utility.IsNullOrWhiteSpace(hover.text); } return false; } private static bool IsHoveringInteractAlt(this Player player) { if (player.HasHoverText(out TMP_Text hover)) { return hover.text.Contains(InteractAltPattern); } return false; } [HarmonyPostfix] [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] private static void Hud_UpdateCrosshair(Hud __instance, Player player) { if (player.HasHoverText(out TMP_Text hover)) { hover.ReplaceInteractAltPrompt(); } } private static void ReplaceInteractAltPrompt(this TMP_Text hover) { string[] vanillaInteractAltPrompts = VanillaInteractAltPrompts; for (int i = 0; i < vanillaInteractAltPrompts.Length; i++) { string oldValue = vanillaInteractAltPrompts[i].Localize().GlyphFix(); hover.text = hover.text.Replace(oldValue, InteractAltPattern); } } } } namespace Zen.Lib.Config { public static class Config { internal static ConfigFile? File; public static IEnumerable ContainersCommon => new <>z__ReadOnlyArray(new string[7] { "piece_chest_wood", "piece_chest", "piece_chest_blackmetal", "piece_chest_barrel", "piece_pot1", "piece_pot2", "piece_pot3" }); public static IEnumerable ContainersAll => ContainersCommon.Concat(new <>z__ReadOnlyArray(new string[4] { "piece_chest_private", "piece_gift1", "piece_gift2", "piece_gift3" })); public static ConfigEntry Define(bool isAdmin, string section, string key, T defaultValue) { return Define(isAdmin, section, key, defaultValue, (AcceptableValueBase?)null, string.Empty); } public static ConfigEntry Define(bool isAdmin, string section, string key, T defaultValue, string description) { return Define(isAdmin, section, key, defaultValue, (AcceptableValueBase?)null, description); } public static ConfigEntry Define(bool isAdmin, string section, string key, T defaultValue, AcceptableValueRange? acceptableValues, string description) where T : IComparable { return Define(isAdmin, section, key, defaultValue, (AcceptableValueBase?)(object)acceptableValues, description); } public static ConfigEntry Define(bool isAdmin, string section, string key, T defaultValue, AcceptableValueList? acceptableValues, string description) where T : IEquatable { return Define(isAdmin, section, key, defaultValue, (AcceptableValueBase?)(object)acceptableValues, description); } private static ConfigEntry Define(bool isAdmin, string section, string key, T defaultValue, AcceptableValueBase? acceptableValues, string description) { //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_001f: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if (File == null) { throw new InvalidOperationException("Config file not set"); } ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = isAdmin }; return File.Bind(section, key, defaultValue, new ConfigDescription((isAdmin ? "[Admin] " : string.Empty) + description, acceptableValues, new object[1] { val })); } public static AcceptableValueRange AcceptRange(T min, T max) where T : IComparable { return new AcceptableValueRange(min, max); } public static AcceptableValueList AcceptList(params T[] list) where T : IEquatable { return new AcceptableValueList(list); } } public class StringList : List { private const char ElementSeparator = ','; private const char FieldSeparator = ':'; internal static readonly Tally AccessCount; private List? _listCache; private HashSet? _hashCache; private Dictionary? _dictCache; public static StringList Empty => new StringList(); public StringList() { } public StringList(IEnumerable collection) : base(collection) { } public static StringList Parse(string? str) { if (str == null) { return Empty; } return new StringList(from s in str.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select s.Trim()); } static StringList() { AccessCount = new Tally(); AddToTomlTypeConverter(); } private static void AddToTomlTypeConverter() { //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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown if (!TomlTypeConverter.CanConvert(typeof(StringList))) { TypeConverter val = new TypeConverter { ConvertToString = (object obj, Type _) => ((StringList)obj).ToString(), ConvertToObject = delegate(string str, Type _) { CheckPerformance(str); return Parse(str); } }; TomlTypeConverter.AddConverter(typeof(StringList), val); Logging.Info("StringList added to TomlTypeConverter"); } } private static void CheckPerformance(string s) { int value = ModLib.Configs.ConfigThrashWarningLimit.Value; if (value > 0 && !string.IsNullOrEmpty(s)) { if (!ConfigurationManager.IsDisplayingWindow()) { AccessCount[s]++; } if (AccessCount[s] > value) { Logging.Warning("Possible performance issue. (ConfigWatcher maybe?) " + $"ConvertToObject access count {AccessCount[s]} > {value}: \"{s}\""); } } } private IEnumerable Split(char splitChar, bool trim = true) { if (_listCache != null) { return _listCache; } _listCache = new List(); using (List.Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { string[] array = enumerator.Current.Split(new char[1] { splitChar }); if (trim) { array = array.Select((string s) => s.Trim()).ToArray(); } _listCache.Add(array); } } return _listCache; } public bool Contains(string key, bool unique = true) { if (!unique) { return base.Contains(key); } if (_hashCache == null) { HashSet hashSet = new HashSet(); using (List.Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { string current = enumerator.Current; hashSet.Add(current); } } _hashCache = hashSet; } return _hashCache.Contains(key); } public Dictionary ToDictionary(char splitChar = ':') { if (_dictCache != null) { return _dictCache; } try { _dictCache = Split(splitChar).ToDictionary((string[] pair) => pair[0], (string[] pair) => pair[1]); return _dictCache; } catch (Exception ex) { Logging.Error($"Unable to parse dictionary. {ex.Message} {this}", 0); } return new Dictionary(); } public Requirement[] ToRequirements(char splitChar = ':') { return ((IEnumerable)ToRequirementConfigs(splitChar)).Select((Func)((RequirementConfig config) => new Requirement { m_resItem = ObjectDB.instance.GetItemPrefab(config.Item).GetComponent(), m_amount = config.Amount, m_amountPerLevel = config.AmountPerLevel, m_recover = config.Recover })).ToArray(); } public RequirementConfig[] ToRequirementConfigs(char splitChar = ':') { try { return Split(splitChar).Select((Func)((string[] element) => new RequirementConfig(element[0], int.Parse(element[1]), (element.Length > 2) ? int.Parse(element[2]) : 0, element.Length <= 3 || bool.Parse(element[3])))).ToArray(); } catch (Exception ex) { Logging.Error($"Unable to parse requirements. {ex.Message} {this}", 0); } return Array.Empty(); } public override string ToString() { return GeneralExtensions.Join(this.Select((string s) => s.Trim()), (Func)null, string.Format("{0}{1}", ',', " ")); } } } namespace Zen.Interop { public static class HoverItem { private const string ModID = "ZenDragon.ZenHoverItem"; public static string Message_UpdateIcons => "UpdateIcons"; public static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("ZenDragon.ZenHoverItem"); private static void SendUpdateIcons(object arg) { Message.Send("ZenDragon.ZenHoverItem", Message_UpdateIcons, arg); } public static void UpdateIcons(Sprite sprite, string label) { SendUpdateIcons((sprite, label)); } public static void UpdateIcons(string prefabName, string label) { SendUpdateIcons((prefabName, label)); } public static void UpdateIcons(IEnumerable sprites) { SendUpdateIcons(sprites); } public static void UpdateIcons(IEnumerable sprites) { SendUpdateIcons(sprites); } public static void UpdateIcons(IEnumerable<(Sprite Icon, string Label)> sprites) { SendUpdateIcons(sprites); } public static void UpdateIcons(IEnumerable<(string PrefabName, string Label)> sprites) { SendUpdateIcons(sprites); } public static void UpdateIcons(params (Sprite Icon, string Label)[] elements) { SendUpdateIcons(elements); } public static void UpdateIcons(params (string PrefabName, string Label)[] elements) { SendUpdateIcons(elements); } public static void UpdateIcons(params Sprite[] sprites) { SendUpdateIcons(sprites); } public static void UpdateIcons(params string[] prefabNames) { SendUpdateIcons(prefabNames); } } public interface IMessageListener { void ReceiveMessage(string message, object? arg); } public static class Message { internal const string Separator = "::"; public static void Send(string pluginGUID, string message, object? arg) { if (!string.IsNullOrEmpty(pluginGUID) && !string.IsNullOrEmpty(message)) { ((Component)ZenMod.Instance).SendMessage(pluginGUID + "::" + message, arg, (SendMessageOptions)1); } } public static object? Request(string pluginGUID, string message, object? arg) { object[] array = new object[2] { arg, null }; Send(pluginGUID, message, array); return array[1]; } } [HarmonyPatch] internal static class MessagePatch { private enum CacheKind { Missing, Found } private sealed class CacheEntry { public readonly CacheKind Kind; public readonly BaseUnityPlugin? Plugin; public readonly string? Msg; private CacheEntry(CacheKind kind, BaseUnityPlugin? plugin, string? msg) { Kind = kind; Plugin = plugin; Msg = msg; } public static CacheEntry MissingPlugin() { return new CacheEntry(CacheKind.Missing, null, null); } public static CacheEntry ForPlugin(BaseUnityPlugin plugin, string message) { return new CacheEntry(CacheKind.Found, plugin, message); } } private static readonly Dictionary Cache = new Dictionary(StringComparer.Ordinal); private const int CacheMaxEntries = 2048; [UsedImplicitly] private static IEnumerable TargetMethods() { return new <>z__ReadOnlyArray(new MethodBase[2] { AccessTools.DeclaredMethod(typeof(Component), "SendMessage", new Type[3] { typeof(string), typeof(object), typeof(SendMessageOptions) }, (Type[])null), AccessTools.DeclaredMethod(typeof(GameObject), "SendMessage", new Type[3] { typeof(string), typeof(object), typeof(SendMessageOptions) }, (Type[])null) }); } [HarmonyPrefix] [UsedImplicitly] [HarmonyPriority(800)] private static bool SendMessage_Patch(string? methodName, object? value, SendMessageOptions options) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Invalid comparison between Unknown and I4 //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (methodName == null) { return true; } int num = methodName.IndexOf("::", StringComparison.Ordinal); if (num < 0) { return true; } if (num == 0 || num == methodName.Length - "::".Length) { return false; } bool value2 = ModLib.Configs.EnableMessageCache.Value; if (value2 && Cache.TryGetValue(methodName, out CacheEntry value3)) { switch (value3.Kind) { case CacheKind.Missing: Logging.Debug("Target plugin not found in cache"); return false; case CacheKind.Found: if (Object.op_Implicit((Object)(object)value3.Plugin) && value3.Msg != null) { Dispatch(value3.Plugin, value3.Msg, value, options); return false; } Cache.Remove(methodName); break; } } if (!value2 || Cache.Count >= 2048) { Cache.Clear(); } if ((int)options != 1) { Logging.Warning("SendMessage invoked without specifying DontRequireReceiver, this may result in errors if target mod is missing."); } string key = methodName.Substring(0, num); string message = methodName.Substring(num + "::".Length); if (!Chainloader.PluginInfos.TryGetValue(key, out var value4)) { Logging.Info("Target plugin not installed / missing: " + methodName); if (value2) { Cache[methodName] = CacheEntry.MissingPlugin(); } return false; } BaseUnityPlugin instance = value4.Instance; if (value2) { Cache[methodName] = CacheEntry.ForPlugin(instance, message); } Dispatch(instance, message, value, options); return false; } private static void Dispatch(BaseUnityPlugin plugin, string message, object? value, SendMessageOptions options) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (plugin is IMessageListener messageListener) { messageListener.ReceiveMessage(message, value); } else { ((Component)plugin).SendMessage(message, value, options); } } } public static class Portal { private const string ModID = "ZenDragon.ZenPortal"; public static string Message_PortalSymbols => "PortalSymbols"; public static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("ZenDragon.ZenPortal"); public static string? RequestPortalSymbols(ZDO portalZDO) { return (string)Message.Request("ZenDragon.ZenPortal", Message_PortalSymbols, portalZDO); } } } namespace Zen.FixVanilla { [HarmonyPatch] internal static class FixAddPlayerKeyOnBossDeath { private static float MaxDistance => ModLib.Configs.FixApplyPlayerKeyOnBossDeathDistance.Value; [HarmonyPostfix] [HarmonyPatch(typeof(Character), "Awake")] private static void Character_Awake(Character __instance) { if (ModLib.Configs.FixApplyPlayerKeyOnBossDeath.Value && Object.op_Implicit((Object)(object)__instance.m_nview)) { __instance.m_nview.Register("RPC_SetPlayerKeyOnDeath", (Action)RPC_SetPlayerKeyOnDeath); } } internal static void Shutdown() { if (!ModLib.Configs.FixApplyPlayerKeyOnBossDeath.Value) { return; } foreach (Character item in Character.s_characters.Where((Character c) => Object.op_Implicit((Object)(object)c.m_nview))) { item.m_nview.Unregister("RPC_SetPlayerKeyOnDeath"); } } private static void RPC_SetPlayerKeyOnDeath(long sender, string key, Vector3 position) { //IL_0011: 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) if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((MonoBehaviour)(object)Player.m_localPlayer).DistanceTo(position) < MaxDistance) { Logging.Info($"Set key: {key} at position: {position}"); ((Humanoid)Player.m_localPlayer).AddUniqueKey(key); } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "OnDeath")] private static void Character_OnDeath(Character __instance) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (ModLib.Configs.FixApplyPlayerKeyOnBossDeath.Value && !__instance.IsPlayer() && !string.IsNullOrEmpty(__instance.m_defeatSetGlobalKey) && Object.op_Implicit((Object)(object)__instance.m_nview) && __instance.m_nview.IsOwner()) { __instance.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetPlayerKeyOnDeath", new object[2] { __instance.m_defeatSetGlobalKey, ((Component)__instance).transform.position }); } } } [HarmonyPatch] internal static class FixAutoPickupMemAlloc { private static readonly Collider[] Buffer = (Collider[])(object)new Collider[1024]; private static int _count; [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "AutoPickup")] private static IEnumerable Player_AutoPickup_Transpiler(IEnumerable codes) { MethodInfo methodInfo = AccessTools.Method(typeof(Physics), "OverlapSphere", new Type[3] { typeof(Vector3), typeof(float), typeof(int) }, (Type[])null); Func func = OverlapSphere_Intercept; Func getCount = GetCount; return Transpilers.Manipulator(Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)func.Method), (Func)((CodeInstruction code) => code.opcode == OpCodes.Ldlen), (Action)delegate(CodeInstruction code) { code.opcode = OpCodes.Call; code.operand = getCount.Method; }); } private static Collider[] OverlapSphere_Intercept(Vector3 center, float radius, int layerMask) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) _count = Physics.OverlapSphereNonAlloc(center, radius, Buffer, layerMask); return Buffer; } private static int GetCount(Array a) { if (Buffer != a) { return a.Length; } return _count; } } [HarmonyPatch] internal static class FixBlankPlayerKey { [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "AddUniqueKey")] private static IEnumerable Player_AddUniqueKey_Transpiler(IEnumerable codes) { MethodInfo methodInfo = AccessTools.Method(typeof(HashSet), "Contains", (Type[])null, (Type[])null); Func, string, bool> func = HashSet_Contains_Intercept; return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)func.Method); } private static bool HashSet_Contains_Intercept(HashSet self, string? item) { Logging.Info("Fixed: Player key can not be blank"); self.Remove(string.Empty); self.Remove(null); if (!Utility.IsNullOrWhiteSpace(item)) { return self.Contains(item); } return true; } } [HarmonyPatch] internal static class FixDebugFlyAnim { [HarmonyPostfix] [HarmonyPatch(typeof(Character), "UpdateDebugFly")] private static void Character_UpdateDebugFly(Character __instance) { __instance.m_zanim.SetBool(Character.s_onGround, false); __instance.m_zanim.SetBool(Character.s_encumbered, false); __instance.m_zanim.SetBool(Character.s_animatorFalling, true); } } [HarmonyPatch] internal static class FixExploitChairBypass { private static readonly Collider[] HitBuffer = (Collider[])(object)new Collider[32]; private static readonly Dictionary KnownChairs = new Dictionary(); private static int RayMask => Character.s_blockedRayMask; [HarmonyPrefix] [HarmonyPatch(typeof(Player), "SetPlacementGhostValid")] private static void Player_SetPlacementGhostValid(Player __instance, ref bool valid) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (ModLib.Configs.FixExploitChairBypass.Value && valid) { Piece component = __instance.m_placementGhost.GetComponent(); if (Object.op_Implicit((Object)(object)component) && IsChair(component) && IsObstructed(component)) { __instance.m_placementStatus = (PlacementStatus)1; valid = false; } } } private static bool IsChair(Piece piece) { string prefabName = ((Component)piece).gameObject.GetPrefabName(); if (KnownChairs.TryGetValue(prefabName, out var value)) { return value; } Chair[] componentsInChildren = ((Component)piece).GetComponentsInChildren(); value = componentsInChildren.Length != 0 && componentsInChildren.All((Chair c) => !c.m_inShip); return KnownChairs[prefabName] = value; } private static bool IsObstructed(Piece piece) { List colliders = ((StaticTarget)piece).GetAllColliders(); if (colliders == null || colliders.Count == 0) { return false; } return colliders.Any(IsCollision); bool IsBoxCollision(BoxCollider box) { //IL_0008: 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_0018: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Transform transform2 = ((Component)box).transform; Vector3 val3 = Vector3.Scale(box.size, transform2.lossyScale.Abs()) * 0.5f; int size3 = Physics.OverlapBoxNonAlloc(transform2.TransformPoint(box.center) + transform2.up * (val3.y + 0.1f), val3, HitBuffer, transform2.rotation, RayMask); return IsCollisionHit(size3); } bool IsCollision(Collider collider) { BoxCollider val4 = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); if (val4 != null) { return IsBoxCollision(val4); } SphereCollider val5 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null); if (val5 != null) { return IsSphereCollision(val5); } return false; } bool IsCollisionHit(int size) { for (int i = 0; i < size; i++) { Collider val2 = HitBuffer[i]; if (!colliders.Contains(val2)) { Transform parent = ((Component)val2).transform.parent; string text = ((parent != null) ? ((Object)parent).name : null) + " " + ((Object)val2).name; Logging.Info("Prevent chair exploit. Obstructed: " + text); return true; } } return false; } bool IsSphereCollision(SphereCollider sphere) { //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_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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)sphere).transform; Vector3 val = transform.TransformPoint(sphere.center); float num = sphere.radius * transform.lossyScale.Abs().Max(); int size2 = Physics.OverlapSphereNonAlloc(val + transform.up * (num + 0.1f), num, HitBuffer, RayMask); return IsCollisionHit(size2); } } } [HarmonyPatch] internal static class FixExploitTooHardMsg { [HarmonyTranspiler] [HarmonyPatch(typeof(Destructible), "RPC_Damage")] [HarmonyPriority(0)] private static IEnumerable Destructible_RPC_Damage(IEnumerable codes) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(DamageText), "ShowText", new Type[4] { typeof(TextType), typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null); Action action = ShowTextIntercept; return new CodeMatcher(codes, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)methodInfo, (string)null) }).ThrowIfInvalid("Unable to match IL sequence").InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_2, (object)null) }) .Set(OpCodes.Call, (object)action.Method) .InstructionEnumeration(); static bool IsOnlyVulnerableToPickaxe(Destructible destructible) { //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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: 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_0017: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //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_0029: Invalid comparison between Unknown and I4 DamageModifiers damages = destructible.m_damages; if ((int)damages.m_pickaxe != 3) { if ((int)damages.m_blunt == 3 && (int)damages.m_chop == 3) { return (int)damages.m_slash == 3; } return false; } return false; } static void ShowTextIntercept(DamageText instance, TextType type, Vector3 pos, float dmg, bool player, Destructible destructible, HitData hitData) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) if (ModLib.Configs.FixExploitTooHardMsg.Value && !(hitData.m_damage.m_pickaxe > 0f) && IsOnlyVulnerableToPickaxe(destructible)) { Logging.Info($"{((Object)destructible).name} Can not find ore with ground hits: '{type}' message is suppressed."); } else { instance.ShowText(type, pos, dmg, player); } } } } internal static class FixFuelLeak { [HarmonyPatch] private static class FixSmelters { [UsedImplicitly] private static IEnumerable TargetMethods() { return new <>z__ReadOnlyArray(new MethodBase[2] { AccessTools.DeclaredMethod(typeof(Smelter), "OnAddFuel", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(Smelter), "OnAddOre", (Type[])null, (Type[])null) }); } [UsedImplicitly] private static IEnumerable Transpiler(IEnumerable codes) { FieldInfo field = AccessTools.DeclaredField(typeof(Smelter), "m_nview"); return Process(codes, field); } } [HarmonyPatch] private static class FixFireplaces { [UsedImplicitly] private static IEnumerable TargetMethods() { return new <>z__ReadOnlyArray(new MethodBase[2] { AccessTools.DeclaredMethod(typeof(Fireplace), "Interact", (Type[])null, (Type[])null), AccessTools.DeclaredMethod(typeof(Fireplace), "UseItem", (Type[])null, (Type[])null) }); } [UsedImplicitly] private static IEnumerable Transpiler(IEnumerable codes) { FieldInfo field = AccessTools.DeclaredField(typeof(Fireplace), "m_nview"); return Process(codes, field); } } private static IEnumerable Process(IEnumerable codes, FieldInfo field) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown Func func = ZNetViewIntercept; return new CodeMatcher(codes, (ILGenerator)null).End().MatchStartBackwards((CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)field, (string)null) }).ThrowIfInvalid("Unable to match IL") .Advance(1) .Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)func.Method) }) .InstructionEnumeration(); static ZNetView ZNetViewIntercept(ZNetView nview) { if (!ModLib.Configs.FixFuelLeak.Value) { return nview; } if (Object.op_Implicit((Object)(object)nview.m_body) && nview.HasOwner()) { return nview; } Logging.Info("Claim ZDO for fueling"); nview.ClaimOwnership(); return nview; } } } [HarmonyPatch] internal static class FixHideKeyHintExitMenu { [HarmonyPostfix] [HarmonyPatch(typeof(KeyHints), "Awake")] internal static void KeyHints_Awake() { Logging.Info("Hiding KeyHint: Inventory.ExitMenu"); KeyHint.SetVisible(HintType.Inventory, "ExitMenu", isVisible: false); } } [HarmonyPatch] internal static class FixInventoryChangeCraftingUpdate { [HarmonyPostfix] [HarmonyPatch(typeof(InventoryGui), "OnTakeAll")] private static void InventoryGui_OnTakeAll() { InventoryGui.instance.UpdateCraftingPanel(false); } [HarmonyPostfix] [HarmonyPatch(typeof(InventoryGui), "OnStackAll")] private static void InventoryGui_OnStackAll() { InventoryGui.instance.UpdateCraftingPanel(false); } [HarmonyPostfix] [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData) })] private static void Inventory_MoveItemToThis(Inventory __instance) { if (!InventoryGui.IsVisible()) { return; } InventoryGui instance = InventoryGui.instance; if (__instance != instance.m_playerGrid.GetInventory()) { InventoryGrid containerGrid = instance.m_containerGrid; if (__instance != ((containerGrid != null) ? containerGrid.GetInventory() : null)) { return; } } InventoryGui.instance.UpdateCraftingPanel(false); } [HarmonyPostfix] [HarmonyPatch(typeof(Humanoid), "DropItem")] private static void Humanoid_DropItem(Humanoid __instance, bool __result) { if (Player.m_localPlayer.Is((Character)(object)__instance) && InventoryGui.IsVisible() && __result) { InventoryGui.instance.UpdateCraftingPanel(false); } } [HarmonyTranspiler] [HarmonyPatch(typeof(InventoryGui), "OnDropOutside")] private static IEnumerable InventoryGui_OnDropOutside_Transpiler(IEnumerable codes) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", (Type[])null, (Type[])null), (string)null) }; return new CodeMatcher(codes, (ILGenerator)null).End().MatchStartBackwards(array).SetAndAdvance(OpCodes.Nop, (object)null) .SetAndAdvance(OpCodes.Nop, (object)null) .SetAndAdvance(OpCodes.Nop, (object)null) .InstructionEnumeration(); } } [HarmonyPatch] internal static class FixInventoryTextInput { [HarmonyPrefix] [HarmonyPatch(typeof(InventoryGui), "Hide")] private static void InventoryGui_Hide(InventoryGui __instance, ref bool __runOriginal) { if (__runOriginal) { __runOriginal = !TextInput.IsVisible(); } } [HarmonyPostfix] [HarmonyPatch(typeof(TextInput), "Update")] private static void TextInput_Update(TextInput __instance) { if (InventoryGui.IsVisible() && !__instance.m_bShouldHideNextFrame && ZInput.GetButtonDown("JoyButtonB")) { __instance.Hide(); } } } [HarmonyPatch] internal static class FixIsInsideBurningArea { [HarmonyPrefix] [HarmonyPatch(typeof(EffectArea), "IsPointPlus025InsideBurningArea")] private static void EffectArea_IsPointPlus025InsideBurningArea(EffectArea __instance, Vector3 p, ref bool __runOriginal, ref bool __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (ModLib.Configs.FixFireIsLit.Value) { __runOriginal = false; __result = EffectArea.s_BurningAreas.Any(delegate(KeyValuePair burningArea) { //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_000b: Unknown result type (might be due to invalid IL or missing references) Bounds key = burningArea.Key; return ((Bounds)(ref key)).Contains(p) && ((Behaviour)burningArea.Value).isActiveAndEnabled; }); } } } [HarmonyPatch] internal static class FixJoyAltPlaceNoBuild { [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "Update")] private static IEnumerable Player_Update_Transpile(IEnumerable codes) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown Func func = ApplyFix; return new CodeMatcher(codes, (ILGenerator)null).MatchEndForward((CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(ZInput), "IsGamepadActive", (Type[])null, (Type[])null), (string)null), new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldloc_0, (object)null, (string)null) }).ThrowIfInvalid("Invalid IL match sequence").Advance(1) .Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)func.Method) }) .InstructionEnumeration(); } private static bool ApplyFix(bool isInventoryGuiVisible) { if (!isInventoryGuiVisible) { return !UI.IsBuildModeActive; } return true; } } [HarmonyPatch] internal static class FixLogParsePlatformUserID { [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPriority(0)] private static IEnumerable PlatformUserID_Transpiler(IEnumerable codes) { MethodInfo methodInfo = AccessTools.Method(typeof(Debug), "Log", new Type[1] { typeof(object) }, (Type[])null); Action action = DebugLog_Intercept; return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)action.Method); } private static void DebugLog_Intercept(object message) { if (Logging.IsEnabled) { Debug.Log(message); } } } [HarmonyPatch] internal static class FixMouse3Mouse4Swap { private static void FixInputKey(ref KeyCode key) { //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_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 if (!ModLib.Configs.SwapMouse3Mouse4.Value) { return; } KeyCode val = key; if ((int)val != 326) { if ((int)val == 327) { key = (KeyCode)326; } } else { key = (KeyCode)327; } } [HarmonyPrefix] [HarmonyPatch(typeof(ZInput), "GetKey")] [HarmonyPriority(800)] private static void ZInput_GetKey(ref KeyCode key) { FixInputKey(ref key); } [HarmonyPrefix] [HarmonyPatch(typeof(ZInput), "GetKeyUp")] [HarmonyPriority(800)] private static void ZInput_GetKeyUp(ref KeyCode key) { FixInputKey(ref key); } [HarmonyPrefix] [HarmonyPatch(typeof(ZInput), "GetKeyDown")] [HarmonyPriority(800)] private static void ZInput_GetKeyDown(ref KeyCode key) { FixInputKey(ref key); } } [HarmonyPatch] internal static class FixRecipeGetAmountSingleItem { [HarmonyTranspiler] [HarmonyPatch(typeof(Recipe), "GetAmount")] private static IEnumerable Recipe_GetAmount_Transpiler(IEnumerable codes) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) Func func = SingleReqItemQuality_Intercept; CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldarg_3, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldind_Ref, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(ItemData), "m_quality"), (string)null) }; return new CodeMatcher(codes, (ILGenerator)null).End().MatchEndBackwards(array).ThrowIfInvalid("Unable to match IL") .Set(OpCodes.Call, (object)func.Method) .InstructionEnumeration(); } private static int SingleReqItemQuality_Intercept(ItemData? singleReqItem) { return singleReqItem?.m_quality ?? 1; } } [HarmonyPatch] internal static class FixRunAttackStaminaDrain { [HarmonyPostfix] [HarmonyPatch(typeof(Character), "CheckRun")] private static void Character_CheckRun(Character __instance, ref bool __result) { if (ModLib.Configs.FixRunAttackStaminaDrain.Value && __result) { __result = !__instance.InAttack(); } } } [HarmonyPatch] internal static class FixShieldGenNullRefOnQuit { [HarmonyPrefix] [HarmonyPatch(typeof(ShieldDomeImageEffect), "ToggleActiveImageEffect")] private static bool ShieldDomeImageEffect_ToggleActiveImageEffect() { return !ModLib.IsApplicationQuit; } } [HarmonyPatch] internal static class FixShipChairs { [HarmonyPostfix] [HarmonyPatch(typeof(ZNetScene), "Awake")] [HarmonyPriority(100)] private static void ZNetScene_Awake(ZNetScene __instance) { CollectionExtensions.Do(__instance.m_prefabs.Where((GameObject prefab) => Object.op_Implicit((Object)(object)prefab.GetComponentInChildren())), (Action)delegate(GameObject ship) { CollectionExtensions.Do((IEnumerable)ship.GetComponentsInChildren(), (Action)delegate(Chair chair) { chair.m_inShip = true; }); }); } } [HarmonyPatch] internal static class FixTextInputInventoryHide { [HarmonyTranspiler] [HarmonyPatch(typeof(InventoryGui), "Update")] [HarmonyPriority(100)] private static IEnumerable InventoryGui_Update_Transpiler(IEnumerable codes) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) CodeMatch val = new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(InventoryGui), "Hide", (Type[])null, (Type[])null), (string)null); Action action = InventoryGui_HideCancel_Intercept; Action action2 = InventoryGui_HideForce_Intercept; return new CodeMatcher(codes, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { val }).ThrowIfInvalid("Unable to match first IL").Set(OpCodes.Call, (object)action2.Method) .MatchStartForward((CodeMatch[])(object)new CodeMatch[1] { val }) .ThrowIfInvalid("Unable to match second IL") .Set(OpCodes.Call, (object)action.Method) .InstructionEnumeration(); } private static void InventoryGui_HideForce_Intercept(InventoryGui gui) { if (TextInput.IsVisible()) { TextInput.instance.Hide(); } gui.Hide(); } private static void InventoryGui_HideCancel_Intercept(InventoryGui gui) { if (!TextInput.IsVisible()) { gui.Hide(); } } } [HarmonyPatch] internal static class FixToolUseRotateCamera { [HarmonyTranspiler] [HarmonyPatch(typeof(Player), "AlwaysRotateCamera")] private static IEnumerable Player_AlwaysRotateCamera(IEnumerable codes) { MethodInfo methodInfo = AccessTools.Method(typeof(Character), "InPlaceMode", (Type[])null, (Type[])null); Func func = InPlaceMode_Intercept; return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)func.Method); } private static bool InPlaceMode_Intercept(Character c) { if (c.InPlaceMode()) { return !Hud.IsUserHidden(); } return false; } } [HarmonyPatch] internal static class FixTurretLocalization { [HarmonyPostfix] [HarmonyPatch(typeof(Localization), "Localize", new Type[] { typeof(string) })] private static void Localization_Localize(Localization __instance, string text, ref string __result) { if (text == "$msg_turretotherammo" && !__result.EndsWith(" ")) { __result += " "; } } } [HarmonyPatch] internal static class FixWolfEatMeat { private const string WolfID = "Wolf"; [HarmonyPostfix] [HarmonyPatch(typeof(MonsterAI), "Awake")] private static void MonsterAI_Awake(MonsterAI __instance) { if (((Component)__instance).gameObject.GetPrefabName() != "Wolf") { return; } foreach (string item in ModLib.Configs.FixWolfEatMeats.Value) { __instance.AddFood(item); } } private static void AddFood(this MonsterAI monster, string foodID) { ItemDrop prefab = GlobalStatic.GetPrefab(foodID, useCache: true); if (!monster.m_consumeItems.Contains(prefab)) { monster.m_consumeItems.Add(prefab); } } } } namespace Zen.Components { [DisallowMultipleComponent] internal class QuickOutline : MonoBehaviour { public enum Mode { OutlineAll, OutlineVisible, OutlineHidden, OutlineAndSilhouette, SilhouetteOnly } private static class SP { public static readonly int OutlineColor = Shader.PropertyToID("_OutlineColor"); public static readonly int ZTest = Shader.PropertyToID("_ZTest"); public static readonly int OutineWidth = Shader.PropertyToID("_OutlineWidth"); } private static readonly HashSet RegisteredMeshes = new HashSet(); [SerializeField] private Mode outlineMode; [SerializeField] private Color outlineColor = Color.white; [SerializeField] [Range(0f, 10f)] private float outlineWidth = 2f; [Header("Optional")] private Renderer[] _renderers = Array.Empty(); private static Material _outlineMaskMaterial = null; private static Material _outlineFillMaterial = null; private bool _needsUpdate; public Mode OutlineMode { get { return outlineMode; } set { outlineMode = value; _needsUpdate = true; } } public Color OutlineColor { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return outlineColor; } set { //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) outlineColor = value; _needsUpdate = true; } } public float OutlineWidth { get { return outlineWidth; } set { outlineWidth = value; _needsUpdate = true; } } public static void InitMaterials() { if (!Object.op_Implicit((Object)(object)_outlineMaskMaterial) || !Object.op_Implicit((Object)(object)_outlineFillMaterial)) { Logging.Info("Init material assets"); AssetBundle obj = AssetUtils.LoadAssetBundleFromResources("Resources.quickoutline"); _outlineMaskMaterial = obj.LoadAsset("OutlineMask"); _outlineFillMaterial = obj.LoadAsset("OutlineFill"); ((Object)_outlineMaskMaterial).name = "OutlineMask (Instance)"; ((Object)_outlineFillMaterial).name = "OutlineFill (Instance)"; obj.Unload(false); } } public void ComputeRenderers() { _renderers = (from r in ((Component)this).GetComponentsInChildren() where !(r is ParticleSystemRenderer) select r).ToArray(); LoadSmoothNormals(); _needsUpdate = true; } private void Awake() { ComputeRenderers(); } private void OnEnable() { if (_renderers.Length == 0) { ((Behaviour)this).enabled = false; return; } Renderer[] renderers = _renderers; foreach (Renderer obj in renderers) { List list = obj.sharedMaterials.ToList(); list.Add(_outlineMaskMaterial); list.Add(_outlineFillMaterial); obj.materials = list.ToArray(); } } private void Update() { if (_needsUpdate) { _needsUpdate = false; UpdateMaterialProperties(); } } private void OnDisable() { Renderer[] renderers = _renderers; foreach (Renderer obj in renderers) { List list = obj.sharedMaterials.ToList(); list.Remove(_outlineMaskMaterial); list.Remove(_outlineFillMaterial); obj.materials = list.ToArray(); } } internal static void DisableAll() { QuickOutline[] array = Object.FindObjectsByType((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { ((Behaviour)array[i]).enabled = false; } } private void LoadSmoothNormals() { MeshFilter[] componentsInChildren = ((Component)this).GetComponentsInChildren(); foreach (MeshFilter val in componentsInChildren) { Mesh sharedMesh = val.sharedMesh; if (sharedMesh.isReadable && RegisteredMeshes.Add(sharedMesh)) { List list = SmoothNormals(sharedMesh); sharedMesh.SetUVs(3, list); Renderer component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { CombineSubmeshes(sharedMesh, component.sharedMaterials); } } } SkinnedMeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren(); foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { Mesh sharedMesh2 = val2.sharedMesh; if (sharedMesh2.isReadable && RegisteredMeshes.Add(sharedMesh2)) { sharedMesh2.uv4 = (Vector2[])(object)new Vector2[sharedMesh2.vertexCount]; CombineSubmeshes(sharedMesh2, ((Renderer)val2).sharedMaterials); } } } private static List SmoothNormals(Mesh mesh) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) IEnumerable> enumerable = from pair in mesh.vertices.Select((Vector3 vertex, int index) => (vertex, index)) group pair by pair.Vertex; List list = new List(mesh.normals); foreach (IGrouping item in enumerable) { if (item.Count() == 1) { continue; } Vector3 val = Vector3.zero; foreach (var item2 in item) { val += list[item2.Item2]; } ((Vector3)(ref val)).Normalize(); foreach (var item3 in item) { list[item3.Item2] = val; } } return list; } private static void CombineSubmeshes(Mesh mesh, Material[] materials) { if (mesh.subMeshCount != 1 && mesh.subMeshCount <= materials.Length) { int subMeshCount = mesh.subMeshCount; mesh.subMeshCount = subMeshCount + 1; mesh.SetTriangles(mesh.triangles, mesh.subMeshCount - 1); } } private void UpdateMaterialProperties() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) _outlineFillMaterial.SetColor(SP.OutlineColor, outlineColor); switch (outlineMode) { case Mode.OutlineAll: _outlineMaskMaterial.SetFloat(SP.ZTest, 8f); _outlineFillMaterial.SetFloat(SP.ZTest, 8f); _outlineFillMaterial.SetFloat(SP.OutineWidth, outlineWidth); break; case Mode.OutlineVisible: _outlineMaskMaterial.SetFloat(SP.ZTest, 8f); _outlineFillMaterial.SetFloat(SP.ZTest, 4f); _outlineFillMaterial.SetFloat(SP.OutineWidth, outlineWidth); break; case Mode.OutlineHidden: _outlineMaskMaterial.SetFloat(SP.ZTest, 8f); _outlineFillMaterial.SetFloat(SP.ZTest, 5f); _outlineFillMaterial.SetFloat(SP.OutineWidth, outlineWidth); break; case Mode.OutlineAndSilhouette: _outlineMaskMaterial.SetFloat(SP.ZTest, 4f); _outlineFillMaterial.SetFloat(SP.ZTest, 8f); _outlineFillMaterial.SetFloat(SP.OutineWidth, outlineWidth); break; case Mode.SilhouetteOnly: _outlineMaskMaterial.SetFloat(SP.ZTest, 4f); _outlineFillMaterial.SetFloat(SP.ZTest, 5f); _outlineFillMaterial.SetFloat(SP.OutineWidth, 0f); break; } } } } namespace Zen.Compatibility { internal static class ConfigurationManager { private static Type? _cachedType; private static object? _instance; private static bool _notFound; private const string AssemblyName = "ConfigurationManager"; private const string TypeName = "ConfigurationManager.ConfigurationManager"; private const string MethodName = "DisplayingWindow"; private const string InstanceFieldName = "instance"; public static bool IsDisplayingWindow() { if (_notFound) { return false; } if (_cachedType == null) { _cachedType = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager"); if (_cachedType == null) { _notFound = true; return false; } _notFound = !AccessTools.GetFieldNames(_cachedType).Contains("instance"); if (_notFound) { return false; } _instance = AccessTools.Field(_cachedType, "instance").GetValue(null); } return (bool)AccessTools.Property(_cachedType, "DisplayingWindow").GetValue(_instance); } } [HarmonyPatch] public static class MultiUserChest { [AttributeUsage(AttributeTargets.Class)] public sealed class DisableAttribute : Attribute { public DisableAttribute(params Type[] types) { _disabledTypes = types; } } private static Type[] _disabledTypes = Array.Empty(); [HarmonyBefore(new string[] { "com.maxsch.valheim.MultiUserChest" })] [HarmonyPostfix] [HarmonyPatch(typeof(Container), "Awake")] private static void Container_Awake(Container __instance) { Type[] disabledTypes = _disabledTypes; foreach (Type type in disabledTypes) { if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent(type))) { Disable(__instance); } } } private static void Disable(Container container) { if (container.IsOwner()) { ZDO zDO = container.m_nview.GetZDO(); if (!zDO.GetBool("MUC_Ignore", false)) { zDO.Set("MUC_Ignore", true); } Logging.Debug("Disabled MultiUserChest for " + ((Object)container).name); } } } [HarmonyPatch] internal static class SanitizeData { private static readonly Dictionary ItemNameToItemDrop = new Dictionary(); private const int SuperFirst = 10800; [HarmonyPrefix] [HarmonyPatch(typeof(Game), "Start")] [HarmonyPriority(10800)] private static void Game_Start() { SanitizeItemsAndRecipes("Early - Game Start"); } internal static bool TryGetItemDropFromItemName(string itemName, out ItemDrop itemDrop) { Logging.Info("Lookup ItemDrop from item name: " + itemName); bool num = ItemNameToItemDrop.TryGetValue(itemName, out itemDrop); if (!num) { Logging.Warning("Unable to find ItemDrop for item name: " + itemName); } return num; } internal static void SanitizeItemsAndRecipes(string entry) { ItemNameToItemDrop.Clear(); if (!ModLib.Configs.SanitizeData.Value) { Logging.Warning("Data sanitization is DISABLED in the config settings."); return; } Logging.Message("Sanitizing items and recipes: " + entry); foreach (Recipe recipe in ObjectDB.instance.m_recipes) { ItemDrop item = recipe.m_item; if (!Object.op_Implicit((Object)(object)item)) { Logging.Info("Recipe " + ((Object)recipe).name + " has no m_item. Skipping."); continue; } ValidateItem("Recipe: " + ((Object)recipe).name, item); Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { ValidateItem("Recipe: " + ((Object)recipe).name + "/resource", val.m_resItem); } } GameObject[] array = ObjectDB.instance.m_items.ToArray(); foreach (GameObject val2 in array) { ItemDrop component = val2.GetComponent(); ValidateItem("ObjectDB.m_items " + ((Object)val2).name, component); } } private static void ValidateItem(string logPrefix, ItemDrop? itemDrop) { ItemDrop itemDrop2 = itemDrop; ItemDrop obj = itemDrop2; Logging.Info(logPrefix + " validate item: " + (((obj != null) ? ((Object)obj).name : null) ?? "(null)")); if ((Object)(object)itemDrop2 == (Object)null) { Logging.Error(logPrefix + " malformed, missing ItemDrop componenet", 0); return; } if ((Object)(object)((Component)itemDrop2).gameObject == (Object)null) { Logging.Error(logPrefix + " malformed, missing GameObject", 0); return; } if (itemDrop2.m_itemData == null) { Logging.Error(logPrefix + " malformed, missing ItemDrop.m_itemData", 0); return; } if (itemDrop2.m_itemData.m_shared == null) { Logging.Error(logPrefix + " malformed, missing ItemData.m_shared", 0); return; } Logging.Info($"{logPrefix} Validating {((Object)itemDrop2).name} {itemDrop2.GetName()} GameObject: {((object)((Component)itemDrop2).gameObject).GetHashCode():x8}"); int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)itemDrop2).name); Logging.Info("Adding item name to prefab lookup: " + itemDrop2.GetName()); ItemNameToItemDrop[itemDrop2.GetName()] = itemDrop2; if (!ObjectDB.instance.m_items.Contains(((Component)itemDrop2).gameObject)) { Logging.Warning(((Object)itemDrop2).name + " Possibly missing from ObjectDB, verifying..."); if (ObjectDB.instance.m_itemByHash.TryGetValue(stableHashCode, out var _)) { Logging.Warning(((Object)itemDrop2).name + " is missing from ObjectDB, but found in ObjectDB.m_itemByHash index, ignoring"); } else if (ObjectDB.instance.m_items.Any((GameObject p) => ((Object)p).name == ((Object)itemDrop2).name)) { Logging.Warning(((Object)itemDrop2).name + " is missing from ObjectDB, adding it"); ObjectDB.instance.m_items.Add(((Component)itemDrop2).gameObject); } else { Logging.Warning(((Object)itemDrop2).name + " is already in ObjectDB but it is not this instance of GameObject"); } } if (!ObjectDB.instance.m_itemByHash.ContainsKey(stableHashCode)) { Logging.Warning(((Object)itemDrop2).name + " is not in index: ObjectDB.m_itemByHash, fixing"); ObjectDB.instance.m_itemByHash[stableHashCode] = ((Component)itemDrop2).gameObject; } SharedData shared = itemDrop2.m_itemData.m_shared; if (shared == null) { Logging.Error(((Object)itemDrop2).name + " is missing ItemData.m_shared", 0); } else if (!ObjectDB.instance.m_itemByData.ContainsKey(shared)) { Logging.Warning(((Object)itemDrop2).name + " is not in index: ObjectDB.m_itemByData, fixing"); ObjectDB.instance.m_itemByData[shared] = ((Component)itemDrop2).gameObject; } if (!Object.op_Implicit((Object)(object)itemDrop2.m_itemData.m_dropPrefab)) { Logging.Info(((Object)itemDrop2).name + " missing ItemData.m_dropPrefab, trying to fix..."); FixMissingDropPrefab(itemDrop2); } } private static void FixMissingDropPrefab(ItemDrop itemDrop) { ItemDrop itemDrop2 = itemDrop; Logging.Info("Trying shared data index lookup..."); if (ObjectDB.instance.m_itemByData.TryGetValue(itemDrop2.m_itemData.m_shared, out var value)) { Logging.Info("Found shared data, fixed: " + ((Object)value).name); itemDrop2.m_itemData.m_dropPrefab = value; return; } Logging.Warning("Unable to find prefab in shared data lookup, trying lookup by name..."); List list = ObjectDB.instance.m_items.Where((GameObject p) => ((Object)p).name == ((Object)itemDrop2).name).ToList(); if (list.Count > 1) { Logging.Warning("Multiple prefabs found for " + ((Object)itemDrop2).name + ", using first."); } GameObject val = list.FirstOrDefault(); if (Object.op_Implicit((Object)(object)val)) { Logging.Warning("Found prefab by name, fixed."); itemDrop2.m_itemData.m_dropPrefab = val; } else { Logging.Error("Unable to find item prefab for item: " + ((Object)itemDrop2).name, 0); } } } internal static class Seasons { private static bool _isInitialized; private static Func? _getSecToBurnFire; private static void Init() { _isInitialized = true; if (!ModLib.Configs.UseModSeasonsFuelBurnRate.Value || !Chainloader.PluginInfos.TryGetValue("shudnal.Seasons", out var value)) { return; } FieldInfo fieldInfo = AccessTools.Field(Assembly.GetAssembly(((object)value.Instance).GetType()).GetType("Seasons.Seasons"), "seasonState"); if (fieldInfo == null) { Logging.Error("Seasons.seasonState not found, returning to default calculations.", 0); return; } MethodInfo methodInfo = AccessTools.Method(fieldInfo.FieldType, "GetSecondsToBurnFire", new Type[1] { typeof(Fireplace) }, (Type[])null); if (methodInfo == null) { Logging.Error("Seasons.seasonState.GetSecondsToBurnFire not found, returning to default calculations.", 0); return; } try { _getSecToBurnFire = (Func)methodInfo.CreateDelegate(typeof(Func), fieldInfo.GetValue(null)); } catch (Exception ex) { Logging.Error("Failed to create delegate for GetSecondsToBurnFire: " + ex.Message, 0); return; } Logging.Message("Using Seasons calculations for fireplace burn time"); } public static double GetTimeRemaining(Fireplace fireplace) { if (!_isInitialized) { Init(); } return _getSecToBurnFire?.Invoke(fireplace) ?? (-1.0); } } } namespace Zen.Commands { [HarmonyPatch] internal static class Relay { private const string CommandName = "relay"; private const int None = 0; private static long _netTarget; public static string Syntax => "relay "; private static string MyPlayerName { get { Player localPlayer = Player.m_localPlayer; return ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "Unknown"; } } private static bool IsRelayRequest => _netTarget != 0; private static void RedirectOutput(long uid) { _netTarget = uid; } internal static void InitTerminal() { ZenMod.Terminal.CreateCommand("relay", "Execute a command as another player's character.", isCheat: true, usePrefix: false, Exec); } private static void Exec(string[] args) { string text = GeneralExtensions.Join(args.Skip(2), (Func)null, " "); if (Utility.IsNullOrWhiteSpace(text) || args.Length < 3) { ((Terminal)Console.instance).AddString("Syntax: " + Syntax); return; } string text2 = args[1]; long playerUID = ZNet.instance.GetPlayerUID(text2); if (playerUID == 0L) { ((Terminal)Console.instance).AddString("Unable to find player: " + text2); return; } if (playerUID == ZNet.GetUID()) { ((Terminal)Console.instance).AddString("You cannot relay commands to yourself"); return; } ZRoutedRpc.instance.InvokeRoutedRPC(playerUID, "RPC_RelayCommand", new object[2] { MyPlayerName, text }); } internal static void RegisterRPC() { if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsDedicated()) { ZRoutedRpc.instance.Register("RPC_RelayCommand", (Action)RPC_RelayCommand); ZRoutedRpc.instance.Register("RPC_RelayResponse", (Action)RPC_RelayResponse); } } private static void UnregisterRPC() { if (Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsDedicated()) { ZRoutedRpc.instance.Unregister("RPC_RelayCommand"); ZRoutedRpc.instance.Unregister("RPC_RelayResponse"); } } internal static void Shutdown() { UnregisterRPC(); Terminal.commands.Remove("relay".ToLower()); } private static void RPC_RelayCommand(long sender, string senderName, string command) { string text = command.Split(new char[1] { ' ' }).FirstOrDefault() ?? string.Empty; Logging.Message("Remote command recieved from " + senderName + ": " + text + "..."); if (!ModLib.Configs.CommandRelayEnabled.Value) { SendResponse(sender, "Not accepting relay commands."); return; } if (text.ToLower() == "relay".ToLower()) { SendResponse(sender, "You cannot double relay"); return; } ((Terminal)Console.instance).AddString("Executing command on behalf of " + senderName); RedirectOutput(sender); ((Terminal)Console.instance).TryRunCommand(command, false, false); RedirectOutput(0L); } private static void SendResponse(long target, string text) { Logging.Info("Sending response to remote: " + text); ZRoutedRpc.instance.InvokeRoutedRPC(target, "RPC_RelayResponse", new object[2] { MyPlayerName, text }); } private static void RPC_RelayResponse(long sender, string senderName, string response) { Logging.Info("Response received from " + senderName + ": " + response); ((Terminal)Console.instance).AddString("[" + senderName + "] " + response); } [HarmonyPrefix] [HarmonyPatch(typeof(Terminal), "AddString", new Type[] { typeof(string) })] private static void Console_AddString(ref string text, ref bool __runOriginal) { if (IsRelayRequest) { SendResponse(_netTarget, text); __runOriginal = false; } } [HarmonyPostfix] [HarmonyPatch(typeof(ConsoleCommand), "IsValid")] private static void ConsoleCommand_IsValid(ref bool __result) { __result = __result || IsRelayRequest; } } } [CompilerGenerated] internal sealed class <>z__ReadOnlyArray : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection.Count => _items.Length; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Length; bool ICollection.IsReadOnly => true; T IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return ((ICollection)_items).Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { ((ICollection)_items).CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return ((IList)_items).IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } }