Decompiled source of ShipwrightsTouch v1.1.1

ShipwrightsTouch.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("ShipwrightsTouch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Extra features for Valheim boats: naming and sail coloring.")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1+4908229b7775c88d0441ffff846b2f074e974ab5")]
[assembly: AssemblyProduct("ShipwrightsTouch")]
[assembly: AssemblyTitle("ShipwrightsTouch")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 ValheimBoatCustomizer
{
	[HarmonyPatch]
	public static class ColoringPatches
	{
		private static int m_selectedStyle = 0;

		private const int MaxStyles = 6;

		private static readonly Color[] SailColors = (Color[])(object)new Color[6]
		{
			Color.white,
			Color.red,
			Color.blue,
			Color.green,
			Color.yellow,
			new Color(0.2f, 0.2f, 0.2f)
		};

		private static readonly string[] ColorNames = new string[6] { "White", "Red", "Blue", "Green", "Yellow", "Black" };

		private static bool m_isPlacing = false;

		[HarmonyPatch(typeof(Player), "UpdatePlacement")]
		[HarmonyPrefix]
		private static void Prefix_UpdatePlacement(Player __instance, bool takeInput, float dt, GameObject ___m_placementGhost)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)___m_placementGhost == (Object)null)
			{
				return;
			}
			Ship component = ___m_placementGhost.GetComponent<Ship>();
			if (!((Object)(object)component == (Object)null))
			{
				ApplyStyle(component, m_selectedStyle);
				if (takeInput && Keybinds.IsDown(Plugin.SailColorPlacingKey.Value))
				{
					m_selectedStyle = (m_selectedStyle + 1) % 6;
					MessageHud.instance.ShowMessage((MessageType)2, "Sail Color: <color=yellow>" + ColorNames[m_selectedStyle] + "</color>", 0, (Sprite)null, false, true);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		[HarmonyPrefix]
		private static void Prefix_PlacePiece(Player __instance, Piece piece)
		{
			if ((Object)(object)piece != (Object)null && (Object)(object)((Component)piece).GetComponent<Ship>() != (Object)null)
			{
				m_isPlacing = true;
			}
		}

		[HarmonyPatch(typeof(Player), "PlacePiece")]
		[HarmonyPostfix]
		private static void Postfix_PlacePiece()
		{
			if (m_isPlacing)
			{
				m_isPlacing = false;
			}
		}

		[HarmonyPatch(typeof(Ship), "Awake")]
		[HarmonyPostfix]
		private static void Postfix_ShipAwake(Ship __instance)
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			if (m_isPlacing && component.IsOwner())
			{
				ZLog.LogWarning((object)$"[ShipwrightsTouch] Setting initial sail style {m_selectedStyle} for new ship: {((Object)((Component)__instance).gameObject).name}");
				component.GetZDO().Set("custom_sail_style", m_selectedStyle);
				if (Plugin.AssignBuilderIdentity.Value && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					component.GetZDO().Set("shipwrightstouch.builder_id", Player.m_localPlayer.GetPlayerID());
					component.GetZDO().Set("shipwrightstouch.builder_name", Player.m_localPlayer.GetPlayerName());
				}
			}
			UpdateSailAppearance(__instance);
		}

		[HarmonyPatch(typeof(Ship), "Start")]
		[HarmonyPostfix]
		private static void Postfix_ShipStart(Ship __instance)
		{
			UpdateSailAppearance(__instance);
		}

		private static void UpdateSailAppearance(Ship ship)
		{
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid())
			{
				int style = component.GetZDO().GetInt("custom_sail_style", 0);
				ApplyStyle(ship, style);
			}
		}

		private static void ApplyStyle(Ship ship, int style)
		{
			//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)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (style < 0 || style >= SailColors.Length)
			{
				return;
			}
			Color val = SailColors[style];
			Renderer[] componentsInChildren = ((Component)ship).GetComponentsInChildren<Renderer>(true);
			int num = 0;
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				string text = ((Object)((Component)val2).gameObject).name.ToLower();
				if (text.Contains("sail") || text.Contains("cloth") || text.Contains("flag"))
				{
					num++;
					MaterialPropertyBlock val3 = new MaterialPropertyBlock();
					val2.GetPropertyBlock(val3);
					val3.SetColor("_Color", val);
					val2.SetPropertyBlock(val3);
				}
			}
			_ = 0;
		}

		[HarmonyPatch(typeof(Ship), "UpdateSail")]
		[HarmonyPostfix]
		private static void Postfix_UpdateSail(Ship __instance)
		{
			UpdateSailAppearance(__instance);
		}

		[HarmonyPatch(typeof(Ship), "UpdateSailSize")]
		[HarmonyPostfix]
		private static void Postfix_UpdateSailSize(Ship __instance)
		{
			UpdateSailAppearance(__instance);
		}

		[HarmonyPatch(typeof(Player), "Update")]
		[HarmonyPostfix]
		private static void Postfix_PlayerUpdate(Player __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || TextInput.IsVisible() || !Keybinds.IsDown(Plugin.SailColorShipKey.Value) || !Keybinds.CanTakeInput(__instance))
			{
				return;
			}
			GameObject hoverObject = ((Humanoid)__instance).GetHoverObject();
			if ((Object)(object)hoverObject == (Object)null || (Object)(object)hoverObject.GetComponentInParent<Container>() != (Object)null)
			{
				return;
			}
			Ship parentShip = NamingPatches.GetParentShip(hoverObject.GetComponent<Component>());
			if ((Object)(object)parentShip == (Object)null)
			{
				return;
			}
			if (Plugin.CanModifyShip(parentShip, out var ownerName))
			{
				ZNetView component = ((Component)parentShip).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					int num = (component.GetZDO().GetInt("custom_sail_style", 0) + 1) % 6;
					component.GetZDO().Set("custom_sail_style", num);
					UpdateSailAppearance(parentShip);
					MessageHud.instance.ShowMessage((MessageType)2, "Sail Color: <color=yellow>" + ColorNames[num] + "</color>", 0, (Sprite)null, false, true);
				}
			}
			else
			{
				MessageHud.instance.ShowMessage((MessageType)2, "Only " + ownerName + " can change this ship's sail color.", 0, (Sprite)null, false, true);
			}
		}
	}
	[HarmonyPatch]
	public static class DeconstructionPatches
	{
		[HarmonyPatch(typeof(Player), "CheckCanRemovePiece")]
		[HarmonyPrefix]
		private static void Prefix_CheckCanRemovePiece(ref Piece piece)
		{
			if ((Object)(object)piece == (Object)null || !Plugin.AllowShipDeconstruction.Value)
			{
				return;
			}
			Ship componentInParent = ((Component)piece).GetComponentInParent<Ship>();
			string ownerName;
			if ((Object)(object)componentInParent == (Object)null)
			{
				if (piece.m_name.Contains("karve") || piece.m_name.Contains("longship") || piece.m_name.Contains("raft"))
				{
					ZLog.LogWarning((object)("[ShipwrightsTouch] Found ship piece " + piece.m_name + " but no Ship component in parent."));
				}
			}
			else if (Plugin.CanModifyShip(componentInParent, out ownerName) && !piece.m_canBeRemoved)
			{
				piece.m_canBeRemoved = true;
				ZLog.LogWarning((object)("[ShipwrightsTouch] Force-allowing deconstruction of ship piece: " + piece.m_name));
			}
		}

		[HarmonyPatch(typeof(Player), "RemovePiece")]
		[HarmonyPrefix]
		private static bool Prefix_RemovePiece(Player __instance)
		{
			if (!Plugin.AllowShipDeconstruction.Value)
			{
				return true;
			}
			GameObject hoverObject = ((Humanoid)__instance).GetHoverObject();
			if ((Object)(object)hoverObject == (Object)null)
			{
				return true;
			}
			Ship componentInParent = hoverObject.GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return true;
			}
			ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon();
			if (currentWeapon == null || (Object)(object)currentWeapon.m_shared.m_buildPieces == (Object)null)
			{
				return true;
			}
			Piece component = ((Component)componentInParent).GetComponent<Piece>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (!Plugin.CanModifyShip(componentInParent, out var ownerName))
			{
				MessageHud.instance.ShowMessage((MessageType)2, "Only " + ownerName + " can deconstruct this ship.", 0, (Sprite)null, false, true);
				return false;
			}
			if (!component.m_canBeRemoved)
			{
				component.m_canBeRemoved = true;
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class HoverTextPatches
	{
		[HarmonyPatch(typeof(HoverText), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_HoverText(HoverText __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		[HarmonyPatch(typeof(ShipControlls), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_RudderHoverText(ShipControlls __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		[HarmonyPatch(typeof(Container), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_ContainerHoverText(Container __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		[HarmonyPatch(typeof(Chair), "GetHoverText")]
		[HarmonyPostfix]
		[HarmonyPriority(100)]
		private static void Postfix_ChairHoverText(Chair __instance, ref string __result)
		{
			ApplyNamingHover((Component)(object)__instance, ref __result);
		}

		private static void ApplyNamingHover(Component instance, ref string result)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Ship parentShip = NamingPatches.GetParentShip(instance);
			if ((Object)(object)parentShip == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)parentShip).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			string text = component.GetZDO().GetString("custom_ship_name", "");
			string text2 = component.GetZDO().GetString("shipwrightstouch.builder_name", "");
			if (!string.IsNullOrEmpty(text))
			{
				string text3 = "<color=yellow>" + text + "</color>";
				if (result == null || !result.StartsWith(text3))
				{
					result = (string.IsNullOrEmpty(result) ? text3 : (text3 + "\n" + result));
				}
			}
			if (instance is Container)
			{
				return;
			}
			if (Plugin.CanModifyShip(parentShip, out var _))
			{
				AppendPrompt(ref result, Plugin.RenameShipKey.Value, NamingPatches.GetRenameTitle());
				AppendPrompt(ref result, Plugin.SailColorShipKey.Value, "Change Sail Color");
			}
			if (!string.IsNullOrEmpty(text2))
			{
				string text4 = "<size=80%><color=#C0C0C0>Built by: " + text2 + "</color></size>";
				if (result != null && !result.Contains("Built by:"))
				{
					result = result + "\n" + text4;
				}
			}
		}

		private static void AppendPrompt(ref string result, KeyboardShortcut shortcut, string label)
		{
			//IL_0006: 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)
			if (result != null && (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0)
			{
				string text = "[<color=yellow><b>" + Keybinds.Format(shortcut) + "</b></color>] " + label;
				if (!result.Contains(text))
				{
					result = result + "\n" + text;
				}
			}
		}
	}
	[HarmonyPatch]
	public static class Keybinds
	{
		private static readonly HashSet<string> IgnoredVanillaButtons = new HashSet<string> { "Use", "TabLeft", "TabRight" };

		private static readonly MethodInfo TakeInputMethod = AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null);

		private static readonly FieldInfo ButtonsField = AccessTools.Field(typeof(ZInput), "m_buttons");

		private static readonly MethodInfo KeyCodeToPathMethod = AccessTools.Method(typeof(ZInput), "KeyCodeToPath", (Type[])null, (Type[])null);

		private static List<string> s_lastConflicts = new List<string>();

		public static bool IsDown(KeyboardShortcut shortcut)
		{
			//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_0008: 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_0015: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey;
			if ((int)mainKey == 0 || !ZInput.IsKeyCodeValid(mainKey))
			{
				return false;
			}
			if (!ZInput.GetKeyDown(mainKey, false))
			{
				return false;
			}
			if (ModifierMatches(shortcut, (KeyCode)304, (KeyCode)303) && ModifierMatches(shortcut, (KeyCode)306, (KeyCode)305))
			{
				return ModifierMatches(shortcut, (KeyCode)308, (KeyCode)307);
			}
			return false;
		}

		public static bool CanTakeInput(Player player)
		{
			return (bool)TakeInputMethod.Invoke(player, null);
		}

		public static string Format(KeyboardShortcut shortcut)
		{
			//IL_0002: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0)
			{
				return "Not set";
			}
			List<string> list = new List<string>();
			if (HasModifier(shortcut, (KeyCode)306, (KeyCode)305))
			{
				list.Add("Ctrl");
			}
			if (HasModifier(shortcut, (KeyCode)304, (KeyCode)303))
			{
				list.Add("Shift");
			}
			if (HasModifier(shortcut, (KeyCode)308, (KeyCode)307))
			{
				list.Add("Alt");
			}
			list.Add(((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString());
			return string.Join(" + ", list);
		}

		private static bool ModifierMatches(KeyboardShortcut shortcut, KeyCode left, KeyCode right)
		{
			//IL_0000: 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_0014: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			bool flag = ZInput.GetKey(left, false) || ZInput.GetKey(right, false);
			return HasModifier(shortcut, left, right) == flag;
		}

		private static bool HasModifier(KeyboardShortcut shortcut, KeyCode left, KeyCode right)
		{
			//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: 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)
			return ((KeyboardShortcut)(ref shortcut)).Modifiers.Any((KeyCode m) => m == left || m == right);
		}

		private static string GetBoundPath(ButtonDef button)
		{
			try
			{
				return button.GetActionPath(true);
			}
			catch (ArgumentOutOfRangeException)
			{
				return null;
			}
		}

		[HarmonyPatch(typeof(ZInput), "Load")]
		[HarmonyPostfix]
		private static void Postfix_ZInputLoad(ZInput __instance)
		{
			CheckConflicts(__instance);
		}

		[HarmonyPatch(typeof(ZInput), "Save")]
		[HarmonyPostfix]
		private static void Postfix_ZInputSave(ZInput __instance)
		{
			CheckConflicts(__instance);
		}

		[HarmonyPatch(typeof(ZInput), "ResetToDefault")]
		[HarmonyPostfix]
		private static void Postfix_ZInputResetToDefault(ZInput __instance)
		{
			CheckConflicts(__instance);
		}

		public static void CheckConflicts(ZInput input = null)
		{
			try
			{
				FindAndLogConflicts(input ?? ZInput.instance);
			}
			catch (Exception ex)
			{
				ZLog.LogWarning((object)("[ShipwrightsTouch] Keybinding conflict check failed: " + ex.Message));
			}
		}

		private static void FindAndLogConflicts(ZInput input)
		{
			//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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			if (input == null || ButtonsField == null || KeyCodeToPathMethod == null || !(ButtonsField.GetValue(input) is Dictionary<string, ButtonDef> dictionary))
			{
				return;
			}
			List<string> list = new List<string>();
			ConfigEntry<KeyboardShortcut>[] array = new ConfigEntry<KeyboardShortcut>[3]
			{
				Plugin.RenameShipKey,
				Plugin.SailColorShipKey,
				Plugin.SailColorPlacingKey
			};
			foreach (ConfigEntry<KeyboardShortcut> val in array)
			{
				if (val == null)
				{
					continue;
				}
				KeyboardShortcut value = val.Value;
				KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
				if ((int)mainKey == 0)
				{
					continue;
				}
				string key = ((ConfigEntryBase)val).Definition.Key;
				if (!ZInput.IsKeyCodeValid(mainKey))
				{
					list.Add($"{key} ({Format(value)}) uses {mainKey}, which Valheim cannot read. The shortcut will never fire.");
					continue;
				}
				string path = (string)KeyCodeToPathMethod.Invoke(null, new object[2] { mainKey, false });
				foreach (string item in (from b in dictionary.Values
					where !IgnoredVanillaButtons.Contains(b.Name)
					where string.Equals(GetBoundPath(b), path, StringComparison.OrdinalIgnoreCase)
					select b.Name).Distinct())
				{
					list.Add($"{key} ({Format(value)}) shares {mainKey} with the game's \"{item}\" binding. Both will trigger.");
				}
			}
			if (Plugin.RenameShipKey != null && Plugin.SailColorShipKey != null && Format(Plugin.RenameShipKey.Value) == Format(Plugin.SailColorShipKey.Value))
			{
				KeyboardShortcut value2 = Plugin.RenameShipKey.Value;
				if ((int)((KeyboardShortcut)(ref value2)).MainKey != 0)
				{
					list.Add("RenameShip and ChangeSailColor are both " + Format(Plugin.RenameShipKey.Value) + ". Both will trigger at once.");
				}
			}
			if (list.SequenceEqual(s_lastConflicts))
			{
				return;
			}
			foreach (string item2 in list)
			{
				ZLog.LogWarning((object)("[ShipwrightsTouch] Keybinding conflict: " + item2));
			}
			if (list.Count == 0)
			{
				ZLog.Log((object)"[ShipwrightsTouch] Keybinding conflicts resolved.");
			}
			s_lastConflicts = list;
		}
	}
	[HarmonyPatch]
	public static class NamingPatches
	{
		private class ShipNameTextReceiver : TextReceiver
		{
			private readonly Ship m_ship;

			public ShipNameTextReceiver(Ship ship)
			{
				m_ship = ship;
			}

			public string GetText()
			{
				ZNetView component = ((Component)m_ship).GetComponent<ZNetView>();
				if (!((Object)(object)component != (Object)null) || !component.IsValid())
				{
					return "";
				}
				return component.GetZDO().GetString("custom_ship_name", "");
			}

			public void SetText(string text)
			{
				ZNetView component = ((Component)m_ship).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.GetZDO().Set("custom_ship_name", text);
				}
			}
		}

		public static Ship GetParentShip(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			Ship val = (Ship)(object)((component is Ship) ? component : null);
			if (val != null)
			{
				return val;
			}
			Ship componentInParent = component.GetComponentInParent<Ship>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			Transform root = component.transform.root;
			if ((Object)(object)root != (Object)null)
			{
				return ((Component)root).GetComponentInChildren<Ship>();
			}
			return null;
		}

		internal static string GetRenameTitle()
		{
			try
			{
				string text = Localization.instance.Localize("$text_rename");
				if (string.IsNullOrEmpty(text) || text.StartsWith("$") || text.ToLower().Contains("text_rename"))
				{
					return "Rename Ship";
				}
				return text;
			}
			catch
			{
				return "Rename Ship";
			}
		}

		[HarmonyPatch(typeof(Player), "Interact")]
		[HarmonyPrefix]
		private static bool Prefix_PlayerInteract(Player __instance, GameObject go, bool hold, bool alt)
		{
			//IL_0013: 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 (hold || (Object)(object)go == (Object)null)
			{
				return true;
			}
			if (!Keybinds.IsDown(Plugin.RenameShipKey.Value) && !Keybinds.IsDown(Plugin.SailColorShipKey.Value))
			{
				return true;
			}
			if ((Object)(object)go.GetComponentInParent<Container>() != (Object)null)
			{
				return true;
			}
			return (Object)(object)GetParentShip(go.GetComponent<Component>()) == (Object)null;
		}

		[HarmonyPatch(typeof(Player), "Update")]
		[HarmonyPostfix]
		private static void Postfix_PlayerUpdate(Player __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || TextInput.IsVisible() || !Keybinds.IsDown(Plugin.RenameShipKey.Value) || !Keybinds.CanTakeInput(__instance))
			{
				return;
			}
			GameObject hoverObject = ((Humanoid)__instance).GetHoverObject();
			if ((Object)(object)hoverObject == (Object)null || (Object)(object)hoverObject.GetComponentInParent<Container>() != (Object)null)
			{
				return;
			}
			Ship parentShip = GetParentShip(hoverObject.GetComponent<Component>());
			if (!((Object)(object)parentShip == (Object)null))
			{
				if (Plugin.CanModifyShip(parentShip, out var ownerName))
				{
					TextInput.instance.RequestText((TextReceiver)(object)new ShipNameTextReceiver(parentShip), GetRenameTitle(), 20);
				}
				else
				{
					MessageHud.instance.ShowMessage((MessageType)2, "Only " + ownerName + " can rename this ship.", 0, (Sprite)null, false, true);
				}
			}
		}
	}
	[BepInPlugin("com.malafein.shipwrightstouch", "Shipwright's Touch", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "com.malafein.shipwrightstouch";

		public const string ModName = "Shipwright's Touch";

		public const string ModVersion = "1.1.1";

		public const string ZdoOwnerIdKey = "shipwrightstouch.builder_id";

		public const string ZdoOwnerNameKey = "shipwrightstouch.builder_name";

		public const string ZdoNameKey = "custom_ship_name";

		public const string ZdoStyleKey = "custom_sail_style";

		public static ConfigEntry<bool> AllowShipDeconstruction;

		public static ConfigEntry<bool> AssignBuilderIdentity;

		public static ConfigEntry<KeyboardShortcut> RenameShipKey;

		public static ConfigEntry<KeyboardShortcut> SailColorShipKey;

		public static ConfigEntry<KeyboardShortcut> SailColorPlacingKey;

		private readonly Harmony harmony = new Harmony("com.malafein.shipwrightstouch");

		private void Awake()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			AllowShipDeconstruction = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowShipDeconstruction", false, "Allow deconstructing ships with the hammer (middle-mouse button).");
			AssignBuilderIdentity = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AssignBuilderIdentity", true, "Automatically assign your character as the owner when constructing a ship, restricting modifications (renaming, recoloring, deconstruction) to yourself.");
			RenameShipKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "RenameShip", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Rename the ship you are looking at (rudder, seats, mast, or hull). Either Shift, Ctrl, or Alt key satisfies a modifier.");
			SailColorShipKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "ChangeSailColor", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Cycle the sail color of the ship you are looking at. Either Shift, Ctrl, or Alt key satisfies a modifier.");
			SailColorPlacingKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "ChangeSailColorWhilePlacing", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Cycle the sail color of a ship while placing it with the hammer.");
			RenameShipKey.SettingChanged += OnKeybindChanged;
			SailColorShipKey.SettingChanged += OnKeybindChanged;
			SailColorPlacingKey.SettingChanged += OnKeybindChanged;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Shipwright's Touch 1.1.1 is loading...");
			try
			{
				harmony.PatchAll();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Shipwright's Touch patches applied successfully.");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("{0} failed to apply some patches: {1}", "Shipwright's Touch", arg));
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Shipwright's Touch loaded!");
			Keybinds.CheckConflicts();
		}

		private static void OnKeybindChanged(object sender, EventArgs e)
		{
			Keybinds.CheckConflicts();
		}

		public static bool CanModifyShip(Ship ship, out string ownerName)
		{
			ownerName = string.Empty;
			if ((Object)(object)ship == (Object)null)
			{
				return true;
			}
			ZNetView component = ((Component)ship).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return true;
			}
			long num = component.GetZDO().GetLong("shipwrightstouch.builder_id", 0L);
			ownerName = component.GetZDO().GetString("shipwrightstouch.builder_name", "");
			if (num != 0L)
			{
				Player localPlayer = Player.m_localPlayer;
				return num == ((localPlayer != null) ? new long?(localPlayer.GetPlayerID()) : ((long?)null));
			}
			return true;
		}
	}
}