Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AdvancedRadarScanner v0.3.17
plugins/AdvancedRadarScanner/AdvancedRadarScanner.dll
Decompiled 18 minutes agousing 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; } } } }