Decompiled source of NameMoreThings v1.2.0

NameMoreThings.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GUIFramework;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("NameMoreThings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+f30a305e3921f94f70683cb90252d81814df54de")]
[assembly: AssemblyProduct("NameMoreThings")]
[assembly: AssemblyTitle("NameMoreThings")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.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 NameMoreThings
{
	[HarmonyPatch(typeof(EnemyHud), "LateUpdate")]
	internal static class BoatLabels
	{
		private static readonly Dictionary<NamedObject, TMP_Text> s_labels = new Dictionary<NamedObject, TMP_Text>();

		private static void Postfix(EnemyHud __instance)
		{
			//IL_0094: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_0174: Unknown result type (might be due to invalid IL or missing references)
			Camera mainCamera = Utils.GetMainCamera();
			bool flag = ModConfig.LabelsEnabled.Value && (Object)(object)mainCamera != (Object)null;
			float value = ModConfig.LabelMaxDistance.Value;
			float num = value * 0.75f;
			foreach (NamedObject boat in NamedObject.Boats)
			{
				s_labels.TryGetValue(boat, out var value2);
				if (!flag || !boat.HasName || !DisplayPrefs.ShowName(boat.Uid) || boat.DisplayName.Length == 0)
				{
					Hide(value2);
					continue;
				}
				Vector3 val = ((Component)boat).transform.position + Vector3.up * (boat.LabelHeight + ModConfig.LabelHeightOffset.Value);
				float num2 = Vector3.Distance(((Component)mainCamera).transform.position, val);
				Vector3 val2 = Utils.WorldToScreenPointScaled(mainCamera, val);
				if (num2 > value || val2.z <= 0f)
				{
					Hide(value2);
					continue;
				}
				if (!Object.op_Implicit((Object)(object)value2))
				{
					value2 = CreateLabel(__instance);
					s_labels[boat] = value2;
				}
				if (value2.text != boat.DisplayName)
				{
					value2.text = boat.DisplayName;
				}
				value2.fontSize = ModConfig.LabelFontSize.Value;
				value2.alpha = ((num2 <= num) ? 1f : Mathf.Clamp01((value - num2) / (value - num)));
				value2.transform.position = val2;
				if (!((Component)value2).gameObject.activeSelf)
				{
					((Component)value2).gameObject.SetActive(true);
				}
			}
		}

		public static void Remove(NamedObject boat)
		{
			if (s_labels.TryGetValue(boat, out var value))
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				s_labels.Remove(boat);
			}
		}

		private static void Hide(TMP_Text label)
		{
			if (Object.op_Implicit((Object)(object)label) && ((Component)label).gameObject.activeSelf)
			{
				((Component)label).gameObject.SetActive(false);
			}
		}

		private static TMP_Text CreateLabel(EnemyHud hud)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = hud.m_hudRoot.transform;
			Transform val = (Object.op_Implicit((Object)(object)hud.m_baseHud) ? hud.m_baseHud.transform.Find("Name") : null);
			TMP_Text val2 = (Object.op_Implicit((Object)(object)val) ? Object.Instantiate<GameObject>(((Component)val).gameObject, transform, false).GetComponent<TMP_Text>() : null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				GameObject val3 = new GameObject("Name", new Type[1] { typeof(RectTransform) });
				val3.transform.SetParent(transform, false);
				val2 = (TMP_Text)(object)val3.AddComponent<TextMeshProUGUI>();
			}
			((Object)val2).name = "BoatName";
			RectTransform rectTransform = val2.rectTransform;
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(0.5f, 0.5f);
			rectTransform.anchorMax = val4;
			rectTransform.anchorMin = val4;
			rectTransform.pivot = new Vector2(0.5f, 0f);
			rectTransform.sizeDelta = new Vector2(800f, 100f);
			val2.alignment = (TextAlignmentOptions)1026;
			val2.textWrappingMode = (TextWrappingModes)0;
			val2.overflowMode = (TextOverflowModes)0;
			val2.enableAutoSizing = false;
			val2.richText = false;
			((Graphic)val2).raycastTarget = false;
			((Component)val2).gameObject.SetActive(false);
			return val2;
		}
	}
	internal static class DisplayPrefs
	{
		private const string KeyPrefix = "NameMoreThings.";

		private const int ShowNameFlag = 1;

		private const int ShowOnMapFlag = 2;

		private static readonly Dictionary<long, int> s_flags = new Dictionary<long, int>();

		private static Player s_loadedFor;

		public static bool ShowName(long uid)
		{
			return Get(uid, 1, ModConfig.LabelShowByDefault.Value);
		}

		public static bool ShowOnMap(long uid, NamedKind kind)
		{
			return Get(uid, 2, ModConfig.ShowOnMapByDefault(kind));
		}

		public static void Set(long uid, bool showName, bool showOnMap)
		{
			Player localPlayer = Player.m_localPlayer;
			if (uid != 0L && !((Object)(object)localPlayer == (Object)null))
			{
				Load(localPlayer);
				int value = (showName ? 1 : 0) | (showOnMap ? 2 : 0);
				s_flags[uid] = value;
				localPlayer.m_customData["NameMoreThings." + uid.ToString("x")] = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		private static bool Get(long uid, int flag, bool fallback)
		{
			Player localPlayer = Player.m_localPlayer;
			if (uid == 0L || (Object)(object)localPlayer == (Object)null)
			{
				return fallback;
			}
			Load(localPlayer);
			if (!s_flags.TryGetValue(uid, out var value))
			{
				return fallback;
			}
			return (value & flag) != 0;
		}

		private static void Load(Player player)
		{
			if ((Object)(object)player == (Object)(object)s_loadedFor)
			{
				return;
			}
			s_loadedFor = player;
			s_flags.Clear();
			foreach (KeyValuePair<string, string> customDatum in player.m_customData)
			{
				if (customDatum.Key.StartsWith("NameMoreThings.") && long.TryParse(customDatum.Key.Substring("NameMoreThings.".Length), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result) && int.TryParse(customDatum.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
				{
					s_flags[result] = result2;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Minimap), "UpdateDynamicPins")]
	internal static class MapPins
	{
		private class Entry
		{
			public PinData Pin;

			public string Name;
		}

		private struct Thing
		{
			public ZDOID Id;

			public string Name;

			public Vector3 Position;

			public int Prefab;

			public NamedKind Kind;
		}

		private const float PinSpeed = 200f;

		private const float StaticRefreshInterval = 1f;

		private static readonly string[] FallbackIconPrefabs = new string[3] { "Karve", "wood_door", "portal_wood" };

		private static readonly Dictionary<ZDOID, Entry> s_pins = new Dictionary<ZDOID, Entry>();

		private static readonly HashSet<ZDOID> s_loaded = new HashSet<ZDOID>();

		private static readonly HashSet<ZDOID> s_shown = new HashSet<ZDOID>();

		private static readonly List<ZDOID> s_remove = new List<ZDOID>();

		private static readonly Dictionary<int, Sprite> s_icons = new Dictionary<int, Sprite>();

		private static readonly List<Thing> s_staticPins = new List<Thing>();

		private static readonly List<Thing> s_candidates = new List<Thing>();

		private static float s_nextStaticRefresh;

		private static Minimap s_map;

		private static void Postfix(Minimap __instance, float dt)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_map != (Object)(object)__instance)
			{
				s_map = __instance;
				s_pins.Clear();
				s_icons.Clear();
				s_nextStaticRefresh = 0f;
			}
			s_loaded.Clear();
			s_shown.Clear();
			if (ModConfig.MapEnabled.Value && ((int)__instance.m_mode == 2 || ModConfig.ShowOnMinimap.Value))
			{
				foreach (NamedObject item in NamedObject.All)
				{
					if (item.IsValid)
					{
						s_loaded.Add(item.Id);
						if (item.Kind == NamedKind.Boat && IsShown(item))
						{
							Show(__instance, item.Id, item.DisplayName, ((Component)item).transform.position, item.PrefabHash, item.Kind, dt);
						}
					}
				}
				foreach (KeyValuePair<ZDOID, NameTracker.Remote> item2 in NameTracker.Remotes[0])
				{
					NameTracker.Remote value = item2.Value;
					if (IsShown(item2.Key, value, NamedKind.Boat))
					{
						Show(__instance, item2.Key, value.Name, value.Position, value.Prefab, NamedKind.Boat, dt);
					}
				}
				if (Time.time >= s_nextStaticRefresh)
				{
					s_nextStaticRefresh = Time.time + 1f;
					RefreshStaticPins();
				}
				foreach (Thing s_staticPin in s_staticPins)
				{
					Show(__instance, s_staticPin.Id, s_staticPin.Name, s_staticPin.Position, s_staticPin.Prefab, s_staticPin.Kind, dt);
				}
			}
			s_remove.Clear();
			foreach (KeyValuePair<ZDOID, Entry> s_pin in s_pins)
			{
				if (!s_shown.Contains(s_pin.Key))
				{
					s_remove.Add(s_pin.Key);
				}
			}
			foreach (ZDOID item3 in s_remove)
			{
				__instance.RemovePin(s_pins[item3].Pin);
				s_pins.Remove(item3);
			}
		}

		private static bool IsShown(NamedObject thing)
		{
			if (thing.HasName && DisplayPrefs.ShowOnMap(thing.Uid, thing.Kind))
			{
				return thing.DisplayName.Length > 0;
			}
			return false;
		}

		private static bool IsShown(ZDOID id, NameTracker.Remote thing, NamedKind kind)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!s_loaded.Contains(id) && thing.Name.Length > 0)
			{
				return DisplayPrefs.ShowOnMap(thing.Uid, kind);
			}
			return false;
		}

		private static void RefreshStaticPins()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			s_staticPins.Clear();
			s_candidates.Clear();
			foreach (NamedObject item in NamedObject.All)
			{
				if (item.IsValid && item.Kind == NamedKind.Door && IsShown(item))
				{
					s_candidates.Add(new Thing
					{
						Id = item.Id,
						Name = item.DisplayName,
						Position = ((Component)item).transform.position,
						Prefab = item.PrefabHash,
						Kind = NamedKind.Door
					});
				}
			}
			AddRemoteCandidates(NamedKind.Door);
			AddMerged(ModConfig.MergeDoors.Value, sameNameOnly: true);
			s_candidates.Clear();
			AddRemoteCandidates(NamedKind.Portal);
			AddMerged(ModConfig.MergePortals.Value, sameNameOnly: false);
		}

		private static void AddRemoteCandidates(NamedKind kind)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<ZDOID, NameTracker.Remote> item in NameTracker.Remotes[(int)kind])
			{
				NameTracker.Remote value = item.Value;
				if (IsShown(item.Key, value, kind))
				{
					s_candidates.Add(new Thing
					{
						Id = item.Key,
						Name = value.Name,
						Position = value.Position,
						Prefab = value.Prefab,
						Kind = kind
					});
				}
			}
		}

		private static void AddMerged(bool merge, bool sameNameOnly)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			int count = s_candidates.Count;
			if (!merge || count < 2)
			{
				s_staticPins.AddRange(s_candidates);
				return;
			}
			int[] array = new int[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = i;
			}
			float value = ModConfig.MergeDistance.Value;
			float num = value * value;
			for (int j = 0; j < count; j++)
			{
				for (int k = j + 1; k < count; k++)
				{
					Thing thing = s_candidates[j];
					Thing thing2 = s_candidates[k];
					if (!sameNameOnly || !(thing.Name != thing2.Name))
					{
						float num2 = thing.Position.x - thing2.Position.x;
						float num3 = thing.Position.z - thing2.Position.z;
						if (num2 * num2 + num3 * num3 <= num)
						{
							Union(array, j, k);
						}
					}
				}
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[count];
			int[] array3 = new int[count];
			int[] array4 = new int[count];
			int num4;
			ref Vector3 reference;
			for (int l = 0; l < count; reference = ref array2[num4], reference += s_candidates[l].Position, array3[num4]++, l++)
			{
				num4 = Find(array, l);
				if (array3[num4] != 0)
				{
					Thing thing3 = s_candidates[l];
					if (((ZDOID)(ref thing3.Id)).CompareTo(s_candidates[array4[num4]].Id) >= 0)
					{
						continue;
					}
				}
				array4[num4] = l;
			}
			for (int m = 0; m < count; m++)
			{
				if (array3[m] == 0)
				{
					continue;
				}
				Thing item = s_candidates[array4[m]];
				if (array3[m] > 1)
				{
					item.Position = array2[m] / (float)array3[m];
					if (!sameNameOnly)
					{
						item.Name = "";
					}
				}
				s_staticPins.Add(item);
			}
		}

		private static int Find(int[] group, int i)
		{
			while (group[i] != i)
			{
				group[i] = group[group[i]];
				i = group[i];
			}
			return i;
		}

		private static void Union(int[] group, int a, int b)
		{
			a = Find(group, a);
			b = Find(group, b);
			if (a != b)
			{
				group[b] = a;
			}
		}

		private static void Show(Minimap map, ZDOID id, string name, Vector3 position, int prefab, NamedKind kind, float dt)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			s_shown.Add(id);
			if (s_pins.TryGetValue(id, out var value) && value.Name == name && map.m_pins.Contains(value.Pin))
			{
				Vector3 val = Vector3.MoveTowards(value.Pin.m_pos, position, 200f * dt);
				if (val != value.Pin.m_pos)
				{
					value.Pin.m_pos = val;
					map.m_pinUpdateRequired = true;
				}
				return;
			}
			if (value != null)
			{
				map.RemovePin(value.Pin);
			}
			PinData val2 = map.AddPin(position, (PinType)8, name, false, false, 0L, default(PlatformUserID));
			val2.m_icon = GetIcon(map, prefab, kind);
			s_pins[id] = new Entry
			{
				Pin = val2,
				Name = name
			};
		}

		private static Sprite GetIcon(Minimap map, int prefab, NamedKind kind)
		{
			if (s_icons.TryGetValue(prefab, out var value))
			{
				return value;
			}
			value = PieceIcon(prefab);
			if (!Object.op_Implicit((Object)(object)value))
			{
				value = PieceIcon(StringExtensionMethods.GetStableHashCode(FallbackIconPrefabs[(int)kind]));
			}
			if (!Object.op_Implicit((Object)(object)value))
			{
				value = map.GetSprite((PinType)3);
			}
			s_icons[prefab] = value;
			return value;
		}

		private static Sprite PieceIcon(int prefab)
		{
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(prefab) : null);
			Piece val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<Piece>() : null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				return null;
			}
			return val2.m_icon;
		}
	}
	internal static class ModConfig
	{
		private const string ServerSection = "1 - Server";

		private const string ControlsSection = "2 - Controls";

		private const string LabelSection = "3 - Names above boats";

		private const string MapSection = "4 - Map";

		public static ConfigEntry<int> MaxNameLength;

		public static ConfigEntry<bool> AllowNamingBoats;

		public static ConfigEntry<bool> AllowNamingDoors;

		public static ConfigEntry<float> MapUpdateInterval;

		public static ConfigEntry<KeyCode> NameKey;

		public static ConfigEntry<bool> LabelsEnabled;

		public static ConfigEntry<bool> LabelShowByDefault;

		public static ConfigEntry<float> LabelMaxDistance;

		public static ConfigEntry<int> LabelFontSize;

		public static ConfigEntry<float> LabelHeightOffset;

		public static ConfigEntry<bool> MapEnabled;

		public static ConfigEntry<bool> ShowOnMinimap;

		public static ConfigEntry<bool> MapShowBoatsByDefault;

		public static ConfigEntry<bool> MapShowDoorsByDefault;

		public static ConfigEntry<bool> MapShowPortals;

		public static ConfigEntry<bool> MergeDoors;

		public static ConfigEntry<bool> MergePortals;

		public static ConfigEntry<float> MergeDistance;

		public static void Bind(ConfigFile config)
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			MaxNameLength = BindSynced(config, "1 - Server", "MaxNameLength", 24, "Longest name allowed, in characters.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 64));
			AllowNamingBoats = BindSynced(config, "1 - Server", "AllowNamingBoats", value: true, "Allow players to name boats. Existing names are kept either way.");
			AllowNamingDoors = BindSynced(config, "1 - Server", "AllowNamingDoors", value: true, "Allow players to name doors. Existing names are kept either way.");
			MapUpdateInterval = BindSynced(config, "1 - Server", "MapUpdateInterval", 2f, "Seconds between the server sending far-away boat positions to players.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f));
			NameKey = config.Bind<KeyCode>("2 - Controls", "NameKey", (KeyCode)110, "Key that opens the naming menu for the boat or door you're looking at. Controllers use the alternate interact instead (the same button that renames tamed creatures).");
			LabelsEnabled = config.Bind<bool>("3 - Names above boats", "Enabled", true, "Show names floating above boats. false hides them all and removes the toggle from the naming menu.");
			LabelShowByDefault = config.Bind<bool>("3 - Names above boats", "ShowByDefault", true, "Show the name above boats you haven't set yourself in the naming menu.");
			LabelMaxDistance = config.Bind<float>("3 - Names above boats", "MaxDistance", 100f, new ConfigDescription("Names are shown for boats within this many meters of the camera.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), Array.Empty<object>()));
			LabelFontSize = config.Bind<int>("3 - Names above boats", "FontSize", 20, new ConfigDescription("Font size of the name above the boat.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 64), Array.Empty<object>()));
			LabelHeightOffset = config.Bind<float>("3 - Names above boats", "HeightOffset", 1f, new ConfigDescription("Meters between the top of the boat (usually the mast) and its name.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-20f, 20f), Array.Empty<object>()));
			MapEnabled = config.Bind<bool>("4 - Map", "Enabled", true, "Show named boats, doors and portals on the map. false hides them all and removes the toggle from the naming menu.");
			ShowOnMinimap = config.Bind<bool>("4 - Map", "ShowOnMinimap", true, "Also show them on the small minimap, not just the large map.");
			MapShowBoatsByDefault = config.Bind<bool>("4 - Map", "ShowBoatsByDefault", true, "Show named boats you haven't set yourself in the naming menu.");
			MapShowDoorsByDefault = config.Bind<bool>("4 - Map", "ShowDoorsByDefault", true, "Show named doors you haven't set yourself in the naming menu.");
			MapShowPortals = config.Bind<bool>("4 - Map", "ShowPortals", true, "Show portals that have a tag, with the tag as their name.");
			MergeDoors = config.Bind<bool>("4 - Map", "MergeDoors", true, "Show doors with the same name that are close together as one pin.");
			MergePortals = config.Bind<bool>("4 - Map", "MergePortals", true, "Show portals that are close together, like a portal room, as one pin without a name.");
			MergeDistance = config.Bind<float>("4 - Map", "MergeDistance", 50f, new ConfigDescription("Meters apart that doors or portals can be and still merge. A row of portals each this close to the next merges into one pin.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
		}

		public static bool NamingAllowed(NamedKind kind)
		{
			return kind switch
			{
				NamedKind.Boat => AllowNamingBoats.Value, 
				NamedKind.Door => AllowNamingDoors.Value, 
				_ => false, 
			};
		}

		public static bool ShowOnMapByDefault(NamedKind kind)
		{
			return kind switch
			{
				NamedKind.Boat => MapShowBoatsByDefault.Value, 
				NamedKind.Door => MapShowDoorsByDefault.Value, 
				_ => MapShowPortals.Value, 
			};
		}

		private static ConfigEntry<T> BindSynced<T>(ConfigFile config, string section, string key, T value, string description, AcceptableValueBase range = null)
		{
			//IL_0010: 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_001d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			return config.Bind<T>(section, key, value, new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
		}
	}
	internal class NameReceiver : TextReceiver
	{
		private readonly NamedObject _target;

		public NameReceiver(NamedObject target)
		{
			_target = target;
		}

		public string GetText()
		{
			if (!Object.op_Implicit((Object)(object)_target))
			{
				return "";
			}
			return _target.DisplayName;
		}

		public void SetText(string text)
		{
			if (Object.op_Implicit((Object)(object)_target) && _target.IsValid)
			{
				if (!NameDialog.NameLocked && text != _target.DisplayName)
				{
					_target.SetName(text);
				}
				DisplayPrefs.Set(_target.Uid, NameDialog.ShowNameChecked, NameDialog.ShowOnMapChecked);
			}
		}
	}
	internal static class NameDialog
	{
		[HarmonyPatch(typeof(TextInput), "RequestText")]
		private static class RequestTextPatch
		{
			private static void Prefix(TextInput __instance, TextReceiver sign)
			{
				GuiInputField inputField = __instance.m_inputField;
				if ((Object)(object)s_fieldStateFor != (Object)(object)__instance)
				{
					s_fieldStateFor = __instance;
					s_selectAllOnFocus = ((TMP_InputField)inputField).onFocusSelectAll;
					s_fieldInteractable = ((Selectable)inputField).interactable;
				}
				((TMP_InputField)inputField).onFocusSelectAll = s_selectAllOnFocus;
				((Selectable)inputField).interactable = s_fieldInteractable && (!(sign is NameReceiver) || !NameLocked);
			}

			private static void Postfix(TextInput __instance, TextReceiver sign)
			{
				bool flag = (s_open = sign is NameReceiver);
				if (flag && (Object)(object)s_builtFor != (Object)(object)__instance)
				{
					Build(__instance);
				}
				if (!((Object)(object)s_builtFor != (Object)(object)__instance) && Object.op_Implicit((Object)(object)s_strip))
				{
					((Component)s_strip).gameObject.SetActive(flag);
					if (flag)
					{
						Layout();
					}
				}
			}
		}

		private const float StripHeight = 52f;

		private const float StripGap = 6f;

		private const float BoxSize = 26f;

		private const float LabelGap = 10f;

		private const float ToggleSpacing = 40f;

		private const float FontSize = 20f;

		internal static bool ShowNameChecked;

		internal static bool ShowOnMapChecked;

		internal static bool NameLocked;

		private static TextInput s_builtFor;

		private static RectTransform s_strip;

		private static Toggle s_showNameToggle;

		private static Toggle s_showOnMapToggle;

		private static readonly List<GameObject> s_hints = new List<GameObject>();

		private static bool s_open;

		private static TextInput s_fieldStateFor;

		private static bool s_selectAllOnFocus;

		private static bool s_fieldInteractable;

		private static NamedKind s_kind;

		public static bool CanRename(NamedObject target, bool flash)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (ModConfig.NamingAllowed(target.Kind))
			{
				return PrivateArea.CheckAccess(((Component)target).transform.position, 0f, flash, false);
			}
			return false;
		}

		public static bool CanOpen(NamedObject target)
		{
			if (!target.HasName)
			{
				return CanRename(target, flash: false);
			}
			return true;
		}

		public static void Update()
		{
			CheckNameKey();
			UpdateGamepad();
		}

		private static void UpdateGamepad()
		{
			if (!s_open || !TextInput.IsVisible() || !Object.op_Implicit((Object)(object)s_strip) || !((Component)s_strip).gameObject.activeInHierarchy)
			{
				return;
			}
			bool flag = ZInput.IsGamepadActive();
			foreach (GameObject s_hint in s_hints)
			{
				if (Object.op_Implicit((Object)(object)s_hint) && s_hint.activeSelf != flag)
				{
					s_hint.SetActive(flag);
				}
			}
			if (flag)
			{
				if (ZInput.GetButtonDown("JoyButtonY"))
				{
					Flip(s_showNameToggle);
				}
				if (ZInput.GetButtonDown("JoyLTrigger"))
				{
					Flip(s_showOnMapToggle);
				}
			}
		}

		private static void Flip(Toggle toggle)
		{
			if (Object.op_Implicit((Object)(object)toggle) && ((Component)toggle).gameObject.activeInHierarchy)
			{
				toggle.isOn = !toggle.isOn;
			}
		}

		private static void CheckNameKey()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && ZInput.GetButtonDown(Plugin.NameButton.Name) && ((Character)localPlayer).TakeInput() && !((Character)localPlayer).InPlaceMode())
			{
				GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
				NamedObject namedObject = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<NamedObject>() : null);
				if (Object.op_Implicit((Object)(object)namedObject) && namedObject.IsValid)
				{
					Open(namedObject, (Humanoid)(object)localPlayer);
				}
			}
		}

		public static bool Open(NamedObject target, Humanoid user)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			bool flag = CanRename(target, flash: true);
			if (!flag && !target.HasName)
			{
				if (ModConfig.NamingAllowed(target.Kind))
				{
					((Character)user).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false);
				}
				return false;
			}
			IDistributionPlatform distributionPlatform = PlatformManager.DistributionPlatform;
			if (!PrivilegeResultExtentions.IsGranted(distributionPlatform.PrivilegeProvider.CheckPrivilege((Privilege)2)))
			{
				ResolvePrivilegeUI resolvePrivilege = distributionPlatform.UIProvider.ResolvePrivilege;
				if (resolvePrivilege != null)
				{
					resolvePrivilege.Open((Privilege)2, (PrivilegeResult)64);
				}
				return false;
			}
			TextInput instance = TextInput.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return false;
			}
			NameLocked = !flag;
			s_kind = target.Kind;
			ShowNameChecked = DisplayPrefs.ShowName(target.Uid);
			ShowOnMapChecked = DisplayPrefs.ShowOnMap(target.Uid, target.Kind);
			string text = ((target.Kind == NamedKind.Boat) ? "$namemorethings_topic_boat" : "$namemorethings_topic_door");
			instance.RequestText((TextReceiver)(object)new NameReceiver(target), text, ModConfig.MaxNameLength.Value);
			return true;
		}

		private static void Layout()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			bool flag = s_kind == NamedKind.Boat && ModConfig.LabelsEnabled.Value;
			bool value = ModConfig.MapEnabled.Value;
			((Component)s_strip).gameObject.SetActive(flag || value);
			((Component)s_showNameToggle).gameObject.SetActive(flag);
			((Component)s_showOnMapToggle).gameObject.SetActive(value);
			s_showNameToggle.SetIsOnWithoutNotify(ShowNameChecked);
			s_showOnMapToggle.SetIsOnWithoutNotify(ShowOnMapChecked);
			float num = (flag ? PreferredWidth(s_showNameToggle) : 0f);
			float num2 = (value ? PreferredWidth(s_showOnMapToggle) : 0f);
			float num3 = num + num2 + ((flag && value) ? 40f : 0f);
			Rect rect = s_strip.rect;
			float num4 = ((Rect)(ref rect)).width - 40f;
			float num5 = ((num3 > num4) ? (num4 / num3) : 1f);
			float left = (0f - num3) * num5 / 2f;
			if (flag)
			{
				left = Place(s_showNameToggle, left, num * num5) + 40f * num5;
			}
			if (value)
			{
				Place(s_showOnMapToggle, left, num2 * num5);
			}
		}

		private static float PreferredWidth(Toggle toggle)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)toggle).transform.Find("Label");
			TMP_Text val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<TMP_Text>() : null);
			float num = (Object.op_Implicit((Object)(object)val2) ? val2.GetPreferredValues(val2.text).x : 0f);
			return 36f + ((num > 1f) ? num : 150f);
		}

		private static float Place(Toggle toggle, float left, float width)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)toggle).transform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(0f, 0.5f);
			val.sizeDelta = new Vector2(width, 32f);
			val.anchoredPosition = new Vector2(left, 0f);
			return left + width;
		}

		private static void Build(TextInput input)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)s_strip))
			{
				Object.Destroy((Object)(object)((Component)s_strip).gameObject);
			}
			s_builtFor = input;
			RectTransform val = (RectTransform)input.m_panel.transform;
			GameObject val2 = new GameObject("NameMoreThingsOptions", new Type[1] { typeof(RectTransform) });
			s_strip = (RectTransform)val2.transform;
			((Transform)s_strip).SetParent((Transform)(object)val, false);
			RectTransform obj = s_strip;
			RectTransform obj2 = s_strip;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0f);
			obj2.anchorMax = val3;
			obj.anchorMin = val3;
			s_strip.pivot = new Vector2(0.5f, 1f);
			RectTransform obj3 = s_strip;
			Rect rect = val.rect;
			obj3.sizeDelta = new Vector2(((Rect)(ref rect)).width, 52f);
			s_strip.anchoredPosition = new Vector2(0f, -6f);
			Image val4 = val2.AddComponent<Image>();
			Image component = ((Component)val).GetComponent<Image>();
			if (Object.op_Implicit((Object)(object)component))
			{
				val4.sprite = component.sprite;
				val4.type = component.type;
				((Graphic)val4).color = ((Graphic)component).color;
				((Graphic)val4).material = ((Graphic)component).material;
				val4.fillCenter = component.fillCenter;
				val4.pixelsPerUnitMultiplier = component.pixelsPerUnitMultiplier;
			}
			else
			{
				GUIManager.Instance.ApplyWoodpanelStyle(val2.transform);
			}
			Transform val5 = ((Transform)val).Find("Cancel/Text");
			TMP_Text val6 = (Object.op_Implicit((Object)(object)val5) ? ((Component)val5).GetComponent<TMP_Text>() : null);
			if (!Object.op_Implicit((Object)(object)val6))
			{
				val6 = input.m_topic;
			}
			s_hints.Clear();
			Transform val7 = ((Transform)val).Find("Cancel/gamepad_hint");
			GameObject hintTemplate = (Object.op_Implicit((Object)(object)val7) ? ((Component)val7).gameObject : null);
			s_showNameToggle = CreateToggle((Transform)(object)s_strip, "$namemorethings_show_name", "$KEY_ButtonY", val6, hintTemplate, delegate(bool on)
			{
				ShowNameChecked = on;
			});
			s_showOnMapToggle = CreateToggle((Transform)(object)s_strip, "$namemorethings_show_on_map", "$KEY_LTrigger", val6, hintTemplate, delegate(bool on)
			{
				ShowOnMapChecked = on;
			});
			val2.SetActive(false);
		}

		private static Toggle CreateToggle(Transform parent, string labelToken, string joyHint, TMP_Text textTemplate, GameObject hintTemplate, Action<bool> onChanged)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Toggle", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			GameObject val2 = new GameObject("Background", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform val3 = (RectTransform)val2.transform;
			((Transform)val3).SetParent(val.transform, false);
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(0f, 0.5f);
			val3.anchorMax = val4;
			val3.anchorMin = val4;
			val3.pivot = new Vector2(0f, 0.5f);
			val3.sizeDelta = new Vector2(26f, 26f);
			val3.anchoredPosition = Vector2.zero;
			GameObject val5 = new GameObject("Checkmark", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform val6 = (RectTransform)val5.transform;
			((Transform)val6).SetParent((Transform)(object)val3, false);
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val4 = (val6.offsetMin = (val6.offsetMax = Vector2.zero));
			Toggle val8 = val.AddComponent<Toggle>();
			((Selectable)val8).targetGraphic = (Graphic)(object)val2.GetComponent<Image>();
			val8.graphic = (Graphic)(object)val5.GetComponent<Image>();
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)val8).navigation = navigation;
			GUIManager.Instance.ApplyToogleStyle(val8);
			TMP_Text val9;
			if (Object.op_Implicit((Object)(object)textTemplate))
			{
				val9 = Object.Instantiate<GameObject>(((Component)textTemplate).gameObject, val.transform, false).GetComponent<TMP_Text>();
			}
			else
			{
				val9 = (TMP_Text)(object)new GameObject("Label", new Type[1] { typeof(RectTransform) }).AddComponent<TextMeshProUGUI>();
				val9.transform.SetParent(val.transform, false);
			}
			((Object)val9).name = "Label";
			RectTransform rectTransform = val9.rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.pivot = new Vector2(0f, 0.5f);
			rectTransform.offsetMin = new Vector2(36f, 0f);
			rectTransform.offsetMax = Vector2.zero;
			val9.enableAutoSizing = false;
			val9.fontSize = 20f;
			val9.alignment = (TextAlignmentOptions)4097;
			val9.textWrappingMode = (TextWrappingModes)0;
			val9.overflowMode = (TextOverflowModes)1;
			((Graphic)val9).raycastTarget = true;
			val9.text = Localization.instance.Localize(labelToken);
			if (Object.op_Implicit((Object)(object)hintTemplate))
			{
				GameObject val10 = Object.Instantiate<GameObject>(hintTemplate, (Transform)(object)val3, false);
				RectTransform val11 = (RectTransform)val10.transform;
				((Vector2)(ref val4))..ctor(0f, 1f);
				val11.anchorMax = val4;
				val11.anchorMin = val4;
				val11.anchoredPosition = Vector2.zero;
				TMP_Text componentInChildren = val10.GetComponentInChildren<TMP_Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.text = Localization.instance.Localize(joyHint);
				}
				val10.SetActive(false);
				s_hints.Add(val10);
			}
			((UnityEvent<bool>)(object)val8.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on)
			{
				onChanged(on);
				RefocusInput();
			});
			return val8;
		}

		private static void RefocusInput()
		{
			GuiInputField val = (Object.op_Implicit((Object)(object)s_builtFor) ? s_builtFor.m_inputField : null);
			if (Object.op_Implicit((Object)(object)val) && !((TMP_InputField)val).isFocused)
			{
				((TMP_InputField)val).onFocusSelectAll = false;
				val.ActivateInputField();
			}
		}
	}
	internal enum NamedKind
	{
		Boat,
		Door,
		Portal
	}
	internal static class NameData
	{
		public static readonly int NameKey = StringExtensionMethods.GetStableHashCode("NameMoreThings_Name");

		public static readonly int AuthorKey = StringExtensionMethods.GetStableHashCode("NameMoreThings_Author");

		public static readonly int UidKey = StringExtensionMethods.GetStableHashCode("NameMoreThings_Uid");

		public static string Sanitize(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder(name.Length);
			foreach (char c in name)
			{
				stringBuilder.Append(char.IsControl(c) ? ' ' : c);
			}
			string text = StringExtensionMethods.RemoveRichTextTags(stringBuilder.ToString()).Trim();
			int num = ModConfig.MaxNameLength.Value;
			if (text.Length > num)
			{
				if (char.IsHighSurrogate(text[num - 1]))
				{
					num--;
				}
				text = text.Substring(0, num).TrimEnd(Array.Empty<char>());
			}
			return text;
		}

		public static string Display(string raw, string author)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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 (string.IsNullOrEmpty(raw))
			{
				return "";
			}
			PlatformUserID val = ((string.IsNullOrEmpty(author) || author == "host") ? default(PlatformUserID) : new PlatformUserID(author));
			return StringExtensionMethods.RemoveRichTextTags(CensorShittyWords.FilterUGC(raw, (UGCType)4, val, 0L, (GetUserProfileCompletedHandler)null));
		}

		public static string LocalAuthor()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ILocalUser localUser = PlatformManager.DistributionPlatform.LocalUser;
			if (!localUser.IsSignedIn)
			{
				return "host";
			}
			return ((object)((IUser)localUser).PlatformUserID/*cast due to .constrained prefix*/).ToString();
		}
	}
	public class NamedObject : MonoBehaviour
	{
		internal static readonly List<NamedObject> All = new List<NamedObject>();

		internal static readonly List<NamedObject> Boats = new List<NamedObject>();

		internal NamedKind Kind;

		private ZNetView _nview;

		private string _cachedRaw;

		private string _cachedAuthor;

		private string _displayName = "";

		private float _labelHeight = -1f;

		public bool IsValid
		{
			get
			{
				if ((Object)(object)_nview != (Object)null)
				{
					return _nview.IsValid();
				}
				return false;
			}
		}

		public ZDOID Id => _nview.GetZDO().m_uid;

		public int PrefabHash => _nview.GetZDO().GetPrefab();

		public bool HasName
		{
			get
			{
				if (IsValid)
				{
					return _nview.GetZDO().GetString(NameData.NameKey, "").Length > 0;
				}
				return false;
			}
		}

		public long Uid
		{
			get
			{
				if (!IsValid)
				{
					return 0L;
				}
				return _nview.GetZDO().GetLong(NameData.UidKey, 0L);
			}
		}

		public string DisplayName
		{
			get
			{
				if (!IsValid)
				{
					return "";
				}
				ZDO zDO = _nview.GetZDO();
				string text = zDO.GetString(NameData.NameKey, "");
				string text2 = zDO.GetString(NameData.AuthorKey, "");
				if (text != _cachedRaw || text2 != _cachedAuthor)
				{
					_cachedRaw = text;
					_cachedAuthor = text2;
					_displayName = NameData.Display(text, text2);
				}
				return _displayName;
			}
		}

		public float LabelHeight
		{
			get
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				if (_labelHeight < 0f)
				{
					float num = 0f;
					bool flag = false;
					MeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshRenderer>();
					foreach (MeshRenderer val in componentsInChildren)
					{
						float num2 = num;
						Bounds bounds = ((Renderer)val).bounds;
						num = Mathf.Max(num2, ((Bounds)(ref bounds)).max.y - ((Component)this).transform.position.y);
						flag = true;
					}
					_labelHeight = (flag ? Mathf.Clamp(num, 1f, 30f) : 3f);
				}
				return _labelHeight;
			}
		}

		private void Awake()
		{
			Kind = ((!Object.op_Implicit((Object)(object)((Component)this).GetComponent<Ship>())) ? NamedKind.Door : NamedKind.Boat);
			_nview = ((Component)this).GetComponent<ZNetView>();
			if (IsValid)
			{
				All.Add(this);
				if (Kind == NamedKind.Boat)
				{
					Boats.Add(this);
				}
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
			Boats.Remove(this);
			BoatLabels.Remove(this);
		}

		public void SetName(string name)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid)
			{
				if (!_nview.IsOwner())
				{
					_nview.ClaimOwnership();
				}
				ZDO zDO = _nview.GetZDO();
				if (zDO.GetLong(NameData.UidKey, 0L) == 0L)
				{
					zDO.Set(NameData.UidKey, Utils.GenerateUID());
				}
				zDO.Set(NameData.NameKey, NameData.Sanitize(name));
				zDO.Set(NameData.AuthorKey, NameData.LocalAuthor());
				NameTracker.NotifyServer(Id);
			}
		}
	}
	internal static class NameTracker
	{
		public struct Remote
		{
			public long Uid;

			public string Name;

			public Vector3 Position;

			public int Prefab;
		}

		[HarmonyPatch(typeof(Game), "Start")]
		private static class RegisterRpcs
		{
			private static void Postfix()
			{
				Dictionary<ZDOID, Remote>[] remotes = Remotes;
				for (int i = 0; i < remotes.Length; i++)
				{
					remotes[i].Clear();
				}
				s_serverHasMod = false;
				ZRoutedRpc.instance.Register<ZDOID>("NameMoreThings_Track", (Action<long, ZDOID>)RPC_Track);
				ZRoutedRpc.instance.Register<ZPackage>("NameMoreThings_List", (Action<long, ZPackage>)RPC_List);
			}
		}

		private const string TrackRpc = "NameMoreThings_Track";

		private const string ListRpc = "NameMoreThings_List";

		private const int PackageVersion = 2;

		private const int SectorsPerFrame = 400;

		private const float SweepInterval = 60f;

		private const float StaticResendInterval = 15f;

		public static readonly Dictionary<ZDOID, Remote>[] Remotes = new Dictionary<ZDOID, Remote>[3]
		{
			new Dictionary<ZDOID, Remote>(),
			new Dictionary<ZDOID, Remote>(),
			new Dictionary<ZDOID, Remote>()
		};

		private static bool s_serverHasMod;

		private static readonly Dictionary<ZDOID, NamedKind> s_tracked = new Dictionary<ZDOID, NamedKind>();

		private static readonly Dictionary<int, NamedKind> s_prefabKinds = new Dictionary<int, NamedKind>();

		private static readonly List<ZDO>[] s_send = new List<ZDO>[3]
		{
			new List<ZDO>(),
			new List<ZDO>(),
			new List<ZDO>()
		};

		private static readonly List<ZDOID> s_gone = new List<ZDOID>();

		private static ZNetScene s_prefabScene;

		private static ZDOMan s_zdoMan;

		private static int s_sweepIndex;

		private static float s_nextSweep;

		private static float s_nextSend;

		private static readonly float[] s_nextStaticResend = new float[3];

		private static readonly byte[][] s_lastStaticList = new byte[3][];

		public static void NotifyServer(ZDOID id)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ZNet.instance == (Object)null) && ZRoutedRpc.instance != null)
			{
				if (ZNet.instance.IsServer())
				{
					Track(id);
				}
				else if (s_serverHasMod)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC("NameMoreThings_Track", new object[1] { id });
				}
			}
		}

		public static void Update()
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || !instance.IsServer() || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || ZRoutedRpc.instance == null)
			{
				return;
			}
			if (s_zdoMan != ZDOMan.instance)
			{
				s_zdoMan = ZDOMan.instance;
				s_tracked.Clear();
				s_sweepIndex = 0;
				Array.Clear(s_lastStaticList, 0, s_lastStaticList.Length);
			}
			if ((Object)(object)s_prefabScene != (Object)(object)ZNetScene.instance)
			{
				FindPrefabs();
			}
			Sweep();
			if (Time.time >= s_nextSend)
			{
				s_nextSend = Time.time + ModConfig.MapUpdateInterval.Value;
				if (!instance.IsDedicated() || instance.GetPeers().Count > 0)
				{
					SendLists();
				}
			}
		}

		private static void FindPrefabs()
		{
			s_prefabScene = ZNetScene.instance;
			s_prefabKinds.Clear();
			foreach (GameObject prefab in s_prefabScene.m_prefabs)
			{
				if (Object.op_Implicit((Object)(object)prefab))
				{
					if (Object.op_Implicit((Object)(object)prefab.GetComponent<Ship>()))
					{
						s_prefabKinds[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = NamedKind.Boat;
					}
					else if (Object.op_Implicit((Object)(object)prefab.GetComponent<Door>()))
					{
						s_prefabKinds[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = NamedKind.Door;
					}
				}
			}
		}

		private static void Track(ZDOID id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = ZDOMan.instance.GetZDO(id);
			if (zDO != null && s_prefabKinds.TryGetValue(zDO.GetPrefab(), out var value))
			{
				s_tracked[id] = value;
			}
		}

		private static void Sweep()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (s_sweepIndex < 0)
			{
				if (Time.time < s_nextSweep)
				{
					return;
				}
				s_sweepIndex = 0;
			}
			List<ZDO>[] objectsBySector = s_zdoMan.m_objectsBySector;
			if (objectsBySector == null)
			{
				return;
			}
			int num = 0;
			while (s_sweepIndex < objectsBySector.Length && num < 400)
			{
				List<ZDO> list = objectsBySector[s_sweepIndex++];
				if (list == null || list.Count == 0)
				{
					continue;
				}
				num++;
				foreach (ZDO item in list)
				{
					if (s_prefabKinds.TryGetValue(item.GetPrefab(), out var value) && item.GetString(NameData.NameKey, "").Length > 0)
					{
						s_tracked[item.m_uid] = value;
					}
				}
			}
			if (s_sweepIndex >= objectsBySector.Length)
			{
				s_sweepIndex = -1;
				s_nextSweep = Time.time + 60f;
			}
		}

		private static void SendLists()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			List<ZDO>[] array = s_send;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Clear();
			}
			s_gone.Clear();
			foreach (KeyValuePair<ZDOID, NamedKind> item in s_tracked)
			{
				ZDO zDO = s_zdoMan.GetZDO(item.Key);
				if (zDO == null)
				{
					s_gone.Add(item.Key);
				}
				else if (zDO.GetString(NameData.NameKey, "").Length > 0)
				{
					s_send[(int)item.Value].Add(zDO);
				}
			}
			foreach (ZDOID item2 in s_gone)
			{
				s_tracked.Remove(item2);
			}
			foreach (List<ZDO> value in s_zdoMan.GetPortals().Values)
			{
				foreach (ZDO item3 in value)
				{
					if (item3.GetString(ZDOVars.s_tag, "").Length > 0)
					{
						s_send[2].Add(item3);
					}
				}
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(0L, "NameMoreThings_List", new object[1] { BuildList(NamedKind.Boat) });
			SendIfChanged(NamedKind.Door);
			SendIfChanged(NamedKind.Portal);
		}

		private static void SendIfChanged(NamedKind kind)
		{
			ZPackage val = BuildList(kind);
			byte[] array = val.GetArray();
			if (!(Time.time < s_nextStaticResend[(int)kind]) || !SameBytes(array, s_lastStaticList[(int)kind]))
			{
				s_lastStaticList[(int)kind] = array;
				s_nextStaticResend[(int)kind] = Time.time + 15f;
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "NameMoreThings_List", new object[1] { val });
			}
		}

		private static ZPackage BuildList(NamedKind kind)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			List<ZDO> list = s_send[(int)kind];
			int num = ((kind == NamedKind.Portal) ? ZDOVars.s_tag : NameData.NameKey);
			int num2 = ((kind == NamedKind.Portal) ? ZDOVars.s_tagauthor : NameData.AuthorKey);
			ZPackage val = new ZPackage();
			val.Write(2);
			val.Write((int)kind);
			val.Write(list.Count);
			foreach (ZDO item in list)
			{
				val.Write(item.m_uid);
				val.Write(item.GetLong(NameData.UidKey, 0L));
				val.Write(item.GetString(num, ""));
				val.Write(item.GetString(num2, ""));
				val.Write(item.GetPosition());
				val.Write(item.GetPrefab());
			}
			return val;
		}

		private static bool SameBytes(byte[] a, byte[] b)
		{
			if (a == null || b == null || a.Length != b.Length)
			{
				return false;
			}
			for (int i = 0; i < a.Length; i++)
			{
				if (a[i] != b[i])
				{
					return false;
				}
			}
			return true;
		}

		private static void RPC_Track(long sender, ZDOID id)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				Track(id);
			}
		}

		private static void RPC_List(long sender, ZPackage pkg)
		{
			//IL_0067: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated() || sender != ZRoutedRpc.instance.GetServerPeerID() || pkg.ReadInt() != 2)
			{
				return;
			}
			int num = pkg.ReadInt();
			if (num >= 0 && num < Remotes.Length)
			{
				s_serverHasMod = true;
				Dictionary<ZDOID, Remote> dictionary = Remotes[num];
				dictionary.Clear();
				int num2 = pkg.ReadInt();
				for (int i = 0; i < num2; i++)
				{
					ZDOID key = pkg.ReadZDOID();
					long uid = pkg.ReadLong();
					string raw = pkg.ReadString();
					string author = pkg.ReadString();
					Vector3 position = pkg.ReadVector3();
					int prefab = pkg.ReadInt();
					dictionary[key] = new Remote
					{
						Uid = uid,
						Name = NameData.Display(raw, author),
						Position = position,
						Prefab = prefab
					};
				}
			}
		}
	}
	[HarmonyPatch(typeof(Ship), "Awake")]
	internal static class ShipAwakePatch
	{
		private static void Postfix(Ship __instance)
		{
			Patches.AddNamedObject(__instance.m_nview);
		}
	}
	[HarmonyPatch(typeof(Door), "Awake")]
	internal static class DoorAwakePatch
	{
		private static void Postfix(Door __instance)
		{
			Patches.AddNamedObject(__instance.m_nview);
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "Interact")]
	internal static class RudderInteractPatch
	{
		private static bool Prefix(ShipControlls __instance, Humanoid character, bool repeat, bool alt, ref bool __result)
		{
			return Patches.TryGamepadName(Object.op_Implicit((Object)(object)__instance.m_ship) ? ((Component)__instance.m_ship).GetComponent<NamedObject>() : null, character, repeat, alt, ref __result);
		}
	}
	[HarmonyPatch(typeof(Door), "Interact")]
	internal static class DoorInteractPatch
	{
		private static bool Prefix(Door __instance, Humanoid character, bool hold, bool alt, ref bool __result)
		{
			return Patches.TryGamepadName(((Component)__instance).GetComponent<NamedObject>(), character, hold, alt, ref __result);
		}
	}
	[HarmonyPatch(typeof(ShipControlls), "GetHoverText")]
	internal static class RudderHoverTextPatch
	{
		private static void Postfix(ShipControlls __instance, ref string __result)
		{
			NamedObject target = (Object.op_Implicit((Object)(object)__instance.m_ship) ? ((Component)__instance.m_ship).GetComponent<NamedObject>() : null);
			bool inRange = (Object)(object)Player.m_localPlayer != (Object)null && __instance.InUseDistance((Humanoid)(object)Player.m_localPlayer);
			Patches.AddHoverText(target, inRange, ref __result);
		}
	}
	[HarmonyPatch(typeof(Door), "GetHoverText")]
	internal static class DoorHoverTextPatch
	{
		private static void Postfix(Door __instance, ref string __result)
		{
			if (!string.IsNullOrEmpty(__result))
			{
				Patches.AddHoverText(((Component)__instance).GetComponent<NamedObject>(), inRange: true, ref __result);
			}
		}
	}
	internal static class Patches
	{
		public static void AddNamedObject(ZNetView nview)
		{
			if (Object.op_Implicit((Object)(object)nview) && nview.GetZDO() != null && !Object.op_Implicit((Object)(object)((Component)nview).GetComponent<NamedObject>()))
			{
				((Component)nview).gameObject.AddComponent<NamedObject>();
			}
		}

		public static bool TryGamepadName(NamedObject target, Humanoid character, bool hold, bool alt, ref bool result)
		{
			if (!alt || !ZInput.IsGamepadActive() || (Object)(object)target == (Object)null || !target.IsValid || !NameDialog.CanOpen(target))
			{
				return true;
			}
			result = !hold && NameDialog.Open(target, character);
			return false;
		}

		public static void AddHoverText(NamedObject target, bool inRange, ref string text)
		{
			if ((Object)(object)target == (Object)null || !target.IsValid)
			{
				return;
			}
			string displayName = target.DisplayName;
			if (displayName.Length > 0)
			{
				text = "<b>" + displayName + "</b>\n" + text;
			}
			if (!inRange)
			{
				return;
			}
			bool flag = NameDialog.CanRename(target, flash: false);
			if (flag || target.HasName)
			{
				string text2 = ((!ZInput.IsGamepadActive()) ? ZInput.instance.GetBoundKeyString(Plugin.NameButton.Name, true) : (ZInput.IsNonClassicFunctionality() ? "$KEY_AltKeys + $KEY_Use" : "$KEY_AltPlace + $KEY_Use"));
				if (text2.Length != 0)
				{
					string text3 = ((!flag) ? "$namemorethings_display" : ((target.Kind == NamedKind.Boat) ? "$namemorethings_name_boat" : "$namemorethings_name_door"));
					text += Localization.instance.Localize("\n[<color=yellow><b>" + text2 + "</b></color>] " + text3);
				}
			}
		}
	}
	[BepInPlugin("com.lhoffl.NameMoreThings", "NameMoreThings", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.lhoffl.NameMoreThings";

		public const string PluginName = "NameMoreThings";

		public const string PluginVersion = "1.2.0";

		internal static ManualLogSource Log;

		internal static ButtonConfig NameButton;

		private Harmony _harmony;

		private FileSystemWatcher _configWatcher;

		private volatile bool _configFileChanged;

		private void Awake()
		{
			//IL_001b: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			AddTranslations();
			NameButton = new ButtonConfig
			{
				Name = "Name",
				Config = ModConfig.NameKey
			};
			InputManager.Instance.AddButton("com.lhoffl.NameMoreThings", NameButton);
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.lhoffl.NameMoreThings");
			WatchConfigFile();
		}

		private void Update()
		{
			if (_configFileChanged)
			{
				_configFileChanged = false;
				((BaseUnityPlugin)this).Config.Reload();
				Log.LogInfo((object)"Config reloaded");
			}
			NameTracker.Update();
			NameDialog.Update();
		}

		private void OnDestroy()
		{
			_configWatcher?.Dispose();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void AddTranslations()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "namemorethings_topic_boat", "Boat name" },
				{ "namemorethings_topic_door", "Door name" },
				{ "namemorethings_name_boat", "Name boat" },
				{ "namemorethings_name_door", "Name door" },
				{ "namemorethings_display", "Display options" },
				{ "namemorethings_show_name", "Show name above boat" },
				{ "namemorethings_show_on_map", "Show on map" }
			});
		}

		private void WatchConfigFile()
		{
			string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
			_configWatcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath))
			{
				NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite),
				IncludeSubdirectories = false,
				EnableRaisingEvents = true
			};
			_configWatcher.Changed += delegate
			{
				_configFileChanged = true;
			};
			_configWatcher.Created += delegate
			{
				_configFileChanged = true;
			};
			_configWatcher.Renamed += delegate
			{
				_configFileChanged = true;
			};
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}