using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DrakeRenameit.API; using DrakeRenameit.Ext.UI; using DrakeRenameit.Patches; using DrakeRenameit.Permissions; using DrakeRenameit.UI; using HarmonyLib; using JetBrains.Annotations; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("DrakeRenameit")] [assembly: AssemblyDescription("Manage your doors and chests better")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("DrakeMods")] [assembly: AssemblyProduct("DrakeRenameit")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("5DF97E86-BF46-46C5-894F-6B2D80EA6645")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DrakeRenameit { public static class RenameitConfig { private const string SectionGeneral = "General"; private const string SectionUI = "UI-NotSynced"; private const string SectionExclusions = "Exclusions"; private const string SectionLimits = "Limits"; private const string SectionAdmin = "Admin"; private const string SectionUnlock = "UnlockCost"; private const string SectionCraftedBy = "CraftedBy"; private static ConfigSync configSync = new ConfigSync("DrakesRenameit") { DisplayName = "DrakesRenameit", CurrentVersion = "0.9.1", MinimumRequiredVersion = "0.9.1" }; private static ConfigEntry _lockToOwner; private static ConfigEntry _rewriteDescriptionsEnable; private static ConfigEntry _RenameEnable; private static ConfigEntry _nameClaimsOwner; private static ConfigEntry _allowAdminOverride; private static ConfigEntry _allowRenameResources; private static ConfigEntry _nameCharLimit; private static ConfigEntry _descCharLimit; private static ConfigEntry _craftedByCharLimit; private static ConfigEntry _vipList; private static ConfigEntry _menuHintColor; private static ConfigEntry _excludedNames; private static ConfigEntry _excludedCategory; private static ConfigEntry _renameAllowlist; private static ConfigEntry _vipOnlyOverride; private static ConfigEntry _showReason; private static ConfigEntry _separateStacks; private static ConfigEntry _separateStacksHardLock; private static ConfigEntry _craftedByLabelEnabled; private static ConfigEntry _craftedByLabelCustomizable; private static ConfigEntry _craftedByAllowedLabels; private static ConfigEntry _menuOpenModifier; private static ConfigEntry _unlockCostEnabled; private static ConfigEntry _unlockCost; private static ConfigEntry _showItemStandItemNameWhenNoAccess; public static bool LockToOwner => _lockToOwner.Value; public static int DescCharLimit => _descCharLimit.Value; public static bool NameClaimsOwner => _nameClaimsOwner.Value; public static bool RewriteDescriptionsEnabled => _rewriteDescriptionsEnable.Value; public static bool RenameEnabled => _RenameEnable.Value; public static bool CraftedByLabelEnabled => _craftedByLabelEnabled.Value; public static bool CraftedByLabelCustomizable => _craftedByLabelCustomizable.Value; public static string CraftedByAllowedLabels => _craftedByAllowedLabels.Value; public static bool AllowRenameResources => _allowRenameResources.Value; public static bool AllowAdminOverride => _allowAdminOverride.Value; public static int NameCharLimit => _nameCharLimit.Value; public static int CraftedByCharLimit => _craftedByCharLimit.Value; public static string VipList => _vipList.Value; public static string MenuHintColor => _menuHintColor.Value; public static string ExcludedNames => _excludedNames.Value; public static string ExcludedCategory => _excludedCategory.Value; public static string RenameAllowlist => _renameAllowlist.Value; public static bool VipOnlyOverride => _vipOnlyOverride.Value; public static bool ShowReason => _showReason.Value; public static bool SeparateStacks => _separateStacks.Value; public static bool SeparateStacksHardLock => _separateStacksHardLock.Value; public static string MenuOpenModifier => _menuOpenModifier.Value; public static bool UnlockCostEnabled => _unlockCostEnabled.Value; public static string UnlockCost => _unlockCost.Value; public static bool ShowItemStandItemNameWhenNoAccess => _showItemStandItemNameWhenNoAccess.Value; public static bool MenuModifierIsShift => string.Equals(_menuOpenModifier.Value, "Shift", StringComparison.OrdinalIgnoreCase); public static List GetCraftedByAllowedLabelsList() { string text = _craftedByAllowedLabels?.Value; if (string.IsNullOrWhiteSpace(text)) { return new List { "Crafted By", "Belongs To", "Return to" }; } List list = (from s in text.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) select s.Trim() into s where s.Length > 0 select s).ToList(); if (list.Count == 0) { return new List { "Crafted By", "Belongs To", "Return to" }; } List list2 = new List(); foreach (string p in list) { if (!list2.Exists((string x) => string.Equals(x, p, StringComparison.Ordinal))) { list2.Add(p); } } return list2; } public static void Bind(ConfigFile config) { //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Expected O, but got Unknown _lockToOwner = config.BindSynced("General", "LockToOwner", defaultValue: true, "If true, only the crafter/owner can rename or edit description. Items with no crafter (raw resources, m_crafterID 0 and no crafter name) are not locked until someone claims them (NameClaimsOwner) or they are crafted."); _nameClaimsOwner = config.BindSynced("General", "NameClaimsOwner", defaultValue: true, "If true, renaming an unowned item assigns ownership to the renamer. Used in conjunction with LockToOwner, when you rename an unclaimed item, you will have laid claim to it."); _allowRenameResources = config.BindSynced("General", "AllowRenameResources", defaultValue: true, "If true, items with no crafter (picked-up / uncrafted stacks) can be renamed. This is NOT the same as ExcludedCategory Material: Material blocks by item type even for crafted items. If disabled, NameClaimsOwner cannot apply to those stacks."); _RenameEnable = config.BindSynced("General", "RenameEnabled", defaultValue: true, "If enabled, allows players to edit item names. Could be cycled to pre change some items in a world then block others from adding new ones."); _rewriteDescriptionsEnable = config.BindSynced("General", "RewriteDescriptionsEnabled", defaultValue: true, "If enabled, allows players to also edit descriptions of items. Could be turned off preplace items with descriptions."); _craftedByLabelEnabled = config.BindSynced("General", "CraftedByLabelEnabled", defaultValue: true, "If true, players may set a display-only override for the Crafted by line (real crafter id/name unchanged). Server-synced."); _showReason = config.BindSynced("General", "ShowReason", defaultValue: true, "If true, denied rename/description actions show specific reasons (ownership, exclusion, resources). If false, generic messages only. Server-synced so clients cannot override the server's disclosure policy."); _showItemStandItemNameWhenNoAccess = config.BindSynced("General", "ShowItemStandItemNameWhenNoAccess", defaultValue: true, "If true, item stands inside warded/private areas still show 'no access' but also append the stand's current item name to the hover label (display only; permissions unchanged)."); _separateStacks = config.BindSynced("General", "SeparateStacks", defaultValue: true, "If true, stacks only combine when Drake custom name, description, and crafted-by display match (same identity). Renamed or customized stacks no longer absorb mismatched pickups automatically."); _separateStacksHardLock = config.BindSynced("General", "SeparateStacksHardLock", defaultValue: false, "Only applies when SeparateStacks is on. If true, mismatched stacks never merge — including manual drags. If false, auto pickup still will not combine mismatched stacks, but you can drag one stack onto another to merge immediately (no dialog; target stack keeps its custom name, description, and crafted-by display)."); _unlockCostEnabled = config.BindSynced("UnlockCost", "UnlockCostEnabled", defaultValue: false, "If true, each item stack must be unlocked once (pay UnlockCost from your inventory) before rename, description, or crafted-by edits apply. After unlock, edits are free for that stack. Invalid/empty UnlockCost is ignored (no gate). Elevated players (AdminOverride) skip the cost."); _unlockCost = config.BindSynced("UnlockCost", "UnlockCost", "Coins:5", "Comma or semicolon separated: PrefabName:amount (e.g. Coins:4, Coal:10) or $item_token:amount. Uses player inventory. Paid once per stack via the Unlock button in the action menu."); _nameCharLimit = config.BindSynced("Limits", "NameCharacterLimit", 50, "Defines the limit for max characters in rename, be sure to account for tag codes etc."); _craftedByCharLimit = config.BindSynced("Limits", "CraftedByCharLimit", 50, "Defines the limit for max characters in crafted by: edit, be sure to account for tag codes etc."); _craftedByLabelCustomizable = config.BindSynced("CraftedBy", "LabelCustomizable", defaultValue: true, "If true, players who can edit crafted-by may choose a tooltip line label from AllowedLabels. If false, the label picker is greyed out for normal players (shows the default line only) while admins/VIPs can still change it. Separate from CraftedByLabelEnabled in General."); _craftedByAllowedLabels = config.BindSynced("CraftedBy", "AllowedLabels", "Crafted By, Belongs To, Return to", "Comma- or semicolon-separated labels shown before the crafter name (e.g. “Belongs To: Name”). The first entry is the default (vanilla localized “crafted by” line is used on the tooltip when that option is selected)."); _descCharLimit = config.BindSynced("Limits", "DescriptionCharacterLimit", 1000, "Defines the limit for max characters description, be sure to account for tag codes etc."); _allowAdminOverride = config.BindSynced("Admin", "AllowAdminOverride", defaultValue: true, "If enabled anyone designated as admin or added to VIP list with api hook, will be able to edit names and descriptions regardless of ownership or enabled."); _vipList = config.BindSynced("Admin", "VipList", "", "Comma-separated player names or player IDs (same as API AddVIP). When AdminOverride is on, VIPs can bypass restrictions. If VipOnlyOverride is on, ONLY VIP/API users count as elevated (Valheim server admin is ignored for overrides)."); _vipOnlyOverride = config.BindSynced("Admin", "VipOnlyOverride", defaultValue: false, "If true (and AdminOverride is on), only VIP list / AddVIP API users are treated as elevated for bypassing rules—Valheim server admin is NOT. Useful for testing VIP behavior locally. If false, Valheim admin OR VIP is elevated."); _menuHintColor = config.BindSynced("UI-NotSynced", "MenuHintColor", "yellow", "Color for the 'Modifier + Right Click for options' inventory tooltip hint. Accepts Unity color names (yellow, green, red, white) or hex values (#fff or #ffffff).", sync: false); _menuOpenModifier = config.Bind("UI-NotSynced", "MenuOpenModifier", "Shift", new ConfigDescription("Which key + right-click opens the Drake menu (Rename / Description / Crafted by): Shift or Ctrl. The other modifier + right-click uses vanilla behavior.", (AcceptableValueBase)(object)new AcceptableValueList(new string[2] { "Shift", "Ctrl" }), Array.Empty())); configSync.AddConfigEntry(_menuOpenModifier).SynchronizedConfig = false; _excludedNames = config.BindSynced("Exclusions", "ExcludedNames", "", "Comma-separated entries: Jotunn item list Token column (m_shared.m_name, e.g. $item_axe_stone) OR Item column (spawn/prefab name, e.g. AxeStone, ShieldBronzeBuckler), OR localized display name (English Name column). List: https://valheim-modding.github.io/Jotunn/data/objects/item-list.html — Admins/VIP (when AdminOverride is on) ignore this. See also ExcludedCategory and RenameAllowlist."); _excludedCategory = config.BindSynced("Exclusions", "ExcludedCategory", "", "Comma-separated category tokens (non-elevated players). Examples: Swords,Armor,Material,Bows. Full lists of Skills.SkillType and ItemDrop.ItemData.ItemType names plus aliases are written to BepInEx/config//ExcludedCategoryReference.txt on first run (or when the mod version changes). Does not bypass RenameEnabled when that is off. Elevated users ignore when AdminOverride is on."); _renameAllowlist = config.BindSynced("Exclusions", "RenameAllowlist", "", "Comma-separated entries: Jotunn Token ($item_...) or Item (spawn name) or English display name — same rules as ExcludedNames. When RenameEnabled / RewriteDescriptionsEnabled are ON, these items bypass ExcludedNames, ExcludedCategory, and the uncrafted (AllowRenameResources) rule. Does NOT bypass global RenameEnabled/RewriteDescriptionsEnabled when those are off (only elevated users can). Does not bypass LockToOwner ownership."); } private static ConfigEntry BindSynced(this ConfigFile config, string section, string key, T defaultValue, string description, bool sync = true) { ConfigEntry val = config.Bind(section, key, defaultValue, description); SyncedConfigEntry syncedConfigEntry = configSync.AddConfigEntry(val); syncedConfigEntry.SynchronizedConfig = sync; return val; } } internal static class RenameUnlockCost { private static ManualLogSource? _log; internal static void Init(ManualLogSource log) { _log = log; } internal static bool HasValidCostConfigured() { List<(string, int, string)> lines; string error; return TryBuildResolvedCost(out lines, out error); } internal static bool UnlockCostApplies() { return RenameitConfig.UnlockCostEnabled && HasValidCostConfigured(); } internal static bool CanPlayerAfford(Player? player) { if ((Object)(object)player == (Object)null) { return false; } if (!TryBuildResolvedCost(out List<(string, int, string)> lines, out string _)) { return true; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return false; } foreach (var (text, num, _) in lines) { if (inventory.CountItems(text, -1, true) < num) { return false; } } return true; } internal static bool TryConsumeUnlockCost(Player? player, out string errorMessage) { errorMessage = ""; if ((Object)(object)player == (Object)null) { errorMessage = "No local player."; return false; } if (!TryBuildResolvedCost(out List<(string, int, string)> lines, out string error)) { errorMessage = error ?? "Unlock cost is not configured."; return false; } if (lines.Count == 0) { errorMessage = "Unlock cost is empty."; return false; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { errorMessage = "No inventory."; return false; } foreach (var (text, num, _) in lines) { if (inventory.CountItems(text, -1, true) < num) { errorMessage = "Not enough items to unlock (see tooltip / config)."; return false; } } foreach (var (text2, num2, _) in lines) { inventory.RemoveItem(text2, num2, -1, true); } return true; } internal static string GetCostDisplayShort() { if (!TryBuildResolvedCost(out List<(string, int, string)> lines, out string _) || lines.Count == 0) { return ""; } List list = new List(); foreach (var item3 in lines) { string item = item3.Item1; int item2 = item3.Item2; string arg = item; if (Localization.instance != null) { arg = Localization.instance.Localize(item); } list.Add($"{item2}x {arg}"); } return string.Join(", ", list); } internal static List<(string LocalizedName, int Amount, string PrefabName)> GetCostDisplayEntries() { List<(string, int, string)> list = new List<(string, int, string)>(); if (!TryBuildResolvedCost(out List<(string, int, string)> lines, out string _) || lines.Count == 0) { return list; } foreach (var item5 in lines) { string item = item5.Item1; int item2 = item5.Item2; string item3 = item5.Item3; string item4 = item; if (Localization.instance != null) { item4 = Localization.instance.Localize(item); } list.Add((item4, item2, item3)); } return list; } internal static string GetItemTokenPublic(string prefabName) { return ResolveItemSharedName(prefabName); } internal static Sprite? GetItemIconSprite(string configPrefabName) { if (string.IsNullOrWhiteSpace(configPrefabName) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(configPrefabName); if ((Object)(object)itemPrefab == (Object)null) { return null; } ItemDrop component = itemPrefab.GetComponent(); object result; if (component == null) { result = null; } else { ItemData itemData = component.m_itemData; result = ((itemData != null) ? itemData.GetIcon() : null); } return (Sprite?)result; } private static bool TryBuildResolvedCost(out List<(string SharedName, int Amount, string ConfigKey)> lines, out string? error) { lines = new List<(string, int, string)>(); error = null; string text = RenameitConfig.UnlockCost?.Trim() ?? ""; if (string.IsNullOrEmpty(text)) { error = "UnlockCost is empty."; return false; } string[] array = text.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); string[] array2 = array; foreach (string text2 in array2) { string text3 = text2.Trim(); if (string.IsNullOrEmpty(text3)) { continue; } int num = text3.LastIndexOf(':'); if (num <= 0 || num >= text3.Length - 1) { ManualLogSource? log = _log; if (log != null) { log.LogWarning((object)("[UnlockCost] Ignoring invalid segment (need Name:Amount): \"" + text3 + "\"")); } continue; } string text4 = text3.Substring(0, num).Trim(); string s = text3.Substring(num + 1).Trim(); if (!int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result <= 0) { ManualLogSource? log2 = _log; if (log2 != null) { log2.LogWarning((object)("[UnlockCost] Ignoring invalid amount in: \"" + text3 + "\"")); } continue; } string text5 = ResolveItemSharedName(text4); if (string.IsNullOrEmpty(text5)) { ManualLogSource? log3 = _log; if (log3 != null) { log3.LogWarning((object)("[UnlockCost] Unknown item or token: \"" + text4 + "\"")); } } else { lines.Add((text5, result, text4)); } } if (lines.Count == 0) { error = "No valid UnlockCost entries (use Item prefab name or $item_ token, e.g. Coins:4)."; return false; } return true; } private static string ResolveItemSharedName(string tokenOrPrefab) { if (string.IsNullOrWhiteSpace(tokenOrPrefab)) { return ""; } if ((Object)(object)ObjectDB.instance == (Object)null) { return tokenOrPrefab.StartsWith("$", StringComparison.Ordinal) ? tokenOrPrefab : ""; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(tokenOrPrefab); if ((Object)(object)itemPrefab != (Object)null) { string text = itemPrefab.GetComponent()?.m_itemData?.m_shared?.m_name; if (!string.IsNullOrEmpty(text)) { return text; } } if (tokenOrPrefab.StartsWith("$", StringComparison.Ordinal)) { return tokenOrPrefab; } return ""; } } [BepInPlugin("com.DrakeMods.DrakesRenameit", "DrakesRenameit", "0.9.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class DrakeRenameit : BaseUnityPlugin { public const string CompanyName = "DrakeMods"; public const string ModName = "DrakesRenameit"; public const string Version = "0.9.1"; public const string GUID = "com.DrakeMods.DrakesRenameit"; public const string DrakeNewName = "Drake_Rename"; public const string DrakeNewDesc = "Drake_Rename_Desc"; public const string DrakeCraftedByDisplay = "Drake_CraftedByDisplay"; public const string DrakeCraftedByLineLabel = "Drake_CraftedByLineLabel"; public const string DrakeRenameUnlocked = "Drake_RenameUnlocked"; public const string TooltipUnlockCostLockedEmoji = "\ud83d\udd12"; public const string TooltipDrakeEditableEmoji = "\ud83d\udd8a\ufe0f"; private readonly Harmony harmony = new Harmony("drakesmod.DrakeRenameit"); private Texture2D TestTex; private Sprite TestSprite; public static ItemData? CurrentItem { get; set; } public static bool IsItemInLocalPlayerInventory(ItemData? item) { if (item == null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); return inventory != null && inventory.ContainsItem(item); } private void Awake() { RenameitConfig.Bind(((BaseUnityPlugin)this).Config); ExcludedCategoryReferenceWriter.EnsureGenerated(); AddVip(); RenamePermissionManager.Init(((BaseUnityPlugin)this).Logger); RenameUnlockCost.Init(((BaseUnityPlugin)this).Logger); InventoryStackPatches.Apply(harmony, ((BaseUnityPlugin)this).Logger); ItemTooltipPatches.Apply(harmony, ((BaseUnityPlugin)this).Logger); DropHudMessagePatches.ApplyDropItemPendingCapture(harmony, ((BaseUnityPlugin)this).Logger); harmony.PatchAll(); DropHudMessagePatches.ApplyMessageHudShowMessage(harmony, ((BaseUnityPlugin)this).Logger); } private static void AddVip() { List list = (from s in RenameitConfig.VipList.Split(new char[1] { ',' }) select s.Trim().ToLowerInvariant() into s where !string.IsNullOrEmpty(s) select s).ToList(); RenameitPermission.AddVIP(list); } public static string GetPropperName(ItemData? item) { return getPropperName(item, item.m_shared.m_name); } public static string GetDisplayNameForUi(ItemData? item, bool localize) { if (item?.m_shared == null) { return ""; } string text = GetPropperName(item) ?? item.m_shared.m_name; string text2 = TooltipRichText.EnsureRichTextTagsClosedForTooltip(text); if (!localize || Localization.instance == null) { return text2; } return Localization.instance.Localize(text2); } public static bool hasNewDesc(ItemData? item) { if (item.m_customData == null) { return false; } string value; return item.m_customData.TryGetValue("Drake_Rename_Desc", out value); } public static bool hasNewName(ItemData? item) { if (item == null || item.m_customData == null) { return false; } string value; return item.m_customData.TryGetValue("Drake_Rename", out value); } public static bool HasAnyDrakeRenameCustomization(ItemData? item) { if (item?.m_customData == null) { return false; } if (hasNewName(item)) { return true; } if (hasNewDesc(item)) { return true; } if (HasCraftedByDisplayOverride(item)) { return true; } return HasCraftedByLineLabelOverride(item); } private static bool ReadRenameUnlockedFlag(ItemData item) { if (!item.m_customData.TryGetValue("Drake_RenameUnlocked", out var value)) { return false; } return value == "1" || string.Equals(value, "true", StringComparison.OrdinalIgnoreCase); } public static bool IsRenameUnlocked(ItemData? item) { if (item?.m_customData == null) { return false; } bool flag = ReadRenameUnlockedFlag(item); if (RenameUnlockCost.UnlockCostApplies()) { if (!flag && HasAnyDrakeRenameCustomization(item)) { SetRenameUnlocked(item); return true; } return flag; } return flag; } internal static void SetRenameUnlocked(ItemData item) { if (item.m_customData == null) { item.m_customData = new Dictionary(); } item.m_customData["Drake_RenameUnlocked"] = "1"; } public static bool WouldHaveAnyDrakeEditIfUnlockIgnored(ItemData? item) { if (item == null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } RenamePermissionManager.BeginIgnoreUnlockRequirement(); try { return CanChangeName(item) || CanChangeDesc(item) || CanChangeCraftedByLabel(item); } finally { RenamePermissionManager.EndIgnoreUnlockRequirement(); } } public static bool ShowUnlockButton(ItemData? item) { if (item == null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } if (!RenameUnlockCost.UnlockCostApplies()) { return false; } if (IsRenameUnlocked(item)) { return false; } if (RenameitPermission.IsElevatedForOverrides(Player.m_localPlayer)) { return false; } return WouldHaveAnyDrakeEditIfUnlockIgnored(item); } public static bool TryPayRenameUnlock(ItemData? item) { if (item == null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } if (!IsItemInLocalPlayerInventory(item)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "That item is no longer in your inventory. Put it back, then unlock again.", 0, (Sprite)null); return false; } if (!RenameUnlockCost.UnlockCostApplies() || IsRenameUnlocked(item)) { return false; } if (!WouldHaveAnyDrakeEditIfUnlockIgnored(item)) { string menuBlockedReason = GetMenuBlockedReason(item); ((Character)Player.m_localPlayer).Message((MessageType)2, string.IsNullOrEmpty(menuBlockedReason) ? "This item cannot be edited." : menuBlockedReason, 0, (Sprite)null); return false; } if (!RenameUnlockCost.TryConsumeUnlockCost(Player.m_localPlayer, out string errorMessage)) { ((Character)Player.m_localPlayer).Message((MessageType)2, errorMessage, 0, (Sprite)null); return false; } SetRenameUnlocked(item); ((Character)Player.m_localPlayer).Message((MessageType)2, "Item unlocked for editing.", 0, (Sprite)null); return true; } public static bool HasCraftedByDisplayOverride(ItemData? item) { if (item?.m_customData == null) { return false; } string value; return item.m_customData.TryGetValue("Drake_CraftedByDisplay", out value) && !string.IsNullOrEmpty(value); } public static bool HasCraftedByLineLabelOverride(ItemData? item) { if (item?.m_customData == null) { return false; } string value; return item.m_customData.TryGetValue("Drake_CraftedByLineLabel", out value) && !string.IsNullOrEmpty(value); } public static bool CanResetAnyCustomization(ItemData? item) { if (item == null) { return false; } if (CanChangeName(item) && hasNewName(item)) { return true; } if (CanChangeDesc(item) && hasNewDesc(item)) { return true; } if (CanChangeCraftedByLabel(item) && (HasCraftedByDisplayOverride(item) || HasCraftedByLineLabelOverride(item))) { return true; } return false; } public static void ResetAllCustomizations(ItemData? item) { if (item == null) { return; } if (!IsItemInLocalPlayerInventory(item)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "That item is no longer in your inventory.", 0, (Sprite)null); } return; } if (CanChangeName(item) && hasNewName(item)) { resetName(item); } if (CanChangeDesc(item) && hasNewDesc(item)) { resetDesc(item); } if (CanChangeCraftedByLabel(item) && (HasCraftedByDisplayOverride(item) || HasCraftedByLineLabelOverride(item)) && item.m_customData != null) { string craftedByDisplay = getCraftedByDisplay(item); item.m_customData.Remove("Drake_CraftedByDisplay"); item.m_customData.Remove("Drake_CraftedByLineLabel"); string newDisplay = item.m_crafterName ?? ""; RenameEvents.RaiseCraftedByDisplayChanged(Player.m_localPlayer, item, item.m_shared.m_name, craftedByDisplay, newDisplay); } } public static string resetName(ItemData? item) { if (item == null) { return ""; } item.m_customData.Remove("Drake_Rename"); return item.m_shared.m_name; } public static string resetDesc(ItemData? item) { if (item == null) { return ""; } item.m_customData.Remove("Drake_Rename_Desc"); return item.m_shared.m_name; } public static string getPropperName(ItemData? item) { return getPropperName(item, item.m_shared.m_name); } public static string getPropperName(ItemData? item, string defaultName) { if (item.m_customData == null) { item.m_customData = new Dictionary(); } string value; return item.m_customData.TryGetValue("Drake_Rename", out value) ? value : defaultName; } public static string getPropperDesc(ItemData? item) { return getPropperDesc(item, item.m_shared.m_description); } public static string getPropperDesc(ItemData? item, string defaultDesc) { if (item.m_customData == null) { item.m_customData = new Dictionary(); } string value; return item.m_customData.TryGetValue("Drake_Rename_Desc", out value) ? value : defaultDesc; } public static void OpenRename(ItemData? item) { if (!((Object)(object)InventoryGui.instance == (Object)null) && item != null) { CurrentItem = item; if ((Object)(object)UIPanels.InputNamePanel == (Object)null) { UIPanels.CreateRenameInput(); } string propperName = GetPropperName(item); UIPanels.RenameNameInput.text = propperName; UIPanels.InputNamePanel.SetActive(true); UIPanels.EnsureInputBlocked(); } } public static void OpenRewriteDesc(ItemData? item) { if (!((Object)(object)InventoryGui.instance == (Object)null) && item != null) { CurrentItem = item; if ((Object)(object)UIPanels.InputDescPanel == (Object)null) { UIPanels.CreateRenameDescInput(); } string propperDesc = getPropperDesc(item); UIPanels.RenameDescInput.text = propperDesc; UIPanels.InputDescPanel.SetActive(true); UIPanels.EnsureInputBlocked(); } } public static void RenameItem(string name) { if (CurrentItem == null) { return; } if (CurrentItem.m_customData == null) { CurrentItem.m_customData = new Dictionary(); } if (string.IsNullOrEmpty(name)) { CurrentItem.m_customData.Remove("Drake_Rename"); } else { CurrentItem.m_customData["Drake_Rename"] = name; RenameEvents.RaiseNameChanged(Player.m_localPlayer, CurrentItem, CurrentItem.m_shared.m_name, name); } if (RenameitConfig.NameClaimsOwner && (RenameitConfig.AllowRenameResources || RenameExclusionRules.MatchesRenameAllowlist(CurrentItem)) && string.IsNullOrEmpty(CurrentItem.m_crafterName)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { CurrentItem.m_crafterID = localPlayer.GetPlayerID(); CurrentItem.m_crafterName = localPlayer.GetPlayerName(); } } } public static void RewriteItemDesc(string name) { if (CurrentItem == null) { return; } if (CurrentItem.m_customData == null) { CurrentItem.m_customData = new Dictionary(); } if (string.IsNullOrEmpty(name)) { CurrentItem.m_customData.Remove("Drake_Rename_Desc"); } else { CurrentItem.m_customData["Drake_Rename_Desc"] = name; RenameEvents.RaiseDescriptionChanged(Player.m_localPlayer, CurrentItem, CurrentItem.m_shared.m_name, name); } if (RenameitConfig.NameClaimsOwner && (RenameitConfig.AllowRenameResources || RenameExclusionRules.MatchesRenameAllowlist(CurrentItem)) && string.IsNullOrEmpty(CurrentItem.m_crafterName)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { CurrentItem.m_crafterID = localPlayer.GetPlayerID(); CurrentItem.m_crafterName = localPlayer.GetPlayerName(); } } } public static void ApplyRewriteDesc(string newDesc) { if (CurrentItem == null) { return; } if (!IsItemInLocalPlayerInventory(CurrentItem)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "That item is no longer in your inventory. Put it back, then try again.", 0, (Sprite)null); } UIPanels.CloseAllRenameEditingUi(); } else { RewriteItemDesc(newDesc); ItemData currentItem = CurrentItem; UIPanels.InputDescPanel.SetActive(false); UIPanels.OpenActionMenu(currentItem); } } public static void ApplyRename(string newName) { if (CurrentItem == null) { return; } if (!IsItemInLocalPlayerInventory(CurrentItem)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "That item is no longer in your inventory. Put it back, then try again.", 0, (Sprite)null); } UIPanels.CloseAllRenameEditingUi(); } else { RenameItem(newName); ItemData currentItem = CurrentItem; UIPanels.InputNamePanel.SetActive(false); UIPanels.OpenActionMenu(currentItem); } } public static bool CanChangeName(ItemData? item, bool showError = false) { return RenamePermissionManager.Evaluate(RenamePermissionOperation.RenameItemName, item, Player.m_localPlayer, showError).Allowed; } public static bool CanChangeDesc(ItemData item, bool showError = false) { return RenamePermissionManager.Evaluate(RenamePermissionOperation.RewriteDescription, item, Player.m_localPlayer, showError).Allowed; } public static bool CanChangeCraftedByLabel(ItemData? item, bool showError = false) { if (item == null) { return false; } if (item.m_crafterID == 0L && string.IsNullOrEmpty(item.m_crafterName)) { return false; } return RenamePermissionManager.Evaluate(RenamePermissionOperation.EditCraftedByLabel, item, Player.m_localPlayer, showError).Allowed; } public static bool AnyInventoryActionAvailable(ItemData? item) { if (item == null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } if (!RenameUnlockCost.UnlockCostApplies() || IsRenameUnlocked(item)) { return CanChangeName(item) || CanChangeDesc(item) || CanChangeCraftedByLabel(item); } if (RenameitPermission.IsElevatedForOverrides(Player.m_localPlayer)) { return CanChangeName(item) || CanChangeDesc(item) || CanChangeCraftedByLabel(item); } return WouldHaveAnyDrakeEditIfUnlockIgnored(item); } public static bool IsMenuOpenModifierHeld() { return (!RenameitConfig.MenuModifierIsShift) ? (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) : (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)); } public static string GetMenuTooltipLockSuffix(ItemData? item) { if (item == null || (Object)(object)Player.m_localPlayer == (Object)null) { return ""; } if (!RenameUnlockCost.UnlockCostApplies()) { return ""; } if (RenameitPermission.IsElevatedForOverrides(Player.m_localPlayer)) { return " \ud83d\udd8a\ufe0f"; } return IsRenameUnlocked(item) ? " \ud83d\udd8a\ufe0f" : " \ud83d\udd12"; } public static string GetMenuBlockedReason(ItemData? item) { if (item == null || (Object)(object)Player.m_localPlayer == (Object)null) { return ""; } List list = new List(); RenamePermissionResult renamePermissionResult = RenamePermissionManager.TryGetDenial(RenamePermissionOperation.RenameItemName, item, Player.m_localPlayer); if (!renamePermissionResult.Allowed) { list.Add(RenamePermissionManager.FormatDenialForPlayer(RenamePermissionOperation.RenameItemName, renamePermissionResult.Reasons)); } RenamePermissionResult renamePermissionResult2 = RenamePermissionManager.TryGetDenial(RenamePermissionOperation.RewriteDescription, item, Player.m_localPlayer); if (!renamePermissionResult2.Allowed && (list.Count == 0 || renamePermissionResult2.Reasons != renamePermissionResult.Reasons)) { list.Add(RenamePermissionManager.FormatDenialForPlayer(RenamePermissionOperation.RewriteDescription, renamePermissionResult2.Reasons)); } RenamePermissionResult renamePermissionResult3 = RenamePermissionManager.TryGetDenial(RenamePermissionOperation.EditCraftedByLabel, item, Player.m_localPlayer); if (!renamePermissionResult3.Allowed && (list.Count == 0 || (renamePermissionResult3.Reasons != renamePermissionResult.Reasons && renamePermissionResult3.Reasons != renamePermissionResult2.Reasons))) { list.Add(RenamePermissionManager.FormatDenialForPlayer(RenamePermissionOperation.EditCraftedByLabel, renamePermissionResult3.Reasons)); } if (list.Count == 0) { return "This item cannot be edited."; } HashSet hashSet = new HashSet(); List list2 = new List(); foreach (string item2 in list) { if (hashSet.Add(item2)) { list2.Add(item2); } } return string.Join(" | ", list2); } public static string getCraftedByDisplay(ItemData? item) { if (item?.m_customData == null) { return item?.m_crafterName ?? ""; } if (item.m_customData.TryGetValue("Drake_CraftedByDisplay", out var value) && !string.IsNullOrEmpty(value)) { return value; } return item.m_crafterName ?? ""; } public static void OpenCraftedByEditor(ItemData? item) { if (!((Object)(object)InventoryGui.instance == (Object)null) && item != null) { CurrentItem = item; if ((Object)(object)UIPanels.InputCraftedByPanel == (Object)null) { UIPanels.CreateCraftedByInput(); } UIPanels.RenameCraftedByInput.text = getCraftedByDisplay(item); UIPanels.RefreshCraftedByLineLabelPicker(item); UIPanels.InputCraftedByPanel.SetActive(true); UIPanels.EnsureInputBlocked(); } } public static void ApplyCraftedByLabel(string display) { if (CurrentItem == null) { return; } if (!IsItemInLocalPlayerInventory(CurrentItem)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "That item is no longer in your inventory. Put it back, then try again.", 0, (Sprite)null); } UIPanels.CloseAllRenameEditingUi(); return; } if (CurrentItem.m_customData == null) { CurrentItem.m_customData = new Dictionary(); } string craftedByDisplay = getCraftedByDisplay(CurrentItem); if (string.IsNullOrEmpty(display)) { CurrentItem.m_customData.Remove("Drake_CraftedByDisplay"); } else { CurrentItem.m_customData["Drake_CraftedByDisplay"] = display; } if (RenameitConfig.CraftedByLabelCustomizable || RenameitPermission.IsElevatedForOverrides(Player.m_localPlayer)) { string craftedByLineLabelPendingToken = UIPanels.CraftedByLineLabelPendingToken; if (string.IsNullOrEmpty(craftedByLineLabelPendingToken)) { CurrentItem.m_customData.Remove("Drake_CraftedByLineLabel"); } else if (IsAllowedCustomCraftedByLineLabel(craftedByLineLabelPendingToken)) { CurrentItem.m_customData["Drake_CraftedByLineLabel"] = craftedByLineLabelPendingToken; } } string newDisplay = (string.IsNullOrEmpty(display) ? (CurrentItem.m_crafterName ?? "") : display); RenameEvents.RaiseCraftedByDisplayChanged(Player.m_localPlayer, CurrentItem, CurrentItem.m_shared.m_name, craftedByDisplay, newDisplay); ItemData currentItem = CurrentItem; UIPanels.InputCraftedByPanel.SetActive(false); UIPanels.OpenActionMenu(currentItem); } public static bool IsExcluded(ItemData? item) { return RenameExclusionRules.IsExcludedFromConfig(item); } public static bool IsRenameAllowlisted(ItemData? item) { return RenameExclusionRules.MatchesRenameAllowlist(item); } private static bool IsAllowedCustomCraftedByLineLabel(string value) { List craftedByAllowedLabelsList = RenameitConfig.GetCraftedByAllowedLabelsList(); for (int i = 1; i < craftedByAllowedLabelsList.Count; i++) { if (string.Equals(craftedByAllowedLabelsList[i], value, StringComparison.Ordinal)) { return true; } } return false; } } internal static class StackIdentity { internal static string GetFingerprint(ItemData? item) { if (item?.m_customData == null) { return ""; } StringBuilder stringBuilder = new StringBuilder(); Append(stringBuilder, item, "Drake_Rename"); Append(stringBuilder, item, "Drake_Rename_Desc"); Append(stringBuilder, item, "Drake_CraftedByDisplay"); Append(stringBuilder, item, "Drake_CraftedByLineLabel"); return stringBuilder.ToString(); } private static void Append(StringBuilder sb, ItemData item, string key) { if (item.m_customData.TryGetValue(key, out var value) && !string.IsNullOrEmpty(value)) { sb.Append('|').Append(value); } else { sb.Append('|'); } } internal static bool SameDrakeStackIdentity(ItemData? a, ItemData? b) { if (a == null || b == null) { return false; } return string.Equals(GetFingerprint(a), GetFingerprint(b), StringComparison.Ordinal); } } } namespace DrakeRenameit.UI { internal static class TooltipRichText { private enum RtKind { Color, Size } private static readonly Regex HexColorRegex = new Regex("^[0-9a-fA-F]{3,8}$", RegexOptions.Compiled); internal static string EnsureRichTextTagsClosedForTooltip(string? text) { if (string.IsNullOrEmpty(text)) { return text ?? ""; } Stack stack = new Stack(); int num = 0; while (num < text.Length) { if (text[num] != '<') { num++; continue; } int num2 = text.IndexOf('>', num); if (num2 < 0) { break; } string text2 = text.Substring(num, num2 - num + 1); if (text2.Length >= 2 && text2[1] == '/') { if (text2.StartsWith(" 0 && stack.Peek() == RtKind.Color) { stack.Pop(); } } else if (text2.StartsWith(" 0 && stack.Peek() == RtKind.Size) { stack.Pop(); } } else if (text2.StartsWith(" 0) { RtKind rtKind = stack.Pop(); stringBuilder.Append((rtKind == RtKind.Color) ? "" : ""); } return stringBuilder.ToString(); } internal static string WrapCraftedByDisplayWithDefaultStatColorIfNeeded(string text) { if (string.IsNullOrEmpty(text)) { return text; } if (HasExplicitColorMarkup(text)) { return text; } return GetValheimTooltipStatColorOpenTag() + text + ""; } internal static bool HasExplicitColorMarkup(string text) { if (string.IsNullOrEmpty(text)) { return false; } if (text.IndexOf("= 0) { return true; } for (int i = 0; i < text.Length - 3; i++) { if (text[i] == '<' && text[i + 1] == '#') { int j; for (j = i + 2; j < text.Length && IsHex(text[j]); j++) { } if (j != i + 2 && j - (i + 2) >= 3 && j - (i + 2) <= 8 && j < text.Length && text[j] == '>') { return true; } } } return false; } private static bool IsHex(char c) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': return true; default: return false; } } private static string GetValheimTooltipStatColorOpenTag() { //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_001d: Unknown result type (might be due to invalid IL or missing references) try { GUIManager instance = GUIManager.Instance; if (instance != null) { Color valheimOrange = instance.ValheimOrange; return ""; } } catch { } return ""; } private static bool IsHashColorOpenTag(string tag) { if (tag.Length < 5 || tag[0] != '<' || tag[1] != '#' || tag[tag.Length - 1] != '>') { return false; } string input = tag.Substring(2, tag.Length - 3); return HexColorRegex.IsMatch(input); } } public static class UIPanels { [CompilerGenerated] private static class <>O { public static UnityAction <0>__CloseActionMenuOnly; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__56_0; public static UnityAction <>9__56_1; public static UnityAction <>9__56_2; public static UnityAction <>9__56_3; public static UnityAction <>9__56_4; public static UnityAction <>9__64_0; public static UnityAction <>9__64_1; public static UnityAction <>9__66_0; public static UnityAction <>9__66_1; public static UnityAction <>9__67_0; public static UnityAction <>9__74_0; public static UnityAction <>9__74_1; public static UnityAction <>9__75_0; public static UnityAction <>9__75_1; internal void b__56_0() { ItemData currentItem = DrakeRenameit.CurrentItem; if (currentItem != null) { ActionMenuPanel.SetActive(false); OpenUnlockConfirmPanel(currentItem); } } internal void b__56_1() { ItemData currentItem = DrakeRenameit.CurrentItem; CloseActionMenuOnly(); if (currentItem != null) { DrakeRenameit.OpenRename(currentItem); } } internal void b__56_2() { ItemData currentItem = DrakeRenameit.CurrentItem; CloseActionMenuOnly(); if (currentItem != null) { DrakeRenameit.OpenRewriteDesc(currentItem); } } internal void b__56_3() { ItemData currentItem = DrakeRenameit.CurrentItem; CloseActionMenuOnly(); if (currentItem != null) { DrakeRenameit.OpenCraftedByEditor(currentItem); } } internal void b__56_4() { ItemData currentItem = DrakeRenameit.CurrentItem; if (currentItem != null) { DrakeRenameit.ResetAllCustomizations(currentItem); } CloseActionMenuOnly(); } internal void b__64_0() { ItemData currentItem = DrakeRenameit.CurrentItem; if (currentItem == null) { CloseUnlockConfirmPanel(reopenActionMenu: false); } else if (!DrakeRenameit.TryPayRenameUnlock(currentItem)) { if (DrakeRenameit.CurrentItem == null || !DrakeRenameit.IsItemInLocalPlayerInventory(DrakeRenameit.CurrentItem)) { CloseAllRenameEditingUi(); return; } RefreshUnlockConfirmBody(); ((Selectable)_buttonConfirmUnlock).interactable = RenameUnlockCost.CanPlayerAfford(Player.m_localPlayer); } else { CloseUnlockConfirmPanel(reopenActionMenu: true); } } internal void b__64_1() { CloseUnlockConfirmPanel(reopenActionMenu: false); } internal void b__66_0() { DrakeRenameit.ApplyCraftedByLabel(RenameCraftedByInput.text.Trim()); } internal void b__66_1() { if (DrakeRenameit.CurrentItem != null) { RenameCraftedByInput.text = DrakeRenameit.CurrentItem.m_crafterName ?? ""; } List craftedByAllowedLabelsList = RenameitConfig.GetCraftedByAllowedLabelsList(); _craftedByLineLabelPendingToken = null; SetCraftedByLineLabelPickButtonText(craftedByAllowedLabelsList, 0); CloseCraftedByLineLabelPopover(); } internal void b__67_0() { if (!((Object)(object)_buttonCraftedByLineLabelPick == (Object)null) && ((Selectable)_buttonCraftedByLineLabelPick).interactable) { ToggleCraftedByLineLabelPopover(); } } internal void b__74_0() { DrakeRenameit.ApplyRename(RenameNameInput.text.Trim()); } internal void b__74_1() { if (DrakeRenameit.CurrentItem != null) { RenameNameInput.text = DrakeRenameit.resetName(DrakeRenameit.CurrentItem); } } internal void b__75_0() { if (string.IsNullOrEmpty(RenameDescInput.text)) { g__GetPlayerAndSendError|75_2("Description must not be empty!"); } else { DrakeRenameit.ApplyRewriteDesc(RenameDescInput.text.Trim()); } } internal void b__75_1() { RenameDescInput.text = DrakeRenameit.resetDesc(DrakeRenameit.CurrentItem); } } private const string RenameItemDescription = "Rewrite Item Desc"; private static Button _buttonOkName; private static Button _buttonOkDesc; private static Button _buttonResetName; private static Button _buttonResetDesc; private static Button? _buttonMenuRename; private static Button? _buttonMenuDesc; private static Button? _buttonMenuCraftedBy; private static Button? _buttonMenuResetAll; private static Button? _buttonMenuUnlock; private static Button? _buttonMenuCancel; private static Button? _buttonOkCraftedBy; private static Button? _buttonResetCraftedBy; private static Button? _buttonCraftedByLineLabelPick; private static GameObject? _craftedByLineLabelPopover; private static string? _craftedByLineLabelPendingToken; private static GameObject? _unlockConfirmPanel; private static RectTransform? _unlockCostListRoot; private static Text? _unlockAffordWarning; private static Button? _buttonConfirmUnlock; private static Button? _buttonConfirmCancel; private static bool _inputBlocked; public static GameObject? InputNamePanel { get; private set; } public static GameObject? InputDescPanel { get; private set; } public static InputField? RenameNameInput { get; private set; } public static InputField? RenameDescInput { get; private set; } public static GameObject? ActionMenuPanel { get; private set; } public static GameObject? InputCraftedByPanel { get; private set; } public static InputField? RenameCraftedByInput { get; private set; } internal static string? CraftedByLineLabelPendingToken => _craftedByLineLabelPendingToken; internal static void EnsureInputBlocked() { if (!_inputBlocked) { GUIManager.BlockInput(true); _inputBlocked = true; } } internal static void EnsureInputUnblocked() { if (_inputBlocked) { GUIManager.BlockInput(false); _inputBlocked = false; } } public static void CloseAllRenameEditingUi() { if ((Object)(object)InputNamePanel != (Object)null) { InputNamePanel.SetActive(false); } if ((Object)(object)InputDescPanel != (Object)null) { InputDescPanel.SetActive(false); } if ((Object)(object)InputCraftedByPanel != (Object)null) { InputCraftedByPanel.SetActive(false); } CloseCraftedByLineLabelPopover(); if ((Object)(object)ActionMenuPanel != (Object)null) { ActionMenuPanel.SetActive(false); } if ((Object)(object)_unlockConfirmPanel != (Object)null) { _unlockConfirmPanel.SetActive(false); } DrakeRenameit.CurrentItem = null; EnsureInputUnblocked(); } public static void OpenActionMenu(ItemData item) { if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { return; } if (!DrakeRenameit.IsItemInLocalPlayerInventory(item)) { CloseAllRenameEditingUi(); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "That item is no longer in your inventory.", 0, (Sprite)null); } return; } EnsureActionMenu(); if ((Object)(object)ActionMenuPanel == (Object)null || (Object)(object)_buttonMenuRename == (Object)null || (Object)(object)_buttonMenuResetAll == (Object)null || (Object)(object)_buttonMenuUnlock == (Object)null) { return; } DrakeRenameit.CurrentItem = item; bool flag = DrakeRenameit.ShowUnlockButton(item); ((Component)_buttonMenuUnlock).gameObject.SetActive(flag); if (flag) { Text componentInChildren = ((Component)_buttonMenuUnlock).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { string costDisplayShort = RenameUnlockCost.GetCostDisplayShort(); componentInChildren.text = (string.IsNullOrEmpty(costDisplayShort) ? "\ud83d\udd12 Unlock" : ("\ud83d\udd12 Unlock (" + costDisplayShort + ")")); } ((Selectable)_buttonMenuRename).interactable = false; ((Selectable)_buttonMenuDesc).interactable = false; ((Selectable)_buttonMenuCraftedBy).interactable = false; ((Selectable)_buttonMenuResetAll).interactable = false; ((Selectable)_buttonMenuUnlock).interactable = true; } else { ((Selectable)_buttonMenuRename).interactable = DrakeRenameit.CanChangeName(item); ((Selectable)_buttonMenuDesc).interactable = DrakeRenameit.CanChangeDesc(item); ((Selectable)_buttonMenuCraftedBy).interactable = DrakeRenameit.CanChangeCraftedByLabel(item); ((Selectable)_buttonMenuResetAll).interactable = DrakeRenameit.CanResetAnyCustomization(item); } ActionMenuPanel.SetActive(true); ActionMenuPanel.transform.SetAsLastSibling(); EnsureInputBlocked(); } private static void EnsureActionMenu() { //IL_004e: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Expected O, but got Unknown //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Expected O, but got Unknown //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Expected O, but got Unknown if ((Object)(object)ActionMenuPanel != (Object)null || GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { return; } ActionMenuPanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 320f, 280f, false); GUIManager.Instance.CreateText("DrakesRenameIt", ActionMenuPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -48f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 280f, 40f, false); _buttonMenuUnlock = GUIManager.Instance.CreateButton("\ud83d\udd12 Unlock", ActionMenuPanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 72f), 220f, 30f).GetComponent