Decompiled source of OneMapToRuleThemAll v2.8.1

plugins/OneMapToRuleThemAll.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("One Map To Rule Them All")]
[assembly: AssemblyDescription("Valheim One Map To Rule Them All Mod by DrummerCraig")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("One Map To Rule Them All")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6A5B7C8D-E9F0-1234-5678-9ABCDEF01234")]
[assembly: AssemblyFileVersion("2.8.1")]
[assembly: AssemblyVersion("2.8.1.0")]
namespace OneMapToRuleThemAll;

public static class AdminCommands
{
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	private static class TerminalInitPatch
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass0_0
		{
			public Vector3 origin;

			internal float <Postfix>b__21(GameObject g)
			{
				//IL_0006: 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_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = g.transform.position - origin;
				return ((Vector3)(ref val)).sqrMagnitude;
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static ConsoleEvent <>9__0_1;

			public static ConsoleEvent <>9__0_2;

			public static ConsoleEvent <>9__0_3;

			public static ConsoleEvent <>9__0_4;

			public static ConsoleEvent <>9__0_5;

			public static ConsoleEvent <>9__0_6;

			public static ConsoleEvent <>9__0_7;

			public static ConsoleEvent <>9__0_8;

			public static ConsoleEvent <>9__0_9;

			public static ConsoleEvent <>9__0_10;

			public static ConsoleEvent <>9__0_11;

			public static ConsoleEvent <>9__0_12;

			public static ConsoleEvent <>9__0_13;

			public static ConsoleEvent <>9__0_14;

			public static ConsoleEvent <>9__0_15;

			public static ConsoleEvent <>9__0_16;

			public static ConsoleEvent <>9__0_17;

			public static ConsoleEvent <>9__0_18;

			public static ConsoleEvent <>9__0_19;

			public static ConsoleEvent <>9__0_20;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				//IL_013a: 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_013f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Expected O, but got Unknown
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				if (args.Length < 2)
				{
					args.Context.AddString("Usage: om_clearpins all|type|abbr [value] [radius]");
					return;
				}
				int num;
				switch (args[1].ToLowerInvariant())
				{
				case "all":
					num = 0;
					break;
				case "type":
					num = 1;
					break;
				case "abbr":
					num = 2;
					break;
				default:
					args.Context.AddString("Usage: om_clearpins all|type|abbr [value] [radius]");
					return;
				}
				List<string> list = new List<string>();
				for (int i = 2; i < args.Length; i++)
				{
					list.Add(args[i]);
				}
				float num2 = 0f;
				if (list.Count > 0 && float.TryParse(list[list.Count - 1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && result > 0f)
				{
					num2 = result;
					list.RemoveAt(list.Count - 1);
				}
				string text = string.Join(" ", list);
				if ((num == 1 || num == 2) && text.Length == 0)
				{
					args.Context.AddString((num == 1) ? "Usage: om_clearpins type <catalog name> [radius]" : "Usage: om_clearpins abbr <abbreviation> [radius]");
					return;
				}
				Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero);
				ZPackage val2 = new ZPackage();
				val2.Write(num);
				val2.Write(text);
				val2.Write(val);
				val2.Write(num2);
				val2.SetPos(0);
				if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
				{
					OnAdminClearPins(null, val2);
					return;
				}
				ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
				if (serverRPC != null)
				{
					serverRPC.Invoke("OM_AdminClearPins", new object[1] { val2 });
				}
				args.Context.AddString("OneMapToRuleThemAll: clearing auto pins on server...");
			}

			internal void <Postfix>b__0_1(ConsoleEventArgs args)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Expected O, but got Unknown
				if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
				{
					OnAdminReloadCatalog(null, new ZPackage());
				}
				else
				{
					ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
					if (serverRPC != null)
					{
						serverRPC.Invoke("OM_AdminReloadCatalog", new object[1] { (object)new ZPackage() });
					}
				}
				args.Context.AddString("OneMapToRuleThemAll: reloading the object catalog.");
			}

			internal void <Postfix>b__0_2(ConsoleEventArgs args)
			{
				try
				{
					args.Context.AddString("OneMapToRuleThemAll fog status:");
					foreach (string item in ExplorationSynchronizer.FogStatus())
					{
						args.Context.AddString("  " + item);
					}
				}
				catch (Exception ex)
				{
					args.Context.AddString("OneMapToRuleThemAll: fog status failed: " + ex.Message);
				}
			}

			internal void <Postfix>b__0_3(ConsoleEventArgs args)
			{
				try
				{
					foreach (string item in PerfGauges.Report())
					{
						args.Context.AddString(item);
						ManualLogSource log = ModSettings.Log;
						if (log != null)
						{
							log.LogInfo((object)("[om_perf] " + item));
						}
					}
				}
				catch (Exception ex)
				{
					args.Context.AddString("OneMapToRuleThemAll: perf report failed: " + ex.Message);
				}
			}

			internal void <Postfix>b__0_4(ConsoleEventArgs args)
			{
				try
				{
					foreach (string item in MinimapScale.Report())
					{
						args.Context.AddString(item);
						ManualLogSource log = ModSettings.Log;
						if (log != null)
						{
							log.LogInfo((object)("[om_minimapinfo] " + item));
						}
					}
				}
				catch (Exception ex)
				{
					args.Context.AddString("OneMapToRuleThemAll: minimap info failed: " + ex.Message);
				}
			}

			internal void <Postfix>b__0_5(ConsoleEventArgs args)
			{
				try
				{
					foreach (string item in ResolvedIdentity.VerifyAgainstFreshClassification())
					{
						args.Context.AddString(item);
						ManualLogSource log = ModSettings.Log;
						if (log != null)
						{
							log.LogInfo((object)("[om_verifyidentity] " + item));
						}
					}
				}
				catch (Exception ex)
				{
					args.Context.AddString("OneMapToRuleThemAll: verify failed: " + ex.Message);
				}
			}

			internal void <Postfix>b__0_6(ConsoleEventArgs args)
			{
				try
				{
					CustomPrefabScanner.RescanNow();
					args.Context.AddString("OneMapToRuleThemAll: re-scanned loaded mods; catalog refreshed.");
				}
				catch (Exception ex)
				{
					args.Context.AddString("OneMapToRuleThemAll: mod scan failed: " + ex.Message);
				}
			}

			internal void <Postfix>b__0_7(ConsoleEventArgs args)
			{
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Expected O, but got Unknown
				if (args.Length < 3)
				{
					args.Context.AddString("Usage: om_setabbr <display_or_keyword> <abbr>");
					return;
				}
				string text = args[args.Length - 1];
				List<string> list = new List<string>();
				for (int i = 1; i < args.Length - 1; i++)
				{
					list.Add(args[i]);
				}
				string text2 = string.Join(" ", list);
				ZPackage val = new ZPackage();
				val.Write(text2);
				val.Write(text);
				val.SetPos(0);
				if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
				{
					OnAdminSetAbbr(null, val);
					return;
				}
				ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
				if (serverRPC != null)
				{
					serverRPC.Invoke("OM_AdminSetAbbr", new object[1] { val });
				}
			}

			internal void <Postfix>b__0_8(ConsoleEventArgs args)
			{
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Expected O, but got Unknown
				if (args.Length < 3)
				{
					args.Context.AddString("Usage: om_seticon <display_or_keyword> <itemId>  (itemId = ObjectDB item, e.g. CopperOre; 'none' to clear)");
					return;
				}
				string text = args[args.Length - 1];
				List<string> list = new List<string>();
				for (int i = 1; i < args.Length - 1; i++)
				{
					list.Add(args[i]);
				}
				string text2 = string.Join(" ", list);
				ZPackage val = new ZPackage();
				val.Write(text2);
				val.Write(text);
				val.SetPos(0);
				if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
				{
					OnAdminSetIcon(null, val);
					return;
				}
				ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
				if (serverRPC != null)
				{
					serverRPC.Invoke("OM_AdminSetIcon", new object[1] { val });
				}
			}

			internal void <Postfix>b__0_9(ConsoleEventArgs args)
			{
				if ((Object)(object)MinimapProxy.Instance == (Object)null)
				{
					args.Context.AddString("OneMapToRuleThemAll: minimap not ready.");
					return;
				}
				if (!(Traverse.Create((object)MinimapProxy.Instance).Field("m_pins").GetValue() is List<PinData> list))
				{
					args.Context.AddString("OneMapToRuleThemAll: pin list unavailable.");
					return;
				}
				bool value = AutoPinConfig.DiscoveryPinObjectIcon.Value;
				int num = 0;
				foreach (SharedPin clientPin in MapStateRepository.ClientPins)
				{
					if (clientPin.OwnerId != "auto")
					{
						continue;
					}
					string keyword = clientPin.Keyword;
					if (string.IsNullOrEmpty(keyword))
					{
						continue;
					}
					foreach (PinData item in list)
					{
						if (MapStateRepository.ArePinsEqual(clientPin, item))
						{
							if (value && RadarIconLoader.TryGetIcon(keyword, out var sprite))
							{
								item.m_icon = sprite;
							}
							num++;
							break;
						}
					}
				}
				Traverse.Create((object)MinimapProxy.Instance).Method("UpdatePins", Array.Empty<object>()).GetValue();
				args.Context.AddString($"OneMapToRuleThemAll: refreshed icons on {num} discovery pin(s).");
			}

			internal void <Postfix>b__0_10(ConsoleEventArgs args)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
				{
					OnAdminPinCounts(null, new ZPackage());
					return;
				}
				ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
				if (serverRPC != null)
				{
					serverRPC.Invoke("OM_AdminPinCounts", new object[1] { (object)new ZPackage() });
				}
				args.Context.AddString("OneMapToRuleThemAll: requesting pin counts from server...");
			}

			internal void <Postfix>b__0_11(ConsoleEventArgs args)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
				{
					OnAdminCheckDuplicates(null, new ZPackage());
					return;
				}
				ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
				if (serverRPC != null)
				{
					serverRPC.Invoke("OM_AdminCheckDuplicates", new object[1] { (object)new ZPackage() });
				}
				args.Context.AddString("OneMapToRuleThemAll: checking for duplicate pins on server...");
			}

			internal void <Postfix>b__0_12(ConsoleEventArgs args)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Expected O, but got Unknown
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
				{
					OnAdminRemoveDuplicates(null, new ZPackage());
					return;
				}
				ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
				if (serverRPC != null)
				{
					serverRPC.Invoke("OM_AdminRemoveDuplicates", new object[1] { (object)new ZPackage() });
				}
				args.Context.AddString("OneMapToRuleThemAll: removing duplicate pins on server...");
			}

			internal void <Postfix>b__0_13(ConsoleEventArgs args)
			{
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
				<>c__DisplayClass0_0 CS$<>8__locals2 = new <>c__DisplayClass0_0();
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					args.Context.AddString("OneMapToRuleThemAll: no local player.");
					return;
				}
				bool flag = args.Length >= 2;
				GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
				if ((Object)(object)hoverObject != (Object)null && !flag)
				{
					InspectObject(ObjectRootOf((Component)(object)hoverObject.transform), args.Context);
					return;
				}
				float result = 10f;
				if (args.Length >= 2)
				{
					float.TryParse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
				}
				if (result <= 0f)
				{
					result = 10f;
				}
				string arg = (flag ? "radius given" : "nothing hovered");
				args.Context.AddString($"OneMapToRuleThemAll: {arg}; scanning {result:0.#}m for nearby objects...");
				ManualLogSource log = ModSettings.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[om_inspect] {arg}; scanning {result:0.#}m radius");
				}
				Collider[] array = Physics.OverlapSphere(((Component)localPlayer).transform.position, result, -1, (QueryTriggerInteraction)2);
				HashSet<GameObject> hashSet = new HashSet<GameObject>();
				Collider[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					GameObject val = ObjectRootOf((Component)(object)array2[i]);
					if (!((Object)(object)val == (Object)null) && !IsScenery(val) && (Object)(object)val != (Object)(object)((Component)localPlayer).gameObject)
					{
						hashSet.Add(val);
					}
				}
				if (hashSet.Count == 0)
				{
					args.Context.AddString("OneMapToRuleThemAll: no colliders found nearby.");
					ManualLogSource log2 = ModSettings.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"[om_inspect] no colliders found nearby.");
					}
					return;
				}
				string text = $"{array.Length} collider(s) resolved to {hashSet.Count} object(s) " + "(terrain, clutter and your own body excluded)";
				args.Context.AddString("OneMapToRuleThemAll: " + text);
				ManualLogSource log3 = ModSettings.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)("[om_inspect] " + text));
				}
				CS$<>8__locals2.origin = ((Component)localPlayer).transform.position;
				List<GameObject> list = hashSet.OrderBy(delegate(GameObject g)
				{
					//IL_0006: 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_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val2 = g.transform.position - CS$<>8__locals2.origin;
					return ((Vector3)(ref val2)).sqrMagnitude;
				}).ToList();
				if (list.Count > 40)
				{
					string text2 = $"showing nearest {40} of {list.Count}; the rest are in the log only";
					args.Context.AddString("OneMapToRuleThemAll: " + text2);
					ManualLogSource log4 = ModSettings.Log;
					if (log4 != null)
					{
						log4.LogInfo((object)("[om_inspect] " + text2));
					}
				}
				for (int num = 0; num < list.Count; num++)
				{
					InspectObject(list[num], (num < 40) ? args.Context : null);
				}
			}

			internal void <Postfix>b__0_14(ConsoleEventArgs args)
			{
				ExportCatalog(args.Context);
			}

			internal void <Postfix>b__0_15(ConsoleEventArgs args)
			{
				AuditPins(args.Context);
			}

			internal void <Postfix>b__0_16(ConsoleEventArgs args)
			{
				RenderIcons(args.Context);
			}

			internal void <Postfix>b__0_17(ConsoleEventArgs args)
			{
				CatalogGenerator.Generate(args.Context);
			}

			internal void <Postfix>b__0_18(ConsoleEventArgs args)
			{
				ScanWearNTear(args.Context);
			}

			internal void <Postfix>b__0_19(ConsoleEventArgs args)
			{
				float result = 40f;
				if (args.Length >= 2)
				{
					float.TryParse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
				}
				if (result <= 0f)
				{
					result = 40f;
				}
				ReportWhyNoPin(args.Context, result);
			}

			internal void <Postfix>b__0_20(ConsoleEventArgs args)
			{
				float result = 50f;
				if (args.Length >= 2)
				{
					float.TryParse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
				}
				if (result <= 0f)
				{
					result = 50f;
				}
				ReportSpent(args.Context, result);
			}
		}

		private static void Postfix()
		{
			//IL_0033: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_006c: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00de: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0189: 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)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Expected O, but got Unknown
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Expected O, but got Unknown
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Expected O, but got Unknown
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Expected O, but got Unknown
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Expected O, but got Unknown
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Expected O, but got Unknown
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Expected O, but got Unknown
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Expected O, but got Unknown
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Expected O, but got Unknown
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Expected O, but got Unknown
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					//IL_013a: 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_013f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0141: Unknown result type (might be due to invalid IL or missing references)
					//IL_0148: Expected O, but got Unknown
					//IL_015b: Unknown result type (might be due to invalid IL or missing references)
					if (args.Length < 2)
					{
						args.Context.AddString("Usage: om_clearpins all|type|abbr [value] [radius]");
					}
					else
					{
						int num;
						switch (args[1].ToLowerInvariant())
						{
						case "all":
							num = 0;
							break;
						case "type":
							num = 1;
							break;
						case "abbr":
							num = 2;
							break;
						default:
							args.Context.AddString("Usage: om_clearpins all|type|abbr [value] [radius]");
							return;
						}
						List<string> list = new List<string>();
						for (int i = 2; i < args.Length; i++)
						{
							list.Add(args[i]);
						}
						float num2 = 0f;
						if (list.Count > 0 && float.TryParse(list[list.Count - 1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && result > 0f)
						{
							num2 = result;
							list.RemoveAt(list.Count - 1);
						}
						string text = string.Join(" ", list);
						if ((num == 1 || num == 2) && text.Length == 0)
						{
							args.Context.AddString((num == 1) ? "Usage: om_clearpins type <catalog name> [radius]" : "Usage: om_clearpins abbr <abbreviation> [radius]");
						}
						else
						{
							Vector3 val22 = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero);
							ZPackage val23 = new ZPackage();
							val23.Write(num);
							val23.Write(text);
							val23.Write(val22);
							val23.Write(num2);
							val23.SetPos(0);
							if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
							{
								OnAdminClearPins(null, val23);
							}
							else
							{
								ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
								if (serverRPC != null)
								{
									serverRPC.Invoke("OM_AdminClearPins", new object[1] { val23 });
								}
								args.Context.AddString("OneMapToRuleThemAll: clearing auto pins on server...");
							}
						}
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("om_clearpins", "all | type <catalog name> | abbr <abbreviation>  [radius] — remove AUTO pins only (never player pins). 'all' clears every auto pin; 'type' clears one catalog object type (e.g. Raspberries) and is the narrower form; 'abbr' clears EVERY object sharing that abbreviation, which may be more than one, since duplicate abbreviations are allowed. 'abbr' ALSO matches a pre-2.1.0 pin that carries no keyword, by its label text. Prefer 'type' when it matters. An optional trailing radius (m) limits removal to your vicinity.", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleEvent val2 = delegate(ConsoleEventArgs args)
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Expected O, but got Unknown
					//IL_0036: Unknown result type (might be due to invalid IL or missing references)
					//IL_003c: Expected O, but got Unknown
					if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
					{
						OnAdminReloadCatalog(null, new ZPackage());
					}
					else
					{
						ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
						if (serverRPC != null)
						{
							serverRPC.Invoke("OM_AdminReloadCatalog", new object[1] { (object)new ZPackage() });
						}
					}
					args.Context.AddString("OneMapToRuleThemAll: reloading the object catalog.");
				};
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("om_reloadcatalog", "Reload the object catalog file and push it (labels/abbreviations) to all clients, relabeling pins", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj3 = <>c.<>9__0_2;
			if (obj3 == null)
			{
				ConsoleEvent val3 = delegate(ConsoleEventArgs args)
				{
					try
					{
						args.Context.AddString("OneMapToRuleThemAll fog status:");
						foreach (string item in ExplorationSynchronizer.FogStatus())
						{
							args.Context.AddString("  " + item);
						}
					}
					catch (Exception ex)
					{
						args.Context.AddString("OneMapToRuleThemAll: fog status failed: " + ex.Message);
					}
				};
				<>c.<>9__0_2 = val3;
				obj3 = (object)val3;
			}
			new ConsoleCommand("om_fogstatus", "Report the fog-of-war (shared map) handshake state on this machine. Local diagnostic; no server round trip.", (ConsoleEvent)obj3, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj4 = <>c.<>9__0_3;
			if (obj4 == null)
			{
				ConsoleEvent val4 = delegate(ConsoleEventArgs args)
				{
					try
					{
						foreach (string item2 in PerfGauges.Report())
						{
							args.Context.AddString(item2);
							ManualLogSource log = ModSettings.Log;
							if (log != null)
							{
								log.LogInfo((object)("[om_perf] " + item2));
							}
						}
					}
					catch (Exception ex)
					{
						args.Context.AddString("OneMapToRuleThemAll: perf report failed: " + ex.Message);
					}
				};
				<>c.<>9__0_3 = val4;
				obj4 = (object)val4;
			}
			new ConsoleCommand("om_perf", "Report steady-state mod performance gauges: live tracker/cluster/pin counts and per-second rates since the previous call. Local diagnostic; no server round trip and no config toggle required. Run it twice a few seconds apart — the first call has no previous sample to measure a rate against.", (ConsoleEvent)obj4, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj5 = <>c.<>9__0_4;
			if (obj5 == null)
			{
				ConsoleEvent val5 = delegate(ConsoleEventArgs args)
				{
					try
					{
						foreach (string item3 in MinimapScale.Report())
						{
							args.Context.AddString(item3);
							ManualLogSource log = ModSettings.Log;
							if (log != null)
							{
								log.LogInfo((object)("[om_minimapinfo] " + item3));
							}
						}
					}
					catch (Exception ex)
					{
						args.Context.AddString("OneMapToRuleThemAll: minimap info failed: " + ex.Message);
					}
				};
				<>c.<>9__0_4 = val5;
				obj5 = (object)val5;
			}
			new ConsoleCommand("om_minimapinfo", "Report the corner minimap's measured layout: panel and child rects, pin sizes, zoom, the resulting map magnification, and any layout component that would fight the MinimapScale setting. Local diagnostic; reads only, changes nothing.", (ConsoleEvent)obj5, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj6 = <>c.<>9__0_5;
			if (obj6 == null)
			{
				ConsoleEvent val6 = delegate(ConsoleEventArgs args)
				{
					try
					{
						foreach (string item4 in ResolvedIdentity.VerifyAgainstFreshClassification())
						{
							args.Context.AddString(item4);
							ManualLogSource log = ModSettings.Log;
							if (log != null)
							{
								log.LogInfo((object)("[om_verifyidentity] " + item4));
							}
						}
					}
					catch (Exception ex)
					{
						args.Context.AddString("OneMapToRuleThemAll: verify failed: " + ex.Message);
					}
				};
				<>c.<>9__0_5 = val6;
				obj6 = (object)val6;
			}
			new ConsoleCommand("om_verifyidentity", "Reclassify every prefab from scratch and diff it against the live identity table. Proves the identity cache is not stale or lossy. OVERRIDE differences are expected (a catalog Prefabs correction doing its job); anything else is a cache defect. Local diagnostic; reads only, changes nothing.", (ConsoleEvent)obj6, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj7 = <>c.<>9__0_6;
			if (obj7 == null)
			{
				ConsoleEvent val7 = delegate(ConsoleEventArgs args)
				{
					try
					{
						CustomPrefabScanner.RescanNow();
						args.Context.AddString("OneMapToRuleThemAll: re-scanned loaded mods; catalog refreshed.");
					}
					catch (Exception ex)
					{
						args.Context.AddString("OneMapToRuleThemAll: mod scan failed: " + ex.Message);
					}
				};
				<>c.<>9__0_6 = val7;
				obj7 = (object)val7;
			}
			new ConsoleCommand("om_scanmods", "Re-scan loaded mods for trackable prefabs (creatures, pickables, ore, locations) and refresh the catalog. Note: a newly INSTALLED mod requires a game restart to load its DLL first.", (ConsoleEvent)obj7, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj8 = <>c.<>9__0_7;
			if (obj8 == null)
			{
				ConsoleEvent val8 = delegate(ConsoleEventArgs args)
				{
					//IL_0060: Unknown result type (might be due to invalid IL or missing references)
					//IL_0066: Expected O, but got Unknown
					if (args.Length < 3)
					{
						args.Context.AddString("Usage: om_setabbr <display_or_keyword> <abbr>");
					}
					else
					{
						string text = args[args.Length - 1];
						List<string> list = new List<string>();
						for (int i = 1; i < args.Length - 1; i++)
						{
							list.Add(args[i]);
						}
						string text2 = string.Join(" ", list);
						ZPackage val22 = new ZPackage();
						val22.Write(text2);
						val22.Write(text);
						val22.SetPos(0);
						if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
						{
							OnAdminSetAbbr(null, val22);
						}
						else
						{
							ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
							if (serverRPC != null)
							{
								serverRPC.Invoke("OM_AdminSetAbbr", new object[1] { val22 });
							}
						}
					}
				};
				<>c.<>9__0_7 = val8;
				obj8 = (object)val8;
			}
			new ConsoleCommand("om_setabbr", "<display_or_keyword> <abbr> — set an object's pin abbreviation and push it live to all clients", (ConsoleEvent)obj8, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj9 = <>c.<>9__0_8;
			if (obj9 == null)
			{
				ConsoleEvent val9 = delegate(ConsoleEventArgs args)
				{
					//IL_0060: Unknown result type (might be due to invalid IL or missing references)
					//IL_0066: Expected O, but got Unknown
					if (args.Length < 3)
					{
						args.Context.AddString("Usage: om_seticon <display_or_keyword> <itemId>  (itemId = ObjectDB item, e.g. CopperOre; 'none' to clear)");
					}
					else
					{
						string text = args[args.Length - 1];
						List<string> list = new List<string>();
						for (int i = 1; i < args.Length - 1; i++)
						{
							list.Add(args[i]);
						}
						string text2 = string.Join(" ", list);
						ZPackage val22 = new ZPackage();
						val22.Write(text2);
						val22.Write(text);
						val22.SetPos(0);
						if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
						{
							OnAdminSetIcon(null, val22);
						}
						else
						{
							ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
							if (serverRPC != null)
							{
								serverRPC.Invoke("OM_AdminSetIcon", new object[1] { val22 });
							}
						}
					}
				};
				<>c.<>9__0_8 = val9;
				obj9 = (object)val9;
			}
			new ConsoleCommand("om_seticon", "<display_or_keyword> <itemId> — set an object's pin icon (ObjectDB item id) and push it live to all clients; use 'none' to clear", (ConsoleEvent)obj9, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj10 = <>c.<>9__0_9;
			if (obj10 == null)
			{
				ConsoleEvent val10 = delegate(ConsoleEventArgs args)
				{
					if ((Object)(object)MinimapProxy.Instance == (Object)null)
					{
						args.Context.AddString("OneMapToRuleThemAll: minimap not ready.");
					}
					else if (!(Traverse.Create((object)MinimapProxy.Instance).Field("m_pins").GetValue() is List<PinData> list))
					{
						args.Context.AddString("OneMapToRuleThemAll: pin list unavailable.");
					}
					else
					{
						bool value = AutoPinConfig.DiscoveryPinObjectIcon.Value;
						int num = 0;
						foreach (SharedPin clientPin in MapStateRepository.ClientPins)
						{
							if (!(clientPin.OwnerId != "auto"))
							{
								string keyword = clientPin.Keyword;
								if (!string.IsNullOrEmpty(keyword))
								{
									foreach (PinData item5 in list)
									{
										if (MapStateRepository.ArePinsEqual(clientPin, item5))
										{
											if (value && RadarIconLoader.TryGetIcon(keyword, out var sprite))
											{
												item5.m_icon = sprite;
											}
											num++;
											break;
										}
									}
								}
							}
						}
						Traverse.Create((object)MinimapProxy.Instance).Method("UpdatePins", Array.Empty<object>()).GetValue();
						args.Context.AddString($"OneMapToRuleThemAll: refreshed icons on {num} discovery pin(s).");
					}
				};
				<>c.<>9__0_9 = val10;
				obj10 = (object)val10;
			}
			new ConsoleCommand("om_refreshicons", "Re-apply object icons to all discovery pins (run if icons get out of sync)", (ConsoleEvent)obj10, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj11 = <>c.<>9__0_10;
			if (obj11 == null)
			{
				ConsoleEvent val11 = delegate(ConsoleEventArgs args)
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Expected O, but got Unknown
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Expected O, but got Unknown
					if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
					{
						OnAdminPinCounts(null, new ZPackage());
					}
					else
					{
						ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
						if (serverRPC != null)
						{
							serverRPC.Invoke("OM_AdminPinCounts", new object[1] { (object)new ZPackage() });
						}
						args.Context.AddString("OneMapToRuleThemAll: requesting pin counts from server...");
					}
				};
				<>c.<>9__0_10 = val11;
				obj11 = (object)val11;
			}
			new ConsoleCommand("om_pincounts", "Show a breakdown of all auto-discovery pin counts (grouped by abbreviation)", (ConsoleEvent)obj11, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj12 = <>c.<>9__0_11;
			if (obj12 == null)
			{
				ConsoleEvent val12 = delegate(ConsoleEventArgs args)
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Expected O, but got Unknown
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Expected O, but got Unknown
					if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
					{
						OnAdminCheckDuplicates(null, new ZPackage());
					}
					else
					{
						ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
						if (serverRPC != null)
						{
							serverRPC.Invoke("OM_AdminCheckDuplicates", new object[1] { (object)new ZPackage() });
						}
						args.Context.AddString("OneMapToRuleThemAll: checking for duplicate pins on server...");
					}
				};
				<>c.<>9__0_11 = val12;
				obj12 = (object)val12;
			}
			new ConsoleCommand("om_checkduplicatepins", "Show a breakdown of duplicate auto-discovery pins without removing them", (ConsoleEvent)obj12, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj13 = <>c.<>9__0_12;
			if (obj13 == null)
			{
				ConsoleEvent val13 = delegate(ConsoleEventArgs args)
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Expected O, but got Unknown
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Expected O, but got Unknown
					if (ZNetProxy.IsServer(ZNetProxy.ZNetInstance))
					{
						OnAdminRemoveDuplicates(null, new ZPackage());
					}
					else
					{
						ZRpc serverRPC = ZNetProxy.GetServerRPC(ZNetProxy.ZNetInstance);
						if (serverRPC != null)
						{
							serverRPC.Invoke("OM_AdminRemoveDuplicates", new object[1] { (object)new ZPackage() });
						}
						args.Context.AddString("OneMapToRuleThemAll: removing duplicate pins on server...");
					}
				};
				<>c.<>9__0_12 = val13;
				obj13 = (object)val13;
			}
			new ConsoleCommand("om_removeduplicatepins", "Remove all duplicate auto-discovery pins and report what was removed", (ConsoleEvent)obj13, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj14 = <>c.<>9__0_13;
			if (obj14 == null)
			{
				ConsoleEvent val14 = delegate(ConsoleEventArgs args)
				{
					//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
					//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
					//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer == (Object)null)
					{
						args.Context.AddString("OneMapToRuleThemAll: no local player.");
					}
					else
					{
						bool flag = args.Length >= 2;
						GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
						if ((Object)(object)hoverObject != (Object)null && !flag)
						{
							InspectObject(ObjectRootOf((Component)(object)hoverObject.transform), args.Context);
						}
						else
						{
							float result = 10f;
							if (args.Length >= 2)
							{
								float.TryParse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
							}
							if (result <= 0f)
							{
								result = 10f;
							}
							string arg = (flag ? "radius given" : "nothing hovered");
							args.Context.AddString($"OneMapToRuleThemAll: {arg}; scanning {result:0.#}m for nearby objects...");
							ManualLogSource log = ModSettings.Log;
							if (log != null)
							{
								log.LogInfo((object)$"[om_inspect] {arg}; scanning {result:0.#}m radius");
							}
							Collider[] array = Physics.OverlapSphere(((Component)localPlayer).transform.position, result, -1, (QueryTriggerInteraction)2);
							HashSet<GameObject> hashSet = new HashSet<GameObject>();
							Collider[] array2 = array;
							for (int i = 0; i < array2.Length; i++)
							{
								GameObject val22 = ObjectRootOf((Component)(object)array2[i]);
								if (!((Object)(object)val22 == (Object)null) && !IsScenery(val22) && (Object)(object)val22 != (Object)(object)((Component)localPlayer).gameObject)
								{
									hashSet.Add(val22);
								}
							}
							if (hashSet.Count == 0)
							{
								args.Context.AddString("OneMapToRuleThemAll: no colliders found nearby.");
								ManualLogSource log2 = ModSettings.Log;
								if (log2 != null)
								{
									log2.LogInfo((object)"[om_inspect] no colliders found nearby.");
								}
							}
							else
							{
								string text = $"{array.Length} collider(s) resolved to {hashSet.Count} object(s) " + "(terrain, clutter and your own body excluded)";
								args.Context.AddString("OneMapToRuleThemAll: " + text);
								ManualLogSource log3 = ModSettings.Log;
								if (log3 != null)
								{
									log3.LogInfo((object)("[om_inspect] " + text));
								}
								Vector3 origin = ((Component)localPlayer).transform.position;
								List<GameObject> list = hashSet.OrderBy(delegate(GameObject g)
								{
									//IL_0006: 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_0011: Unknown result type (might be due to invalid IL or missing references)
									//IL_0016: Unknown result type (might be due to invalid IL or missing references)
									Vector3 val23 = g.transform.position - origin;
									return ((Vector3)(ref val23)).sqrMagnitude;
								}).ToList();
								if (list.Count > 40)
								{
									string text2 = $"showing nearest {40} of {list.Count}; the rest are in the log only";
									args.Context.AddString("OneMapToRuleThemAll: " + text2);
									ManualLogSource log4 = ModSettings.Log;
									if (log4 != null)
									{
										log4.LogInfo((object)("[om_inspect] " + text2));
									}
								}
								for (int num = 0; num < list.Count; num++)
								{
									InspectObject(list[num], (num < 40) ? args.Context : null);
								}
							}
						}
					}
				};
				<>c.<>9__0_13 = val14;
				obj14 = (object)val14;
			}
			new ConsoleCommand("om_inspect", "[radius] — with no argument, inspects the object under your crosshair. WITH a radius, always scans that many metres around you and ignores the crosshair (use this when the thing you want is buried or has no visible mesh). Prints prefab name, components, identification, and for a deposit how much ore is left. Diagnostic; read-only.", (ConsoleEvent)obj14, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj15 = <>c.<>9__0_14;
			if (obj15 == null)
			{
				ConsoleEvent val15 = delegate(ConsoleEventArgs args)
				{
					ExportCatalog(args.Context);
				};
				<>c.<>9__0_14 = val15;
				obj15 = (object)val15;
			}
			new ConsoleCommand("om_exportcatalog", "Dump every trackable prefab (name, type guess, localized name, drop-icon item, components) to prefab_index.txt for catalog curation.", (ConsoleEvent)obj15, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj16 = <>c.<>9__0_15;
			if (obj16 == null)
			{
				ConsoleEvent val16 = delegate(ConsoleEventArgs args)
				{
					AuditPins(args.Context);
				};
				<>c.<>9__0_15 = val16;
				obj16 = (object)val16;
			}
			new ConsoleCommand("om_auditpins", "Audit what EVERY game prefab resolves to under the current keyword rules -> pin_audit.txt. Reports the keyword claimed, the identify branch, components, near-miss runner-ups and SUSPECT false matches. Read-only diagnostic.", (ConsoleEvent)obj16, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj17 = <>c.<>9__0_16;
			if (obj17 == null)
			{
				ConsoleEvent val17 = delegate(ConsoleEventArgs args)
				{
					RenderIcons(args.Context);
				};
				<>c.<>9__0_16 = val17;
				obj17 = (object)val17;
			}
			new ConsoleCommand("om_rendericons", "Render the MOD creature/pickable/ore objects that resolve NO drop-item icon to rendered_icons/*.png (plus @24 downscales + report.txt), so pin-size legibility can be judged before wiring rendering into the pin path.", (ConsoleEvent)obj17, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj18 = <>c.<>9__0_17;
			if (obj18 == null)
			{
				ConsoleEvent val18 = delegate(ConsoleEventArgs args)
				{
					CatalogGenerator.Generate(args.Context);
				};
				<>c.<>9__0_17 = val18;
				obj18 = (object)val18;
			}
			new ConsoleCommand("om_gencatalog", "Generate a PROPOSED catalog from the game's own data (component category, localized name, real drop icon, ZoneSystem biome) -> catalog.generated.txt. Review only; changes nothing.", (ConsoleEvent)obj18, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj19 = <>c.<>9__0_18;
			if (obj19 == null)
			{
				ConsoleEvent val19 = delegate(ConsoleEventArgs args)
				{
					ScanWearNTear(args.Context);
				};
				<>c.<>9__0_18 = val19;
				obj19 = (object)val19;
			}
			new ConsoleCommand("om_wntscan", "Dump every WearNTear prefab with the signals a WearNTear classifier rule would test (Piece, drop yield, localized name, current verdict) -> wnt_scan.txt. Measurement only; changes nothing.", (ConsoleEvent)obj19, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj20 = <>c.<>9__0_19;
			if (obj20 == null)
			{
				ConsoleEvent val20 = delegate(ConsoleEventArgs args)
				{
					float result = 40f;
					if (args.Length >= 2)
					{
						float.TryParse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
					}
					if (result <= 0f)
					{
						result = 40f;
					}
					ReportWhyNoPin(args.Context, result);
				};
				<>c.<>9__0_19 = val20;
				obj20 = (object)val20;
			}
			new ConsoleCommand("om_whynopin", "[radius] — for every auto-pin watcher near you, report exactly why it has or has not placed a pin: the latch, any existing pin it deferred to (with its distance and count), prevention pins, and the count sweep. Read-only.", (ConsoleEvent)obj20, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj21 = <>c.<>9__0_20;
			if (obj21 == null)
			{
				ConsoleEvent val21 = delegate(ConsoleEventArgs args)
				{
					float result = 50f;
					if (args.Length >= 2)
					{
						float.TryParse(args[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result);
					}
					if (result <= 0f)
					{
						result = 50f;
					}
					ReportSpent(args.Context, result);
				};
				<>c.<>9__0_20 = val21;
				obj21 = (object)val21;
			}
			new ConsoleCommand("om_spent", "[radius] — for each nearby ore pin, report whether the SERVER still sees a deposit for it, and list every object its depletion check considers. Run on the host: this reads the server's own pin store and ZDOs. Read-only.", (ConsoleEvent)obj21, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}

	private struct AuditRow
	{
		public string Prefab;

		public string Branch;

		public string Comps;

		public string Disco;

		public string Radar;

		public string Domain;

		public string Display;

		public string Icon;

		public string Candidates;

		public string Flags;

		public bool IsSuspect;
	}

	private struct GapRow
	{
		public string Prefab;

		public string Mod;

		public string Type;

		public string Result;
	}

	private const int ClearModeAll = 0;

	private const int ClearModeType = 1;

	private const int ClearModeAbbr = 2;

	private static bool _renderBatchRunning;

	private static ZNetScene _renderBatchScene;

	public static void OnAdminClearPins(ZRpc client, ZPackage data)
	{
		//IL_002b: 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 (!IsAdmin(client))
		{
			return;
		}
		data.SetPos(0);
		int mode = data.ReadInt();
		string text = data.ReadString();
		Vector3 pos = data.ReadVector3();
		float radius = data.ReadSingle();
		string text2 = null;
		List<string> list = null;
		if (mode == 1)
		{
			list = ObjectCatalog.KeywordsForName(text);
			text2 = AutoPinConfig.TryResolveTypeAbbreviation(text);
			if (list.Count == 0)
			{
				ReplyToClient(client, new List<string> { "OneMapToRuleThemAll: unknown catalog type '" + text + "'. No pins removed." });
				return;
			}
		}
		else if (mode == 2)
		{
			text2 = text;
			if (string.IsNullOrWhiteSpace(text2))
			{
				ReplyToClient(client, new List<string> { "OneMapToRuleThemAll: no abbreviation given. No pins removed." });
				return;
			}
			list = ObjectCatalog.KeywordsForAbbr(text2);
			if (list.Count > 1)
			{
				ManualLogSource log = ModSettings.Log;
				if (log != null)
				{
					log.LogWarning((object)($"[om_clearpins] abbreviation '{text2}' is shared by {list.Count} objects " + "(" + string.Join(", ", list) + ") — pins for ALL of them will be removed. Use 'type <name>' to target exactly one."));
				}
			}
		}
		bool useRadius = radius > 0f;
		string abbrLocal = text2;
		List<string> keywordsLocal = list;
		Predicate<SharedPin> match = delegate(SharedPin p)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (p.OwnerId != "auto")
			{
				return false;
			}
			if (useRadius && Utils.DistanceXZ(p.Pos, pos) > radius)
			{
				return false;
			}
			if (mode == 0)
			{
				return true;
			}
			return (!string.IsNullOrEmpty(p.Keyword) && keywordsLocal != null && keywordsLocal.Count > 0) ? keywordsLocal.Contains<string>(p.Keyword, StringComparer.OrdinalIgnoreCase) : LabelMatchesAbbreviation(p.Name, abbrLocal);
		};
		int removed;
		if (ModSettings.ModActive)
		{
			List<SharedPin> list2 = (from p in MapStateRepository.GetPins()
				where match(p)
				select p).ToList();
			foreach (SharedPin item in list2)
			{
				RemoveAndBroadcast(item);
			}
			removed = list2.Count;
		}
		else
		{
			removed = RemoveMinimapAutoPins(match);
		}
		ReplyToClient(client, new List<string> { DescribeClearResult(mode, text, text2, list, useRadius, radius, removed) });
	}

	private static string DescribeClearResult(int mode, string filter, string abbr, List<string> keywords, bool useRadius, float radius, int removed)
	{
		string text = ((keywords != null && keywords.Count > 0) ? string.Join(", ", keywords) : null);
		string arg = mode switch
		{
			1 => (text != null) ? ("'" + filter + "' [" + text + "] auto pin(s)") : ("'" + filter + "' (" + abbr + ") auto pin(s)"), 
			2 => (text != null) ? ("auto pin(s) with abbreviation '" + abbr + "' [" + text + "]") : ("auto pin(s) with abbreviation '" + abbr + "' (label match — no catalog entry)"), 
			_ => "auto pin(s)", 
		};
		string arg2 = (useRadius ? $" within {radius:0.#}m of your position" : " on the map");
		return $"OneMapToRuleThemAll: removed {removed} {arg}{arg2}.";
	}

	public static void RelabelPinsForKeyword(string keyword)
	{
		if (string.IsNullOrEmpty(keyword))
		{
			return;
		}
		foreach (SharedPin item in (from p in MapStateRepository.GetPins()
			where p.OwnerId == "auto" && string.Equals(p.Keyword, keyword, StringComparison.OrdinalIgnoreCase)
			select p).ToList())
		{
			string text = AutoPinConfig.BuildLabel(keyword, item.Count);
			if (!(item.Name == text))
			{
				MapStateRepository.SetPinLabel(item, text, item.Count);
				RelabelAndBroadcast(item);
			}
		}
	}

	public static void RenameChangedAbbrPins(Dictionary<string, string> oldMap, Dictionary<string, string> newMap)
	{
		foreach (KeyValuePair<string, string> item in oldMap)
		{
			if (newMap.TryGetValue(item.Key, out var value) && !string.Equals(value, item.Value, StringComparison.OrdinalIgnoreCase))
			{
				RelabelPinsForKeyword(item.Key);
			}
		}
	}

	public static void OnAdminReloadCatalog(ZRpc client, ZPackage data)
	{
		if (IsAdmin(client))
		{
			WorldObjectConfig.ReloadCatalogFromDisk();
		}
	}

	public static void OnAdminSetAbbr(ZRpc client, ZPackage data)
	{
		if (IsAdmin(client))
		{
			data.SetPos(0);
			string text = data.ReadString();
			string text2 = data.ReadString();
			string note;
			string text3 = WorldObjectConfig.SetAbbr(text, text2, out note);
			List<string> list = new List<string>();
			list.Add((text3 == null) ? ("OneMapToRuleThemAll: set abbreviation for '" + text + "' to '" + text2 + "'.") : ("OneMapToRuleThemAll: " + text3));
			List<string> list2 = list;
			if (text3 == null && !string.IsNullOrEmpty(note))
			{
				list2.Add("OneMapToRuleThemAll: note — " + note);
			}
			ReplyToClient(client, list2);
		}
	}

	public static void OnAdminSetIcon(ZRpc client, ZPackage data)
	{
		if (IsAdmin(client))
		{
			data.SetPos(0);
			string text = data.ReadString();
			string text2 = data.ReadString();
			string text3 = WorldObjectConfig.SetIcon(text, text2);
			ReplyToClient(client, new List<string> { (text3 == null) ? ("OneMapToRuleThemAll: set icon for '" + text + "' to '" + text2 + "'.") : ("OneMapToRuleThemAll: " + text3) });
		}
	}

	public static void OnAdminPinCounts(ZRpc client, ZPackage data)
	{
		if (IsAdmin(client))
		{
			ReplyToClient(client, MapStateRepository.BuildPinCountBreakdown());
		}
	}

	public static void OnAdminCheckDuplicates(ZRpc client, ZPackage data)
	{
		if (IsAdmin(client))
		{
			ReplyToClient(client, MapStateRepository.BuildDuplicateBreakdown());
		}
	}

	public static void OnAdminRemoveDuplicates(ZRpc client, ZPackage data)
	{
		if (!IsAdmin(client))
		{
			return;
		}
		List<SharedPin> list = MapStateRepository.RemoveDuplicateDiscoveryPinsList();
		List<ZNetPeer> list2 = Traverse.Create((object)ZNet.instance).Field("m_peers").GetValue() as List<ZNetPeer>;
		foreach (SharedPin item in list)
		{
			if (list2 != null)
			{
				foreach (ZNetPeer item2 in list2)
				{
					if (item2.IsReady())
					{
						item2.m_rpc.Invoke("OM_ServerRemovePin", new object[1] { MapStateRepository.PackPin(item) });
					}
				}
			}
			MapPinSynchronizer.OnServerRemovePin(null, MapStateRepository.PackPin(item));
		}
		if (list.Count > 0)
		{
			MapFilePersistence.MapDirty = true;
		}
		ReplyToClient(client, MapStateRepository.SummariseDuplicates(list));
	}

	public static void OnServerAdminReply(ZRpc rpc, ZPackage data)
	{
		data.SetPos(0);
		int num = data.ReadInt();
		for (int i = 0; i < num; i++)
		{
			PrintToConsole(data.ReadString());
		}
	}

	private static void ReplyToClient(ZRpc client, List<string> lines)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		if (client == null)
		{
			foreach (string line in lines)
			{
				PrintToConsole(line);
			}
			return;
		}
		ZPackage val = new ZPackage();
		val.Write(lines.Count);
		foreach (string line2 in lines)
		{
			val.Write(line2);
		}
		val.SetPos(0);
		client.Invoke("OM_ServerAdminReply", new object[1] { val });
	}

	private static void PrintToConsole(string line)
	{
		ManualLogSource log = ModSettings.Log;
		if (log != null)
		{
			log.LogInfo((object)("[OneMap] " + line));
		}
		Type type = AccessTools.TypeByName("Console");
		if (!(type == null))
		{
			object value = Traverse.Create(type).Property("instance", (object[])null).GetValue();
			object obj = ((value is Terminal) ? value : null);
			if (obj != null)
			{
				((Terminal)obj).AddString(line);
			}
		}
	}

	private static void RelabelAndBroadcast(SharedPin pin)
	{
		if (Traverse.Create((object)ZNet.instance).Field("m_peers").GetValue() is List<ZNetPeer> list)
		{
			foreach (ZNetPeer item in list)
			{
				if (item.IsReady())
				{
					item.m_rpc.Invoke("OM_ServerRelabelPin", new object[1] { MapStateRepository.PackPin(pin) });
				}
			}
		}
		if ((Object)(object)MinimapProxy.Instance != (Object)null)
		{
			MapPinSynchronizer.OnServerRelabelPin(null, MapStateRepository.PackPin(pin));
		}
	}

	private static void RemoveAndBroadcast(SharedPin pin)
	{
		MapStateRepository.RemovePin(pin);
		if (Traverse.Create((object)ZNet.instance).Field("m_peers").GetValue() is List<ZNetPeer> list)
		{
			foreach (ZNetPeer item in list)
			{
				if (item.IsReady())
				{
					item.m_rpc.Invoke("OM_ServerRemovePin", new object[1] { MapStateRepository.PackPin(pin) });
				}
			}
		}
		MapPinSynchronizer.OnServerRemovePin(null, MapStateRepository.PackPin(pin));
	}

	private static int RemoveMinimapAutoPins(Predicate<SharedPin> match)
	{
		if ((Object)(object)MinimapProxy.Instance == (Object)null)
		{
			return 0;
		}
		if (!(Traverse.Create((object)MinimapProxy.Instance).Field("m_pins").GetValue() is List<PinData> source))
		{
			return 0;
		}
		HashSet<PinData> hashSet = new HashSet<PinData>();
		foreach (SharedPin clientPin in MapStateRepository.ClientPins)
		{
			if (match(clientPin))
			{
				PinData val = ((IEnumerable<PinData>)source).FirstOrDefault((Func<PinData, bool>)((PinData p) => MapStateRepository.ArePinsEqual(clientPin, p)));
				if (val != null)
				{
					hashSet.Add(val);
				}
			}
		}
		foreach (PinData item in hashSet)
		{
			MapPinSynchronizer.UnregisterPinKeyword(item);
			MinimapProxy.RemovePin(MinimapProxy.Instance, item);
		}
		return hashSet.Count;
	}

	private static bool LabelMatchesAbbreviation(string pinLabel, string abbr)
	{
		if (!string.Equals(pinLabel, abbr, StringComparison.OrdinalIgnoreCase))
		{
			return pinLabel.StartsWith(abbr + " ", StringComparison.OrdinalIgnoreCase);
		}
		return true;
	}

	internal static bool IsAdmin(ZRpc client)
	{
		if (client == null)
		{
			return true;
		}
		ZNetPeer val = (Traverse.Create((object)ZNet.instance).Field("m_peers").GetValue() as List<ZNetPeer>)?.FirstOrDefault((Func<ZNetPeer, bool>)((ZNetPeer p) => p.m_rpc == client));
		if (val == null)
		{
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogInfo((object)"[IsAdmin] peer not found in m_peers");
			}
			return false;
		}
		ISocket socket = val.m_socket;
		string hostName = ((socket != null) ? socket.GetHostName() : null);
		ManualLogSource log2 = ModSettings.Log;
		if (log2 != null)
		{
			log2.LogInfo((object)("[IsAdmin] hostName=" + hostName));
		}
		if (string.IsNullOrEmpty(hostName))
		{
			return false;
		}
		object value = Traverse.Create((object)ZNet.instance).Field("m_adminList").GetValue();
		if (value == null)
		{
			ManualLogSource log3 = ModSettings.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)"[IsAdmin] m_adminList is null");
			}
			return false;
		}
		bool flag = false;
		MethodInfo methodInfo = AccessTools.Method(value.GetType(), "Contains", (Type[])null, (Type[])null);
		if (methodInfo != null)
		{
			flag = (bool)(methodInfo.Invoke(value, new object[1] { hostName }) ?? ((object)false));
			ManualLogSource log4 = ModSettings.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)$"[IsAdmin] AccessTools Contains({hostName})={flag}");
			}
			return flag;
		}
		if (Traverse.Create(value).Field("m_list").GetValue() is List<string> list)
		{
			flag = list.Any((string id) => string.Equals(id.Trim(), hostName.Trim(), StringComparison.OrdinalIgnoreCase));
			ManualLogSource log5 = ModSettings.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)string.Format("[IsAdmin] m_list fallback Contains({0})={1}  list=[{2}]", hostName, flag, string.Join(",", list)));
			}
			return flag;
		}
		ManualLogSource log6 = ModSettings.Log;
		if (log6 != null)
		{
			log6.LogInfo((object)("[IsAdmin] could not check admin list for " + hostName));
		}
		return false;
	}

	private static GameObject ObjectRootOf(Component c)
	{
		if ((Object)(object)c == (Object)null)
		{
			return null;
		}
		Transform val = c.transform;
		while ((Object)(object)val != (Object)null)
		{
			if ((Object)(object)((Component)val).GetComponent<ZNetView>() != (Object)null)
			{
				return ((Component)val).gameObject;
			}
			val = val.parent;
		}
		return c.gameObject;
	}

	private static bool IsScenery(GameObject go)
	{
		if ((Object)(object)go == (Object)null)
		{
			return true;
		}
		if ((Object)(object)go.GetComponent<Heightmap>() != (Object)null)
		{
			return true;
		}
		if ((Object)(object)go.GetComponent<ClutterSystem>() != (Object)null)
		{
			return true;
		}
		return false;
	}

	private static void InspectObject(GameObject go, Terminal context)
	{
		if (!((Object)(object)go == (Object)null))
		{
			string name = ((Object)go).name;
			string text = name.Replace("(Clone)", "").Trim();
			Component[] components = go.GetComponents<Component>();
			string text2 = string.Join(", ", from c in components
				where (Object)(object)c != (Object)null
				select ((object)c).GetType().Name);
			WorldObjectIdentification.IdentificationResult identificationResult = WorldObjectIdentification.IdentifyAny(go);
			string text3 = "=== om_inspect: '" + text + "' (raw '" + name + "') ===";
			string text4 = "  components: " + text2;
			string text5 = string.Format("  identify: tracked={0} discovery='{1}' radar='{2}'", identificationResult.IsTracked, identificationResult.DiscoveryKeyword ?? "-", identificationResult.RadarKeyword ?? "-");
			if ((Object)(object)go.GetComponent<MineRock5>() != (Object)null)
			{
				text5 = text5 + " zdoPrefab='" + (PrefabIndex.PrefabNameFromZdo(go) ?? "<unresolved>") + "'";
			}
			string radarKeyword = identificationResult.RadarKeyword;
			bool flag = radarKeyword != null && WorldObjectConfig.RadarKeywordSet.Contains(radarKeyword);
			bool flag2 = (Object)(object)go.GetComponent<RadarPinComponent>() != (Object)null;
			bool flag3 = radarKeyword != null && WorldObjectConfig.IsKeywordRadarVisible(radarKeyword);
			string text6 = $"  radar: inRadarSet={flag} hasRadarComponent={flag2} " + $"visible={flag3} clientRadarActive={RadarConfig.ClientActive}";
			string discoveryKeyword = identificationResult.DiscoveryKeyword;
			bool flag4 = discoveryKeyword != null && WorldObjectConfig.DiscoveryKeywordSet.Contains(discoveryKeyword);
			bool flag5 = (Object)(object)go.GetComponent<ProximityWatcher>() != (Object)null;
			bool flag6 = discoveryKeyword != null && WorldObjectConfig.IsKeywordDiscoveryVisible(discoveryKeyword);
			string text7 = $"  autopin: inDiscoverySet={flag4} hasProximityWatcher={flag5} " + $"visible={flag6} clientDiscoveryActive={AutoPinConfig.ClientActive} " + $"pickableRadius={ServerGlobalConfig.ActivePickableAutoPin} initialPinsReceived={MapStateRepository.InitialPinsReceived}";
			string text8 = "  LocationsRadar=[" + string.Join(",", WorldObjectConfig.LocationsRadar) + "]";
			if (context != null)
			{
				context.AddString(text3);
			}
			if (context != null)
			{
				context.AddString(text4);
			}
			if (context != null)
			{
				context.AddString(text5);
			}
			if (context != null)
			{
				context.AddString(text6);
			}
			if (context != null)
			{
				context.AddString(text7);
			}
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogInfo((object)("[om_inspect] " + text3));
			}
			ManualLogSource log2 = ModSettings.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("[om_inspect] " + text4));
			}
			ManualLogSource log3 = ModSettings.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)("[om_inspect] " + text5));
			}
			ManualLogSource log4 = ModSettings.Log;
			if (log4 != null)
			{
				log4.LogInfo((object)("[om_inspect] " + text6));
			}
			ManualLogSource log5 = ModSettings.Log;
			if (log5 != null)
			{
				log5.LogInfo((object)("[om_inspect] " + text7));
			}
			ManualLogSource log6 = ModSettings.Log;
			if (log6 != null)
			{
				log6.LogInfo((object)("[om_inspect] " + text8));
			}
		}
	}

	private static void ExportCatalog(Terminal context)
	{
		ZNetScene instance = ZNetScene.instance;
		if ((Object)(object)instance == (Object)null)
		{
			if (context != null)
			{
				context.AddString("OneMapToRuleThemAll: ZNetScene not ready (load a world first).");
			}
			return;
		}
		Dictionary<string, GameObject> seen = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
		foreach (GameObject prefab in instance.m_prefabs)
		{
			Add(prefab);
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("# OneMapToRuleThemAll — prefab index (VNEI-style export)");
		stringBuilder.AppendLine("# Format:  PrefabName | TypeGuess | LocalizedName | DropIconItem | Components");
		stringBuilder.AppendLine("#   DropIconItem = the ObjectDB item this prefab yields; use it as the catalog Icon.");
		stringBuilder.AppendLine("#   TypeGuess is component-based. Location rows come from ZoneSystem.m_locations");
		stringBuilder.AppendLine("#   (Components column shows biome=<Biome> for those).");
		stringBuilder.AppendLine();
		List<(string, string, string, string, string)> list = new List<(string, string, string, string, string)>();
		foreach (GameObject value in seen.Values)
		{
			list.Add((PrefabIndex.CleanName(value), PrefabIndex.TypeGuess(value), PrefabIndex.ResolveDisplayName(value), PrefabIndex.ResolveDropIcon(value), string.Join(";", from c in value.GetComponents<Component>()
				where (Object)(object)c != (Object)null
				select ((object)c).GetType().Name)));
		}
		int num = 0;
		try
		{
			ZoneSystem instance2 = ZoneSystem.instance;
			if (instance2?.m_locations != null)
			{
				HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
				foreach (ZoneLocation location in instance2.m_locations)
				{
					try
					{
						if (location != null && location.m_enable)
						{
							string prefabName = location.m_prefabName;
							if (!string.IsNullOrEmpty(prefabName) && hashSet.Add(prefabName))
							{
								list.Add((prefabName, "Location", prefabName, "", "biome=" + ((object)Unsafe.As<Biome, Biome>(ref location.m_biome)/*cast due to .constrained prefix*/).ToString()));
								num++;
							}
						}
					}
					catch
					{
					}
				}
			}
		}
		catch
		{
		}
		foreach (var item in list.OrderBy<(string, string, string, string, string), string>(((string Name, string Type, string Display, string Icon, string Comps) r) => r.Type).ThenBy<(string, string, string, string, string), string>(((string Name, string Type, string Display, string Icon, string Comps) r) => r.Name, StringComparer.OrdinalIgnoreCase))
		{
			stringBuilder.AppendLine(item.Item1 + " | " + item.Item2 + " | " + item.Item3 + " | " + item.Item4 + " | " + item.Item5);
		}
		string text = Path.Combine(ModSettings.ModFolder, "prefab_index.txt");
		try
		{
			Directory.CreateDirectory(ModSettings.ModFolder);
			File.WriteAllText(text, stringBuilder.ToString());
			string text2 = $"OneMapToRuleThemAll: exported {list.Count} rows ({num} locations) to {text}";
			if (context != null)
			{
				context.AddString(text2);
			}
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogInfo((object)("[om_exportcatalog] " + text2));
			}
		}
		catch (Exception ex)
		{
			string text3 = "OneMapToRuleThemAll: export failed: " + ex.Message;
			if (context != null)
			{
				context.AddString(text3);
			}
			ManualLogSource log2 = ModSettings.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)("[om_exportcatalog] " + text3));
			}
		}
		void Add(GameObject go)
		{
			if (!((Object)(object)go == (Object)null) && PrefabIndex.IsTrackableCandidate(go))
			{
				string key = PrefabIndex.CleanName(go);
				if (!seen.ContainsKey(key))
				{
					seen[key] = go;
				}
			}
		}
	}

	private unsafe static void ReportWhyNoPin(Terminal context, float radius)
	{
		//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_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: 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_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_0418: Unknown result type (might be due to invalid IL or missing references)
		//IL_041d: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				if (context != null)
				{
					context.AddString("OneMapToRuleThemAll: no local player.");
				}
				return;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			ProximityWatcher[] array = Object.FindObjectsByType<ProximityWatcher>((FindObjectsSortMode)0);
			int num = 0;
			bool flag = ModSettings.ModActive && AutoPinConfig.ClientActive && (!AutoPinConfig.SyncsToServer || MapStateRepository.InitialPinsReceived);
			string text = $"gates: modActive={ModSettings.ModActive} " + $"clientActive={AutoPinConfig.ClientActive} " + $"syncsToServer={AutoPinConfig.SyncsToServer} " + $"initialPinsReceived={MapStateRepository.InitialPinsReceived}" + (flag ? "" : "  => WATCHERS ARE RETURNING EARLY; nothing below is acted on");
			if (context != null)
			{
				context.AddString(text);
			}
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogInfo((object)("[om_whynopin] " + text));
			}
			long countSweeps = PerfGauges.CountSweeps;
			long pinIndexRebuilds = PerfGauges.PinIndexRebuilds;
			long pinIndexRebuiltEntries = PerfGauges.PinIndexRebuiltEntries;
			ProximityWatcher[] array2 = array;
			foreach (ProximityWatcher proximityWatcher in array2)
			{
				if ((Object)(object)proximityWatcher == (Object)null)
				{
					continue;
				}
				try
				{
					Vector3 position2 = ((Component)proximityWatcher).transform.position;
					float num2 = position2.x - position.x;
					float num3 = position2.z - position.z;
					float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
					if (num4 > radius)
					{
						continue;
					}
					string keyword = proximityWatcher.Keyword;
					string text2 = $"=== om_whynopin: '{PrefabIndex.CleanName(((Component)proximityWatcher).gameObject)}' {num4:0.#}m away";
					if (context != null)
					{
						context.AddString(text2);
					}
					ManualLogSource log2 = ModSettings.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("[om_whynopin] " + text2));
					}
					string text3 = "    " + proximityWatcher.DescribeDecisionState();
					if (context != null)
					{
						context.AddString(text3);
					}
					ManualLogSource log3 = ModSettings.Log;
					if (log3 != null)
					{
						log3.LogInfo((object)("[om_whynopin] " + text3));
					}
					float num5 = AutoPinConfig.ClusterRadiusFor(keyword);
					SharedPin sharedPin = AutoPinPlacer.FindNearbyPin(position2, keyword);
					string text4;
					if (sharedPin == null)
					{
						text4 = $"    existingPin=NONE within cluster {num5:0.#}m " + "=> would place its own pin" + (flag ? "" : " (BUT the gates above are closed)");
					}
					else
					{
						float num6 = sharedPin.Pos.x - position2.x;
						float num7 = sharedPin.Pos.z - position2.z;
						PinData val = MapPinSynchronizer.FindMapPin(sharedPin);
						string text5 = ((val != null && (Object)(object)val.m_icon != (Object)null) ? ((Object)val.m_icon).name : "NULL");
						text4 = $"    existingPin='{sharedPin.Name}' count={sharedPin.Count} " + $"checked={sharedPin.Checked} at {Mathf.Sqrt(num6 * num6 + num7 * num7):0.#}m " + $"pos={sharedPin.Pos} hasMinimapIcon={val != null}" + ((val == null) ? "  <== GHOST: record with no icon" : "") + $" (cluster {num5:0.#}m) => RELABELS that pin, places none";
						if (val != null)
						{
							string[] obj = new string[17]
							{
								"      pinData: name='",
								val.m_name,
								"' type=",
								((object)Unsafe.As<PinType, PinType>(ref val.m_type)/*cast due to .constrained prefix*/).ToString(),
								" sprite=",
								text5,
								" save=",
								val.m_save.ToString(),
								" checked=",
								val.m_checked.ToString(),
								" uiElement=",
								((Object)(object)val.m_uiElement != (Object)null).ToString(),
								" iconElement=",
								((Object)(object)val.m_iconElement != (Object)null).ToString(),
								" pos=",
								null,
								null
							};
							Vector3 pos = val.m_pos;
							obj[15] = ((object)(*(Vector3*)(&pos))/*cast due to .constrained prefix*/).ToString();
							obj[16] = (((Object)(object)val.m_icon == (Object)null) ? "   <== NO SPRITE: nothing will be drawn" : "");
							string text6 = string.Concat(obj);
							if (context != null)
							{
								context.AddString(text6);
							}
							ManualLogSource log4 = ModSettings.Log;
							if (log4 != null)
							{
								log4.LogInfo((object)("[om_whynopin] " + text6));
							}
						}
					}
					if (context != null)
					{
						context.AddString(text4);
					}
					ManualLogSource log5 = ModSettings.Log;
					if (log5 != null)
					{
						log5.LogInfo((object)("[om_whynopin] " + text4));
					}
					bool flag2 = ServerGlobalConfig.ActiveAutoPinPrevention && PreventionPins.AnyWithin(position2, ServerGlobalConfig.ActiveAutoPinPreventionRadius);
					Vector3 origin = sharedPin?.Pos ?? position2;
					bool flag3 = AutoPinPlacer.SweepFullyLoaded(origin, num5, localPlayer);
					string text7;
					if (sharedPin != null && !flag3)
					{
						text7 = "SKIPPED (partial sweep; the watcher would use UNKNOWN and leave the pin alone)";
					}
					else
					{
						int num8 = AutoPinPlacer.CountNearbyObjects(origin, keyword, num5);
						text7 = ((num8 == 0) ? "UNKNOWN(sentinel)" : num8.ToString());
					}
					string text8 = $"    preventionBlocked={flag2} sweepFullyLoaded={flag3} " + "countNow=" + text7;
					if (context != null)
					{
						context.AddString(text8);
					}
					ManualLogSource log6 = ModSettings.Log;
					if (log6 != null)
					{
						log6.LogInfo((object)("[om_whynopin] " + text8));
					}
					num++;
				}
				catch (Exception ex)
				{
					string text9 = "    (watcher skipped: " + ex.GetType().Name + ": " + ex.Message + ")";
					if (context != null)
					{
						context.AddString(text9);
					}
					ManualLogSource log7 = ModSettings.Log;
					if (log7 != null)
					{
						log7.LogWarning((object)("[om_whynopin] " + text9));
					}
				}
			}
			PerfGauges.CountSweeps = countSweeps;
			PerfGauges.PinIndexRebuilds = pinIndexRebuilds;
			PerfGauges.PinIndexRebuiltEntries = pinIndexRebuiltEntries;
			string text10 = $"OneMapToRuleThemAll: om_whynopin reported {num} watcher(s) within " + $"{radius:0.#}m of {array.Length} total. " + "This frame's StutterMonitor sample is this command's own work, not gameplay.";
			if (context != null)
			{
				context.AddString(text10);
			}
			ManualLogSource log8 = ModSettings.Log;
			if (log8 != null)
			{
				log8.LogInfo((object)("[om_whynopin] " + text10));
			}
		}
		catch (Exception ex2)
		{
			string text11 = "OneMapToRuleThemAll: om_whynopin failed: " + ex2.Message;
			if (context != null)
			{
				context.AddString(text11);
			}
			ManualLogSource log9 = ModSettings.Log;
			if (log9 != null)
			{
				log9.LogWarning((object)("[om_whynopin] " + text11));
			}
		}
	}

	private static void ReportSpent(Terminal context, float radius)
	{
		try
		{
			ReportSpentCore(context, radius);
		}
		catch (Exception ex)
		{
			string text = "OneMapToRuleThemAll: om_spent failed: " + ex.Message;
			if (context != null)
			{
				context.AddString(text);
			}
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogWarning((object)("[om_spent] " + text));
			}
		}
	}

	private static void ReportSpentCore(Terminal context, float radius)
	{
		//IL_003e: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			if (context != null)
			{
				context.AddString("OneMapToRuleThemAll: no local player.");
			}
			return;
		}
		if (!ZNetProxy.IsServer(ZNetProxy.ZNetInstance) && context != null)
		{
			context.AddString("OneMapToRuleThemAll: om_spent reads the SERVER's pin store and ZDOs — run it on the host. Reporting what this client can see anyway:");
		}
		Vector3 position = ((Component)localPlayer).transform.position;
		bool flag = ZNetProxy.IsServer(ZNetProxy.ZNetInstance);
		List<SharedPin> list = (flag ? MapStateRepository.GetPins() : MapStateRepository.ClientPins);
		if (list == null || list.Count == 0)
		{
			if (context != null)
			{
				context.AddString("OneMapToRuleThemAll: no pins in the " + (flag ? "server store" : "client cache") + ".");
			}
			return;
		}
		int num = 0;
		List<string> list2 = new List<string>();
		foreach (SharedPin item in list)
		{
			if (item == null || item.OwnerId != "auto" || string.IsNullOrEmpty(item.Keyword))
			{
				continue;
			}
			float num2 = item.Pos.x - position.x;
			float num3 = item.Pos.z - position.z;
			float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
			if (num4 > radius)
			{
				continue;
			}
			bool flag2 = WorldObjectIdentification.KeywordNeverRespawns(item.Keyword);
			list2.Clear();
			bool flag3 = MapPinSynchronizer.NoDepositRemainsNear(item, list2);
			string text = (flag ? "serverSeesSpent" : "clientSeesSpent");
			string text2 = $"=== om_spent: '{item.Keyword}' count={item.Count} checked={item.Checked} " + $"{num4:0.#}m away — {text}={flag3} deletableType={flag2}";
			if (context != null)
			{
				context.AddString(text2);
			}
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogInfo((object)("[om_spent] " + text2));
			}
			if (list2.Count == 0)
			{
				if (context != null)
				{
					context.AddString("    (no resolvable objects within cluster radius)");
				}
				ManualLogSource log2 = ModSettings.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"[om_spent]     (no resolvable objects within cluster radius)");
				}
			}
			else
			{
				foreach (string item2 in list2)
				{
					if (context != null)
					{
						context.AddString("    " + item2);
					}
					ManualLogSource log3 = ModSettings.Log;
					if (log3 != null)
					{
						log3.LogInfo((object)("[om_spent]     " + item2));
					}
				}
			}
			num++;
		}
		string text3 = $"OneMapToRuleThemAll: om_spent reported {num} discovery pin(s) " + $"within {radius:0.#}m  (RemoveMinedOutPins={ServerGlobalConfig.ActiveRemoveMinedOutPins})";
		if (context != null)
		{
			context.AddString(text3);
		}
		ManualLogSource log4 = ModSettings.Log;
		if (log4 != null)
		{
			log4.LogInfo((object)("[om_spent] " + text3));
		}
	}

	private static void ScanWearNTear(Terminal context)
	{
		ZNetScene instance = ZNetScene.instance;
		if ((Object)(object)instance == (Object)null)
		{
			if (context != null)
			{
				context.AddString("OneMapToRuleThemAll: ZNetScene not ready (load a world first).");
			}
			return;
		}
		Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
		foreach (GameObject prefab in instance.m_prefabs)
		{
			if (!((Object)(object)prefab == (Object)null) && (!((Object)(object)prefab.GetComponent<WearNTear>() == (Object)null) || !((Object)(object)prefab.GetComponent<Beehive>() == (Object)null)))
			{
				string text = PrefabIndex.CleanName(prefab);
				if (!string.IsNullOrEmpty(text) && !dictionary.ContainsKey(text))
				{
					dictionary[text] = prefab;
				}
			}
		}
		List<(string, bool)> list = new List<(string, bool)>(dictionary.Count);
		int num = 0;
		int num2 = 0;
		foreach (KeyValuePair<string, GameObject> item2 in dictionary.OrderBy<KeyValuePair<string, GameObject>, string>((KeyValuePair<string, GameObject> k) => k.Key, StringComparer.OrdinalIgnoreCase))
		{
			bool flag = false;
			string item;
			try
			{
				GameObject value = item2.Value;
				bool flag2 = (Object)(object)value.GetComponent<WearNTear>() != (Object)null;
				bool flag3 = (Object)(object)value.GetComponent<Piece>() != (Object)null;
				bool flag4 = (Object)(object)value.GetComponent<Beehive>() != (Object)null;
				bool flag5 = (Object)(object)value.GetComponent<Destructible>() != (Object)null;
				bool flag6 = (Object)(object)value.GetComponent<MineRock>() != (Object)null || (Object)(object)value.GetComponent<MineRock5>() != (Object)null;
				bool flag7 = (Object)(object)value.GetComponent<Location>() != (Object)null;
				bool flag8 = (Object)(object)value.GetComponent<Character>() != (Object)null;
				string text2 = PrefabIndex.ResolveDisplayName(value) ?? "";
				string text3 = PrefabIndex.ResolveDropIcon(value) ?? "";
				bool flag9 = !string.IsNullOrEmpty(text2) && !string.Equals(text2, item2.Key, StringComparison.OrdinalIgnoreCase);
				bool flag10 = CatalogGenerator.IsBulkYield(text3);
				CatalogGenerator.Classified classified = CatalogGenerator.Classify(value);
				string text4 = (classified.Tracked ? (classified.Type + ":" + classified.GroupId) : "REJECTED");
				if (classified.Tracked)
				{
					num2++;
				}
				flag = flag2 && !flag3 && !flag5 && !flag6 && !flag7 && !flag8 && !string.IsNullOrEmpty(text3) && !flag10;
				if (flag)
				{
					num++;
				}
				string text5 = string.Join(";", from x in value.GetComponents<Component>()
					where (Object)(object)x != (Object)null
					select ((object)x).GetType().Name);
				item = string.Join(" | ", item2.Key, $"wnt={flag2} piece={flag3} bee={flag4} dest={flag5} mine={flag6} loc={flag7} char={flag8}", $"display='{text2}' named={flag9}", $"icon='{text3}' bulk={flag10}", text4, flag ? "CANDIDATE" : "", text5);
			}
			catch (Exception ex)
			{
				item = item2.Key + " | ERROR:" + ex.GetType().Name + " | " + ex.Message;
			}
			list.Add((item, flag));
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("# OneMapToRuleThemAll — WearNTear classifier-gap scan");
		stringBuilder.AppendLine(string.Format("# plugin {0}   rows={1}", "2.8.1", list.Count));
		stringBuilder.AppendLine("# Every prefab carrying a WearNTear (or a Beehive component). Measurement only.");
		stringBuilder.AppendLine("#");
		stringBuilder.AppendLine("# Format: Prefab | components-of-interest | display | yield | verdict | CANDIDATE | full components");
		stringBuilder.AppendLine("#   verdict   = what CatalogGenerator.Classify decides TODAY. REJECTED means no pin.");
		stringBuilder.AppendLine("#   CANDIDATE = would be caught by the PROPOSED rule:");
		stringBuilder.AppendLine("#               WearNTear && !Piece && !Destructible && !MineRock* && !Location");
		stringBuilder.AppendLine("#               && !Character && yields a non-bulk item.");
		stringBuilder.AppendLine("#   The candidate list is the review list: every row in it must be a genuine");
		stringBuilder.AppendLine("#   world structure. Masonry or dungeon parts appearing there means the rule");
		stringBuilder.AppendLine("#   is too wide and must be tightened BEFORE it ships.");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine($"##   WearNTear/Beehive prefabs      : {list.Count}");
		stringBuilder.AppendLine($"##   already tracked today          : {num2}");
		stringBuilder.AppendLine($"##   NEW rows the rule would add    : {num}");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine($"## CANDIDATES ({num})");
		foreach (var item3 in list.Where<(string, bool)>(((string Line, bool Candidate) r) => r.Candidate))
		{
			stringBuilder.AppendLine(item3.Item1);
		}
		stringBuilder.AppendLine();
		stringBuilder.AppendLine($"## ALL ROWS ({list.Count})");
		foreach (var item4 in list)
		{
			stringBuilder.AppendLine(item4.Item1);
		}
		string text6 = Path.Combine(ModSettings.ModFolder, "wnt_scan.txt");
		try
		{
			Directory.CreateDirectory(ModSettings.ModFolder);
			File.WriteAllText(text6, stringBuilder.ToString());
			string text7 = $"OneMapToRuleThemAll: scanned {list.Count} WearNTear prefabs " + $"({num} candidates, {num2} already tracked) to {text6}";
			if (context != null)
			{
				context.AddString(text7);
			}
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogInfo((object)("[om_wntscan] " + text7));
			}
		}
		catch (Exception ex2)
		{
			string text8 = "OneMapToRuleThemAll: scan failed: " + ex2.Message;
			if (context != null)
			{
				context.AddString(text8);
			}
			ManualLogSource log2 = ModSettings.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)("[om_wntscan] " + text8));
			}
		}
	}

	private static void AuditPins(Terminal context)
	{
		ZNetScene instance = ZNetScene.instance;
		if ((Object)(object)instance == (Object)null)
		{
			if (context != null)
			{
				context.AddString("OneMapToRuleThemAll: ZNetScene not ready (load a world first).");
			}
			return;
		}
		HashSet<string> oreSet = ToSet(WorldObjectConfig.OresDiscovery, WorldObjectConfig.OresRadar);
		HashSet<string> locSet = ToSet(WorldObjectConfig.LocationsDiscovery, WorldObjectConfig.LocationsRadar);
		HashSet<string> pickSet = ToSet(WorldObjectConfig.PickablesDiscovery, WorldObjectConfig.PickablesRadar);
		Dictionary<string, CatalogEntry> dictionary = new Dictionary<string, CatalogEntry>(StringComparer.OrdinalIgnoreCase);
		try
		{
			foreach (CatalogEntry item2 in ObjectCatalog.Load())
			{
				if (!string.IsNullOrEmpty(item2.Display) && !dictionary.ContainsKey(item2.Display))
				{
					dictionary[item2.Display] = item2;
				}
			}
			foreach (CatalogEntry item3 in ObjectCatalog.Load())
			{
				if (!string.IsNullOrEmpty(item3.Keyword))
				{
					dictionary[item3.Keyword] = item3;
				}
			}
		}
		catch
		{
		}
		Dictionary<string, GameObject> dictionary2 = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
		foreach (GameObject prefab in instance.m_prefabs)
		{
			if (!((Object)(object)prefab == (Object)null) && PrefabIndex.IsAuditCandidate(prefab))
			{
				string key = PrefabIndex.CleanName(prefab);
				if (!dictionary2.ContainsKey(key))
				{
					dictionary2[key] = prefab;
				}
			}
		}
		List<AuditRow> list = new List<AuditRow>(dictionary2.Count);
		Dictionary<string, int> dictionary3 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
		int unpinnedPickable = 0;
		int unpinnedMineRock = 0;
		int iconMismatch = 0;
		foreach (KeyValuePair<string, GameObject> item4 in dictionary2)
		{
			try
			{
				AuditRow item = BuildAuditRow(item4.Key, item4.Value, oreSet, locSet, pickSet, dictionary, ref unpinnedPickable, ref unpinnedMineRock, ref iconMismatch);
				list.Add(item);
				foreach (string item5 in new string[2] { item.Disco, item.Radar }.Distinct<string>(StringComparer.OrdinalIgnoreCase))
				{
					if (!string.IsNullOrEmpty(item5) && item5 != "-")
					{
						dictionary3[item5] = ((!dictionary3.TryGetValue(item5, out var value)) ? 1 : (value + 1));
					}
				}
			}
			catch (Exception ex)
			{
				list.Add(new AuditRow
				{
					Prefab = item4.Key,
					Branch = "?",
					Comps = "?",
					Disco = "-",
					Radar = "-",
					Domain = "-",
					Display = "-",
					Icon = "-",
					Candidates = "-",
					Flags = "ERROR:" + ex.GetType().Name,
					IsSuspect = true
				});
			}
		}
		int num = 0;
		try
		{
			ZoneSystem instance2 = ZoneSystem.instance;
			if (instance2?.m_locations != null)
			{
				HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
				foreach (ZoneLocation location in instance2.m_locations)
				{
					try
					{
						if (location == null || !location.m_enable)
						{
							continue;
						}
						string prefabName = location.m_prefabName;
						if (string.IsNullOrEmpty(prefabName) || !hashSet.Add(prefabName))
						{
							continue;
						}
						string text = null;
						string text2 = null;
						string candidates = "-";
						if (ResolvedIdentity.TryResolve(prefabName, out var groupId, out var type) && !string.IsNullOrEmpty(groupId))
						{
							candidates = type + ":" + groupId;
							text = (WorldObjectConfig.DiscoveryKeywordSet.Contains(groupId) ? groupId : null);
							text2 = (WorldObjectConfig.RadarKeywordSet.Contains(groupId) ? groupId : null);
						}
						list.Add(new AuditRow
						{
							Prefab = prefabName,
							Branch = "ZoneLocation",
							Comps = "biome=" + ((object)Unsafe.As<Biome, Biome>(ref location.m_biome)/*cast due to .constrained prefix*/).ToString(),
							Disco = (text ?? "-"),
							Radar = (text2 ?? "-"),
							Domain = (((text ?? text2) == null) ? "-" : "Location"),
							Display = LookupDisplay(dictionary, text ?? text2),
							Icon = LookupIcon(dictionary, text ?? text2),
							Candidates = candidates,
							Flags = "",
							IsSuspect = false
						});
						foreach (string item6 in new string[2] { text, text2 }.Distinct<string>(StringComparer.OrdinalIgnoreCase))
						{
							if (!string.IsNullOrEmpty(item6))
							{
								dictionary3[item6] = ((!dictionary3.TryGetValue(item6, out var value2)) ? 1 : (value2 + 1));
							}
						}
						num++;
					}
					catch
					{
					}
				}
			}
		}
		catch
		{
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("# OneMapToRuleThemAll — pin identification audit");
		stringBuilder.AppendLine(string.Format("# plugin {0}   prefabs={1}   zone-locations={2}", "2.8.1", dictionary2.Count, num));
		stringBuilder.AppendLine("# Identity is the EXACT prefab name resolved to a catalog group — a dictionary");
		stringBuilder.AppendLine("# lookup, no substring matching.");
		stringBuilder.AppendLine("#");
		stringBuilder.AppendLine("# For every prefab the mod CAN identify, what keyword it resolves to under the");
		stringBuilder.AppendLine("# current rules, and why. Read the SUSPECT section first; it is the review list.");
		stringBuilder.AppendLine("#");
		stringBuilder.AppendLine("# Format: Prefab | Branch | Components | discovery | radar | Domain | Display | Icon | Resolved | Flags");
		stringBuilder.AppendLine("#   Branch     = which WorldObjectIdentification.IdentifyAny branch claimed it.");
		stringBuilder.AppendLine("#   Resolved   = the classifier's Type:GroupId for this exact prefab name.");
		stringBuilder.AppendLine("#   Display/Icon = the catalog entry the resolved group maps to. Icon is the");
		stringBuilder.AppendLine("#                ObjectDB item whose sprite the pin draws; blank falls back to Keyword.");
		stringBuilder.AppendLine("#   Flags      = SUSPECT reasons. Empty is good. Meanings:");
		stringBuilder.AppendLine("#     SPAWNER-AS-ORE/LOC  carries SpawnArea. A creature spawner is never a deposit");
		stringBuilder.AppendLine("#                         or a location, so this classification is wrong.");
		stringBuilder.AppendLine("#     BUILDPIECE-AS-LOC   WearNTear with no Destructible/MineRock: a build piece.");
		stringBuilder.AppendLine("#                         Curated wild structures (the Beehive) are exempt.");
		stringBuilder.AppendLine("#     LOCKW-NO-LOCATION   resolved to a Location group but has no Location component.");
		stringBuilder.AppendLine("#                         EXPECTED for the breakable props filed as landmarks:");
		stringBuilder.AppendLine("#                         mudpile, giant_skull and the wild Beehive.");
		stringBuilder.AppendLine("#   FALSE-NEGATIVE flags — objects that SHOULD pin and do not:");
		stringBuilder.AppendLine("#     UNPINNED-PICKABLE   a Pickable no group reaches.");
		stringBuilder.AppendLine("#     UNPINNED-MINEROCK   a MineRock/MineRock5/ResourceRoot no group reaches,");
		stringBuilder.AppendLine("#                         excluding *_frac / *_fractured / *_destruction rubble.");
		stringBuilder.AppendLine("#     ICON-MISSING        the catalog names an ObjectDB item for this pin's sprite,");
		stringBuilder.AppendLine("#                         but the id does not resolve, so the pin draws a generic dot.");
		stringBuilder.AppendLine("#   NOT defects — your own decisions, reported but never counted as suspect:");
		stringBuilder.AppendLine("#     DISABLED            the catalog row for this object's group is commented out.");
		stringBuilder.AppendLine();
		stringBuilder.AppendLine("## SUMMARY — keyword claim counts (descending)");
		stringBuilder.AppendLine("## One keyword claiming many prefabs is the signature of a false match.");
		foreach (KeyValuePair<string, int> item7 in dictionary3.OrderByDescending((KeyValuePair<string, int> c) => c.Value).ThenBy<KeyValuePair<string, int>, string>((KeyValuePair<string, int> c) => c.Key, StringComparer.OrdinalIgnoreCase))
		{
			stringBuilder.AppendLine($"##   {item7.Value,5}  {item7.Key}");
		}
		stringBuilder.AppendLine("##");
		stringBuilder.AppendLine($"##   suspect rows                 : {list.Count((AuditRow r) => r.IsSuspect)}");
		stringBuilder.AppendLine($"##   unpinned pickables           : {unpinnedPickable}");
		stringBuilder.AppendLine($"##   unpinned minerock/resourceroot: {unpinnedMineRock}  (excludes fracture rubble)");
		stringBuilder.AppendLine($"##   unresolvable pin icons       : {iconMismatch}");
		stringBuilder.AppendLine($"##   identity table entries       : {ResolvedIdentity.Count}  (source: {ResolvedIdentity.LastBuildSource})");
		stringBuilder.AppendLine();
		List<AuditRow> list2 = list.Where((AuditRow r) => r.IsSuspect).OrderBy<AuditRow, string>((AuditRow r) => r.Prefab, StringComparer.OrdinalIgnoreCase).ToList();
		stringBuilder.AppendLine($"## SUSPECT ROWS ({list2.Count})");
		foreach (AuditRow item8 in list2)
		{
			stringBuilder.AppendLine(Fmt(item8));
		}
		stringBuilder.AppendLine();
		stringBuilder.AppendLine($"## ALL ROWS ({list.Count})");
		foreach (AuditRow item9 in list.OrderBy<AuditRow, string>((AuditRow r) => r.Branch, StringComparer.OrdinalIgnoreCase).ThenBy<AuditRow, string>((AuditRow r) => r.Prefab, StringComparer.OrdinalIgnoreCase))
		{
			stringBuilder.AppendLine(Fmt(item9));
		}
		WorldObjectIdentification.ClearIdentificationCache();
		string text3 = Path.Combine(ModSettings.ModFolder, "pin_audit.txt");
		try
		{
			Directory.CreateDirectory(ModSettings.ModFolder);
			File.WriteAllText(text3, stringBuilder.ToString());
			string text4 = $"OneMapToRuleThemAll: audited {list.Count} rows " + $"({list2.Count} suspect, {num} locations) to {text3}";
			if (context != null)
			{
				context.AddString(text4);
			}
			ManualLogSource log = ModSettings.Log;
			if (log != null)
			{
				log.LogInfo((object)("[om_auditpins] " + text4));
			}
		}
		catch (Exception ex2)
		{
			string text5 = "OneMapToRuleThemAll: audit failed: " + ex2.Message;
			if (context != null)
			{
				context.AddString(text5);
			}
			ManualLogSource log2 = ModSettings.Log;
			if (log2 != null)
			{
				log2.LogWarning((object)("[om_auditpins] " + text5));
			}
		}
	}

	private static string Fmt(AuditRow r)
	{
		return r.Prefab + " | " + r.Branch + " | " + r.Comps + " | " + r.Disco + " | " + r.Radar + " | " + r.Domain + " | " + r.Display + " | " + r.Icon + " | " + r.Candidates + " | " + r.Flags;
	}

	private static HashSet<string> ToSet(string[] a, string[] b)
	{
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		if (a != null)
		{
			string[] array = a;
			foreach (string text in array)
			{
				if (!string.IsNullOrEmpty(text))
				{
					hashSet.Add(text);
				}
			}
		}
		if (b != null)
		{
			string[] array = b;
			foreach (string text2 in array)
			{
				if (!string.IsNullOrEmpty(text2))
				{
					hashSet.Add(text2);
				}
			}
		}
		return hashSet;
	}

	private static string LookupDisplay(Dictionary<string, CatalogEntry> map, string key)
	{
		if (key == null || !map.TryGetValue(key, out var value) || string.IsNullOrEmpty(value.Display))
		{
			return "-";
		}
		return value.Display;
	}

	private static string LookupIcon(Dictionary<string, CatalogEntry> map, string key)
	{
		if (key == null || !map.TryGetValue(key, out var value))
		{
			return "-";
		}
		if (!string.IsNullOrEmpty(value.Icon))
		{
			return value.Icon;
		}
		if (!string.IsNullOrEmpty(value.Keyword))
		{
			return value.Keyword;
		}
		return "-";
	}

	private static AuditRow BuildAuditRow(string name, GameObject go, HashSet<string> oreSet, HashSet<string> locSet, HashSet<string> pickSet, Dictionary<string, CatalogEntry> entryByKey, ref int unpinnedPickable, ref int unpinnedMineRock, ref int iconMismatch)
	{
		string text = WorldObjectIdentification.AuditBranch(go);
		WorldObjectIdentification.IdentificationResult identificationResult = WorldObjectIdentification.IdentifyAny(go);
		string discoveryKeyword = identificationResult.DiscoveryKeyword;
		string radarKeyword = identificationResult.RadarKeyword;
		string text2 = discoveryKeyword ?? radarKeyword;
		bool flag = text == "Creature" || text == "Creature(Beehive)";
		ResolvedIdentity.TryResolve(name, out var groupId, out var type);
		string candidates = (string.IsNullOrEmpty(groupId) ? "-" : (type + ":" + groupId));
		List<string> list = new List<string>();
		if (text2 != null && PrefabIndex.IsSpawner(go))
		{
			if (oreSet.Contains(text2))
			{
				list.Add("SPAWNER-AS-ORE");
			}
			else if (locSet.Contains(text2))
			{
				list.Add("SPAWNER-AS-LOC");
			}
		}
		if (text2 != null && PrefabIndex.IsBuildPiece(go) && locSet.Contains(text2) && !CatalogGenerator.IsWildStructure(name))
		{
			list.Add("BUILDPIECE-AS-LOC");
		}
		if (text2 != null && !flag && locSet.Contains(text2) && !oreSet.Contains(text2) && (Object)(object)go.GetComponent<Location>() == (Object)null)
		{
			list.Add("LOCKW-NO-LOCATION");
		}
		bool flag2 = false;
		if (text2 == null && !string.IsNullOrEmpty(groupId))
		{
			list.Add("DISABLED(catalog row off: " + groupId + ")");
			flag2 = true;
		}
		if (text2 == null && !flag2)
		{
			switch (text)
			{
			case "Pickable":
				list.Add("UNPINNED-PICKABLE");
				unpinnedPickable++;
				break;
			case "MineRock":
			case "MineRock5":
			case "ResourceRoot":
				if (!PrefabIndex.IsFractureDebris(name))
				{
					list.Add("UNPINNED-MINEROCK");
					unpinnedMineRock++;
				}
				break;
			}
		}
		string display = LookupDisplay(entryByKey, text2);
		string icon = LookupIcon(entryByKey, text2);
		CatalogEntry value = null;
		if (text2 != null)
		{
			entryByKey.TryGetValue(text2, out value);
		}
		string text3 = ((value != null && !string.IsNullOrEmpty(value.Icon)