Decompiled source of AdvancedRadarScanner v0.3.17

plugins/AdvancedRadarScanner/AdvancedRadarScanner.dll

Decompiled 18 minutes ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2;
using R2API.Utils;
using RoR2;
using RoR2.Networking;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("AdvancedRadarScanner.Tests")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AdvancedRadarScanner")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.17.0")]
[assembly: AssemblyInformationalVersion("0.3.17")]
[assembly: AssemblyProduct("AdvancedRadarScanner")]
[assembly: AssemblyTitle("AdvancedRadarScanner")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.17.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AdvancedRadarScanner
{
	internal enum AdvancedIconKind
	{
		None,
		LegendaryChest,
		Multishop,
		Scrapper,
		EquipmentBarrel,
		VoidCradle,
		RadioScanner,
		Lunar
	}
	internal static class ClassificationRules
	{
		internal static AdvancedIconKind Classify(string fingerprint)
		{
			string value = Normalize(fingerprint);
			if (ContainsAny(value, "SCRAPPER"))
			{
				return AdvancedIconKind.Scrapper;
			}
			if (ContainsAny(value, "EQUIPMENTBARREL", "EQUIPMENT BARREL"))
			{
				return AdvancedIconKind.EquipmentBarrel;
			}
			if (ContainsAny(value, "VOIDCHEST", "VOIDCRADLE", "VOID CRADLE"))
			{
				return AdvancedIconKind.VoidCradle;
			}
			if (ContainsAny(value, "RADARSCANNER", "RADAR SCANNER"))
			{
				return AdvancedIconKind.RadioScanner;
			}
			if (ContainsAny(value, "LUNAR"))
			{
				return AdvancedIconKind.Lunar;
			}
			if (ContainsAny(value, "TRIPLESHOP", "MULTISHOP", "MULTI SHOP"))
			{
				return AdvancedIconKind.Multishop;
			}
			if (ContainsAny(value, "GOLDCHEST", "LEGENDARYCHEST", "CHEST2"))
			{
				return AdvancedIconKind.LegendaryChest;
			}
			return AdvancedIconKind.None;
		}

		private static bool ContainsAny(string value, params string[] candidates)
		{
			foreach (string value2 in candidates)
			{
				if (value.IndexOf(value2, StringComparison.Ordinal) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		private static string Normalize(string value)
		{
			return value.ToUpperInvariant().Replace("_", string.Empty);
		}
	}
	internal static class InteractableClassifier
	{
		internal static AdvancedIconKind Classify(GameObject target, out string fingerprint)
		{
			List<PurchaseInteraction> list = CollectNearby<PurchaseInteraction>(target);
			StringBuilder stringBuilder = new StringBuilder(((Object)target).name);
			AppendHierarchyNames(target.transform, stringBuilder);
			AppendComponentNames(target, stringBuilder);
			foreach (PurchaseInteraction item in list)
			{
				Append(stringBuilder, item.displayNameToken);
				Append(stringBuilder, item.contextToken);
			}
			foreach (GenericDisplayNameProvider item2 in CollectNearby<GenericDisplayNameProvider>(target))
			{
				Append(stringBuilder, item2.displayToken);
			}
			fingerprint = Normalize(stringBuilder.ToString());
			return ClassificationRules.Classify(fingerprint);
		}

		private static List<T> CollectNearby<T>(GameObject target) where T : Component
		{
			List<T> list = new List<T>();
			AddUnique(list, target.GetComponents<T>());
			AddUnique(list, target.GetComponentsInParent<T>(true));
			AddUnique(list, target.GetComponentsInChildren<T>(true));
			return list;
		}

		private static void AddUnique<T>(List<T> destination, IEnumerable<T> source) where T : Component
		{
			foreach (T item in source)
			{
				if (Object.op_Implicit((Object)(object)item) && !destination.Contains(item))
				{
					destination.Add(item);
				}
			}
		}

		private static void AppendHierarchyNames(Transform transform, StringBuilder builder)
		{
			Transform val = transform;
			int num = 0;
			while (Object.op_Implicit((Object)(object)val) && num < 4)
			{
				Append(builder, ((Object)val).name);
				num++;
				val = val.parent;
			}
		}

		private static void AppendComponentNames(GameObject target, StringBuilder builder)
		{
			Component[] components = target.GetComponents<Component>();
			foreach (Component val in components)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Append(builder, ((object)val).GetType().Name);
				}
			}
		}

		private static void Append(StringBuilder builder, string? value)
		{
			if (!string.IsNullOrWhiteSpace(value))
			{
				builder.Append(' ').Append(value);
			}
		}

		private static string Normalize(string value)
		{
			return value.ToUpperInvariant().Replace("_", string.Empty);
		}
	}
	internal sealed class MarkerVisibilityState : MonoBehaviour
	{
		private readonly Dictionary<Renderer, bool> rendererStates = new Dictionary<Renderer, bool>();

		private readonly Dictionary<Graphic, bool> graphicStates = new Dictionary<Graphic, bool>();

		internal void Hide(params GameObject?[] roots)
		{
			if (rendererStates.Count != 0 || graphicStates.Count != 0)
			{
				return;
			}
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			foreach (GameObject val in roots)
			{
				if (val == null || !Object.op_Implicit((Object)(object)val) || !hashSet.Add(val))
				{
					continue;
				}
				Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val2 in componentsInChildren)
				{
					if (!rendererStates.ContainsKey(val2))
					{
						rendererStates.Add(val2, val2.enabled);
						val2.enabled = false;
					}
				}
				Graphic[] componentsInChildren2 = val.GetComponentsInChildren<Graphic>(true);
				foreach (Graphic val3 in componentsInChildren2)
				{
					if (!graphicStates.ContainsKey(val3))
					{
						graphicStates.Add(val3, ((Behaviour)val3).enabled);
						((Behaviour)val3).enabled = false;
					}
				}
			}
		}

		internal void Restore()
		{
			foreach (KeyValuePair<Renderer, bool> rendererState in rendererStates)
			{
				if (Object.op_Implicit((Object)(object)rendererState.Key))
				{
					rendererState.Key.enabled = rendererState.Value;
				}
			}
			foreach (KeyValuePair<Graphic, bool> graphicState in graphicStates)
			{
				if (Object.op_Implicit((Object)(object)graphicState.Key))
				{
					((Behaviour)graphicState.Key).enabled = graphicState.Value;
				}
			}
			rendererStates.Clear();
			graphicStates.Clear();
			Object.Destroy((Object)(object)this);
		}
	}
	[BepInPlugin("com.nolan.AdvancedRadarScanner", "Advanced Radar Scanner", "0.3.17")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_OnEnable <0>__RevealedObjectOnEnable;
		}

		public const string PluginGuid = "com.nolan.AdvancedRadarScanner";

		public const string PluginName = "Advanced Radar Scanner";

		public const string PluginVersion = "0.3.17";

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> EnableLegendaryChest { get; private set; }

		internal static ConfigEntry<bool> EnableMultishop { get; private set; }

		internal static ConfigEntry<bool> EnableScrapper { get; private set; }

		internal static ConfigEntry<bool> EnableEquipmentBarrel { get; private set; }

		internal static ConfigEntry<bool> EnableVoidCradle { get; private set; }

		internal static ConfigEntry<bool> EnableRadioScanner { get; private set; }

		internal static ConfigEntry<bool> EnableLunar { get; private set; }

		internal static ConfigEntry<KeyboardShortcut> ToggleIgnoreShortcut { get; private set; }

		internal static ConfigEntry<bool> ShareIgnoredMarkers { get; private set; }

		internal static ConfigEntry<bool> DebugLogging { get; private set; }

		private void Awake()
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			EnableLegendaryChest = ((BaseUnityPlugin)this).Config.Bind<bool>("Icons", "LegendaryChest", true, "Replace the Radar Scanner icon for legendary/gold chests.");
			EnableMultishop = ((BaseUnityPlugin)this).Config.Bind<bool>("Icons", "Multishop", true, "Replace the Radar Scanner icon for multishop terminals.");
			EnableScrapper = ((BaseUnityPlugin)this).Config.Bind<bool>("Icons", "Scrapper", true, "Replace the Radar Scanner icon for item scrappers.");
			EnableEquipmentBarrel = ((BaseUnityPlugin)this).Config.Bind<bool>("Icons", "EquipmentBarrel", true, "Replace the Radar Scanner icon for equipment barrels.");
			EnableVoidCradle = ((BaseUnityPlugin)this).Config.Bind<bool>("Icons", "VoidCradle", true, "Replace the Radar Scanner icon for void cradles.");
			EnableRadioScanner = ((BaseUnityPlugin)this).Config.Bind<bool>("Icons", "RadioScanner", true, "Replace the Radar Scanner icon for Radar Scanner interactables.");
			EnableLunar = ((BaseUnityPlugin)this).Config.Bind<bool>("Icons", "Lunar", true, "Replace the Radar Scanner icon for Lunar interactables.");
			ToggleIgnoreShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Ignore", "ToggleShortcut", new KeyboardShortcut((KeyCode)102, Array.Empty<KeyCode>()), "While aiming at an interactable, toggle whether Radar Scanner markers are hidden for it.");
			ShareIgnoredMarkers = ((BaseUnityPlugin)this).Config.Bind<bool>("Ignore", "ShareWithModdedClients", true, "When the host also enables this, synchronize ignored scanner markers only with clients that have this mod enabled.");
			DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "LogClassifications", false, "Log every scanner target and its selected advanced icon.");
			RuntimeIconFactory.Initialize();
			RadarIgnoreController.Initialize();
			object obj = <>O.<0>__RevealedObjectOnEnable;
			if (obj == null)
			{
				hook_OnEnable val = RevealedObjectOnEnable;
				<>O.<0>__RevealedObjectOnEnable = val;
				obj = (object)val;
			}
			RevealedObject.OnEnable += (hook_OnEnable)obj;
			Log.LogInfo((object)"Advanced Radar Scanner 0.3.17 loaded.");
		}

		private void Update()
		{
			try
			{
				RadarIgnoreController.Tick();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to toggle a scanner ignore marker: {arg}");
			}
		}

		private static void RevealedObjectOnEnable(orig_OnEnable orig, RevealedObject self)
		{
			orig.Invoke(self);
			try
			{
				RadarMarkerCustomizer.TryCustomize(self);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to customize scanner marker for {((Object)((Component)self).gameObject).name}: {arg}");
			}
		}

		private void OnDestroy()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__RevealedObjectOnEnable;
			if (obj == null)
			{
				hook_OnEnable val = RevealedObjectOnEnable;
				<>O.<0>__RevealedObjectOnEnable = val;
				obj = (object)val;
			}
			RevealedObject.OnEnable -= (hook_OnEnable)obj;
			RadarIgnoreController.Dispose();
			RuntimeIconFactory.Dispose();
		}
	}
	internal static class RadarIgnoreController
	{
		private enum MessageKind : byte
		{
			Hello = 1,
			HelloAcknowledgement,
			ToggleRequest,
			SetIgnored,
			Reset
		}

		private sealed class SharedIgnoreMessage : MessageBase
		{
			internal MessageKind Kind;

			internal NetworkInstanceId NetId;

			internal bool Value;

			internal SharedIgnoreMessage()
			{
			}

			internal SharedIgnoreMessage(MessageKind kind, NetworkInstanceId netId, bool value)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				Kind = kind;
				NetId = netId;
				Value = value;
			}

			public override void Deserialize(NetworkReader reader)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				Kind = (MessageKind)reader.ReadByte();
				NetId = reader.ReadNetworkId();
				Value = reader.ReadBoolean();
			}

			public override void Serialize(NetworkWriter writer)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				writer.Write((byte)Kind);
				writer.Write(NetId);
				writer.Write(Value);
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__OnStartServer;

			public static Action <1>__OnStopServer;

			public static Action<NetworkClient> <2>__OnStartClient;

			public static Action <3>__OnStopClient;

			public static Action<NetworkConnection> <4>__OnClientConnect;

			public static Action<NetworkConnection> <5>__OnServerDisconnect;

			public static Action<Stage> <6>__OnServerStageBegin;

			public static Action<Stage> <7>__OnStageStart;

			public static NetworkMessageDelegate <8>__OnServerMessage;

			public static NetworkMessageDelegate <9>__OnClientMessage;
		}

		private const short SharedIgnoreMessageType = 19073;

		private static readonly HashSet<int> ModdedConnectionIds = new HashSet<int>();

		private static readonly HashSet<NetworkInstanceId> SharedIgnoredIds = new HashSet<NetworkInstanceId>();

		private static NetworkClient? client;

		private static bool serverSupportsSharedIgnore;

		internal static void Initialize()
		{
			NetworkManagerSystem.onStartServerGlobal += OnStartServer;
			NetworkManagerSystem.onStopServerGlobal += OnStopServer;
			NetworkManagerSystem.onStartClientGlobal += OnStartClient;
			NetworkManagerSystem.onStopClientGlobal += OnStopClient;
			NetworkManagerSystem.onClientConnectGlobal += OnClientConnect;
			NetworkManagerSystem.onServerDisconnectGlobal += OnServerDisconnect;
			Stage.onServerStageBegin += OnServerStageBegin;
			Stage.onStageStartGlobal += OnStageStart;
		}

		internal static void Dispose()
		{
			NetworkManagerSystem.onStartServerGlobal -= OnStartServer;
			NetworkManagerSystem.onStopServerGlobal -= OnStopServer;
			NetworkManagerSystem.onStartClientGlobal -= OnStartClient;
			NetworkManagerSystem.onStopClientGlobal -= OnStopClient;
			NetworkManagerSystem.onClientConnectGlobal -= OnClientConnect;
			NetworkManagerSystem.onServerDisconnectGlobal -= OnServerDisconnect;
			Stage.onServerStageBegin -= OnServerStageBegin;
			Stage.onStageStartGlobal -= OnStageStart;
			if (NetworkServer.active)
			{
				NetworkServer.UnregisterHandler((short)19073);
			}
			NetworkClient? obj = client;
			if (obj != null)
			{
				obj.UnregisterHandler((short)19073);
			}
			client = null;
			serverSupportsSharedIgnore = false;
			ModdedConnectionIds.Clear();
			SharedIgnoredIds.Clear();
		}

		internal static void Tick()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = Plugin.ToggleIgnoreShortcut.Value;
			if (!((KeyboardShortcut)(ref value)).IsDown())
			{
				return;
			}
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			if (firstLocalUser == null || firstLocalUser.isUIFocused || !Object.op_Implicit((Object)(object)firstLocalUser.cachedBodyObject))
			{
				return;
			}
			InteractionDriver component = firstLocalUser.cachedBodyObject.GetComponent<InteractionDriver>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			GameObject val = component.currentInteractable;
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = component.FindBestInteractableObject();
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				Chat.AddMessage("<color=#F5D76E>[Advanced Radar Scanner]</color> 没有选中可交互物。");
				return;
			}
			string displayName = GetDisplayName(val);
			if (TryGetNetworkId(val, out var netId) && CanUseSharedIgnore())
			{
				RadarIgnoreMarker radarIgnoreMarker = FindMarker(val);
				if (Object.op_Implicit((Object)(object)radarIgnoreMarker))
				{
					((Behaviour)radarIgnoreMarker).enabled = false;
				}
				if (NetworkServer.active)
				{
					Chat.AddMessage(FormatToggleMessage(ToggleOnServer(netId), displayName, shared: true));
				}
				else if (client != null && client.isConnected)
				{
					SendToServer(MessageKind.ToggleRequest, netId);
					Chat.AddMessage("<color=#F5D76E>[Advanced Radar Scanner]</color> 已请求共享雷达标记:" + displayName);
				}
			}
			else
			{
				ToggleLocally(val, displayName);
			}
		}

		internal static bool IsIgnored(GameObject target)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (!IsLocallyIgnored(target))
			{
				if (TryGetNetworkId(target, out var netId))
				{
					return SharedIgnoredIds.Contains(netId);
				}
				return false;
			}
			return true;
		}

		private static bool CanUseSharedIgnore()
		{
			if (Plugin.ShareIgnoredMarkers.Value)
			{
				if (!NetworkServer.active)
				{
					return serverSupportsSharedIgnore;
				}
				return true;
			}
			return false;
		}

		private static void ToggleLocally(GameObject target, string displayName)
		{
			RadarIgnoreMarker radarIgnoreMarker = FindMarker(target);
			if (Object.op_Implicit((Object)(object)radarIgnoreMarker) && ((Behaviour)radarIgnoreMarker).enabled)
			{
				((Behaviour)radarIgnoreMarker).enabled = false;
				RadarMarkerCustomizer.RefreshIgnoreVisibility(target, ignored: false);
				Chat.AddMessage(FormatToggleMessage(isIgnored: false, displayName, shared: false));
				return;
			}
			if (radarIgnoreMarker == null)
			{
				radarIgnoreMarker = target.AddComponent<RadarIgnoreMarker>();
			}
			((Behaviour)radarIgnoreMarker).enabled = true;
			RadarMarkerCustomizer.RefreshIgnoreVisibility(target, ignored: true);
			Chat.AddMessage(FormatToggleMessage(isIgnored: true, displayName, shared: false));
		}

		private static bool ToggleOnServer(NetworkInstanceId netId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			bool flag = !SharedIgnoredIds.Contains(netId);
			SetIgnoredOnServer(netId, flag);
			return flag;
		}

		private static void SetIgnoredOnServer(NetworkInstanceId netId, bool isIgnored)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (isIgnored)
			{
				SharedIgnoredIds.Add(netId);
			}
			else
			{
				SharedIgnoredIds.Remove(netId);
			}
			RadarMarkerCustomizer.RefreshSharedIgnoreVisibility(netId, isIgnored);
			foreach (int moddedConnectionId in ModdedConnectionIds)
			{
				if (moddedConnectionId >= 0 && moddedConnectionId < NetworkServer.connections.Count)
				{
					NetworkConnection val = NetworkServer.connections[moddedConnectionId];
					if (val != null)
					{
						SendToClient(val, MessageKind.SetIgnored, netId, isIgnored);
					}
				}
			}
		}

		private static void OnStartServer()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			ModdedConnectionIds.Clear();
			SharedIgnoredIds.Clear();
			object obj = <>O.<8>__OnServerMessage;
			if (obj == null)
			{
				NetworkMessageDelegate val = OnServerMessage;
				<>O.<8>__OnServerMessage = val;
				obj = (object)val;
			}
			NetworkServer.RegisterHandler((short)19073, (NetworkMessageDelegate)obj);
		}

		private static void OnStopServer()
		{
			NetworkServer.UnregisterHandler((short)19073);
			ModdedConnectionIds.Clear();
			SharedIgnoredIds.Clear();
		}

		private static void OnStartClient(NetworkClient newClient)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			client = newClient;
			NetworkClient? obj = client;
			object obj2 = <>O.<9>__OnClientMessage;
			if (obj2 == null)
			{
				NetworkMessageDelegate val = OnClientMessage;
				<>O.<9>__OnClientMessage = val;
				obj2 = (object)val;
			}
			obj.RegisterHandler((short)19073, (NetworkMessageDelegate)obj2);
			serverSupportsSharedIgnore = NetworkServer.active && Plugin.ShareIgnoredMarkers.Value;
		}

		private static void OnStopClient()
		{
			NetworkClient? obj = client;
			if (obj != null)
			{
				obj.UnregisterHandler((short)19073);
			}
			client = null;
			serverSupportsSharedIgnore = false;
			SharedIgnoredIds.Clear();
		}

		private static void OnClientConnect(NetworkConnection _)
		{
			if (!NetworkServer.active && Plugin.ShareIgnoredMarkers.Value && client != null && client.isConnected)
			{
				SendToServer(MessageKind.Hello);
			}
		}

		private static void OnServerDisconnect(NetworkConnection connection)
		{
			ModdedConnectionIds.Remove(connection.connectionId);
		}

		private static void OnServerStageBegin(Stage _)
		{
			SharedIgnoredIds.Clear();
			foreach (int moddedConnectionId in ModdedConnectionIds)
			{
				if (moddedConnectionId >= 0 && moddedConnectionId < NetworkServer.connections.Count)
				{
					NetworkConnection val = NetworkServer.connections[moddedConnectionId];
					if (val != null)
					{
						SendToClient(val, MessageKind.Reset);
					}
				}
			}
		}

		private static void OnStageStart(Stage _)
		{
			if (!NetworkServer.active)
			{
				SharedIgnoredIds.Clear();
			}
		}

		private static void OnServerMessage(NetworkMessage message)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			SharedIgnoreMessage sharedIgnoreMessage = new SharedIgnoreMessage();
			((MessageBase)sharedIgnoreMessage).Deserialize(message.reader);
			switch (sharedIgnoreMessage.Kind)
			{
			case MessageKind.Hello:
				ModdedConnectionIds.Add(message.conn.connectionId);
				SendToClient(message.conn, MessageKind.HelloAcknowledgement, (NetworkInstanceId?)default(NetworkInstanceId), (bool?)Plugin.ShareIgnoredMarkers.Value);
				if (Plugin.ShareIgnoredMarkers.Value)
				{
					SendSnapshot(message.conn);
				}
				break;
			case MessageKind.ToggleRequest:
				if (Plugin.ShareIgnoredMarkers.Value && ModdedConnectionIds.Contains(message.conn.connectionId))
				{
					NetworkInstanceId netId = sharedIgnoreMessage.NetId;
					if (((NetworkInstanceId)(ref netId)).Value != 0)
					{
						ToggleOnServer(netId);
					}
				}
				break;
			}
		}

		private static void OnClientMessage(NetworkMessage message)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			SharedIgnoreMessage sharedIgnoreMessage = new SharedIgnoreMessage();
			((MessageBase)sharedIgnoreMessage).Deserialize(message.reader);
			switch (sharedIgnoreMessage.Kind)
			{
			case MessageKind.HelloAcknowledgement:
				serverSupportsSharedIgnore = sharedIgnoreMessage.Value;
				break;
			case MessageKind.SetIgnored:
				if (sharedIgnoreMessage.Value)
				{
					SharedIgnoredIds.Add(sharedIgnoreMessage.NetId);
				}
				else
				{
					SharedIgnoredIds.Remove(sharedIgnoreMessage.NetId);
				}
				RadarMarkerCustomizer.RefreshSharedIgnoreVisibility(sharedIgnoreMessage.NetId, sharedIgnoreMessage.Value);
				break;
			case MessageKind.Reset:
				SharedIgnoredIds.Clear();
				break;
			case MessageKind.ToggleRequest:
				break;
			}
		}

		private static void SendSnapshot(NetworkConnection connection)
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			SendToClient(connection, MessageKind.Reset);
			foreach (NetworkInstanceId sharedIgnoredId in SharedIgnoredIds)
			{
				SendToClient(connection, MessageKind.SetIgnored, sharedIgnoredId, true);
			}
		}

		private static void SendToServer(MessageKind kind, NetworkInstanceId? netId = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (client != null)
			{
				client.Send((short)19073, (MessageBase)(object)new SharedIgnoreMessage(kind, netId.GetValueOrDefault(), value: false));
			}
		}

		private static void SendToClient(NetworkConnection connection, MessageKind kind, NetworkInstanceId? netId = null, bool? value = null)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			connection.Send((short)19073, (MessageBase)(object)new SharedIgnoreMessage(kind, netId.GetValueOrDefault(), value == true));
		}

		private static bool TryGetNetworkId(GameObject target, out NetworkInstanceId netId)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			NetworkIdentity val = target.GetComponentInParent<NetworkIdentity>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = target.GetComponentInChildren<NetworkIdentity>(true);
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				NetworkInstanceId netId2 = val.netId;
				if (((NetworkInstanceId)(ref netId2)).Value != 0)
				{
					netId = val.netId;
					return true;
				}
			}
			netId = default(NetworkInstanceId);
			return false;
		}

		private static RadarIgnoreMarker? FindMarker(GameObject target)
		{
			RadarIgnoreMarker componentInParent = target.GetComponentInParent<RadarIgnoreMarker>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return target.GetComponentInChildren<RadarIgnoreMarker>(true);
			}
			return componentInParent;
		}

		private static bool IsLocallyIgnored(GameObject target)
		{
			RadarIgnoreMarker radarIgnoreMarker = FindMarker(target);
			if (Object.op_Implicit((Object)(object)radarIgnoreMarker))
			{
				return ((Behaviour)radarIgnoreMarker).enabled;
			}
			return false;
		}

		private static string GetDisplayName(GameObject target)
		{
			PurchaseInteraction val = target.GetComponentInParent<PurchaseInteraction>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = target.GetComponentInChildren<PurchaseInteraction>(true);
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				return val.GetDisplayName();
			}
			GenericDisplayNameProvider val2 = target.GetComponentInParent<GenericDisplayNameProvider>();
			if (!Object.op_Implicit((Object)(object)val2))
			{
				val2 = target.GetComponentInChildren<GenericDisplayNameProvider>(true);
			}
			if (!Object.op_Implicit((Object)(object)val2))
			{
				return ((Object)target).name;
			}
			return val2.GetDisplayName();
		}

		private static string FormatToggleMessage(bool isIgnored, string displayName, bool shared)
		{
			return "<color=#F5D76E>[Advanced Radar Scanner]</color> 已" + (isIgnored ? "忽略" : "恢复") + "雷达标记" + (shared ? "(已同步)" : "(仅本地)") + ":" + displayName;
		}
	}
	internal sealed class RadarIgnoreMarker : MonoBehaviour
	{
	}
	internal static class RadarMarkerCustomizer
	{
		private sealed class ActiveMarker
		{
			internal readonly RevealedObject RevealedObject;

			internal readonly PositionIndicator PositionIndicator;

			internal ActiveMarker(RevealedObject revealedObject, PositionIndicator positionIndicator)
			{
				RevealedObject = revealedObject;
				PositionIndicator = positionIndicator;
			}
		}

		private static readonly Dictionary<GameObject, List<ActiveMarker>> ActiveMarkers = new Dictionary<GameObject, List<ActiveMarker>>();

		internal static void TryCustomize(RevealedObject revealedObject)
		{
			PositionIndicator positionIndicator = revealedObject.positionIndicator;
			if (!Object.op_Implicit((Object)(object)positionIndicator))
			{
				Plugin.Log.LogWarning((object)("Scanner target " + ((Object)((Component)revealedObject).gameObject).name + " has no position indicator."));
				return;
			}
			RememberMarker(revealedObject, positionIndicator);
			CustomizeIcon(revealedObject, positionIndicator);
			if (RadarIgnoreController.IsIgnored(((Component)revealedObject).gameObject))
			{
				HideMarker(positionIndicator);
			}
		}

		private static void CustomizeIcon(RevealedObject revealedObject, PositionIndicator positionIndicator)
		{
			string fingerprint;
			AdvancedIconKind advancedIconKind = InteractableClassifier.Classify(((Component)revealedObject).gameObject, out fingerprint);
			if (!IsEnabled(advancedIconKind))
			{
				return;
			}
			Sprite val = RuntimeIconFactory.Get(advancedIconKind);
			if (val != null && Object.op_Implicit((Object)(object)val))
			{
				HashSet<GameObject> hashSet = new HashSet<GameObject>();
				ReplaceSprites(positionIndicator.insideViewObject, advancedIconKind, hashSet);
				ReplaceSprites(positionIndicator.outsideViewObject, advancedIconKind, hashSet);
				ReplaceSprites(positionIndicator.alwaysVisibleObject, advancedIconKind, hashSet);
				if (hashSet.Count == 0)
				{
					ReplaceSprites(((Component)positionIndicator).gameObject, advancedIconKind, hashSet);
				}
				if (Plugin.DebugLogging.Value)
				{
					Plugin.Log.LogInfo((object)($"Scanner target '{((Object)((Component)revealedObject).gameObject).name}' -> {advancedIconKind}; " + $"renderers={hashSet.Count}; fingerprint='{fingerprint}'"));
				}
			}
		}

		internal static void RefreshIgnoreVisibility(GameObject target, bool ignored)
		{
			if (!ignored)
			{
				RestoreForRelatedTarget(target);
				return;
			}
			List<GameObject> list = new List<GameObject>();
			foreach (KeyValuePair<GameObject, List<ActiveMarker>> activeMarker in ActiveMarkers)
			{
				if (!Object.op_Implicit((Object)(object)activeMarker.Key) || !IsRelated(target, activeMarker.Key))
				{
					continue;
				}
				list.Add(activeMarker.Key);
				foreach (ActiveMarker item in activeMarker.Value)
				{
					if (Object.op_Implicit((Object)(object)item.RevealedObject) && Object.op_Implicit((Object)(object)item.PositionIndicator) && ((Component)item.PositionIndicator).gameObject.activeInHierarchy)
					{
						SetMarkerVisibility(item.PositionIndicator, !ignored);
					}
				}
			}
			foreach (GameObject item2 in list)
			{
				ActiveMarkers[item2].RemoveAll((ActiveMarker marker) => !Object.op_Implicit((Object)(object)marker.RevealedObject) || !Object.op_Implicit((Object)(object)marker.PositionIndicator));
				if (ActiveMarkers[item2].Count == 0)
				{
					ActiveMarkers.Remove(item2);
				}
			}
		}

		private static bool IsEnabled(AdvancedIconKind kind)
		{
			return kind switch
			{
				AdvancedIconKind.LegendaryChest => Plugin.EnableLegendaryChest.Value, 
				AdvancedIconKind.Multishop => Plugin.EnableMultishop.Value, 
				AdvancedIconKind.Scrapper => Plugin.EnableScrapper.Value, 
				AdvancedIconKind.EquipmentBarrel => Plugin.EnableEquipmentBarrel.Value, 
				AdvancedIconKind.VoidCradle => Plugin.EnableVoidCradle.Value, 
				AdvancedIconKind.RadioScanner => Plugin.EnableRadioScanner.Value, 
				AdvancedIconKind.Lunar => Plugin.EnableLunar.Value, 
				_ => false, 
			};
		}

		private static void HideMarker(PositionIndicator positionIndicator)
		{
			SetMarkerVisibility(positionIndicator, visible: false);
		}

		private static void SetMarkerVisibility(PositionIndicator positionIndicator, bool visible)
		{
			MarkerVisibilityState markerVisibilityState = ((Component)positionIndicator).GetComponent<MarkerVisibilityState>();
			if (visible)
			{
				if (Object.op_Implicit((Object)(object)markerVisibilityState))
				{
					markerVisibilityState.Restore();
				}
				return;
			}
			if (!Object.op_Implicit((Object)(object)markerVisibilityState))
			{
				markerVisibilityState = ((Component)positionIndicator).gameObject.AddComponent<MarkerVisibilityState>();
			}
			markerVisibilityState.Hide(positionIndicator.insideViewObject, positionIndicator.outsideViewObject, positionIndicator.alwaysVisibleObject, ((Component)positionIndicator).gameObject);
		}

		private static void RememberMarker(RevealedObject revealedObject, PositionIndicator positionIndicator)
		{
			GameObject gameObject = ((Component)revealedObject).gameObject;
			if (!ActiveMarkers.TryGetValue(gameObject, out List<ActiveMarker> value))
			{
				value = new List<ActiveMarker>();
				ActiveMarkers[gameObject] = value;
			}
			if (!value.Exists((ActiveMarker marker) => (Object)(object)marker.RevealedObject == (Object)(object)revealedObject))
			{
				value.Add(new ActiveMarker(revealedObject, positionIndicator));
			}
		}

		private static bool IsRelated(GameObject first, GameObject second)
		{
			if (!((Object)(object)first == (Object)(object)second) && !first.transform.IsChildOf(second.transform))
			{
				return second.transform.IsChildOf(first.transform);
			}
			return true;
		}

		internal static void RefreshSharedIgnoreVisibility(NetworkInstanceId netId, bool ignored)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = ClientScene.FindLocalObject(netId);
			if (Object.op_Implicit((Object)(object)val))
			{
				RefreshIgnoreVisibility(val, ignored);
			}
		}

		private static void RestoreForRelatedTarget(GameObject target)
		{
			foreach (KeyValuePair<GameObject, List<ActiveMarker>> activeMarker in ActiveMarkers)
			{
				if (!Object.op_Implicit((Object)(object)activeMarker.Key) || !IsRelated(target, activeMarker.Key))
				{
					continue;
				}
				foreach (ActiveMarker item in activeMarker.Value)
				{
					if (Object.op_Implicit((Object)(object)item.PositionIndicator) && ((Component)item.PositionIndicator).gameObject.activeInHierarchy)
					{
						SetMarkerVisibility(item.PositionIndicator, visible: true);
					}
				}
			}
		}

		private static void ReplaceSprites(GameObject? root, AdvancedIconKind kind, ISet<GameObject> modifiedObjects)
		{
			if (root == null || !Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			SpriteRenderer[] componentsInChildren = root.GetComponentsInChildren<SpriteRenderer>(true);
			foreach (SpriteRenderer val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val.sprite))
				{
					Sprite sizedLike = RuntimeIconFactory.GetSizedLike(kind, val.sprite);
					if (sizedLike != null && Object.op_Implicit((Object)(object)sizedLike))
					{
						val.sprite = sizedLike;
						modifiedObjects.Add(((Component)val).gameObject);
					}
				}
			}
			Image[] componentsInChildren2 = root.GetComponentsInChildren<Image>(true);
			foreach (Image val2 in componentsInChildren2)
			{
				if (Object.op_Implicit((Object)(object)val2.sprite))
				{
					Sprite val3 = RuntimeIconFactory.Get(kind);
					if (val3 != null && Object.op_Implicit((Object)(object)val3))
					{
						val2.sprite = val3;
						modifiedObjects.Add(((Component)val2).gameObject);
					}
				}
			}
		}
	}
	internal static class RuntimeIconFactory
	{
		private const int Size = 64;

		private static readonly Dictionary<AdvancedIconKind, Sprite> Sprites = new Dictionary<AdvancedIconKind, Sprite>();

		private static readonly Dictionary<string, Sprite> SizedSprites = new Dictionary<string, Sprite>();

		private static readonly List<Texture2D> Textures = new List<Texture2D>();

		private static readonly Color32 Ink = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);

		private static readonly Color32 Clear = new Color32((byte)0, (byte)0, (byte)0, (byte)0);

		private static readonly Color32 Outline = new Color32((byte)0, (byte)0, (byte)0, (byte)125);

		internal static void Initialize()
		{
			if (Sprites.Count != 0)
			{
				return;
			}
			foreach (AdvancedIconKind value in Enum.GetValues(typeof(AdvancedIconKind)))
			{
				if (value != AdvancedIconKind.None)
				{
					Sprites[value] = Create(value);
				}
			}
		}

		internal static Sprite? Get(AdvancedIconKind kind)
		{
			if (!Sprites.TryGetValue(kind, out Sprite value))
			{
				return null;
			}
			return value;
		}

		internal static Sprite? GetSizedLike(AdvancedIconKind kind, Sprite reference)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = Get(kind);
			if (val == null || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)reference))
			{
				return val;
			}
			Bounds bounds = reference.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			float num = Mathf.Max(size.x, size.y);
			if (num <= 0f)
			{
				return val;
			}
			float num2 = 64f / num;
			int num3 = Mathf.Max(1, Mathf.RoundToInt(num2 * 1000f));
			string key = $"{kind}:{num3}";
			if (SizedSprites.TryGetValue(key, out Sprite value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			Sprite val2 = Sprite.Create(val.texture, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), (float)num3 / 1000f);
			((Object)val2).name = $"{((Object)val).name}_Sized_{num3}";
			((Object)val2).hideFlags = (HideFlags)61;
			SizedSprites[key] = val2;
			return val2;
		}

		internal static void Dispose()
		{
			foreach (Sprite value in SizedSprites.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)value);
				}
			}
			foreach (Sprite value2 in Sprites.Values)
			{
				if (Object.op_Implicit((Object)(object)value2))
				{
					Object.Destroy((Object)(object)value2);
				}
			}
			foreach (Texture2D texture in Textures)
			{
				if (Object.op_Implicit((Object)(object)texture))
				{
					Object.Destroy((Object)(object)texture);
				}
			}
			SizedSprites.Clear();
			Sprites.Clear();
			Textures.Clear();
		}

		private static Sprite Create(AdvancedIconKind kind)
		{
			//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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[4096];
			Draw(kind, array);
			AddTransparentOutline(array);
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
			{
				name = $"AdvancedRadarScanner_{kind}",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1,
				hideFlags = (HideFlags)61
			};
			val.SetPixels32(array);
			val.Apply(false, true);
			Textures.Add(val);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f);
			((Object)obj).name = ((Object)val).name;
			((Object)obj).hideFlags = (HideFlags)61;
			return obj;
		}

		private static void Draw(AdvancedIconKind kind, Color32[] pixels)
		{
			switch (kind)
			{
			case AdvancedIconKind.LegendaryChest:
				DrawChest(pixels);
				break;
			case AdvancedIconKind.Multishop:
				DrawMultishop(pixels);
				break;
			case AdvancedIconKind.Scrapper:
				DrawScrapper(pixels);
				break;
			case AdvancedIconKind.EquipmentBarrel:
				DrawEquipmentBarrel(pixels);
				break;
			case AdvancedIconKind.VoidCradle:
				DrawVoidCradle(pixels);
				break;
			case AdvancedIconKind.RadioScanner:
				DrawRadioScanner(pixels);
				break;
			case AdvancedIconKind.Lunar:
				DrawLunar(pixels);
				break;
			}
		}

		private static void DrawChest(Color32[] pixels)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			FillRect(pixels, 8, 14, 56, 40, Ink);
			FillRect(pixels, 6, 38, 58, 48, Ink);
			FillRect(pixels, 8, 30, 56, 33, Clear);
			FillRect(pixels, 28, 14, 35, 40, Clear);
			FillStar(pixels, 32, 40, 9, 4, Clear);
		}

		private static void DrawMultishop(Color32[] pixels)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			FillRect(pixels, 6, 20, 21, 44, Ink);
			FillRect(pixels, 24, 14, 40, 50, Ink);
			FillRect(pixels, 43, 20, 58, 44, Ink);
			FillRect(pixels, 10, 31, 17, 38, Clear);
			FillRect(pixels, 28, 35, 36, 43, Clear);
			FillRect(pixels, 47, 31, 54, 38, Clear);
		}

		private static void DrawScrapper(Color32[] pixels)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			FillRect(pixels, 8, 7, 56, 46, Ink);
			FillDiamond(pixels, 32, 53, 5, Clear);
			FillRect(pixels, 29, 37, 35, 46, Clear);
			FillTriangle(pixels, 24, 38, 40, 38, 32, 29, Clear);
			FillRect(pixels, 13, 10, 51, 13, Clear);
			FillTriangle(pixels, 12, 30, 22, 30, 17, 20, Clear);
			FillTriangle(pixels, 22, 30, 32, 30, 27, 20, Clear);
			FillTriangle(pixels, 32, 30, 42, 30, 37, 20, Clear);
			FillTriangle(pixels, 42, 30, 52, 30, 47, 20, Clear);
		}

		private static void DrawEquipmentBarrel(Color32[] pixels)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			FillRect(pixels, 13, 17, 51, 47, Ink);
			FillEllipse(pixels, 32, 47, 19, 7, Ink);
			FillEllipse(pixels, 32, 17, 19, 7, Ink);
			DrawLine(pixels, 15, 27, 49, 27, 3, Clear);
			DrawLine(pixels, 15, 38, 49, 38, 3, Clear);
			DrawLine(pixels, 37, 40, 28, 31, 5, Clear);
			DrawLine(pixels, 28, 31, 36, 31, 5, Clear);
			DrawLine(pixels, 36, 31, 27, 21, 5, Clear);
		}

		private static void DrawVoidCradle(Color32[] pixels)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			FillEllipse(pixels, 32, 31, 22, 26, Ink);
			FillCircle(pixels, 32, 29, 10, Clear);
			FillTriangle(pixels, 25, 56, 39, 56, 32, 44, Clear);
			FillRect(pixels, 27, 48, 37, 59, Clear);
			FillRect(pixels, 30, 42, 34, 54, Clear);
		}

		private static void DrawRadioScanner(Color32[] pixels)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			DrawArc(pixels, 32, 33, 24, -0.34, 3.48, 6);
			DrawArc(pixels, 32, 33, 16, -0.34, 3.48, 6);
			FillCircle(pixels, 32, 33, 8);
			FillRect(pixels, 29, 12, 35, 33, Ink);
			FillEllipse(pixels, 32, 11, 13, 6, Ink);
		}

		private static void DrawLunar(Color32[] pixels)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			FillCircle(pixels, 31, 32, 24, Ink);
			FillCircle(pixels, 42, 39, 22, Clear);
		}

		private static void DrawBox(Color32[] pixels, int left, int bottom, int right, int top, int thickness)
		{
			DrawLine(pixels, left, bottom, right, bottom, thickness);
			DrawLine(pixels, right, bottom, right, top, thickness);
			DrawLine(pixels, right, top, left, top, thickness);
			DrawLine(pixels, left, top, left, bottom, thickness);
		}

		private static void AddTransparentOutline(Color32[] pixels)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])pixels.Clone();
			bool[] array2 = FindExteriorTransparentPixels(array);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = i * 64 + j;
					if (array[num].a != 0)
					{
						continue;
					}
					int num2 = int.MaxValue;
					for (int k = -4; k <= 4; k++)
					{
						for (int l = -4; l <= 4; l++)
						{
							int num3 = j + l;
							int num4 = i + k;
							if ((uint)num3 < 64u && (uint)num4 < 64u && array[num4 * 64 + num3].a != 0)
							{
								int num5 = l * l + k * k;
								if (num5 < num2)
								{
									num2 = num5;
								}
							}
						}
					}
					int num6 = (array2[num] ? 16 : 4);
					if (num2 <= num6)
					{
						pixels[num] = Outline;
					}
				}
			}
		}

		private static bool[] FindExteriorTransparentPixels(Color32[] pixels)
		{
			bool[] exterior = new bool[4096];
			Queue<int> queue = new Queue<int>();
			for (int i = 0; i < 64; i++)
			{
				EnqueueTransparent(0, i);
				EnqueueTransparent(63, i);
				EnqueueTransparent(i, 0);
				EnqueueTransparent(i, 63);
			}
			while (queue.Count != 0)
			{
				int num = queue.Dequeue();
				int num2 = num % 64;
				int num3 = num / 64;
				EnqueueTransparent(num2 - 1, num3);
				EnqueueTransparent(num2 + 1, num3);
				EnqueueTransparent(num2, num3 - 1);
				EnqueueTransparent(num2, num3 + 1);
			}
			return exterior;
			void EnqueueTransparent(int x, int y)
			{
				if ((uint)x < 64u && (uint)y < 64u)
				{
					int num4 = y * 64 + x;
					if (!exterior[num4] && pixels[num4].a == 0)
					{
						exterior[num4] = true;
						queue.Enqueue(num4);
					}
				}
			}
		}

		private static void FillRect(Color32[] pixels, int left, int bottom, int right, int top, Color32 color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = bottom; i <= top; i++)
			{
				for (int j = left; j <= right; j++)
				{
					SetPixel(pixels, j, i, color);
				}
			}
		}

		private static void FillEllipse(Color32[] pixels, int centerX, int centerY, int radiusX, int radiusY, Color32 color)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			int num = radiusX * radiusX;
			int num2 = radiusY * radiusY;
			int num3 = num * num2;
			for (int i = centerY - radiusY; i <= centerY + radiusY; i++)
			{
				for (int j = centerX - radiusX; j <= centerX + radiusX; j++)
				{
					int num4 = j - centerX;
					int num5 = i - centerY;
					if (num4 * num4 * num2 + num5 * num5 * num <= num3)
					{
						SetPixel(pixels, j, i, color);
					}
				}
			}
		}

		private static void FillStar(Color32[] pixels, int centerX, int centerY, int outerRadius, int innerRadius, Color32 color)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			(int, int)[] array = new(int, int)[10];
			for (int i = 0; i < array.Length; i++)
			{
				int num = ((i % 2 == 0) ? outerRadius : innerRadius);
				double num2 = Math.PI / 2.0 + (double)i * Math.PI / 5.0;
				array[i] = (centerX + (int)Math.Round(Math.Cos(num2) * (double)num), centerY + (int)Math.Round(Math.Sin(num2) * (double)num));
			}
			int num3 = centerX - outerRadius;
			int num4 = centerX + outerRadius;
			int num5 = centerY - outerRadius;
			int num6 = centerY + outerRadius;
			for (int j = num5; j <= num6; j++)
			{
				for (int k = num3; k <= num4; k++)
				{
					if (IsInsidePolygon(k, j, array))
					{
						SetPixel(pixels, k, j, color);
					}
				}
			}
		}

		private static void FillDiamond(Color32[] pixels, int centerX, int centerY, int radius, Color32 color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			FillTriangle(pixels, centerX, centerY + radius, centerX + radius, centerY, centerX, centerY, color);
			FillTriangle(pixels, centerX + radius, centerY, centerX, centerY - radius, centerX, centerY, color);
			FillTriangle(pixels, centerX, centerY - radius, centerX - radius, centerY, centerX, centerY, color);
			FillTriangle(pixels, centerX - radius, centerY, centerX, centerY + radius, centerX, centerY, color);
		}

		private static bool IsInsidePolygon(int x, int y, (int X, int Y)[] points)
		{
			bool flag = false;
			int num = 0;
			int num2 = points.Length - 1;
			while (num < points.Length)
			{
				(int, int) tuple = points[num];
				(int, int) tuple2 = points[num2];
				if (tuple.Item2 > y != tuple2.Item2 > y && (double)x < (double)((tuple2.Item1 - tuple.Item1) * (y - tuple.Item2)) / (double)(tuple2.Item2 - tuple.Item2) + (double)tuple.Item1)
				{
					flag = !flag;
				}
				num2 = num++;
			}
			return flag;
		}

		private static void DrawEllipse(Color32[] pixels, int centerX, int centerY, int radiusX, int radiusY, int thickness)
		{
			int x = centerX + radiusX;
			int y = centerY;
			for (int i = 1; i <= 48; i++)
			{
				double num = (double)i * Math.PI * 2.0 / 48.0;
				int num2 = centerX + (int)Math.Round(Math.Cos(num) * (double)radiusX);
				int num3 = centerY + (int)Math.Round(Math.Sin(num) * (double)radiusY);
				DrawLine(pixels, x, y, num2, num3, thickness);
				x = num2;
				y = num3;
			}
		}

		private static void DrawArc(Color32[] pixels, int centerX, int centerY, int radius, double startAngle, double endAngle, int thickness)
		{
			int x = centerX + (int)Math.Round(Math.Cos(startAngle) * (double)radius);
			int y = centerY + (int)Math.Round(Math.Sin(startAngle) * (double)radius);
			for (int i = 1; i <= 48; i++)
			{
				double num = startAngle + (endAngle - startAngle) * (double)i / 48.0;
				int num2 = centerX + (int)Math.Round(Math.Cos(num) * (double)radius);
				int num3 = centerY + (int)Math.Round(Math.Sin(num) * (double)radius);
				DrawLine(pixels, x, y, num2, num3, thickness);
				x = num2;
				y = num3;
			}
		}

		private static void FillCircle(Color32[] pixels, int centerX, int centerY, int radius)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			FillCircle(pixels, centerX, centerY, radius, Ink);
		}

		private static void FillCircle(Color32[] pixels, int centerX, int centerY, int radius, Color32 color)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			int num = radius * radius;
			for (int i = centerY - radius; i <= centerY + radius; i++)
			{
				for (int j = centerX - radius; j <= centerX + radius; j++)
				{
					if ((j - centerX) * (j - centerX) + (i - centerY) * (i - centerY) <= num)
					{
						SetPixel(pixels, j, i, color);
					}
				}
			}
		}

		private static void FillTriangle(Color32[] pixels, int ax, int ay, int bx, int by, int cx, int cy)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			FillTriangle(pixels, ax, ay, bx, by, cx, cy, Ink);
		}

		private static void FillTriangle(Color32[] pixels, int ax, int ay, int bx, int by, int cx, int cy, Color32 color)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			int num = Math.Min(ax, Math.Min(bx, cx));
			int num2 = Math.Max(ax, Math.Max(bx, cx));
			int num3 = Math.Min(ay, Math.Min(by, cy));
			int num4 = Math.Max(ay, Math.Max(by, cy));
			for (int i = num3; i <= num4; i++)
			{
				for (int j = num; j <= num2; j++)
				{
					int num5 = Sign(j, i, ax, ay, bx, by);
					int num6 = Sign(j, i, bx, by, cx, cy);
					int num7 = Sign(j, i, cx, cy, ax, ay);
					if ((num5 >= 0 && num6 >= 0 && num7 >= 0) || (num5 <= 0 && num6 <= 0 && num7 <= 0))
					{
						SetPixel(pixels, j, i, color);
					}
				}
			}
		}

		private static int Sign(int px, int py, int ax, int ay, int bx, int by)
		{
			return (px - bx) * (ay - by) - (ax - bx) * (py - by);
		}

		private static void DrawLine(Color32[] pixels, int x0, int y0, int x1, int y1, int thickness)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			DrawLine(pixels, x0, y0, x1, y1, thickness, Ink);
		}

		private static void DrawLine(Color32[] pixels, int x0, int y0, int x1, int y1, int thickness, Color32 color)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			int num = Math.Abs(x1 - x0);
			int num2 = ((x0 < x1) ? 1 : (-1));
			int num3 = -Math.Abs(y1 - y0);
			int num4 = ((y0 < y1) ? 1 : (-1));
			int num5 = num + num3;
			int radius = Math.Max(0, thickness / 2);
			while (true)
			{
				FillCircle(pixels, x0, y0, radius, color);
				if (x0 != x1 || y0 != y1)
				{
					int num6 = 2 * num5;
					if (num6 >= num3)
					{
						num5 += num3;
						x0 += num2;
					}
					if (num6 <= num)
					{
						num5 += num;
						y0 += num4;
					}
					continue;
				}
				break;
			}
		}

		private static void SetPixel(Color32[] pixels, int x, int y, Color32 color)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((uint)x < 64u && (uint)y < 64u)
			{
				pixels[y * 64 + x] = color;
			}
		}
	}
}