Decompiled source of WeaponRename v0.1.4

plugins/WeaponRename.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("WeaponRename")]
[assembly: AssemblyDescription("Rename Valheim weapons with a reset-to-default action.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("yunc")]
[assembly: AssemblyProduct("WeaponRename")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a7f4c2e1-8b3d-4e9a-a1c6-0d5f8e2b7a44")]
[assembly: AssemblyFileVersion("0.1.4")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.4.0")]
namespace WeaponRename
{
	internal static class EquippedNameSync
	{
		internal const string ZdoKey = "WeaponRename.Equipped";

		internal static void PublishLocal()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)((Character)localPlayer).m_nview == (Object)null || !((Character)localPlayer).m_nview.IsValid() || !((Character)localPlayer).m_nview.IsOwner())
			{
				return;
			}
			ZDO zDO = ((Character)localPlayer).m_nview.GetZDO();
			if (zDO != null)
			{
				string displayName = GetDisplayName(localPlayer);
				if (!(zDO.GetString("WeaponRename.Equipped", string.Empty) == displayName))
				{
					zDO.Set("WeaponRename.Equipped", displayName);
				}
			}
		}

		internal static void OnItemChanged(ItemData item)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && item != null && (((Humanoid)localPlayer).IsItemEquiped(item) || ((Humanoid)localPlayer).GetCurrentWeapon() == item))
			{
				PublishLocal();
			}
		}

		internal static string ReadDisplayName(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return string.Empty;
			}
			if ((Object)(object)((Character)player).m_nview != (Object)null && ((Character)player).m_nview.IsValid())
			{
				ZDO zDO = ((Character)player).m_nview.GetZDO();
				if (zDO != null)
				{
					string text = zDO.GetString("WeaponRename.Equipped", string.Empty);
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
			}
			return GetDisplayName(player);
		}

		private static string GetDisplayName(Player player)
		{
			return RenameData.GetDisplayName(((Humanoid)player).GetCurrentWeapon(), localize: true);
		}
	}
	[BepInPlugin("com.yunc.weaponrename", "WeaponRename", "0.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.yunc.weaponrename";

		public const string PluginName = "WeaponRename";

		public const string PluginVersion = "0.1.4";

		private readonly Harmony harmony = new Harmony("com.yunc.weaponrename");

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			PluginConfig.Bind(((BaseUnityPlugin)this).Config);
			GUIManager.OnCustomGUIAvailable += RenameUI.OnCustomGuiAvailable;
			harmony.PatchAll();
			Logger.LogInfo((object)"WeaponRename 0.1.4 loaded");
		}

		private void Update()
		{
			if (RenameUI.IsOpen)
			{
				if (!InventoryGui.IsVisible())
				{
					RenameUI.Close();
				}
				else if (ZInput.GetButtonDown("Cancel") || Input.GetKeyDown((KeyCode)27))
				{
					RenameUI.Close();
				}
			}
		}

		private void OnDestroy()
		{
			GUIManager.OnCustomGUIAvailable -= RenameUI.OnCustomGuiAvailable;
			harmony.UnpatchSelf();
		}
	}
	internal static class PluginConfig
	{
		internal static ConfigEntry<bool> RenameEnabled;

		internal static ConfigEntry<int> NameCharacterLimit;

		internal static ConfigEntry<KeyboardShortcut> MenuModifier;

		internal static ConfigEntry<bool> DarwinAwardsShowWeapon;

		internal static void Bind(ConfigFile config)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			RenameEnabled = ConfigFileExtensions.BindConfig<bool>(config, "Server", "RenameEnabled", true, "When on, players may rename weapons from the inventory action panel.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 80);
			NameCharacterLimit = ConfigFileExtensions.BindConfig<int>(config, "Server", "NameCharacterLimit", 40, "Maximum length of a custom weapon name.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			MenuModifier = ConfigFileExtensions.BindConfig<KeyboardShortcut>(config, "UI", "MenuModifier", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "Hold this key and right-click a weapon in inventory to open the rename panel. Not synced so it will not fight other mods on each client.", false, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			DarwinAwardsShowWeapon = ConfigFileExtensions.BindConfig<bool>(config, "Compatibility", "DarwinAwardsShowWeapon", true, "When DarwinAwards is installed, replace {weapon} in PvP death lines with the killing weapon's display name (custom if set). Lines without {weapon} are left unchanged.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}

		internal static bool IsModifierHeld()
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = MenuModifier.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return true;
			}
			return ((KeyboardShortcut)(ref value)).IsPressed();
		}
	}
	internal static class RenameData
	{
		internal const string CustomNameKey = "WeaponRename.Name";

		internal static bool TryGetCustomName(ItemData item, out string name)
		{
			name = null;
			if (item?.m_customData == null)
			{
				return false;
			}
			if (!item.m_customData.TryGetValue("WeaponRename.Name", out var value))
			{
				return false;
			}
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			name = value;
			return true;
		}

		internal static string GetDisplayName(ItemData item, bool localize)
		{
			if (item?.m_shared == null)
			{
				return string.Empty;
			}
			if (TryGetCustomName(item, out var name))
			{
				return name;
			}
			string text = item.m_shared.m_name ?? string.Empty;
			if (!localize || Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text);
		}

		internal static string GetVanillaDisplayName(ItemData item)
		{
			if (item?.m_shared == null)
			{
				return string.Empty;
			}
			string text = item.m_shared.m_name ?? string.Empty;
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text);
		}

		internal static bool SetCustomName(ItemData item, string name, Inventory sourceInventory = null)
		{
			if (item == null)
			{
				return false;
			}
			if (item.m_customData == null)
			{
				item.m_customData = new Dictionary<string, string>();
			}
			string text = name?.Trim() ?? string.Empty;
			if (string.IsNullOrEmpty(text))
			{
				return ClearCustomName(item, sourceInventory);
			}
			int value = PluginConfig.NameCharacterLimit.Value;
			if (text.Length > value)
			{
				text = text.Substring(0, value);
			}
			item.m_customData["WeaponRename.Name"] = text;
			MarkDirty(item, sourceInventory);
			EquippedNameSync.OnItemChanged(item);
			return true;
		}

		internal static bool ClearCustomName(ItemData item, Inventory sourceInventory = null)
		{
			if (item?.m_customData == null)
			{
				return false;
			}
			bool num = item.m_customData.Remove("WeaponRename.Name");
			if (num)
			{
				MarkDirty(item, sourceInventory);
				EquippedNameSync.OnItemChanged(item);
			}
			return num;
		}

		internal static void MarkDirty(ItemData item, Inventory sourceInventory = null)
		{
			if (item == null)
			{
				return;
			}
			if (sourceInventory != null && sourceInventory.ContainsItem(item))
			{
				sourceInventory.Changed();
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				if (inventory != null && inventory != sourceInventory && inventory.ContainsItem(item))
				{
					inventory.Changed();
				}
			}
			InventoryGui instance = InventoryGui.instance;
			Container val = (((Object)(object)instance != (Object)null) ? instance.m_currentContainer : null);
			if ((Object)(object)val != (Object)null && val.m_inventory != null && val.m_inventory != sourceInventory && val.m_inventory.ContainsItem(item))
			{
				val.m_inventory.Changed();
			}
		}
	}
	internal static class RenameUI
	{
		private const float PanelWidth = 380f;

		private const float PanelHeight = 200f;

		private static GameObject panel;

		private static InputField nameInput;

		private static ItemData currentItem;

		private static Inventory currentInventory;

		private static bool inputBlocked;

		internal static bool IsOpen
		{
			get
			{
				if ((Object)(object)panel != (Object)null)
				{
					return panel.activeSelf;
				}
				return false;
			}
		}

		internal static void OnCustomGuiAvailable()
		{
			CreatePanel();
		}

		internal static void Open(ItemData item, InventoryGrid grid)
		{
			if (item == null)
			{
				return;
			}
			if (GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				Logger.LogWarning((object)"Rename UI is not ready yet.");
				return;
			}
			if ((Object)(object)panel == (Object)null)
			{
				CreatePanel();
			}
			if (!((Object)(object)panel == (Object)null) && !((Object)(object)nameInput == (Object)null))
			{
				currentItem = item;
				currentInventory = (((Object)(object)grid != (Object)null) ? grid.m_inventory : null);
				nameInput.characterLimit = PluginConfig.NameCharacterLimit.Value;
				nameInput.text = RenameData.GetDisplayName(item, localize: true);
				panel.SetActive(true);
				panel.transform.SetAsLastSibling();
				nameInput.ActivateInputField();
				((Selectable)nameInput).Select();
				SetInputBlocked(blocked: true);
			}
		}

		internal static void Close()
		{
			if ((Object)(object)panel != (Object)null)
			{
				panel.SetActive(false);
			}
			currentItem = null;
			currentInventory = null;
			SetInputBlocked(blocked: false);
		}

		private static void CreatePanel()
		{
			//IL_0065: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			if (GUIManager.Instance != null && !((Object)(object)GUIManager.CustomGUIFront == (Object)null))
			{
				currentItem = null;
				currentInventory = null;
				SetInputBlocked(blocked: false);
				if ((Object)(object)panel != (Object)null)
				{
					Object.Destroy((Object)(object)panel);
					panel = null;
					nameInput = null;
				}
				Transform transform = GUIManager.CustomGUIFront.transform;
				panel = GUIManager.Instance.CreateWoodpanel(transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 380f, 200f, false);
				panel.SetActive(false);
				GUIManager.Instance.CreateText("Rename weapon", panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -36f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimOrange, true, Color.black, 340f, 36f, false);
				nameInput = GUIManager.Instance.CreateInputField(panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 10f), (ContentType)0, "Weapon name...", 16, 320f, 32f).GetComponent<InputField>();
				((UnityEvent)CreateFooterButton("Rename", new Vector2(-110f, 32f), 100f).onClick).AddListener(new UnityAction(ApplyRename));
				((UnityEvent)CreateFooterButton("Reset", new Vector2(0f, 32f), 100f).onClick).AddListener(new UnityAction(ResetName));
				((UnityEvent)CreateFooterButton("Cancel", new Vector2(110f, 32f), 100f).onClick).AddListener(new UnityAction(Close));
			}
		}

		private static Button CreateFooterButton(string label, Vector2 anchoredPosition, float width)
		{
			//IL_001a: 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)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			return GUIManager.Instance.CreateButton(label, panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), anchoredPosition, width, 32f).GetComponent<Button>();
		}

		private static void ApplyRename()
		{
			if (currentItem == null)
			{
				Close();
				return;
			}
			if (!IsItemStillAvailable(currentItem))
			{
				Message("That weapon is no longer in this inventory.");
				Close();
				return;
			}
			string text = (((Object)(object)nameInput != (Object)null) ? nameInput.text.Trim() : string.Empty);
			if (string.IsNullOrEmpty(text))
			{
				Message("Enter a name, or use Reset to restore the default.");
				return;
			}
			RenameData.SetCustomName(currentItem, text, currentInventory);
			Close();
		}

		private static void ResetName()
		{
			if (currentItem == null)
			{
				Close();
			}
			else if (!IsItemStillAvailable(currentItem))
			{
				Message("That weapon is no longer in this inventory.");
				Close();
			}
			else
			{
				RenameData.ClearCustomName(currentItem, currentInventory);
				Close();
			}
		}

		private static bool IsItemStillAvailable(ItemData item)
		{
			if (currentInventory != null && currentInventory.ContainsItem(item))
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				if (inventory != null && inventory.ContainsItem(item))
				{
					return true;
				}
			}
			InventoryGui instance = InventoryGui.instance;
			Container val = (((Object)(object)instance != (Object)null) ? instance.m_currentContainer : null);
			if ((Object)(object)val != (Object)null && val.m_inventory != null)
			{
				return val.m_inventory.ContainsItem(item);
			}
			return false;
		}

		private static void Message(string text)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null);
			}
		}

		private static void SetInputBlocked(bool blocked)
		{
			if (blocked != inputBlocked)
			{
				GUIManager.BlockInput(blocked);
				inputBlocked = blocked;
			}
		}
	}
	internal static class WeaponFilter
	{
		internal static bool CanRename(ItemData item)
		{
			if (item?.m_shared == null)
			{
				return false;
			}
			if (!PluginConfig.RenameEnabled.Value)
			{
				return false;
			}
			return IsWeapon(item);
		}

		internal static bool IsWeapon(ItemData item)
		{
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_0021: 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_0049: Expected I4, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			if (item?.m_shared == null)
			{
				return false;
			}
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType <= 14)
			{
				switch (itemType - 2)
				{
				default:
					if ((int)itemType == 14)
					{
						break;
					}
					goto IL_0073;
				case 2:
				case 3:
					return true;
				case 1:
					break;
				case 7:
					goto IL_0065;
				case 0:
					return IsBomb(item);
				case 4:
				case 5:
				case 6:
					goto IL_0073;
				}
			}
			else if ((int)itemType != 22)
			{
				if ((int)itemType == 23)
				{
					goto IL_0065;
				}
				goto IL_0073;
			}
			return HasCombatSkill(item);
			IL_0065:
			return IsListedAmmo(item);
			IL_0073:
			return false;
		}

		private static bool HasCombatSkill(ItemData item)
		{
			//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)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			SkillType skillType = item.m_shared.m_skillType;
			if (skillType - 1 <= 10 || (int)skillType == 14)
			{
				return true;
			}
			return false;
		}

		private static bool IsListedAmmo(ItemData item)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			if (IsBomb(item))
			{
				return true;
			}
			string value = item.m_shared.m_ammoType ?? string.Empty;
			if (ContainsIgnoreCase(value, "arrow") || ContainsIgnoreCase(value, "bolt") || ContainsIgnoreCase(value, "missile"))
			{
				return true;
			}
			if ((int)item.m_shared.m_skillType == 8 || (int)item.m_shared.m_skillType == 14)
			{
				return true;
			}
			return NameLooksLikeAmmo(item);
		}

		private static bool IsBomb(ItemData item)
		{
			if (!NameContains(item, "bomb") && !NameContains(item, "ooze"))
			{
				return NameContains(item, "blob");
			}
			return true;
		}

		private static bool NameLooksLikeAmmo(ItemData item)
		{
			if (!NameContains(item, "arrow") && !NameContains(item, "bolt"))
			{
				return NameContains(item, "missile");
			}
			return true;
		}

		private static bool NameContains(ItemData item, string token)
		{
			return ContainsIgnoreCase(item.m_shared.m_name, token);
		}

		private static bool ContainsIgnoreCase(string value, string token)
		{
			if (!string.IsNullOrEmpty(value))
			{
				return value.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}
	}
}
namespace WeaponRename.Patches
{
	internal static class DarwinAwardsCompat
	{
		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static class SaveHitPatch
		{
			private static void Prefix(Character __instance, HitData hit)
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					lastHit = hit;
				}
			}
		}

		[HarmonyPatch]
		private static class DeathRpcPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(ZRoutedRpc)))
				{
					if (declaredMethod.Name == "InvokeRoutedRPC")
					{
						yield return declaredMethod;
					}
				}
			}

			private static void Prefix(object[] __args)
			{
				TryRewriteDeathRpc(__args);
			}
		}

		internal const string DeathRpcName = "DarwinAwards IDied";

		internal const string WeaponToken = "{weapon}";

		private static HitData lastHit;

		private static void TryRewriteDeathRpc(object[] args)
		{
			if (args == null || !PluginConfig.DarwinAwardsShowWeapon.Value)
			{
				return;
			}
			for (int i = 0; i < args.Length; i++)
			{
				if (args[i] is string text && text == "DarwinAwards IDied")
				{
					RewriteAfterName(args, i);
					break;
				}
			}
		}

		private static void RewriteAfterName(object[] args, int nameIndex)
		{
			if (nameIndex + 2 < args.Length && args[nameIndex + 2] is string text)
			{
				args[nameIndex + 2] = ApplyWeapon(text);
			}
			else if (nameIndex + 1 < args.Length && args[nameIndex + 1] is object[] array && array.Length >= 2 && array[1] is string text2)
			{
				array[1] = ApplyWeapon(text2);
			}
		}

		internal static string ApplyWeapon(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			Player val = (Player)((lastHit != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null)
			{
				return text;
			}
			string text2 = EquippedNameSync.ReadDisplayName(val);
			if (string.IsNullOrEmpty(text2))
			{
				return text;
			}
			if (!text.Contains("{weapon}"))
			{
				return text;
			}
			return text.Replace("{weapon}", text2);
		}
	}
	internal static class DisplayNamePatches
	{
		[HarmonyPatch(typeof(ItemDrop), "GetHoverName")]
		private static class ItemDropGetHoverNamePatch
		{
			private static void Postfix(ItemDrop __instance, ref string __result)
			{
				ApplyItemName(__instance?.m_itemData, ref __result);
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "GetHoverText")]
		private static class ItemDropGetHoverTextPatch
		{
			private static void Postfix(ItemDrop __instance, ref string __result)
			{
				ReplaceVanillaName(__instance?.m_itemData, ref __result);
			}
		}

		[HarmonyPatch(typeof(ItemStand), "GetHoverText")]
		private static class ItemStandGetHoverTextPatch
		{
			private static void Postfix(ItemStand __instance, ref string __result)
			{
				ReplaceVanillaName(LoadStandItem(__instance), ref __result);
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip")]
		private static class InventoryGridCreateItemTooltipPatch
		{
			private static bool Prefix(InventoryGrid __instance, ItemData item, UITooltip tooltip)
			{
				//IL_0027: 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)
				if (item == null || (Object)(object)tooltip == (Object)null)
				{
					return true;
				}
				string displayName = RenameData.GetDisplayName(item, localize: false);
				tooltip.Set(displayName, item.GetTooltip(-1), __instance.m_tooltipAnchor, default(Vector2));
				return false;
			}
		}

		private static void ApplyItemName(ItemData item, ref string result)
		{
			if (RenameData.TryGetCustomName(item, out var name))
			{
				result = name;
			}
		}

		private static void ReplaceVanillaName(ItemData item, ref string result)
		{
			if (item != null && !string.IsNullOrEmpty(result) && RenameData.TryGetCustomName(item, out var name))
			{
				string text = item.m_shared?.m_name;
				if (!string.IsNullOrEmpty(text) && result.Contains(text))
				{
					result = result.Replace(text, name);
				}
				string vanillaDisplayName = RenameData.GetVanillaDisplayName(item);
				if (!string.IsNullOrEmpty(vanillaDisplayName) && vanillaDisplayName != name && result.Contains(vanillaDisplayName))
				{
					result = result.Replace(vanillaDisplayName, name);
				}
			}
		}

		private static ItemData LoadStandItem(ItemStand stand)
		{
			if ((Object)(object)stand == (Object)null || !stand.HaveAttachment() || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			string attachedItem = stand.GetAttachedItem();
			if (string.IsNullOrEmpty(attachedItem))
			{
				return null;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(attachedItem);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return null;
			}
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			ItemData val = component.m_itemData.Clone();
			if ((Object)(object)stand.m_nview != (Object)null && stand.m_nview.IsValid())
			{
				ItemDrop.LoadFromZDO(val, stand.m_nview.GetZDO());
			}
			return val;
		}
	}
	internal static class EquippedNameSyncPatches
	{
		[HarmonyPatch(typeof(Humanoid), "EquipItem")]
		private static class EquipItemPatch
		{
			private static void Postfix(Humanoid __instance, bool __result)
			{
				if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					EquippedNameSync.PublishLocal();
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
		private static class UnequipItemPatch
		{
			private static void Postfix(Humanoid __instance)
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					EquippedNameSync.PublishLocal();
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		private static class PlayerOnSpawnedPatch
		{
			private static void Postfix(Player __instance)
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					EquippedNameSync.PublishLocal();
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		private static class PublishOnAttackPatch
		{
			private static void Prefix(Character __instance, HitData hit)
			{
				if (__instance is Player && hit != null && (Object)(object)hit.GetAttacker() == (Object)(object)Player.m_localPlayer)
				{
					EquippedNameSync.PublishLocal();
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
	internal static class InventoryClickPatch
	{
		private static bool Prefix(InventoryGrid grid, ItemData item)
		{
			if (item == null || (Object)(object)grid == (Object)null)
			{
				return true;
			}
			if (!PluginConfig.IsModifierHeld())
			{
				return true;
			}
			if (!WeaponFilter.CanRename(item))
			{
				return true;
			}
			RenameUI.Open(item, grid);
			return false;
		}
	}
}