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 SuperScanner v1.2.3
Zichen-SuperScanner-1.2.3.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Zichen-SuperScanner-1.2.3")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e407da6838a3ec7f66798960e4d3c98780b8058c")] [assembly: AssemblyProduct("Zichen-SuperScanner-1.2.3")] [assembly: AssemblyTitle("Zichen-SuperScanner-1.2.3")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } public enum DisplayLanguage { 中文, English } [BepInPlugin("zichen.superscanner", "Super Scanner", "1.2.3")] public class ZichenSuperScannerPlugin : BaseUnityPlugin { private sealed class EnemyLabelInfo { public Enemy Enemy; public string Name = string.Empty; public Transform ReferenceTransform; public float LabelYOffset; public float DistanceSquared; public int CachedDistanceMeters = -1; public bool CachedShowDistance; public bool CachedIsMasked; public string PlainText = string.Empty; public string RichText = string.Empty; public float NextRuntimeRefreshTime; public int CachedLayoutFontSize = int.MinValue; public Vector2 CachedLayoutSize; } private struct EnemyFrameState { public bool IsUsable; public bool IsAliveAndSpawned; public Transform ReferenceTransform; public Vector3 ReferencePosition; } private enum TeamShareMode { None, Valuable, LotteryCoinBox } private sealed class ScanLabel { public Component Target; public PhysGrabObject PhysGrabObject; public Renderer[] Renderers = Array.Empty<Renderer>(); public string DisplayName = string.Empty; public bool IsValuable; public bool IsItem; public bool IsCart; public bool IsLotteryCoinBox; public bool IsSmallCart; public bool IsVehicle; public bool IsRacingVehicle; public bool IsTeammate; public bool IsDeadTeammate; public string ColorHex = "#62d8ff"; public Vector3 Position; public Vector3 LastAnchorPosition; public bool HasAnchorPosition; public string PlainText = string.Empty; public string RichText = string.Empty; public float DistanceSquared; public int DistanceMeters; public int CachedTextDistanceMeters = int.MinValue; public int CachedTextValue = int.MinValue; public bool CachedShowDistanceMeters; public bool CachedShowValuableNames; public bool CachedShowValuablePrices; public bool CachedIsMasked; public TeamShareMode ShareMode; public bool SharedWithTeam; public float NextRuntimeRefreshTime; public int CachedLayoutFontSize = int.MinValue; public Vector2 CachedLayoutSize; } private struct CartScanInfo { public bool IsCart; public bool IsSmallCart; } internal sealed class CfgI18N { public string SectionCN; public string SectionEN; public string KeyCN; public string KeyEN; public string DisplayEN; public string DescCN; public string DescEN; public ConfigurationManagerAttributes Attrs; public string ValueEN; public string ValueCN; public ConfigEntry<string> ReadOnlyEntry; public ConfigEntryBase Entry; } internal sealed class LiveLabel { public WeakReference<TextMeshProUGUI> Tmp; public CfgI18N I18N; public bool IsSection; } internal sealed class LiveValue { public WeakReference<Object> InputField; public CfgI18N I18N; } internal sealed class LiveSliderOptions { public WeakReference<Object> Slider; public CfgI18N I18N; public string[] OptionsCN; public string[] OptionsEN; } internal sealed class LiveToggleButtons { public WeakReference<TextMeshProUGUI> LeftTmp; public WeakReference<TextMeshProUGUI> RightTmp; } [CompilerGenerated] private sealed class <GetComponentTypeNames>d__411 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IDisposable, IEnumerator { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private GameObject gameObject; public GameObject <>3__gameObject; private Component[] <components>5__2; private int <i>5__3; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetComponentTypeNames>d__411(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <components>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_0079; } <>1__state = -1; if ((Object)(object)gameObject == (Object)null) { return false; } <components>5__2 = gameObject.GetComponents<Component>(); <i>5__3 = 0; goto IL_0089; IL_0079: <i>5__3++; goto IL_0089; IL_0089: if (<i>5__3 < <components>5__2.Length) { Component val = <components>5__2[<i>5__3]; if (!((Object)(object)val == (Object)null)) { <>2__current = ((object)val).GetType().Name; <>1__state = 1; return true; } goto IL_0079; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { <GetComponentTypeNames>d__411 <GetComponentTypeNames>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetComponentTypeNames>d__ = this; } else { <GetComponentTypeNames>d__ = new <GetComponentTypeNames>d__411(0); } <GetComponentTypeNames>d__.gameObject = <>3__gameObject; return <GetComponentTypeNames>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <ResourceNameDumpCoroutine>d__403 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZichenSuperScannerPlugin <>4__this; private float <startTime>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ResourceNameDumpCoroutine>d__403(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown int num = <>1__state; ZichenSuperScannerPlugin zichenSuperScannerPlugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <startTime>5__2 = Time.unscaledTime; break; case 1: <>1__state = -1; break; } if (!AreResourceDumpSourcesReady()) { if (Time.unscaledTime - <startTime>5__2 >= 30f) { ((BaseUnityPlugin)zichenSuperScannerPlugin).Logger.LogWarning((object)"[NameDump] Timed out waiting for item and level resources."); return false; } <>2__current = (object)new WaitForSecondsRealtime(1f); <>1__state = 1; return true; } zichenSuperScannerPlugin.DumpItemResources(); zichenSuperScannerPlugin.DumpValuableResources(); ((BaseUnityPlugin)zichenSuperScannerPlugin).Logger.LogInfo((object)"[NameDump] Completed item and valuable resource dump."); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGuid = "zichen.superscanner"; public const string PluginVersion = "1.2.3"; public const string PluginName = "Super Scanner"; private static ZichenSuperScannerPlugin Instance; private const string LotteryCoinBoxNameZh = "装饰箱"; private const string LotteryCoinBoxNameEn = "Decor Box"; private const int MinimumScanIntervalSeconds = 1; private const int MaximumScanIntervalSeconds = 5; private const int FixedScanHoldSeconds = 5; private const int MinimumScanDistanceMeters = 1; private const int MaximumScanDistanceMeters = 100; private const int TeamShareMaxDistanceMeters = 15; private const float ContainmentRefreshIntervalSeconds = 0.12f; private const int FarFontShrinkPercent = 30; private const float FontScaleDistanceMeters = 30f; private const float EnemyRefreshIntervalSeconds = 0.25f; private const float EnemyProximityRefreshIntervalSeconds = 0.12f; private const float EnemyLabelRefreshIntervalSeconds = 0.12f; private const float EnemyListCleanupIntervalSeconds = 1f; private const float ValuableValueRefreshIntervalSeconds = 0.12f; private const float LocalPlayerRefreshIntervalSeconds = 0.25f; private const float ScanLabelRefreshIntervalSeconds = 0.08f; private static readonly bool EnableStartupResourceNameDump = false; private static readonly bool EnableScanDebugLogging = false; private static readonly FieldInfo ValuableCurrentValueField = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ValuableValueSetField = typeof(ValuableObject).GetField("dollarValueSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ValuablePhysGrabObjectField = typeof(ValuableObject).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemNameField = typeof(ItemAttributes).GetField("itemName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemPhysGrabObjectField = typeof(ItemAttributes).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemShopItemField = typeof(ItemAttributes).GetField("shopItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemPromptNameField = typeof(ItemAttributes).GetField("promptName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemAssetNameField = typeof(ItemAttributes).GetField("itemAssetName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemInstanceNameField = typeof(ItemAttributes).GetField("instanceName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemTagField = typeof(ItemAttributes).GetField("itemTag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemTypeField = typeof(ItemAttributes).GetField("itemType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemEquippableField = typeof(ItemAttributes).GetField("itemEquippable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabObjectDeadField = typeof(PhysGrabObject).GetField("dead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabObjectIsHiddenField = typeof(PhysGrabObject).GetField("isHidden", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabObjectImpactDetectorField = typeof(PhysGrabObject).GetField("impactDetector", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabObjectPlayerGrabbingField = typeof(PhysGrabObject).GetField("playerGrabbing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabObjectImpactDetectorInCartField = typeof(PhysGrabObjectImpactDetector).GetField("inCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabberGrabbedPhysGrabObjectField = typeof(PhysGrabber).GetField("grabbedPhysGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabberGrabbedField = typeof(PhysGrabber).GetField("grabbed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabberPlayerAvatarField = typeof(PhysGrabber).GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabCartItemsInCartField = typeof(PhysGrabCart).GetField("itemsInCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabCartInCartField = typeof(PhysGrabCart).GetField("physGrabInCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabCartIsSmallField = typeof(PhysGrabCart).GetField("isSmallCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabInCartObjectsField = typeof(PhysGrabInCart).GetField("inCartObjects", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PhysGrabInCartCartObjectPhysGrabObjectField = typeof(PhysGrabInCart).GetNestedType("CartObject", BindingFlags.Public | BindingFlags.NonPublic)?.GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo RoundDirectorInstanceField = typeof(RoundDirector).GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo RoundDirectorDollarHaulListField = typeof(RoundDirector).GetField("dollarHaulList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo RoundDirectorValuableBoxHaulListField = typeof(RoundDirector).GetField("valuableBoxHaulList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ValuableDiscoverCustomPhysGrabObjectField = typeof(ValuableDiscoverCustom).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ValuableDiscoverCustomColorCornerField = typeof(ValuableDiscoverCustom).GetField("colorCorner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ValuableObjectDiscoveredField = typeof(ValuableObject).GetField("discovered", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ValuableDiscoverCustomDiscoveredField = typeof(ValuableDiscoverCustom).GetField("discovered", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyParentField = typeof(Enemy).GetField("EnemyParent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyParentEnemyField = typeof(EnemyParent).GetField("Enemy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyParentNameField = typeof(EnemyParent).GetField("enemyName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyParentLocalizedNameField = typeof(EnemyParent).GetField("enemyNameLocalized", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly MethodInfo LocalizedAssetGetStringMethod = typeof(LocalizedAsset).GetMethod("GetLocalizedString", Type.EmptyTypes); private static readonly FieldInfo EnemyParentSpawnedField = typeof(EnemyParent).GetField("Spawned", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyHealthField = typeof(Enemy).GetField("Health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyHealthDeadField = typeof(EnemyHealth).GetField("dead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyCenterTransformField = typeof(Enemy).GetField("CenterTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo EnemyTypeField = typeof(Enemy).GetField("Type", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerIsLocalField = typeof(PlayerAvatar).GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerTransformField = typeof(PlayerAvatar).GetField("playerTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerDeadSetField = typeof(PlayerAvatar).GetField("deadSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerSpectatingField = typeof(PlayerAvatar).GetField("spectating", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerIsDisabledField = typeof(PlayerAvatar).GetField("isDisabled", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ItemVehicleIsRacingField = typeof(ItemVehicle).GetField("isRacingVehicle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerNameField = typeof(PlayerAvatar).GetField("playerName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerDeathHeadField = typeof(PlayerAvatar).GetField("playerDeathHead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo DeathHeadPhysGrabObjectField = typeof(PlayerDeathHead).GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo DeathHeadTriggeredPositionField = typeof(PlayerDeathHead).GetField("triggeredPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo DeathHeadOverridePositionTransformField = typeof(PlayerDeathHead).GetField("overridePositionTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo PlayerLastNavmeshPositionField = typeof(PlayerAvatar).GetField("LastNavmeshPosition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private readonly List<ScanLabel> labels = new List<ScanLabel>(); private readonly Stack<ScanLabel> scanLabelPool = new Stack<ScanLabel>(); private readonly Dictionary<int, GUIStyle> labelStyleCache = new Dictionary<int, GUIStyle>(); private readonly Dictionary<int, GUIStyle> enemyLabelStyleCache = new Dictionary<int, GUIStyle>(); private readonly Dictionary<int, Renderer[]> objectRendererCache = new Dictionary<int, Renderer[]>(); private readonly Dictionary<int, string> objectDisplayNameCache = new Dictionary<int, string>(); private readonly Dictionary<int, PhysGrabObject> objectPhysGrabCache = new Dictionary<int, PhysGrabObject>(); private readonly Dictionary<int, bool> itemHasValuableCache = new Dictionary<int, bool>(); private readonly Dictionary<int, bool> itemShopItemCache = new Dictionary<int, bool>(); private readonly Dictionary<int, CartScanInfo> itemCartInfoCache = new Dictionary<int, CartScanInfo>(); private readonly Dictionary<int, bool> itemShouldScanCache = new Dictionary<int, bool>(); private readonly Dictionary<int, string> customDiscoverColorCache = new Dictionary<int, string>(); private readonly Dictionary<int, float> valuableValueCache = new Dictionary<int, float>(); private readonly Dictionary<int, float> valuableValueCacheExpiry = new Dictionary<int, float>(); private readonly Dictionary<int, bool> physGrabHiddenOrDeadFrameCache = new Dictionary<int, bool>(); private readonly Dictionary<int, EnemyFrameState> enemyFrameStateCache = new Dictionary<int, EnemyFrameState>(); private readonly Dictionary<int, bool> objectIsVehicleCache = new Dictionary<int, bool>(); private readonly GUIContent labelContent = new GUIContent(); private readonly HashSet<int> seenObjects = new HashSet<int>(); private readonly HashSet<object> cartObjectSet = new HashSet<object>(ReferenceObjectComparer.Instance); private readonly HashSet<object> haulObjectSet = new HashSet<object>(ReferenceObjectComparer.Instance); private readonly HashSet<int> sharedValuableIds = new HashSet<int>(); private readonly HashSet<int> sharedCustomDiscoverIds = new HashSet<int>(); private readonly HashSet<int> proximityUnlockedScanTargetIds = new HashSet<int>(); private readonly HashSet<PhysGrabObject> localHeldPhysGrabObjects = new HashSet<PhysGrabObject>(); private readonly Dictionary<int, bool> localHeldStateCache = new Dictionary<int, bool>(); private readonly Dictionary<Type, FieldInfo> playerAvatarFieldCache = new Dictionary<Type, FieldInfo>(); private ConfigEntry<string> moduleNameInfo; private ConfigEntry<string> moduleVersionInfo; private ConfigEntry<DisplayLanguage> displayLanguage; private ConfigEntry<bool> scannerEnabled; private ConfigEntry<bool> shareScansWithTeam; private ConfigEntry<bool> scanExploreMode; private ConfigEntry<bool> showDistanceMeters; private ConfigEntry<bool> alwaysTriggerShare; private ConfigEntry<bool> showValuables; private ConfigEntry<bool> showValuableNames; private ConfigEntry<bool> showValuablePrices; private ConfigEntry<bool> showTeammates; private ConfigEntry<bool> showAliveTeammates; private ConfigEntry<bool> showDeadTeammates; private ConfigEntry<bool> showItems; private ConfigEntry<bool> showItemNames; private ConfigEntry<bool> showLotteryCoinBoxes; private ConfigEntry<bool> showCarts; private ConfigEntry<bool> showBigCarts; private ConfigEntry<bool> showSmallCarts; private ConfigEntry<bool> showVehicles; private ConfigEntry<bool> showCargoVehicles; private ConfigEntry<bool> showRacingVehicles; private ConfigEntry<string> scanKey; private ConfigEntry<int> scanIntervalSeconds; private ConfigEntry<int> scanDistanceMeters; private ConfigEntry<int> fontSize; private ConfigEntry<bool> enemyOverlayEnabled; private ConfigEntry<bool> enemyProximityAutoShowEnabled; private ConfigEntry<int> enemyProximityAutoShowDistance; private ConfigEntry<bool> enemyNicknameEnabled; private ConfigEntry<bool> modEnabled; private float visibleTimer; private float scanCooldownTimer; private int containmentSetFrame = -1; private float enemyVisibleTimer; private float enemyProximityVisibleTimer; private readonly List<EnemyLabelInfo> enemyLabels = new List<EnemyLabelInfo>(); private readonly Stack<EnemyLabelInfo> enemyLabelPool = new Stack<EnemyLabelInfo>(); private readonly HashSet<int> enemiesInsideProximityRange = new HashSet<int>(); private readonly Dictionary<int, float> enemyProximityLingerTimers = new Dictionary<int, float>(); private readonly Dictionary<int, float> enemyProximityPopTimers = new Dictionary<int, float>(); private readonly List<int> enemyProximityTimerKeys = new List<int>(); private readonly List<int> expiredEnemyProximityKeys = new List<int>(); private readonly Dictionary<int, Renderer[]> enemyRendererCache = new Dictionary<int, Renderer[]>(); private readonly Dictionary<int, Collider[]> enemyColliderCache = new Dictionary<int, Collider[]>(); private readonly Dictionary<int, string> enemyDisplayNameCache = new Dictionary<int, string>(); private readonly Dictionary<int, float> enemyLabelYOffsetCache = new Dictionary<int, float>(); private readonly Dictionary<int, Transform> enemyCenterTransformCache = new Dictionary<int, Transform>(); private const float ProximityAutoShowLingerSeconds = 5f; private const float EnemyProximityPopSeconds = 1.2f; private const float EnemyProximityPopFontMultiplier = 2f; private DisplayLanguage enemyDisplayNameCacheLanguage; private bool enemyDisplayNameCacheNicknames = true; private float nextEnemyProximityRefreshTime; private float nextEnemyLabelRefreshTime; private float nextEnemyListCleanupTime; private float nextContainmentRefreshTime; private int cachedLocalPositionFrame = -1; private Vector3 cachedLocalPosition; private Camera cachedCamera; private int cachedGuiScaleFrame = -1; private Camera cachedGuiScaleCamera; private float cachedGuiScaleX = 1f; private float cachedGuiScaleY = 1f; private int cachedPhysGrabStateFrame = -1; private int cachedEnemyStateFrame = -1; private int cachedScanSettingsFrame = -1; private int cachedScanLocalPlayerFrame = -1; private bool cachedScanLocalPlayerReady; private PlayerAvatar cachedScanLocalPlayer; private int cachedScanDistanceMeters = 15; private float cachedScanDistanceSquared = 225f; private int cachedScanFontSize = 28; private bool cachedScanExploreMode; private bool cachedShowDistanceMeters; private bool cachedShowValuableNames = true; private bool cachedShowValuablePrices = true; private PlayerAvatar cachedLocalPlayer; private bool cachedLocalPlayerIsLocal; private readonly List<PhysGrabber> grabberObjectsCache = new List<PhysGrabber>(); private float nextGrabberRefreshTime; private float nextLocalHeldRefreshTime; private float nextLocalPlayerRefreshTime; private DisplayLanguage objectDisplayNameCacheLanguage; private Harmony harmony; private static readonly List<ValuableObject> trackedValuables = new List<ValuableObject>(); private static readonly HashSet<ValuableObject> trackedValuableSet = new HashSet<ValuableObject>(); private static readonly List<ItemAttributes> trackedItems = new List<ItemAttributes>(); private static readonly HashSet<ItemAttributes> trackedItemSet = new HashSet<ItemAttributes>(); private static readonly List<Enemy> trackedEnemies = new List<Enemy>(); private static readonly HashSet<Enemy> trackedEnemySet = new HashSet<Enemy>(); private static readonly List<PhysGrabCart> trackedCarts = new List<PhysGrabCart>(); private static readonly HashSet<PhysGrabCart> trackedCartSet = new HashSet<PhysGrabCart>(); private static readonly List<ItemVehicle> trackedVehicles = new List<ItemVehicle>(); private static readonly HashSet<ItemVehicle> trackedVehicleSet = new HashSet<ItemVehicle>(); private static readonly List<ValuableDiscoverCustom> trackedDiscoverCustoms = new List<ValuableDiscoverCustom>(); private static readonly HashSet<ValuableDiscoverCustom> trackedDiscoverCustomSet = new HashSet<ValuableDiscoverCustom>(); private static readonly List<PhysGrabber> trackedGrabbers = new List<PhysGrabber>(); private static readonly HashSet<PhysGrabber> trackedGrabberSet = new HashSet<PhysGrabber>(); private static float nextEnemyDirectorSyncTime; private const int ScanInputKeyValue = 329; private static readonly InputKey ScanInputKey = (InputKey)329; private static string lastAppliedScanKey; private bool resourceNameDumpStarted; private static readonly string[] AvailableKeybinds = new string[55] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Space", "Enter", "Tab", "LeftShift", "RightShift", "LeftControl", "RightControl" }; private static string cachedOfficialGreenHex; private static int officialColorCacheFrame = -1; private static readonly Regex WhitespaceRegex = new Regex("\\s+", RegexOptions.Compiled); private static readonly string[] ItemKeywords = new string[22] { "weapon", "gun", "melee", "tool", "grenade", "mine", "drone", "tracker", "medkit", "health", "flashlight", "orb", "upgrade", "cart", "pistol", "shotgun", "revolver", "sword", "bat", "hammer", "spear", "mace" }; private static bool inputActionsRegistered; private static InputManager registeredInputManager; private static Dictionary<InputKey, InputAction> registeredInputActions; private const float ResourceDumpRetryIntervalSeconds = 1f; private const float ResourceDumpTimeoutSeconds = 30f; internal static readonly Dictionary<string, CfgI18N> _cfgByEnSection = new Dictionary<string, CfgI18N>(StringComparer.Ordinal); internal static readonly Dictionary<string, CfgI18N> _cfgByEnKey = new Dictionary<string, CfgI18N>(StringComparer.Ordinal); internal static readonly Dictionary<string, List<CfgI18N>> _cfgByKeyOnly = new Dictionary<string, List<CfgI18N>>(StringComparer.Ordinal); private static readonly List<CfgI18N> _cfgI18Ns = new List<CfgI18N>(64); private static readonly string[] _chineseModKeywords = new string[6] { "chinese", "简体", "繁體", "繁体", "汉化", "中文" }; private static readonly string[] _chineseEnvironmentPluginGuids = new string[1] { "gravydevsupreme.xunity.autotranslator" }; private static readonly List<LiveLabel> _liveLabels = new List<LiveLabel>(64); private static readonly List<LiveValue> _liveValues = new List<LiveValue>(8); private static readonly List<LiveSliderOptions> _liveSliderOptions = new List<LiveSliderOptions>(4); private static readonly List<LiveToggleButtons> _liveToggleButtons = new List<LiveToggleButtons>(16); private static readonly Dictionary<Type, FieldInfo> _labelTmpFieldCache = new Dictionary<Type, FieldInfo>(8); private static readonly Dictionary<Type, PropertyInfo> _sliderStringOptionsPropCache = new Dictionary<Type, PropertyInfo>(4); private static readonly Dictionary<Type, FieldInfo> _toggleLeftTmpCache = new Dictionary<Type, FieldInfo>(4); private static readonly Dictionary<Type, FieldInfo> _toggleRightTmpCache = new Dictionary<Type, FieldInfo>(4); private static readonly Dictionary<string, int> _pendingKeyMatchIndex = new Dictionary<string, int>(StringComparer.Ordinal); internal static string _currentRenderingConfigFilePath; internal static bool _createModEntriesPatchInstalled; private static readonly Dictionary<Type, FieldInfo> _inputStringSystemFieldCache = new Dictionary<Type, FieldInfo>(4); private static readonly Dictionary<Type, MethodInfo> _inputStringSystemSetValueCache = new Dictionary<Type, MethodInfo>(4); private static readonly Dictionary<string, string> _enumNameCNtoEN = new Dictionary<string, string>(StringComparer.Ordinal) { ["中文"] = "Chinese", ["文字显示"] = "Text Mode", ["原生UI显示"] = "Native UI" }; private static readonly Dictionary<string, string> _enumNameENtoCN = new Dictionary<string, string>(StringComparer.Ordinal) { ["English"] = "英语", ["Chinese"] = "中文" }; private static DisplayLanguage InstanceLanguage { get { if (!((Object)(object)Instance == (Object)null) && Instance.displayLanguage != null) { return Instance.displayLanguage.Value; } return DisplayLanguage.中文; } } private void Awake() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown DetachFromManager(); Instance = this; ResetConfigIfVersionChanged(); BindConfig(); scanKey.SettingChanged += delegate { RebindScanKey(); }; if (displayLanguage != null) { displayLanguage.SettingChanged += delegate { RefreshAllI18N(); }; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"zichen-superscanner loaded."); harmony = new Harmony("zichen.superscanner"); ApplyHarmonyPatches(); TryHookREPOConfig(harmony); if (EnableStartupResourceNameDump) { StartResourceNameDump(); } } private void DetachFromManager() { try { ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to mark plugin host persistent: " + ex.GetType().Name + ": " + ex.Message)); } } private bool IsModEnabled() { if (modEnabled != null) { return modEnabled.Value; } return true; } private static bool IsStaticModEnabled() { ZichenSuperScannerPlugin instance = Instance; if (!((Object)(object)instance == (Object)null)) { return instance.IsModEnabled(); } return true; } private void LogScanDebug(string message) { if (EnableScanDebugLogging) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } } internal static string GetOfficialValueColorHex() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (officialColorCacheFrame == Time.frameCount && cachedOfficialGreenHex != null) { return cachedOfficialGreenHex; } officialColorCacheFrame = Time.frameCount; try { if ((Object)(object)WorldSpaceUIValue.instance != (Object)null) { cachedOfficialGreenHex = ColorUtility.ToHtmlStringRGB(WorldSpaceUIValue.instance.colorValue); return cachedOfficialGreenHex; } } catch { } cachedOfficialGreenHex = "00C832"; return cachedOfficialGreenHex; } private void BindConfig() { displayLanguage = BindI18N("A.Mod Info", "A.模组信息", "SuperScannerLanguage", "语言", "Switch display language.", "切换显示语言。", DetectDefaultLanguage(), null, 1010, null, "Language"); moduleNameInfo = BindReadOnlyI18N("A.Mod Info", "A.模组信息", "SuperScannerModName", "模组名称", "Super Scanner", "超级扫描仪", 1000, DrawInfo, "Mod Name"); moduleVersionInfo = BindReadOnlyI18N("A.Mod Info", "A.模组信息", "SuperScannerModVersion", "模组版本号", "1.2.3", "1.2.3", 990, DrawInfo, "Mod Version"); modEnabled = BindI18N("B.Global", "B.全局设置", "ModEnabled", "模组启用", "If disabled, all scans and overlays are turned off.", "关闭后整个模组所有扫描和显示功能都不生效。默认开启。", defaultVal: true, null, 1005); enemyNicknameEnabled = BindI18N("B.Global", "B.全局设置", "EnemyNicknameEnabled", "敌人名字优化", "Enable community nicknames (e.g. Big Eye) for enemies. If disabled, standard Chinese names are shown.", "开启后怪物显示社区昵称(如 大眼哥 等)。关闭后显示标准中文名。默认开启。", defaultVal: true, null, 995); scannerEnabled = BindI18N("C.Scanner Settings", "C.扫描设置", "ScannerEnabled", "启用", "If disabled, scanning label display will not take effect.", "关闭后整个扫描显示都不生效。", defaultVal: true, null, 900); shareScansWithTeam = BindI18N("C.Scanner Settings", "C.扫描设置", "ShareScansWithTeam", "信息共享队友", "Only trigger discovery sync when you active scan targets within 15 meters.", "开启后,只有你主动按扫描键时,且目标距离自己不超过 15 米的贵重品 and 装饰箱,才会走游戏原生发现同步,队友不装这个模组也能收到发现效果。默认开启;若扫描探索模式开启,则会等目标解除 ? 后才触发一次同步。默认解锁距离为:贵重品 4 米、其他扫描目标 6 米、怪物 20 米。", defaultVal: true, null, 895); scanExploreMode = BindI18N("C.Scanner Settings", "C.扫描设置", "ScanExploreMode", "扫描探索模式", "Labels show ? until target enters unlock range.", "开启后扫描标签会先显示 ?,只有目标第一次进入解锁距离后才会显示正常名称、价格和米数。默认解锁距离为:贵重品 4 米、其他扫描目标 6 米、怪物 20 米;贵重品与装饰箱的信息共享也会等到解除 ? 后才触发一次。默认关闭。", defaultVal: false, null, 890); showDistanceMeters = BindI18N("C.Scanner Settings", "C.扫描设置", "ShowDistanceMeters", "显示米数", "If enabled, show distance in meters on scan labels.", "开启后扫描标签显示距离米数;关闭后物品、贵重品、装饰箱、推车和怪物都不显示米数。默认开启。", defaultVal: true, null, 875); alwaysTriggerShare = BindI18N("C.Scanner Settings", "C.扫描设置", "AlwaysTriggerShare", "触发方框显示", "If enabled, items within 15 meters will always show discover frames every time you scan, ignoring once-per-level limit.", "开启后,每次按下扫描,只要距离自己在 15 米以内的物品都会再次触发游戏原生的发现方框,无视每局仅触发一次的限制。默认开启。", defaultVal: true, null, 874); fontSize = BindI18N("C.Scanner Settings", "C.扫描设置", "FontSize", "字体大小", "Font size of in-game scan labels.", "局内物品和怪物扫描标签的字体大小。", 26, (AcceptableValueBase)(object)new AcceptableValueRange<int>(8, 48), 873); scanKey = BindI18N("C.Scanner Settings", "C.扫描设置", "ScanKey", "扫描按键", "Key to activate scanner. Displays for 5 seconds.", "按下这个按键后显示附近贵重品、装备、推车、装饰箱和怪物,固定显示5秒。", "F", (AcceptableValueBase)(object)new AcceptableValueList<string>(AvailableKeybinds), 870); scanIntervalSeconds = BindI18N("C.Scanner Settings", "C.扫描设置", "ScanCooldownSeconds", "扫描冷却/秒", "Scanner cooldown in seconds.", "按下扫描按键后,多少秒内再次按下不会重新显示。范围1-5秒,每次调整1秒。", 1, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), 860); scanDistanceMeters = BindI18N("C.Scanner Settings", "C.扫描设置", "ScanDistanceMeters", "扫描距离/米", "Scanning range in meters.", "按下扫描按键时,只扫描并显示距离自己多少米以内的物品和怪物。范围1-100米,每次调整1米。默认15米。", 15, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), 850); showValuables = BindI18N("D.Valuables Scan", "D.贵重品扫描", "ShowValuables", "启用", "Show recoverable valuables.", "显示可回收贵重品。", defaultVal: true, null, 890); showValuableNames = BindI18N("D.Valuables Scan", "D.贵重品扫描", "ShowValuableNames", "显示名称", "If enabled, show valuable names on scan labels.", "开启后贵重品扫描标签显示物品名称。默认开启。", defaultVal: true, null, 889); showValuablePrices = BindI18N("D.Valuables Scan", "D.贵重物品扫描", "ShowValuablePrices", "显示价格", "If enabled, show valuable prices on scan labels.", "开启后贵重品扫描标签显示当前价格。默认关闭。", defaultVal: false, null, 888); showTeammates = BindI18N("E.Teammates Scan", "E.队友扫描", "ShowTeammates", "启用", "Show teammate positions on scanner.", "在扫描仪上显示队友的位置。默认开启。", defaultVal: true, null, 885); showAliveTeammates = BindI18N("E.Teammates Scan", "E.队友扫描", "ShowAliveTeammates", "存活队友", "Show alive teammates on scanner.", "在扫描仪上显示存活的队友。默认关闭。", defaultVal: false, null, 884); showDeadTeammates = BindI18N("E.Teammates Scan", "E.队友扫描", "ShowDeadTeammates", "死亡队友", "Show dead teammates on scanner.", "在扫描仪上显示死亡的队友。默认开启。", defaultVal: true, null, 883); showItems = BindI18N("F.Items Scan", "F.装备武器扫描", "ShowItems", "启用", "Show guns, melee weapons, medkits, grenades, etc.", "显示枪、近战、血包、手雷等装备/武器。", defaultVal: true, null, 880); showItemNames = BindI18N("F.Items Scan", "F.装备武器扫描", "ShowItemNames", "显示名称", "If enabled, show item names on labels.", "开启后装备武器标签显示名称。默认开启。", defaultVal: true, null, 879); showLotteryCoinBoxes = BindI18N("G.Decor Boxes Scan", "G.装饰箱扫描", "ShowLotteryCoinBoxes", "启用", "Show coin machines, token boxes, and decor boxes in levels.", "显示关卡中的投币机、硬币宝箱、代币箱和装饰箱。不同类型用不同颜色区分。默认开启。", defaultVal: true, null, 870); showCarts = BindI18N("H.Carts Scan", "H.推车扫描", "ShowCarts", "启用", "Master toggle for cart scans.", "推车扫描总开关。关闭后大推车和小推车都不会显示。默认关闭。", defaultVal: false, null, 865); showBigCarts = BindI18N("H.Carts Scan", "H.推车扫描", "ShowBigCarts", "显示推车", "If enabled, show large carts.", "开启后扫描时显示推车。默认开启。", defaultVal: true, null, 860); showSmallCarts = BindI18N("H.Carts Scan", "H.推车扫描", "ShowSmallCarts", "显示小推车", "If enabled, show small carts.", "开启后扫描时显示小推车。默认开启。", defaultVal: true, null, 859); showVehicles = BindI18N("I.Vehicles Scan", "I.车辆扫描", "ShowVehicles", "启用", "Master toggle for vehicle scans.", "车辆扫描总开关。关闭后载货车 and 赛车都不会显示。默认关闭。", defaultVal: false, null, 855); showRacingVehicles = BindI18N("I.Vehicles Scan", "I.车辆扫描", "ShowRacingVehicles", "显示赛车", "If enabled, show racing vehicles.", "开启后扫描时显示赛车。默认开启。", defaultVal: true, null, 850); showCargoVehicles = BindI18N("I.Vehicles Scan", "I.车辆扫描", "ShowCargoVehicles", "显示载货车", "If enabled, show cargo vehicles.", "开启后扫描时显示载货车。默认开启。", defaultVal: true, null, 849); enemyOverlayEnabled = BindI18N("J.Enemy Scan", "J.怪物扫描", "EnemyOverlayEnabled", "启用", "If disabled, enemy labels are turned off.", "关闭后不再显示怪物局内标签;显示按键、扫描距离、字体大小和米数显示同步使用 B.扫描设置 的设置。默认开启。", defaultVal: true, null, 800); enemyProximityAutoShowEnabled = BindI18N("J.Enemy Scan", "J.怪物扫描", "EnemyProximityAutoShowEnabled", "启用靠近自动显示", "Temporarily show enemy label when close, disappears after 5 seconds of leaving.", "怪物进入靠近自动显示距离时,会临时显示怪物标签;怪物离开范围后5秒恢复。靠近自动显示距离可独立大于 B.扫描设置 的扫描距离。", defaultVal: true, null, 790); enemyProximityAutoShowDistance = BindI18N("J.Enemy Scan", "J.怪物扫描", "EnemyProximityAutoShowDistance", "靠近自动显示距离/米", "Proximity auto-show range in meters.", "怪物距离你多少米以内时自动临时显示。这个距离可以独立大于 B.扫描设置 的扫描距离。默认30米。", 30, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), 780); } private void ResetConfigIfVersionChanged() { try { string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; string text = ReadConfigPluginVersion(configFilePath); if (!string.IsNullOrWhiteSpace(text) && !(text == "1.2.3")) { ResetConfigFileToDefaults(configFilePath); ((BaseUnityPlugin)this).Logger.LogWarning((object)"Config version changed. Old config was reset to defaults."); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to reset config by version: " + ex.Message)); } } private static string ReadConfigPluginVersion(string configPath) { if (!File.Exists(configPath)) { return null; } string input = File.ReadAllText(configPath); Match match = Regex.Match(input, "(?m)^SuperScannerModVersion\\s*=\\s*(.+?)\\s*$"); if (!match.Success) { match = Regex.Match(input, "(?m)^模组版本号\\s*=\\s*(.+?)\\s*$"); } if (!match.Success) { return null; } return match.Groups[1].Value.Trim(); } private void ResetConfigFileToDefaults(string configPath) { ((BaseUnityPlugin)this).Config.Clear(); if (File.Exists(configPath)) { File.Delete(configPath); } ((BaseUnityPlugin)this).Config.Reload(); } private static void DrawInfo(ConfigEntryBase entry) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(entry.Definition.Key, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Label(entry.BoxedValue?.ToString() ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }); GUILayout.EndHorizontal(); } private void Update() { //IL_0108: Unknown result type (might be due to invalid IL or missing references) try { if (!IsModEnabled()) { visibleTimer = 0f; scanCooldownTimer = 0f; ClearScanLabels(); ClearEnemyLabels(); ClearEnemyProximityTracking(); enemyVisibleTimer = 0f; enemyProximityVisibleTimer = 0f; return; } if ((Object)(object)InputManager.instance != (Object)null && (!inputActionsRegistered || registeredInputManager != InputManager.instance)) { EnsureInputActionsRegistered(); } if (!CanUseLocalScan()) { visibleTimer = 0f; scanCooldownTimer = 0f; ClearScanLabels(); } else if (scannerEnabled == null || !scannerEnabled.Value) { visibleTimer = 0f; scanCooldownTimer = 0f; ClearScanLabels(); } else { if (scanCooldownTimer > 0f) { scanCooldownTimer = Mathf.Max(0f, scanCooldownTimer - Time.deltaTime); } if ((Object)(object)InputManager.instance != (Object)null && SemiFunc.InputDown(ScanInputKey)) { if (scanCooldownTimer <= 0f) { visibleTimer = GetScanHoldSeconds(); scanCooldownTimer = ClampScanInterval((scanIntervalSeconds == null) ? 1f : ((float)scanIntervalSeconds.Value)); LogScanDebug($"[ScanDebug] InputDown accepted. visibleTimer={visibleTimer:F2}, cooldown={scanCooldownTimer:F2}, trackedValuables={trackedValuables.Count}, trackedItems={trackedItems.Count}, trackedEnemies={trackedEnemies.Count}"); if (alwaysTriggerShare != null && alwaysTriggerShare.Value) { sharedValuableIds.Clear(); sharedCustomDiscoverIds.Clear(); } RefreshLabels(); } else { LogScanDebug($"[ScanDebug] InputDown ignored by cooldown. remaining={scanCooldownTimer:F2}"); } } if (visibleTimer > 0f) { visibleTimer = Mathf.Max(0f, visibleTimer - Time.deltaTime); } if (visibleTimer <= 0f) { ClearScanLabels(); } } UpdateEnemyOverlayState(); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"[ScanDebug] Exception in Update: {arg}"); } } private void RefreshLabels() { //IL_089b: Unknown result type (might be due to invalid IL or missing references) //IL_08a0: Unknown result type (might be due to invalid IL or missing references) //IL_08ac: Unknown result type (might be due to invalid IL or missing references) //IL_08b1: Unknown result type (might be due to invalid IL or missing references) //IL_08b3: Unknown result type (might be due to invalid IL or missing references) //IL_08b5: Unknown result type (might be due to invalid IL or missing references) //IL_08b7: Unknown result type (might be due to invalid IL or missing references) //IL_08bc: Unknown result type (might be due to invalid IL or missing references) //IL_0956: Unknown result type (might be due to invalid IL or missing references) //IL_0958: Unknown result type (might be due to invalid IL or missing references) //IL_095f: Unknown result type (might be due to invalid IL or missing references) //IL_0961: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_0a78: Unknown result type (might be due to invalid IL or missing references) //IL_0a7d: Unknown result type (might be due to invalid IL or missing references) //IL_0a81: Unknown result type (might be due to invalid IL or missing references) //IL_0a85: Unknown result type (might be due to invalid IL or missing references) //IL_0a8a: Unknown result type (might be due to invalid IL or missing references) //IL_0a8c: Unknown result type (might be due to invalid IL or missing references) //IL_0a8e: Unknown result type (might be due to invalid IL or missing references) //IL_0a90: Unknown result type (might be due to invalid IL or missing references) //IL_0a95: Unknown result type (might be due to invalid IL or missing references) //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_066f: Unknown result type (might be due to invalid IL or missing references) //IL_0671: Unknown result type (might be due to invalid IL or missing references) //IL_0673: Unknown result type (might be due to invalid IL or missing references) //IL_0678: Unknown result type (might be due to invalid IL or missing references) //IL_0b25: Unknown result type (might be due to invalid IL or missing references) //IL_0b27: Unknown result type (might be due to invalid IL or missing references) //IL_0b2e: Unknown result type (might be due to invalid IL or missing references) //IL_0b30: Unknown result type (might be due to invalid IL or missing references) //IL_0720: Unknown result type (might be due to invalid IL or missing references) //IL_0722: Unknown result type (might be due to invalid IL or missing references) //IL_0729: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0520: Unknown result type (might be due to invalid IL or missing references) //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) try { ClearScanLabels(); seenObjects.Clear(); int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; if (!TryGetScanOriginPosition(out var position)) { LogScanDebug("[ScanDebug] RefreshLabels aborted: no local scan origin."); return; } float scanDistanceSquared = GetScanDistanceSquared(); bool showDistance = ShouldShowDistanceMeters(); bool showName = ShouldShowValuableNames(); bool showPrice = ShouldShowValuablePrices(); ForceRefreshContainmentSets(); Vector3 val; if (showValuables == null || showValuables.Value) { PruneTrackedCollection<ValuableObject>(trackedValuables, trackedValuableSet); foreach (ValuableObject trackedValuable in trackedValuables) { num++; if ((Object)(object)trackedValuable == (Object)null || IsVehicleCached((Component)(object)trackedValuable) || !IsObjectUsable(((Component)trackedValuable).gameObject)) { continue; } PhysGrabObject physGrabObjectCached = GetPhysGrabObjectCached((Component)(object)trackedValuable, ValuablePhysGrabObjectField); if (IsPhysGrabObjectHiddenOrDead(physGrabObjectCached) || IsHeldByLocalPlayer(physGrabObjectCached) || IsObjectInCart((Component)(object)trackedValuable, physGrabObjectCached) || IsObjectInHaul((Component)(object)trackedValuable, physGrabObjectCached)) { continue; } Renderer[] usableRenderersCached = GetUsableRenderersCached((Component)(object)trackedValuable); Vector3 objectAnchorPosition = GetObjectAnchorPosition(((Component)trackedValuable).transform, physGrabObjectCached); Vector3 objectCenter = GetObjectCenter(((Component)trackedValuable).transform, physGrabObjectCached, usableRenderersCached); val = objectCenter - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude > scanDistanceSquared)) { int instanceID = ((Object)trackedValuable).GetInstanceID(); seenObjects.Add(instanceID); int distanceMeters = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude)); string valuableDisplayNameCached = GetValuableDisplayNameCached(trackedValuable); ScanLabel scanLabel = RentScanLabel(); scanLabel.Target = (Component)(object)trackedValuable; scanLabel.PhysGrabObject = physGrabObjectCached; scanLabel.IsValuable = true; scanLabel.ShareMode = TeamShareMode.Valuable; scanLabel.DisplayName = valuableDisplayNameCached; scanLabel.Renderers = usableRenderersCached; scanLabel.Position = objectCenter; scanLabel.LastAnchorPosition = objectAnchorPosition; scanLabel.HasAnchorPosition = true; scanLabel.DistanceSquared = sqrMagnitude; scanLabel.DistanceMeters = distanceMeters; if (!RefreshValuableLabelText(scanLabel, trackedValuable, distanceMeters, sqrMagnitude, showDistance, showName, showPrice)) { ReturnScanLabel(scanLabel); continue; } labels.Add(scanLabel); num2++; } } } bool flag = showLotteryCoinBoxes != null && showLotteryCoinBoxes.Value; bool flag2 = showCarts == null || showCarts.Value; bool flag3 = flag2 && ((showBigCarts != null && showBigCarts.Value) || (showSmallCarts != null && showSmallCarts.Value)); if ((showItems != null && showItems.Value) || flag3) { PruneTrackedCollection<ItemAttributes>(trackedItems, trackedItemSet); foreach (ItemAttributes trackedItem in trackedItems) { num3++; if ((Object)(object)trackedItem == (Object)null || IsVehicleCached((Component)(object)trackedItem) || !IsObjectUsable(((Component)trackedItem).gameObject) || HasValuableObjectCached(trackedItem)) { continue; } PhysGrabObject physGrabObjectCached2 = GetPhysGrabObjectCached((Component)(object)trackedItem, ItemPhysGrabObjectField); if (IsPhysGrabObjectHiddenOrDead(physGrabObjectCached2) || IsHeldByLocalPlayer(physGrabObjectCached2) || IsObjectInCart((Component)(object)trackedItem, physGrabObjectCached2) || IsObjectInHaul((Component)(object)trackedItem, physGrabObjectCached2) || IsShopItemCached(trackedItem)) { continue; } CartScanInfo cartScanInfoCached = GetCartScanInfoCached((Component)(object)trackedItem, physGrabObjectCached2); bool isCart = cartScanInfoCached.IsCart; bool isSmallCart = cartScanInfoCached.IsSmallCart; if ((isCart && !flag2) || (isCart && !isSmallCart && (showBigCarts == null || !showBigCarts.Value)) || (isCart && isSmallCart && (showSmallCarts == null || !showSmallCarts.Value)) || (!isCart && !ShouldScanItemCached(trackedItem)) || (!isCart && (showItems == null || !showItems.Value))) { continue; } Renderer[] usableRenderersCached2 = GetUsableRenderersCached((Component)(object)trackedItem); Vector3 objectAnchorPosition2 = GetObjectAnchorPosition(((Component)trackedItem).transform, physGrabObjectCached2); Vector3 objectCenter2 = GetObjectCenter(((Component)trackedItem).transform, physGrabObjectCached2, usableRenderersCached2); val = objectCenter2 - position; float sqrMagnitude2 = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude2 > scanDistanceSquared) { continue; } string text; string colorHex; if (isCart) { text = ((InstanceLanguage != DisplayLanguage.English) ? (isSmallCart ? "小推车" : "推车") : (isSmallCart ? "Small Cart" : "Cart")); colorHex = "#ffd84d"; } else { text = GetItemDisplayNameCached(trackedItem); colorHex = "#62d8ff"; } if (!string.IsNullOrWhiteSpace(text)) { int distanceMeters2 = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude2)); ScanLabel scanLabel2 = RentScanLabel(); scanLabel2.Target = (Component)(object)trackedItem; scanLabel2.PhysGrabObject = physGrabObjectCached2; scanLabel2.IsItem = true; scanLabel2.IsCart = isCart; scanLabel2.IsSmallCart = isSmallCart; scanLabel2.ShareMode = TeamShareMode.None; scanLabel2.ColorHex = colorHex; scanLabel2.DisplayName = text; scanLabel2.Renderers = usableRenderersCached2; scanLabel2.Position = objectCenter2; scanLabel2.LastAnchorPosition = objectAnchorPosition2; scanLabel2.HasAnchorPosition = true; scanLabel2.DistanceSquared = sqrMagnitude2; scanLabel2.DistanceMeters = distanceMeters2; if (!RefreshItemLabelText(scanLabel2, distanceMeters2, sqrMagnitude2, showDistance)) { ReturnScanLabel(scanLabel2); continue; } labels.Add(scanLabel2); num4++; } } } if (flag) { PruneTrackedCollection<ValuableDiscoverCustom>(trackedDiscoverCustoms, trackedDiscoverCustomSet); foreach (ValuableDiscoverCustom trackedDiscoverCustom in trackedDiscoverCustoms) { num5++; if ((Object)(object)trackedDiscoverCustom == (Object)null || !IsObjectUsable(((Component)trackedDiscoverCustom).gameObject) || seenObjects.Contains(((Object)trackedDiscoverCustom).GetInstanceID())) { continue; } PhysGrabObject physGrabObjectCached3 = GetPhysGrabObjectCached((Component)(object)trackedDiscoverCustom, ValuableDiscoverCustomPhysGrabObjectField); if (IsPhysGrabObjectHiddenOrDead(physGrabObjectCached3) || IsHeldByLocalPlayer(physGrabObjectCached3) || IsObjectInCart((Component)(object)trackedDiscoverCustom, physGrabObjectCached3) || IsObjectInHaul((Component)(object)trackedDiscoverCustom, physGrabObjectCached3)) { continue; } Renderer[] usableRenderersCached3 = GetUsableRenderersCached((Component)(object)trackedDiscoverCustom); Vector3 objectAnchorPosition3 = GetObjectAnchorPosition(((Component)trackedDiscoverCustom).transform, physGrabObjectCached3); Vector3 objectCenter3 = GetObjectCenter(((Component)trackedDiscoverCustom).transform, physGrabObjectCached3, usableRenderersCached3); val = objectCenter3 - position; float sqrMagnitude3 = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude3 > scanDistanceSquared)) { int instanceID2 = ((Object)trackedDiscoverCustom).GetInstanceID(); seenObjects.Add(instanceID2); int distanceMeters3 = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude3)); string customDiscoverColorHexCached = GetCustomDiscoverColorHexCached(trackedDiscoverCustom); string displayName = ((InstanceLanguage == DisplayLanguage.English) ? "Decor Box" : "装饰箱"); ScanLabel scanLabel3 = RentScanLabel(); scanLabel3.Target = (Component)(object)trackedDiscoverCustom; scanLabel3.PhysGrabObject = physGrabObjectCached3; scanLabel3.IsItem = true; scanLabel3.IsLotteryCoinBox = true; scanLabel3.ShareMode = TeamShareMode.LotteryCoinBox; scanLabel3.ColorHex = customDiscoverColorHexCached; scanLabel3.DisplayName = displayName; scanLabel3.Renderers = usableRenderersCached3; scanLabel3.Position = objectCenter3; scanLabel3.LastAnchorPosition = objectAnchorPosition3; scanLabel3.HasAnchorPosition = true; scanLabel3.DistanceSquared = sqrMagnitude3; scanLabel3.DistanceMeters = distanceMeters3; if (!RefreshItemLabelText(scanLabel3, distanceMeters3, sqrMagnitude3, showDistance)) { ReturnScanLabel(scanLabel3); continue; } labels.Add(scanLabel3); num6++; } } } bool num7 = showVehicles == null || showVehicles.Value; bool flag4 = showCargoVehicles != null && showCargoVehicles.Value; bool flag5 = showRacingVehicles != null && showRacingVehicles.Value; if (num7 && (flag4 || flag5)) { PruneTrackedCollection<ItemVehicle>(trackedVehicles, trackedVehicleSet); foreach (ItemVehicle trackedVehicle in trackedVehicles) { if ((Object)(object)trackedVehicle == (Object)null || !IsObjectUsable(((Component)trackedVehicle).gameObject)) { continue; } bool flag6 = false; if (ItemVehicleIsRacingField != null) { try { flag6 = (bool)ItemVehicleIsRacingField.GetValue(trackedVehicle); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to read isRacingVehicle: " + ex.Message)); } } if ((flag6 && !flag5) || (!flag6 && !flag4)) { continue; } Renderer[] usableRenderersCached4 = GetUsableRenderersCached((Component)(object)trackedVehicle); Vector3 position2 = ((Component)trackedVehicle).transform.position; Vector3 objectCenter4 = GetObjectCenter(((Component)trackedVehicle).transform, null, usableRenderersCached4); val = objectCenter4 - position; float sqrMagnitude4 = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude4 > scanDistanceSquared) { continue; } int distanceMeters4 = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude4)); string vehicleDisplayName = ItemNameLocalizer.GetVehicleDisplayName(flag6, InstanceLanguage); if (!string.IsNullOrWhiteSpace(vehicleDisplayName)) { string colorHex2 = "#ffd84d"; ScanLabel scanLabel4 = RentScanLabel(); scanLabel4.Target = (Component)(object)trackedVehicle; scanLabel4.PhysGrabObject = null; scanLabel4.IsItem = false; scanLabel4.IsVehicle = true; scanLabel4.IsRacingVehicle = flag6; scanLabel4.ShareMode = TeamShareMode.None; scanLabel4.ColorHex = colorHex2; scanLabel4.DisplayName = vehicleDisplayName; scanLabel4.Renderers = usableRenderersCached4; scanLabel4.Position = objectCenter4; scanLabel4.LastAnchorPosition = position2; scanLabel4.HasAnchorPosition = true; scanLabel4.DistanceSquared = sqrMagnitude4; scanLabel4.DistanceMeters = distanceMeters4; if (!RefreshItemLabelText(scanLabel4, distanceMeters4, sqrMagnitude4, showDistance)) { ReturnScanLabel(scanLabel4); } else { labels.Add(scanLabel4); } } } } bool num8 = showTeammates == null || showTeammates.Value; bool flag7 = showAliveTeammates != null && showAliveTeammates.Value; bool flag8 = showDeadTeammates == null || showDeadTeammates.Value; if (num8 && (flag7 || flag8)) { foreach (PlayerAvatar allPlayer in GetAllPlayers()) { if ((Object)(object)allPlayer == (Object)null || !IsPlayerAvatarUsable(allPlayer) || IsPlayerAvatarLocal(allPlayer)) { continue; } bool flag9 = IsPlayerDead(allPlayer); if (flag9) { if (!flag8) { continue; } } else if (!flag7) { continue; } Vector3 playerReferencePosition = GetPlayerReferencePosition(allPlayer, flag9); Vector3 playerLabelPosition = GetPlayerLabelPosition(allPlayer, playerReferencePosition, flag9); val = playerLabelPosition - position; float sqrMagnitude5 = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude5 > scanDistanceSquared) { continue; } int distanceMeters5 = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude5)); string playerName = GetPlayerName(allPlayer); if (!string.IsNullOrWhiteSpace(playerName)) { ScanLabel scanLabel5 = RentScanLabel(); scanLabel5.Target = (Component)(object)allPlayer; scanLabel5.PhysGrabObject = null; scanLabel5.IsTeammate = true; scanLabel5.IsDeadTeammate = flag9; scanLabel5.ShareMode = TeamShareMode.None; scanLabel5.ColorHex = "#FFFFFF"; scanLabel5.DisplayName = playerName; scanLabel5.Renderers = GetUsableRenderersCached((Component)(object)allPlayer); scanLabel5.Position = playerLabelPosition; scanLabel5.LastAnchorPosition = playerReferencePosition; scanLabel5.HasAnchorPosition = true; scanLabel5.DistanceSquared = sqrMagnitude5; scanLabel5.DistanceMeters = distanceMeters5; if (!RefreshTeammateLabelText(scanLabel5, distanceMeters5, sqrMagnitude5, showDistance)) { ReturnScanLabel(scanLabel5); } else { labels.Add(scanLabel5); } } } } labels.Sort(CompareScanLabels); LogScanDebug($"[ScanDebug] RefreshLabels done. valuableCandidates={num}, valuableAdded={num2}, itemCandidates={num3}, itemAdded={num4}, customCandidates={num5}, customAdded={num6}, totalLabels={labels.Count}, visibleTimer={visibleTimer:F2}"); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"[ScanDebug] Exception in RefreshLabels: {arg}"); } } private static int CompareScanLabels(ScanLabel a, ScanLabel b) { int num = a.DistanceSquared.CompareTo(b.DistanceSquared); if (num != 0) { return num; } return GetLabelSortPriority(a).CompareTo(GetLabelSortPriority(b)); } private ScanLabel RentScanLabel() { if (scanLabelPool.Count > 0) { return scanLabelPool.Pop(); } return new ScanLabel(); } private void ReturnScanLabel(ScanLabel label) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) if (label != null) { label.Target = null; label.PhysGrabObject = null; label.Renderers = Array.Empty<Renderer>(); label.DisplayName = string.Empty; label.IsValuable = false; label.IsItem = false; label.IsCart = false; label.IsLotteryCoinBox = false; label.IsSmallCart = false; label.IsVehicle = false; label.IsRacingVehicle = false; label.IsTeammate = false; label.IsDeadTeammate = false; label.ColorHex = "#62d8ff"; label.Position = Vector3.zero; label.LastAnchorPosition = Vector3.zero; label.HasAnchorPosition = false; label.PlainText = string.Empty; label.RichText = string.Empty; label.DistanceSquared = 0f; label.DistanceMeters = 0; label.CachedTextDistanceMeters = int.MinValue; label.CachedTextValue = int.MinValue; label.CachedShowDistanceMeters = false; label.CachedShowValuableNames = false; label.CachedShowValuablePrices = false; label.CachedIsMasked = false; label.ShareMode = TeamShareMode.None; label.SharedWithTeam = false; label.NextRuntimeRefreshTime = 0f; label.CachedLayoutFontSize = int.MinValue; label.CachedLayoutSize = Vector2.zero; scanLabelPool.Push(label); } } private void ClearScanLabels() { if (labels.Count != 0) { for (int i = 0; i < labels.Count; i++) { ReturnScanLabel(labels[i]); } labels.Clear(); } } private static int GetLabelSortPriority(ScanLabel label) { if (label.IsTeammate) { return -1; } if (label.IsValuable) { return 0; } if (label.IsVehicle) { return 5; } if (label.IsCart && !label.IsSmallCart) { return 3; } if (label.IsCart && label.IsSmallCart) { return 4; } if (label.IsLotteryCoinBox) { return 2; } return 1; } private bool RevealValuableToTeam(ValuableObject valuable) { if ((Object)(object)valuable == (Object)null) { return false; } int instanceID = ((Object)valuable).GetInstanceID(); if (sharedValuableIds.Contains(instanceID)) { return true; } try { if (alwaysTriggerShare != null && alwaysTriggerShare.Value) { if (ValuableObjectDiscoveredField != null && (bool)ValuableObjectDiscoveredField.GetValue(valuable)) { PhysGrabObject physGrabObjectCached = GetPhysGrabObjectCached((Component)(object)valuable, ValuablePhysGrabObjectField); if ((Object)(object)ValuableDiscover.instance != (Object)null && (Object)(object)physGrabObjectCached != (Object)null) { ValuableDiscover.instance.New(physGrabObjectCached, (State)0, (ValuableDiscoverCustom)null); } } else { valuable.Discover((State)0); } } else { valuable.Discover((State)0); } sharedValuableIds.Add(instanceID); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Native valuable reveal failed: " + ex.GetType().Name + ": " + ex.Message)); return false; } } private bool RevealCustomDiscoverToTeam(ValuableDiscoverCustom custom) { if ((Object)(object)custom == (Object)null) { return false; } int instanceID = ((Object)custom).GetInstanceID(); if (sharedCustomDiscoverIds.Contains(instanceID)) { return true; } try { if (alwaysTriggerShare != null && alwaysTriggerShare.Value) { if (ValuableDiscoverCustomDiscoveredField != null && (bool)ValuableDiscoverCustomDiscoveredField.GetValue(custom)) { PhysGrabObject physGrabObjectCached = GetPhysGrabObjectCached((Component)(object)custom, ValuableDiscoverCustomPhysGrabObjectField); if ((Object)(object)ValuableDiscover.instance != (Object)null && (Object)(object)physGrabObjectCached != (Object)null) { ValuableDiscover.instance.New(physGrabObjectCached, (State)3, custom); } } else { custom.Discover(); } } else { custom.Discover(); } sharedCustomDiscoverIds.Add(instanceID); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Native custom discover reveal failed: " + ex.GetType().Name + ": " + ex.Message)); return false; } } private void UpdateEnemyOverlayState() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!CanUseLocalScan()) { ClearEnemyLabels(); ClearEnemyProximityTracking(); enemyVisibleTimer = 0f; enemyProximityVisibleTimer = 0f; return; } if (enemyOverlayEnabled == null || !enemyOverlayEnabled.Value) { ClearEnemyLabels(); ClearEnemyProximityTracking(); enemyVisibleTimer = 0f; enemyProximityVisibleTimer = 0f; return; } SyncTrackedEnemiesFromDirector(); if ((Object)(object)InputManager.instance != (Object)null && SemiFunc.InputHold(ScanInputKey)) { enemyVisibleTimer = GetScanHoldSeconds(); } if (enemyVisibleTimer > 0f) { enemyVisibleTimer -= Time.deltaTime; } bool flag = UpdateEnemyProximityAutoShowState(); UpdateEnemyProximityPopTimers(); if (!(enemyVisibleTimer > 0f || flag)) { ClearEnemyLabels(); nextEnemyLabelRefreshTime = 0f; } else if (enemyLabels.Count == 0 || Time.unscaledTime >= nextEnemyLabelRefreshTime) { RefreshEnemyLabels(); nextEnemyLabelRefreshTime = Time.unscaledTime + 0.12f; } } private bool UpdateEnemyProximityAutoShowState() { if (enemyProximityAutoShowEnabled == null || !enemyProximityAutoShowEnabled.Value) { enemyProximityVisibleTimer = 0f; ClearEnemyProximityTracking(); return false; } if (Time.unscaledTime >= nextEnemyProximityRefreshTime) { UpdateEnemiesWithinProximityDistance(enemyProximityAutoShowDistance.Value); nextEnemyProximityRefreshTime = Time.unscaledTime + 0.12f; } UpdateEnemyProximityLingerTimers(); bool flag = enemyProximityLingerTimers.Count > 0; enemyProximityVisibleTimer = (flag ? 5f : 0f); return flag; } private bool UpdateEnemiesWithinProximityDistance(float distance) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) enemiesInsideProximityRange.Clear(); if (!TryGetScanOriginPosition(out var position)) { return false; } float num = distance * distance; CleanupTrackedEnemiesThrottled(); foreach (Enemy trackedEnemy in trackedEnemies) { if (!TryGetEnemyFrameState(trackedEnemy, out var state)) { continue; } Vector3 val = state.ReferencePosition - position; if (((Vector3)(ref val)).sqrMagnitude <= num) { int enemyKey = GetEnemyKey(trackedEnemy); enemiesInsideProximityRange.Add(enemyKey); if (!enemyProximityLingerTimers.ContainsKey(enemyKey) && !enemyProximityPopTimers.ContainsKey(enemyKey)) { enemyProximityPopTimers[enemyKey] = 1.2f; } enemyProximityLingerTimers[enemyKey] = 5f; } } return enemiesInsideProximityRange.Count > 0; } private void UpdateEnemyProximityLingerTimers() { if (enemyProximityLingerTimers.Count == 0) { return; } enemyProximityTimerKeys.Clear(); expiredEnemyProximityKeys.Clear(); foreach (KeyValuePair<int, float> enemyProximityLingerTimer in enemyProximityLingerTimers) { enemyProximityTimerKeys.Add(enemyProximityLingerTimer.Key); } for (int i = 0; i < enemyProximityTimerKeys.Count; i++) { int num = enemyProximityTimerKeys[i]; if (!enemiesInsideProximityRange.Contains(num) && enemyProximityLingerTimers.TryGetValue(num, out var value)) { float num2 = value - Time.deltaTime; if (num2 <= 0f) { expiredEnemyProximityKeys.Add(num); } else { enemyProximityLingerTimers[num] = num2; } } } for (int j = 0; j < expiredEnemyProximityKeys.Count; j++) { enemyProximityLingerTimers.Remove(expiredEnemyProximityKeys[j]); } } private void UpdateEnemyProximityPopTimers() { if (enemyProximityPopTimers.Count == 0) { return; } enemyProximityTimerKeys.Clear(); expiredEnemyProximityKeys.Clear(); foreach (KeyValuePair<int, float> enemyProximityPopTimer in enemyProximityPopTimers) { enemyProximityTimerKeys.Add(enemyProximityPopTimer.Key); } for (int i = 0; i < enemyProximityTimerKeys.Count; i++) { int num = enemyProximityTimerKeys[i]; if (enemyProximityPopTimers.TryGetValue(num, out var value)) { float num2 = value - Time.deltaTime; if (num2 <= 0f) { expiredEnemyProximityKeys.Add(num); } else { enemyProximityPopTimers[num] = num2; } } } for (int j = 0; j < expiredEnemyProximityKeys.Count; j++) { enemyProximityPopTimers.Remove(expiredEnemyProximityKeys[j]); } } private void ClearEnemyProximityTracking() { enemiesInsideProximityRange.Clear(); enemyProximityLingerTimers.Clear(); enemyProximityPopTimers.Clear(); enemyProximityTimerKeys.Clear(); expiredEnemyProximityKeys.Clear(); nextEnemyProximityRefreshTime = 0f; } private void RefreshEnemyLabels() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) //IL_006c: Unknown result type (might be due to invalid IL or missing references) ClearEnemyLabels(); if (!TryGetScanOriginPosition(out var position)) { return; } CleanupTrackedEnemiesThrottled(); float activeEnemyLabelDistanceSquared = GetActiveEnemyLabelDistanceSquared(); foreach (Enemy trackedEnemy in trackedEnemies) { if (TryGetEnemyFrameState(trackedEnemy, out var state) && state.IsUsable) { string enemyDisplayNameCached = GetEnemyDisplayNameCached(trackedEnemy); Transform referenceTransform = state.ReferenceTransform; Vector3 val = state.ReferencePosition - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude > activeEnemyLabelDistanceSquared)) { float enemyLabelYOffsetCached = GetEnemyLabelYOffsetCached(trackedEnemy, referenceTransform); EnemyLabelInfo enemyLabelInfo = RentEnemyLabel(); enemyLabelInfo.Enemy = trackedEnemy; enemyLabelInfo.Name = enemyDisplayNameCached; enemyLabelInfo.ReferenceTransform = referenceTransform; enemyLabelInfo.LabelYOffset = enemyLabelYOffsetCached; enemyLabelInfo.DistanceSquared = sqrMagnitude; enemyLabels.Add(enemyLabelInfo); } } } enemyLabels.Sort(CompareEnemyLabelsByDistance); } private static int CompareEnemyLabelsByDistance(EnemyLabelInfo a, EnemyLabelInfo b) { return a.DistanceSquared.CompareTo(b.DistanceSquared); } private EnemyLabelInfo RentEnemyLabel() { if (enemyLabelPool.Count > 0) { return enemyLabelPool.Pop(); } return new EnemyLabelInfo(); } private void ClearEnemyLabels() { //IL_0099: 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) if (enemyLabels.Count == 0) { return; } for (int i = 0; i < enemyLabels.Count; i++) { EnemyLabelInfo enemyLabelInfo = enemyLabels[i]; if (enemyLabelInfo != null) { enemyLabelInfo.Enemy = null; enemyLabelInfo.Name = string.Empty; enemyLabelInfo.ReferenceTransform = null; enemyLabelInfo.LabelYOffset = 0f; enemyLabelInfo.DistanceSquared = 0f; enemyLabelInfo.CachedDistanceMeters = -1; enemyLabelInfo.CachedShowDistance = false; enemyLabelInfo.CachedIsMasked = false; enemyLabelInfo.PlainText = string.Empty; enemyLabelInfo.RichText = string.Empty; enemyLabelInfo.NextRuntimeRefreshTime = 0f; enemyLabelInfo.CachedLayoutFontSize = int.MinValue; enemyLabelInfo.CachedLayoutSize = Vector2.zero; enemyLabelPool.Push(enemyLabelInfo); } } enemyLabels.Clear(); } private string GetEnemyDisplayNameCached(Enemy enemy) { DisplayLanguage instanceLanguage = InstanceLanguage; if ((Object)(object)enemy == (Object)null) { if (instanceLanguage != DisplayLanguage.English) { return "未知怪物"; } return "Unknown Enemy"; } bool flag = instanceLanguage == DisplayLanguage.中文 && enemyNicknameEnabled != null && enemyNicknameEnabled.Value; if (enemyDisplayNameCacheLanguage != instanceLanguage || enemyDisplayNameCacheNicknames != flag) { enemyDisplayNameCache.Clear(); enemyDisplayNameCacheLanguage = instanceLanguage; enemyDisplayNameCacheNicknames = flag; } int enemyKey = GetEnemyKey(enemy); if (!enemyDisplayNameCache.TryGetValue(enemyKey, out var value) || string.IsNullOrWhiteSpace(value)) { value = GetEnemyDisplayName(enemy, instanceLanguage, flag); enemyDisplayNameCache[enemyKey] = value; } return value; } private Transform GetEnemyCenterTransformCached(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return null; } int enemyKey = GetEnemyKey(enemy); if (enemyCenterTransformCache.TryGetValue(enemyKey, out var value) && (Object)(object)value != (Object)null) { return value; } object? obj = EnemyCenterTransformField?.GetValue(enemy); Transform val = (Transform)((obj is Transform) ? obj : null); if ((Object)(object)val != (Object)null) { enemyCenterTransformCache[enemyKey] = val; } return val; } private void CleanupTrackedEnemiesThrottled() { if (!(Time.unscaledTime < nextEnemyListCleanupTime)) { PruneTrackedCollection<Enemy>(trackedEnemies, trackedEnemySet); nextEnemyListCleanupTime = Time.unscaledTime + 1f; } } private float GetEnemyLabelYOffsetCached(Enemy enemy, Transform centerTransform) { if ((Object)(object)enemy == (Object)null) { return 1.1f; } int enemyKey = GetEnemyKey(enemy); if (!enemyLabelYOffsetCache.TryGetValue(enemyKey, out var value) || value <= 0.01f) { value = GetEnemyLabelYOffset(enemy, centerTransform); enemyLabelYOffsetCache[enemyKey] = value; } return value; } private float GetEnemyLabelYOffset(Enemy enemy, Transform centerTransform) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) float result = 1.1f; Transform transform = ((Component)enemy).transform; if ((Object)(object)transform == (Object)null) { return result; } Renderer[] enemyRenderersCached = GetEnemyRenderersCached(enemy); Collider[] enemyCollidersCached = GetEnemyCollidersCached(enemy); float num = float.MinValue; bool flag = false; Renderer[] array = enemyRenderersCached; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null) && val.enabled) { Bounds bounds = val.bounds; float y = ((Bounds)(ref bounds)).max.y; if (y > num) { num = y; } flag = true; } } if (!flag) { Collider[] array2 = enemyCollidersCached; foreach (Collider val2 in array2) { if (!((Object)(object)val2 == (Object)null) && val2.enabled) { Bounds bounds2 = val2.bounds; float y2 = ((Bounds)(ref bounds2)).max.y; if (y2 > num) { num = y2; } flag = true; } } } if (flag) { Vector3 val3 = (((Object)(object)centerTransform != (Object)null) ? centerTransform.position : transform.position); result = Mathf.Max(0.5f, num - val3.y + 0.3f); } return result; } private Renderer[] GetEnemyRenderersCached(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return Array.Empty<Renderer>(); } int enemyKey = GetEnemyKey(enemy); if (!enemyRendererCache.TryGetValue(enemyKey, out var value) || value == null) { value = ((Component)enemy).GetComponentsInChildren<Renderer>(false) ?? Array.Empty<Renderer>(); enemyRendererCache[enemyKey] = value; } return value; } private Collider[] GetEnemyCollidersCached(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return Array.Empty<Collider>(); } int enemyKey = GetEnemyKey(enemy); if (!enemyColliderCache.TryGetValue(enemyKey, out var value) || value == null) { value = ((Component)enemy).GetComponentsInChildren<Collider>(false) ?? Array.Empty<Collider>(); enemyColliderCache[enemyKey] = value; } return value; } private void ClearEnemyRuntimeCaches() { ClearEnemyLabels(); ClearEnemyProximityTracking(); enemyLabelStyleCache.Clear(); enemyRendererCache.Clear(); enemyColliderCache.Clear(); enemyDisplayNameCache.Clear(); enemyLabelYOffsetCache.Clear(); enemyCenterTransformCache.Clear(); enemyFrameStateCache.Clear(); cachedEnemyStateFrame = -1; nextEnemyLabelRefreshTime = 0f; nextEnemyListCleanupTime = 0f; } private static int GetEnemyKey(Enemy enemy) { return ((Object)enemy).GetInstanceID(); } private static bool IsEnemyDrawableFast(Enemy enemy) { if ((Object)(object)enemy != (Object)null && (Object)(object)((Component)enemy).gameObject != (Object)null) { return ((Component)enemy).gameObject.activeInHierarchy; } return false; } private bool ShouldLimitEnemyLabelsToProximity() { if (enemyProximityAutoShowEnabled != null && enemyProximityAutoShowEnabled.Value && enemyVisibleTimer <= 0f) { return enemyProximityLingerTimers.Count > 0; } return false; } private int GetActiveEnemyLabelDistanceMeters() { int num = GetScanDistanceMeters(); if (enemyProximityLingerTimers.Count > 0) { int num2 = Mathf.Clamp((enemyProximityAutoShowDistance == null) ? 30 : enemyProximityAutoShowDistance.Value, 1, 100); return Mathf.Max(num, num2); } return num; } private float GetActiveEnemyLabelDistanceSquared() { int activeEnemyLabelDistanceMeters = GetActiveEnemyLabelDistanceMeters(); return activeEnemyLabelDistanceMeters * activeEnemyLabelDistanceMeters; } private string GetEnemyDisplayName(Enemy enemy) { DisplayLanguage instanceLanguage = InstanceLanguage; bool useNicknames = instanceLanguage == DisplayLanguage.中文 && enemyNicknameEnabled != null && enemyNicknameEnabled.Value; return GetEnemyDisplayName(enemy, instanceLanguage, useNicknames); } private string GetEnemyDisplayName(Enemy enemy, DisplayLanguage language, bool useNicknames) { if ((Object)(object)enemy == (Object)null) { if (language != DisplayLanguage.English) { return "未知怪物"; } return "Unknown Enemy"; } object enemyParent = EnemyParentField?.GetValue(enemy); if (TryGetEnemyParentDisplayName(enemyParent, out var name)) { return EnemyNameLocalizer.Translate(name, language, useNicknames); } object obj = EnemyTypeField?.GetValue(enemy); if (obj != null) { string text = obj.ToString(); if (!string.IsNullOrWhiteSpace(text)) { return EnemyNameLocalizer.Translate(text, language, useNicknames); } } string text2 = CleanName(((Object)(object)((Component)enemy).gameObject == (Object)null) ? string.Empty : ((Object)((Component)enemy).gameObject).name); if (!string.IsNullOrWhiteSpace(text2)) { return EnemyNameLocalizer.Translate(text2, language, useNicknames); } if (language != DisplayLanguage.English) { return "未知怪物"; } return "Unknown Enemy"; } private bool TryGetEnemyParentDisplayName(object enemyParent, out string name) { name = string.Empty; if (enemyParent == null) { return false; } string text = EnemyParentNameField?.GetValue(enemyParent) as string; if (!IsInternalEnemyName(text)) { name = text.Trim(); return true; } object obj = EnemyParentLocalizedNameField?.GetValue(enemyParent); if (obj != null) { try { string text2 = LocalizedAssetGetStringMethod?.Invoke(obj, null) as string; if (!IsInternalEnemyName(text2)) { name = text2.Trim(); return true; } } catch { } } return false; } private static bool IsInternalEnemyName(string name) { if (string.IsNullOrWhiteSpace(name)) { return true; } string a = name.Trim(); if (!string.Equals(a, "ENM", StringComparison.OrdinalIgnoreCase)) { return string.Equals(a, "Enemy", StringComparison.OrdinalIgnoreCase); } return true; } private bool TryGetEnemyFrameState(Enemy enemy, out EnemyFrameState state) { state = default(EnemyFrameState); if ((Object)(object)enemy == (Object)null) { return false; } if (cachedEnemyStateFrame != Time.frameCount) { cachedEnemyStateFrame = Time.frameCount; enemyFrameStateCache.Clear(); } int enemyKey = GetEnemyKey(enemy); if (!enemyFrameStateCache.TryGetValue(enemyKey, out state)) { state = BuildEnemyFrameState(enemy); enemyFrameStateCache[enemyKey] = state; } if (state.IsUsable) { return state.IsAliveAndSpawned; } return false; } private EnemyFrameState BuildEnemyFrameState(Enemy enemy) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) EnemyFrameState result = default(EnemyFrameState); if ((Object)(object)enemy == (Object)null || (Object)(object)((Component)enemy).gameObject == (Object)null) { return result; } int isUsable; if (((Component)enemy).gameObject.activeInHierarchy) { Scene scene = ((Component)enemy).gameObject.scene; isUsable = (((Scene)(ref scene)).IsValid() ? 1 : 0); } else { isUsable = 0; } result.IsUsable = (byte)isUsable != 0; if (!result.IsUsable) { return result; } result.ReferenceTransform = GetEnemyCenterTransformCached(enemy); result.ReferencePosition = (((Object)(object)result.ReferenceTransform != (Object)null) ? result.ReferenceTransform.position : ((Component)enemy).transform.position); object obj = EnemyHealthField?.GetValue(enemy); if (obj != null) { object obj2 = EnemyHealthDeadField?.GetValue(obj); bool flag = default(bool); int num; if (obj2 is bool) { flag = (bool)obj2; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { return result; } } object obj3 = EnemyParentField?.GetValue(enemy); if (obj3 != null) { object obj4 = EnemyParentSpawnedField?.GetValue(obj3); if (obj4 is bool && !(bool)obj4) { return result; } } result.IsAliveAndSpawned = true; return result; } private void OnGUI() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) try { Event current = Event.current; if ((current != null && (int)current.type != 7) || !CanUseLocalScan()) { return; } bool flag = visibleTimer > 0f && labels.Count > 0; bool flag2 = enemyLabels.Count > 0; if (!flag && !flag2) { return; } Camera worldCameraCached = GetWorldCameraCached(); if ((Object)(object)worldCameraCached == (Object)null || !TryGetScanOriginPosition(out var position)) { return; } int maxDistance = GetScanDistanceMeters(); if (flag) { float scanDistanceSquared = GetScanDistanceSquared(); int configuredFontSize = GetConfiguredFontSize(); bool showDistance = ShouldShowDistanceMeters(); bool showValuableName = ShouldShowValuableNames(); bool showValuablePrice = ShouldShowValuablePrices(); RefreshContainmentSetsForFrame(); for (int num = labels.Count - 1; num >= 0; num--) { ScanLabel label = labels[num]; if (!TryRefreshLabel(label, position, scanDistanceSquared, showDistance, showValuableName, showValuablePrice)) { ReturnScanLabel(label); labels.RemoveAt(num); } else { int shrinkPercent = 30; DrawLabel(worldCameraCached, label, maxDistance, configuredFontSize, shrinkPercent); } } } if (flag2) { DrawEnemyWorldLabels(worldCameraCached, position, GetActiveEnemyLabelDistanceMeters()); } } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"[ScanDebug] Exception in OnGUI: {arg}"); } } private void DrawEnemyWorldLabels(Camera camera, Vector3 localPosition, int enemyMaxDistance) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) if (enemyLabels.Count == 0 || (Object)(object)camera == (Object)null) { return; } bool flag = ShouldLimitEnemyLabelsToProximity(); float num = Mathf.Max(1f, (float)enemyMaxDistance); num *= num; int configuredFontSize = GetConfiguredFontSize(); bool flag2 = ShouldShowDistanceMeters(); for (int num2 = enemyLabels.Count - 1; num2 >= 0; num2--) { EnemyLabelInfo enemyLabelInfo = enemyLabels[num2]; Enemy enemy = enemyLabelInfo.Enemy; if (IsEnemyDrawableFast(enemy)) { int enemyKey = GetEnemyKey(enemy); if (!flag || enemyProximityLingerTimers.ContainsKey(enemyKey)) { Vector3 val = (((Object)(object)enemyLabelInfo.ReferenceTransform != (Object)null) ? enemyLabelInfo.ReferenceTransform.position : ((Component)enemy).transform.position); Vector3 val2 = val - localPosition; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (!(sqrMagnitude > num)) { float num3 = ((enemyLabelInfo.LabelYOffset > 0.01f) ? enemyLabelInfo.LabelYOffset : 1.1f); Vector3 worldPosition = val + Vector3.up * num3; if (TryWorldToGuiPoint(camera, worldPosition, out var guiPosition, out var cameraDepth)) { int num4 = Mathf.RoundToInt(Mathf.Sqrt(sqrMagnitude)); bool flag3 = !IsScanTargetUnlockedByProximity((Component)(object)enemy, sqrMagnitude); bool flag4 = flag2 && !flag3; bool num5 = Time.unscaledTime >= enemyLabelInfo.NextRuntimeRefreshTime || enemyLabelInfo.CachedDistanceMeters != num4 || enemyLabelInfo.CachedShowDistance != flag4 || enemyLabelInfo.CachedIsMasked != flag3 || string.IsNullOrWhiteSpace(enemyLabelInfo.PlainText); int distanceScaledFontSize = GetDistanceScaledFontSize(configuredFontSize, 30, cameraDepth, enemyMaxDistance, 48); if (num5) { string text = (flag3 ? BuildMaskedLabelText() : (string.IsNullOrWhiteSpace(enemyLabelInfo.Name) ? GetEnemyDisplayName(enemy) : enemyLabelInfo.Name)); enemyLabelInfo.CachedDistanceMeters = num4; enemyLabelInfo.CachedShowDistance = flag4; enemyLabelInfo.CachedIsMasked = flag3; enemyLabelInfo.PlainText = (flag4 ? $"{text} {num4}m" : text); enemyLabelInfo.RichText = "<color=#ff3333>" + enemyLabelInfo.PlainText + "</color>"; enemyLabelInfo.NextRuntimeRefreshTime = Time.unscaledTime + 0.08f; enemyLabelInfo.CachedLayoutFontSize = int.MinValue; } GUIStyle centeredLabelStyle = GetCenteredLabelStyle(distanceScaledFontSize, shadow: false); Vector2 enemyLabelSizeCached = GetEnemyLabelSizeCached(enemyLabelInfo, centeredLabelStyle); GUI.Label(new Rect(guiPosition.x - enemyLabelSizeCached.x / 2f, guiPosition.y - enemyLabelSizeCached.y / 2f, enemyLabelSizeCached.x + 14f, enemyLabelSizeCached.y + 4f), enemyLabelInfo.RichText, centeredLabelStyle); } } } } } } private GUIStyle GetCenteredLabelStyle(int fontSize, bool shadow) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) int key = (shadow ? (-fontSize) : fontSize); if (enemyLabelStyleCache.TryGetValue(key, out var value)) { return value; } GUIStyle val = new GUIStyle(GUI.skin.label); val.fontSize = fontSize; val.fontStyle = (FontStyle)1; val.alignment = (TextAnchor)4; val.normal.textColor = (shadow ? Color.black : Color.white); enemyLabelStyleCache[key] = val; return val; } private void DrawLabel(Camera camera, ScanLabel label, int maxDistance, int baseFontSize, int shrinkPercent) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (label != null && TryWorldToGuiPoint(camera, label.Position, out var guiPosition, out var cameraDepth)) { int distanceScaledFontSize = GetDistanceScaledFontSize(baseFontSize, shrinkPercent, cameraDepth, maxDistance, 48); GUIStyle centeredStyle = GetCenteredStyle(distanceScaledFontSize, shadow: false); Vector2 scanLabelSizeCached = GetScanLabelSizeCached(label, centeredStyle); float num = Mathf.Clamp(scanLabelSizeCached.x + 18f, 80f, 420f); float num2 = scanLabelSizeCached.y + 6f; GUI.Label(new Rect(guiPosition.x - num / 2f, guiPosition.y - num2 / 2f, num, num2), label.RichText, centeredStyle); } } private bool TryRefreshLabel(ScanLabel label, Vector3 localPosition, float maxDistanceSquared, bool showDistance, bool showValuableName, bool showValuablePrice) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due