Decompiled source of SettlementCharts v0.1.2

plugins/SettlementCharts.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("SettlementCharts")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2")]
[assembly: AssemblyProduct("SettlementCharts")]
[assembly: AssemblyTitle("Settlement Charts")]
[assembly: AssemblyVersion("0.1.2.0")]
[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 SettlementCharts
{
	internal struct ChartedSettlement
	{
		internal Vector3 Position;

		internal string Name;
	}
	internal static class ChartedPins
	{
		internal const string RpcName = "MW_ChartedSettlements";

		private const float PollSeconds = 5f;

		private static float _nextPoll;

		private static string _lastSignature = null;

		private static readonly List<PinData> OurPins = new List<PinData>();

		internal static void Register()
		{
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<ZPackage>("MW_ChartedSettlements", (Action<long, ZPackage>)OnReceive);
			}
		}

		internal static void ServerPoll()
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null || Time.time < _nextPoll)
			{
				return;
			}
			_nextPoll = Time.time + 5f;
			List<ChartedSettlement> list = Collect();
			string text = Signature(list);
			if (!(text == _lastSignature))
			{
				_lastSignature = text;
				Broadcast(list);
				if (ChartsPlugin.Verbose.Value)
				{
					ChartsPlugin.Log.LogInfo((object)$"[charts] broadcasting {list.Count} charted settlement(s).");
				}
			}
		}

		private static List<ChartedSettlement> Collect()
		{
			//IL_006c: 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)
			List<ChartedSettlement> list = new List<ChartedSettlement>();
			List<ZDO> list2 = new List<ZDO>();
			int num = 0;
			while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(ChartRegistry.TablePrefab, list2, ref num) && list2.Count <= 20000)
			{
			}
			foreach (ZDO item in list2)
			{
				if (item != null && item.IsValid() && item.GetBool(ChartRegistry.ChartedHash, false))
				{
					list.Add(new ChartedSettlement
					{
						Position = item.GetPosition(),
						Name = item.GetString("MW_SettlementName", ChartsPlugin.DefaultPinName.Value)
					});
				}
			}
			return list;
		}

		private static string Signature(List<ChartedSettlement> list)
		{
			//IL_002b: 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)
			StringBuilder stringBuilder = new StringBuilder();
			foreach (ChartedSettlement item in list)
			{
				stringBuilder.Append(item.Name).Append('@').Append(Mathf.RoundToInt(item.Position.x))
					.Append(',')
					.Append(Mathf.RoundToInt(item.Position.z))
					.Append(';');
			}
			return stringBuilder.ToString();
		}

		private static void Broadcast(List<ChartedSettlement> charted)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(charted.Count);
			foreach (ChartedSettlement item in charted)
			{
				val.Write(item.Position);
				val.Write(item.Name ?? string.Empty);
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "MW_ChartedSettlements", new object[1] { val });
		}

		private static void OnReceive(long sender, ZPackage pkg)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (pkg != null)
			{
				List<ChartedSettlement> list = new List<ChartedSettlement>();
				int num = pkg.ReadInt();
				for (int i = 0; i < num; i++)
				{
					Vector3 position = pkg.ReadVector3();
					string name = pkg.ReadString();
					list.Add(new ChartedSettlement
					{
						Position = position,
						Name = name
					});
				}
				Apply(list);
			}
		}

		private static void Apply(List<ChartedSettlement> charted)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				return;
			}
			ClearPins();
			PinType val = (PinType)ChartsPlugin.PinType.Value;
			foreach (ChartedSettlement item in charted)
			{
				string text = (string.IsNullOrEmpty(item.Name) ? ChartsPlugin.DefaultPinName.Value : item.Name);
				PinData val2 = Minimap.instance.AddPin(item.Position, val, text, false, false, 0L, default(PlatformUserID));
				if (val2 != null)
				{
					val2.m_doubleSize = ChartsPlugin.PinDoubleSize.Value;
					OurPins.Add(val2);
				}
			}
			if (ChartsPlugin.Verbose.Value)
			{
				ChartsPlugin.Log.LogInfo((object)$"[charts] map now shows {OurPins.Count} charted settlement(s).");
			}
		}

		internal static void ClearPins()
		{
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				OurPins.Clear();
				return;
			}
			foreach (PinData ourPin in OurPins)
			{
				if (ourPin != null)
				{
					Minimap.instance.RemovePin(ourPin);
				}
			}
			OurPins.Clear();
		}
	}
	internal class ChartNameReceiver : TextReceiver
	{
		private readonly MapTable _table;

		internal ChartNameReceiver(MapTable table)
		{
			_table = table;
		}

		public string GetText()
		{
			string name = ChartRegistry.GetName(_table);
			if (!string.IsNullOrEmpty(name))
			{
				return name;
			}
			return string.Empty;
		}

		public void SetText(string text)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			string text2 = (text ?? string.Empty).Trim();
			if (string.IsNullOrEmpty(text2))
			{
				text2 = ChartsPlugin.DefaultPinName.Value;
			}
			if (!ChartRegistry.ChartWithName(_table, text2))
			{
				ChartsPlugin.Log.LogWarning((object)"[charts] could not chart the table — it went out of scope.");
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				((Character)localPlayer).Message((MessageType)2, ChartsPlugin.MessageLit.Value, 0, (Sprite)null);
			}
			ChartsPlugin.Log.LogInfo((object)$"[charts] charted '{text2}' at {((Component)_table).transform.position}.");
		}
	}
	[BepInPlugin("mistwalkers.settlementcharts", "Settlement Charts", "0.1.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class ChartsPlugin : BaseUnityPlugin
	{
		public const string GUID = "mistwalkers.settlementcharts";

		public const string NAME = "Settlement Charts";

		public const string VERSION = "0.1.2";

		internal static ManualLogSource Log;

		internal static ConfigEntry<float> ChartRadius;

		internal static ConfigEntry<float> EventRadius;

		internal static ConfigEntry<int> MinPlayers;

		internal static ConfigEntry<float> ChartReach;

		internal static ConfigEntry<KeyCode> ChartModifier;

		internal static ConfigEntry<bool> Verbose;

		internal static ConfigEntry<string> HoverDark;

		internal static ConfigEntry<string> HoverLit;

		internal static ConfigEntry<string> MessageLit;

		internal static ConfigEntry<string> MessageDark;

		internal static ConfigEntry<string> MessageDarkDuringRaid;

		internal static ConfigEntry<string> StatusSuffix;

		internal static ConfigEntry<string> DefaultPinName;

		internal static ConfigEntry<int> PinType;

		internal static ConfigEntry<bool> PinDoubleSize;

		internal static ConfigEntry<int> NameCharLimit;

		internal static ConfigEntry<string> DialogTopic;

		private bool _rpcRegistered;

		private void Awake()
		{
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ChartRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Charting", "chartRadius", 120f, "Max distance from a charted table for a settlement raid to be selected.");
			EventRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Charting", "eventRadius", 120f, "Raid area radius for settlement raids. Vanilla is 96. Match chartRadius to keep one circle.");
			MinPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("Charting", "minPlayersInRadius", 1, "Players required near a charted table for it to be raided. Set 2 to spare solo players.");
			ChartModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "chartModifierKey", (KeyCode)304, "Held with Use to chart a settlement. Better Cartography Table uses LeftShift too; change one if you enable guilds.");
			ChartReach = ((BaseUnityPlugin)this).Config.Bind<float>("Charting", "chartReach", 15f, "Range of the 'chart' console command.");
			Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "verboseLogging", true, "Log raid selection decisions.");
			HoverDark = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "hoverTextDark", "Chart this settlement", "Prompt shown on an uncharted table.");
			HoverLit = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "hoverTextLit", "Erase from the charts", "Prompt shown on a charted table.");
			MessageLit = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "messageLit", "This settlement is charted. It will be found.", "Message shown when charting.");
			MessageDark = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "messageDark", "Erased from the charts.", "Message shown when erasing.");
			MessageDarkDuringRaid = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "messageDarkDuringRaid", "Erased from the charts. What is already coming will not turn back.", "Message shown when erasing during a raid. Erasing never stops the raid already running.");
			DefaultPinName = ((BaseUnityPlugin)this).Config.Bind<string>("Map", "defaultPinName", "Charted settlement", "Pin label when the name is left blank.");
			PinType = ((BaseUnityPlugin)this).Config.Bind<int>("Map", "pinType", 3, "Minimap pin icon index, 0-4.");
			PinDoubleSize = ((BaseUnityPlugin)this).Config.Bind<bool>("Map", "pinDoubleSize", true, "Draw settlement pins at double size.");
			NameCharLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Map", "nameCharLimit", 24, "Max settlement name length.");
			DialogTopic = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "dialogTopic", "Name this settlement", "Naming dialog heading.");
			StatusSuffix = ((BaseUnityPlugin)this).Config.Bind<string>("Text", "statusSuffix", " <color=#E0A053>(charted)</color>", "Appended to hover text while charted.");
			new Harmony("mistwalkers.settlementcharts").PatchAll();
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartListCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartCheckCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartEventsCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartForceCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartTimerCommand());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ChartDiagCommand());
			Log.LogInfo((object)"Settlement Charts 0.1.2 loaded.");
		}

		private void Update()
		{
			if (!_rpcRegistered && ZRoutedRpc.instance != null)
			{
				ChartedPins.Register();
				_rpcRegistered = true;
				Log.LogInfo((object)"[charts] charted-settlement RPC registered.");
			}
			if (_rpcRegistered && ZRoutedRpc.instance == null)
			{
				_rpcRegistered = false;
				ChartedPins.ClearPins();
			}
			ChartedPins.ServerPoll();
		}
	}
	internal static class ChartRegistry
	{
		internal static readonly int ChartedHash = StringExtensionMethods.GetStableHashCode("MW_Charted");

		internal const string NameKey = "MW_SettlementName";

		private static bool _prefabLearned;

		private static readonly List<MapTable> Tables = new List<MapTable>();

		private static readonly Dictionary<Switch, MapTable> SwitchOwners = new Dictionary<Switch, MapTable>();

		internal static string TablePrefab { get; private set; } = "piece_cartographytable";

		private static void LearnPrefab(MapTable table)
		{
			if (_prefabLearned || (Object)(object)table == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)table).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && AccessTools.Method(typeof(ZNetView), "GetPrefabName", (Type[])null, (Type[])null)?.Invoke(component, null) is string text && !string.IsNullOrEmpty(text))
			{
				if (text != TablePrefab)
				{
					ChartsPlugin.Log.LogWarning((object)("[charts] table prefab is '" + text + "', not '" + TablePrefab + "'. Using the live value."));
				}
				TablePrefab = text;
				_prefabLearned = true;
			}
		}

		internal static string GetName(MapTable table)
		{
			ZNetView val = View(table);
			if ((Object)(object)val == (Object)null)
			{
				return string.Empty;
			}
			return val.GetZDO().GetString("MW_SettlementName", string.Empty);
		}

		internal static bool ChartWithName(MapTable table, string name)
		{
			ZNetView val = View(table);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			val.ClaimOwnership();
			val.GetZDO().Set("MW_SettlementName", name ?? string.Empty);
			val.GetZDO().Set(ChartedHash, true);
			return true;
		}

		internal static bool Erase(MapTable table)
		{
			ZNetView val = View(table);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			val.ClaimOwnership();
			val.GetZDO().Set(ChartedHash, false);
			return true;
		}

		internal static void Register(MapTable table)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)table == (Object)null))
			{
				if (!Tables.Contains(table))
				{
					Tables.Add(table);
				}
				if ((Object)(object)table.m_readSwitch != (Object)null)
				{
					SwitchOwners[table.m_readSwitch] = table;
				}
				LearnPrefab(table);
				ChartsPlugin.Log.LogInfo((object)($"[charts] registered table at {((Component)table).transform.position} " + "(readSwitch=" + (((Object)(object)table.m_readSwitch != (Object)null) ? ((Object)table.m_readSwitch).name : "null") + ", writeSwitch=" + (((Object)(object)table.m_writeSwitch != (Object)null) ? ((Object)table.m_writeSwitch).name : "null") + ")."));
			}
		}

		internal static MapTable OwnerOf(Switch sw)
		{
			if ((Object)(object)sw == (Object)null)
			{
				return null;
			}
			if (!SwitchOwners.TryGetValue(sw, out var value))
			{
				return null;
			}
			if ((Object)(object)value == (Object)null)
			{
				SwitchOwners.Remove(sw);
				return null;
			}
			return value;
		}

		private static ZNetView View(MapTable table)
		{
			if ((Object)(object)table == (Object)null)
			{
				return null;
			}
			ZNetView component = ((Component)table).GetComponent<ZNetView>();
			if (!((Object)(object)component != (Object)null) || !component.IsValid())
			{
				return null;
			}
			return component;
		}

		internal static bool IsCharted(MapTable table)
		{
			ZNetView val = View(table);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			return val.GetZDO().GetBool(ChartedHash, false);
		}

		internal static bool Toggle(MapTable table, out bool lit)
		{
			lit = false;
			ZNetView val = View(table);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			val.ClaimOwnership();
			lit = !val.GetZDO().GetBool(ChartedHash, false);
			val.GetZDO().Set(ChartedHash, lit);
			return true;
		}

		internal static MapTable FindLitTableNear(Vector3 pos, float radius)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			MapTable result = null;
			float num = radius * radius;
			for (int num2 = Tables.Count - 1; num2 >= 0; num2--)
			{
				MapTable val = Tables[num2];
				if ((Object)(object)val == (Object)null)
				{
					Tables.RemoveAt(num2);
				}
				else if (IsCharted(val))
				{
					Vector3 val2 = ((Component)val).transform.position - pos;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude <= num)
					{
						num = sqrMagnitude;
						result = val;
					}
				}
			}
			return result;
		}

		internal static MapTable FindNearestTable(Vector3 pos, float radius)
		{
			//IL_003d: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			MapTable result = null;
			float num = radius * radius;
			for (int num2 = Tables.Count - 1; num2 >= 0; num2--)
			{
				MapTable val = Tables[num2];
				if ((Object)(object)val == (Object)null)
				{
					Tables.RemoveAt(num2);
				}
				else
				{
					Vector3 val2 = ((Component)val).transform.position - pos;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude <= num)
					{
						num = sqrMagnitude;
						result = val;
					}
				}
			}
			return result;
		}

		internal static List<MapTable> AllLive()
		{
			for (int num = Tables.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)Tables[num] == (Object)null)
				{
					Tables.RemoveAt(num);
				}
			}
			return Tables;
		}

		internal static int CountPlayersNear(Vector3 pos, float radius)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			int num = 0;
			float num2 = radius * radius;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (!((Object)(object)allPlayer == (Object)null))
				{
					Vector3 val = ((Component)allPlayer).transform.position - pos;
					if (((Vector3)(ref val)).sqrMagnitude <= num2)
					{
						num++;
					}
				}
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(MapTable), "Start")]
	internal static class MapTableStartPatch
	{
		private static void Postfix(MapTable __instance)
		{
			ChartRegistry.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(MapTable), "GetReadHoverText")]
	internal static class MapTableReadHoverPatch
	{
		private static void Postfix(MapTable __instance, ref string __result)
		{
			HoverText.Append(__instance, ref __result);
		}
	}
	internal static class HoverText
	{
		internal static void Append(MapTable table, ref string result)
		{
			if ((Object)(object)table == (Object)null || result == null)
			{
				return;
			}
			bool num = ChartRegistry.IsCharted(table);
			string text = (num ? ChartsPlugin.HoverLit.Value : ChartsPlugin.HoverDark.Value);
			if (num && !string.IsNullOrEmpty(ChartsPlugin.StatusSuffix.Value))
			{
				int num2 = result.IndexOf('\n');
				if (num2 >= 0)
				{
					result = result.Insert(num2, ChartsPlugin.StatusSuffix.Value);
				}
				else
				{
					result += ChartsPlugin.StatusSuffix.Value;
				}
			}
			string text2 = "\n[<color=yellow><b>" + ModifierLabel() + " + $KEY_Use</b></color>] " + text;
			result += ((Localization.instance != null) ? Localization.instance.Localize(text2) : text2);
		}

		private static string ModifierLabel()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			string text = ((object)ChartsPlugin.ChartModifier.Value/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Left"))
			{
				return text.Substring(4);
			}
			if (text.StartsWith("Right"))
			{
				return text.Substring(5);
			}
			return text;
		}
	}
	[HarmonyPatch(typeof(Switch), "Interact")]
	internal static class SwitchInteractPatch
	{
		private const float DebounceSeconds = 1f;

		private static float _lastToggle = -99f;

		private static bool Prefix(Switch __instance, Humanoid character, bool hold, bool alt, ref bool __result)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			MapTable val = ChartRegistry.OwnerOf(__instance);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			bool key = Input.GetKey(ChartsPlugin.ChartModifier.Value);
			if (ChartsPlugin.Verbose.Value)
			{
				ChartsPlugin.Log.LogInfo((object)$"[charts] Switch.Interact on a cartography table: hold={hold}, alt={alt}, modifier={key}.");
			}
			if (!key && !hold)
			{
				return true;
			}
			if (Time.time - _lastToggle < 1f)
			{
				__result = false;
				return false;
			}
			_lastToggle = Time.time;
			if (ChartRegistry.IsCharted(val))
			{
				if (!ChartRegistry.Erase(val))
				{
					if (character != null)
					{
						((Character)character).Message((MessageType)2, "The table is not ready yet.", 0, (Sprite)null);
					}
					__result = false;
					return false;
				}
				bool flag = RandEventSystem.HaveActiveEvent();
				if (character != null)
				{
					((Character)character).Message((MessageType)2, flag ? ChartsPlugin.MessageDarkDuringRaid.Value : ChartsPlugin.MessageDark.Value, 0, (Sprite)null);
				}
				ChartsPlugin.Log.LogInfo((object)$"[charts] table at {((Component)val).transform.position} erased from the charts.");
			}
			else if ((Object)(object)TextInput.instance == (Object)null)
			{
				ChartRegistry.ChartWithName(val, ChartsPlugin.DefaultPinName.Value);
				if (character != null)
				{
					((Character)character).Message((MessageType)2, ChartsPlugin.MessageLit.Value, 0, (Sprite)null);
				}
				ChartsPlugin.Log.LogWarning((object)"[charts] TextInput unavailable, charted under the default name.");
			}
			else
			{
				TextInput.instance.RequestText((TextReceiver)(object)new ChartNameReceiver(val), ChartsPlugin.DialogTopic.Value, ChartsPlugin.NameCharLimit.Value);
			}
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "GetPossibleRandomEvents")]
	internal static class GetPossibleRandomEventsPatch
	{
		private static void Postfix(List<KeyValuePair<RandomEvent, Vector3>> __result)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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)
			if (__result == null || __result.Count == 0 || ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()))
			{
				return;
			}
			bool value = ChartsPlugin.Verbose.Value;
			List<KeyValuePair<RandomEvent, Vector3>> list = new List<KeyValuePair<RandomEvent, Vector3>>(__result.Count);
			foreach (KeyValuePair<RandomEvent, Vector3> item in __result)
			{
				RandomEvent key = item.Key;
				if (key == null)
				{
					continue;
				}
				if (!key.m_nearBaseOnly)
				{
					list.Add(item);
					continue;
				}
				MapTable val = ChartRegistry.FindLitTableNear(item.Value, ChartsPlugin.ChartRadius.Value);
				if ((Object)(object)val == (Object)null)
				{
					if (value)
					{
						ChartsPlugin.Log.LogInfo((object)$"[charts] '{key.m_name}' dropped: no charted table within {ChartsPlugin.ChartRadius.Value}m.");
					}
					continue;
				}
				Vector3 position = ((Component)val).transform.position;
				int num = ChartRegistry.CountPlayersNear(position, ChartsPlugin.EventRadius.Value);
				if (num < ChartsPlugin.MinPlayers.Value)
				{
					if (value)
					{
						ChartsPlugin.Log.LogInfo((object)$"[charts] '{key.m_name}' dropped: {num} player(s) at the charted table, needs {ChartsPlugin.MinPlayers.Value}.");
					}
					continue;
				}
				key.m_eventRange = ChartsPlugin.EventRadius.Value;
				list.Add(new KeyValuePair<RandomEvent, Vector3>(key, position));
				if (value)
				{
					ChartsPlugin.Log.LogInfo((object)$"[charts] '{key.m_name}' allowed at charted table {position}, range {ChartsPlugin.EventRadius.Value}m, {num} player(s) present.");
				}
			}
			__result.Clear();
			__result.AddRange(list);
		}
	}
	internal class ChartCommand : ConsoleCommand
	{
		public override string Name => "chart";

		public override string Help => "Chart or erase the nearest cartography table.";

		public override void Run(string[] args)
		{
			//IL_0030: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				Console.instance.Print("No local player.");
				return;
			}
			float value = ChartsPlugin.ChartReach.Value;
			MapTable val = ChartRegistry.FindNearestTable(((Component)localPlayer).transform.position, value);
			if ((Object)(object)val == (Object)null)
			{
				Console.instance.Print($"No cartography table within {value}m.");
				return;
			}
			if (!ChartRegistry.Toggle(val, out var lit))
			{
				Console.instance.Print("That table is not ready yet, try again in a moment.");
				return;
			}
			string text = (lit ? "This settlement is charted. It will be found." : "Erased from the charts. This settlement is not a target.");
			Console.instance.Print(text);
			((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null);
			ChartsPlugin.Log.LogInfo((object)string.Format("[charts] table at {0} set to {1}.", ((Component)val).transform.position, lit ? "LIT" : "DARK"));
		}
	}
	internal class ChartCheckCommand : ConsoleCommand
	{
		public override string Name => "chartcheck";

		public override string Help => "Report whether a raid could fire here.";

		public override void Run(string[] args)
		{
			//IL_0025: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_00f0: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				Console.instance.Print("No local player.");
				return;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			float value = ChartsPlugin.ChartRadius.Value;
			float value2 = ChartsPlugin.EventRadius.Value;
			int value3 = ChartsPlugin.MinPlayers.Value;
			Console.instance.Print($"--- chart check at ({position.x:F0}, {position.z:F0}) ---");
			Console.instance.Print($"chartRadius {value}m / eventRadius {value2}m / minPlayers {value3}");
			MapTable val = ChartRegistry.FindLitTableNear(position, value);
			if ((Object)(object)val == (Object)null)
			{
				MapTable val2 = ChartRegistry.FindNearestTable(position, value);
				if ((Object)(object)val2 == (Object)null)
				{
					Console.instance.Print($"NO charted table within {value}m (no table at all in range).");
				}
				else
				{
					Console.instance.Print($"NO charted table within {value}m (nearest table is {Vector3.Distance(position, ((Component)val2).transform.position):F0}m away and dark).");
				}
				Console.instance.Print("VERDICT: settlement raids blocked here. Wilderness events unaffected.");
				return;
			}
			Vector3 position2 = ((Component)val).transform.position;
			float num = Vector3.Distance(position, position2);
			int num2 = ChartRegistry.CountPlayersNear(position2, value2);
			Console.instance.Print($"Charted table {num:F0}m away at ({position2.x:F0}, {position2.z:F0}).");
			Console.instance.Print($"Players within {value2}m of it: {num2} (needs {value3}).");
			if (num2 < value3)
			{
				Console.instance.Print("VERDICT: settlement raids blocked here, not enough players at the table.");
			}
			else
			{
				Console.instance.Print($"VERDICT: settlement raids ALLOWED, anchored on the table at range {value2}m.");
			}
		}
	}
	internal class ChartEventsCommand : ConsoleCommand
	{
		public override string Name => "chartevents";

		public override string Help => "Print which events survive the filter.";

		public override void Run(string[] args)
		{
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: 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)
			object obj = AccessTools.Field(typeof(RandEventSystem), "m_instance")?.GetValue(null);
			if (obj == null)
			{
				Console.instance.Print("RandEventSystem instance not available.");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(RandEventSystem), "GetPossibleRandomEvents", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Console.instance.Print("Could not resolve GetPossibleRandomEvents.");
				return;
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (parameters.Length != 0)
			{
				Console.instance.Print($"GetPossibleRandomEvents expects {parameters.Length} argument(s) — cannot invoke blind:");
				ParameterInfo[] array = parameters;
				foreach (ParameterInfo parameterInfo in array)
				{
					Console.instance.Print("  " + parameterInfo.ParameterType.Name + " " + parameterInfo.Name);
				}
				return;
			}
			object obj2;
			try
			{
				obj2 = methodInfo.Invoke(obj, null);
			}
			catch (Exception ex)
			{
				Console.instance.Print("Invoke failed: " + (ex.InnerException?.Message ?? ex.Message));
				return;
			}
			if (!(obj2 is List<KeyValuePair<RandomEvent, Vector3>> list))
			{
				Console.instance.Print("Unexpected return type: " + (obj2?.GetType().Name ?? "null"));
				return;
			}
			if (list.Count == 0)
			{
				Console.instance.Print("No events survive the filter here. Chart a table and stand at it.");
				return;
			}
			Console.instance.Print($"{list.Count} event(s) currently possible:");
			foreach (KeyValuePair<RandomEvent, Vector3> item in list)
			{
				RandomEvent key = item.Key;
				Vector3 value = item.Value;
				string text = (key.m_nearBaseOnly ? "settlement" : "WILDERNESS");
				Console.instance.Print($"  {key.m_name}  [{text}]  anchor ({value.x:F0}, {value.z:F0})  range {key.m_eventRange:F0}m");
			}
		}
	}
	internal class ChartForceCommand : ConsoleCommand
	{
		public override string Name => "chartforce";

		public override string Help => "Roll for a raid now, through the filter.";

		public override void Run(string[] args)
		{
			RandEventSystem instance = RandEventSystem.instance;
			if ((Object)(object)instance == (Object)null)
			{
				Console.instance.Print("RandEventSystem not available.");
				return;
			}
			if (RandEventSystem.HaveActiveEvent())
			{
				Console.instance.Print("An event is already running. Wait for it to finish.");
				return;
			}
			instance.StartRandomEvent();
			RandomEvent currentRandomEvent = instance.GetCurrentRandomEvent();
			if (currentRandomEvent == null)
			{
				Console.instance.Print("Rolled, but nothing survived the filter here. Chart a table and stand at it.");
				return;
			}
			Console.instance.Print($"Started '{currentRandomEvent.m_name}' at ({currentRandomEvent.m_pos.x:F0}, {currentRandomEvent.m_pos.z:F0}), range {currentRandomEvent.m_eventRange:F0}m.");
		}
	}
	internal class ChartTimerCommand : ConsoleCommand
	{
		public override string Name => "charttimer";

		public override string Help => "Show or set roll interval in minutes and chance in percent.";

		public override void Run(string[] args)
		{
			RandEventSystem instance = RandEventSystem.instance;
			if ((Object)(object)instance == (Object)null)
			{
				Console.instance.Print("RandEventSystem not available.");
				return;
			}
			if (args.Length == 0)
			{
				Console.instance.Print($"interval {instance.m_eventIntervalMin} min / chance {instance.m_eventChance}%");
				Console.instance.Print("Set with: charttimer <minutes> [percent]");
				return;
			}
			if (!float.TryParse(args[0], out var result))
			{
				Console.instance.Print("'" + args[0] + "' is not a number.");
				return;
			}
			instance.m_eventIntervalMin = result;
			if (args.Length > 1)
			{
				if (!float.TryParse(args[1], out var result2))
				{
					Console.instance.Print("'" + args[1] + "' is not a number.");
					return;
				}
				instance.m_eventChance = result2;
			}
			Console.instance.Print($"interval {instance.m_eventIntervalMin} min / chance {instance.m_eventChance}% — testing only, restore before this world matters.");
		}
	}
	internal class ChartDiagCommand : ConsoleCommand
	{
		public override string Name => "chartdiag";

		public override string Help => "Probe prefab name and minimap availability.";

		public override void Run(string[] args)
		{
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: 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)
			Console.instance.Print("--- prefab ---");
			List<MapTable> list = ChartRegistry.AllLive();
			if (list.Count == 0)
			{
				Console.instance.Print("No tables loaded — stand near one and run this again.");
			}
			else
			{
				ZNetView component = ((Component)list[0]).GetComponent<ZNetView>();
				if ((Object)(object)component == (Object)null || !component.IsValid())
				{
					Console.instance.Print("Table has no valid ZNetView.");
				}
				else
				{
					string text = (AccessTools.Method(typeof(ZNetView), "GetPrefabName", (Type[])null, (Type[])null)?.Invoke(component, null) as string) ?? "<reflection failed>";
					Console.instance.Print("prefab name : " + text);
					Console.instance.Print($"prefab hash : {component.GetZDO().GetPrefab()}");
					Console.instance.Print($"name hash   : {StringExtensionMethods.GetStableHashCode(text)} (should match)");
				}
			}
			Console.instance.Print("--- minimap ---");
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				Console.instance.Print("Minimap.instance is NULL — pins are impossible, we would need BCT's system.");
				return;
			}
			Console.instance.Print("Minimap.instance present.");
			try
			{
				Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero);
				PinData val2 = Minimap.instance.AddPin(val, (PinType)3, "chart test", false, false, 0L, default(PlatformUserID));
				if (val2 == null)
				{
					Console.instance.Print("AddPin returned null — pins rejected under this configuration.");
					return;
				}
				Console.instance.Print("AddPin OK. Removing test pin.");
				Minimap.instance.RemovePin(val2);
				Console.instance.Print("RemovePin OK. Global markers are viable.");
			}
			catch (Exception ex)
			{
				Console.instance.Print("Pin test threw: " + ex.Message);
			}
		}
	}
	internal class ChartListCommand : ConsoleCommand
	{
		public override string Name => "chartlist";

		public override string Help => "List loaded tables and their state.";

		public override void Run(string[] args)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			List<MapTable> list = ChartRegistry.AllLive();
			if (list.Count == 0)
			{
				Console.instance.Print("No cartography tables loaded.");
				return;
			}
			Console.instance.Print($"{list.Count} table(s) loaded:");
			foreach (MapTable item in list)
			{
				Vector3 position = ((Component)item).transform.position;
				string arg = (ChartRegistry.IsCharted(item) ? "LIT " : "dark");
				Console.instance.Print($"  [{arg}] ({position.x:F0}, {position.z:F0})");
			}
		}
	}
}