using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Liore")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MobScanner")] [assembly: AssemblyTitle("MobScanner")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MobScanner { [BepInPlugin("Liore.MobScanner", "MobScanner", "1.0")] public class MobScanner : BaseUnityPlugin { internal static ConfigEntry DebugLogging; internal static MobScanner Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } internal static void LogDebug(string message) { if (DebugLogging != null && DebugLogging.Value) { Logger.LogInfo((object)message); } } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; DebugLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugLogging", false, "Write detailed scan, marker, preview and shop diagnostics to the log."); Scanner.ScanKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "ScanKey", (KeyCode)122, "Hold this key to scan."); Scanner.HoldTime = ((BaseUnityPlugin)this).Config.Bind("Scanning", "HoldTime", 3f, "How many seconds you must hold the key without moving."); Scanner.ScanRadius = ((BaseUnityPlugin)this).Config.Bind("Scanning", "ScanRadius", 20f, "How far the scan reaches, in meters. Lower = shorter range."); Scanner.ResultDuration = ((BaseUnityPlugin)this).Config.Bind("Display", "ResultDuration", 15f, "How many seconds the scan results stay on screen."); Scanner.MarkerScale = ((BaseUnityPlugin)this).Config.Bind("Display", "MarkerScale", 1f, "Size of the dot drawn on the map. Raise this if you cannot see it."); Scanner.MarkerHeight = ((BaseUnityPlugin)this).Config.Bind("Display", "MarkerHeight", 0.35f, "How far above the map surface the dot floats. Raise if dots are hidden by unexplored areas."); Scanner.ShowModel = ((BaseUnityPlugin)this).Config.Bind("Display", "ShowModel", true, "Show a spinning 3D model of the monster that was found."); Scanner.SpinSpeed = ((BaseUnityPlugin)this).Config.Bind("Display", "SpinSpeed", 55f, "How fast the 3D model spins, in degrees per second."); Scanner.ModelCycleTime = ((BaseUnityPlugin)this).Config.Bind("Display", "ModelCycleTime", 2f, "Seconds each monster is shown before switching to the next one."); Scanner.UpgradePrice = ((BaseUnityPlugin)this).Config.Bind("Shop", "UpgradePrice", 5f, "Android vision price. The shop displays thousands, so 5 shows as $5K."); Scanner.UsesPerLevel = ((BaseUnityPlugin)this).Config.Bind("Shop", "UsesPerLevel", 2, "How many successful scans you get per level. Set to 0 for unlimited."); Scanner.RequireUpgrade = ((BaseUnityPlugin)this).Config.Bind("Shop", "RequireUpgrade", true, "If false, scanning works without buying the upgrade (useful for testing)."); Scanner.AlwaysInShop = ((BaseUnityPlugin)this).Config.Bind("Shop", "AlwaysInShop", true, "Always offer Android vision in the shop, even if you cannot afford it yet."); Scanner.EyeEffect = ((BaseUnityPlugin)this).Config.Bind("Display", "EyeEffect", true, "Make your eyes glow while scanning. Other players can see this too."); Scanner.EyeFlashSpeed = ((BaseUnityPlugin)this).Config.Bind("Display", "EyeFlashSpeed", 4f, "How many times per second the eyes switch between orange and red."); Scanner.EyeResultTime = ((BaseUnityPlugin)this).Config.Bind("Display", "EyeResultTime", 3f, "Seconds your eyes stay pink (found) or green (clear) after a scan."); Scanner.FontName = ((BaseUnityPlugin)this).Config.Bind("Display", "FontName", "", "Font to use for the scanner text. Leave empty to auto-pick. The log lists every available font name on the first scan."); Scanner.Cooldown = ((BaseUnityPlugin)this).Config.Bind("Scanning", "Cooldown", 3f, "Seconds you must wait after a scan before you can scan again."); ((Component)this).gameObject.AddComponent(); Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public class ModelPreview { private GameObject? _root; private Camera? _camera; private RenderTexture? _texture; private const int PreviewLayer = 31; private static readonly Vector3 StageOrigin = new Vector3(0f, -5000f, 0f); public bool IsValid => (Object)(object)_root != (Object)null && (Object)(object)_texture != (Object)null; public RenderTexture? Texture => _texture; public bool Build(EnemyParent enemyParent, int size) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Expected O, but got Unknown //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Expected O, but got Unknown //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Expected O, but got Unknown //IL_0514: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Expected O, but got Unknown //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_0602: Unknown result type (might be due to invalid IL or missing references) Dispose(); if ((Object)(object)enemyParent == (Object)null || (Object)(object)enemyParent.Enemy == (Object)null) { return false; } GameObject val = (((Object)(object)enemyParent.EnableObject != (Object)null) ? enemyParent.EnableObject : ((Component)enemyParent).gameObject); if ((Object)(object)val == (Object)null) { return false; } try { _root = new GameObject("MobScanner Preview Root"); _root.transform.position = StageOrigin; GameObject val2 = new GameObject("Model"); val2.transform.SetParent(_root.transform, false); val2.transform.localPosition = Vector3.zero; bool activeSelf = val.activeSelf; val.SetActive(false); GameObject val3 = Object.Instantiate(val, val2.transform); val.SetActive(activeSelf); ((Object)val3).name = "ModelBody"; val3.transform.localRotation = Quaternion.identity; val3.transform.localScale = Vector3.one; StripToVisualsOnly(val3); SetLayerRecursive(_root, 31); val3.SetActive(true); Transform[] componentsInChildren = val3.GetComponentsInChildren(true); foreach (Transform val4 in componentsInChildren) { ((Component)val4).gameObject.SetActive(true); } Bounds val5 = CalculateBounds(val3); float num = Mathf.Max(new float[3] { ((Bounds)(ref val5)).size.x, ((Bounds)(ref val5)).size.y, ((Bounds)(ref val5)).size.z }); if (num <= 0.001f) { num = 1f; } float num2 = 2f / num; val3.transform.localScale = Vector3.one * num2; Renderer[] componentsInChildren2 = val3.GetComponentsInChildren(true); Vector3 size2 = ((Bounds)(ref val5)).size; float num3 = Mathf.Max(((Vector3)(ref size2)).magnitude * 3f, 6f); int num4 = 0; int num5 = 0; Renderer[] array = componentsInChildren2; foreach (Renderer val6 in array) { Bounds bounds = val6.bounds; Vector3 size3 = ((Bounds)(ref bounds)).size; float num6 = Mathf.Max(size3.x, Mathf.Max(size3.y, size3.z)); bounds = val6.bounds; bool flag = Vector3.Distance(((Bounds)(ref bounds)).center, ((Bounds)(ref val5)).center) > num3; bool flag2 = num6 > 25f; if (flag || flag2) { val6.enabled = false; num4++; } else { num5++; } } if (num5 == 0) { Renderer[] array2 = componentsInChildren2; foreach (Renderer val7 in array2) { val7.enabled = true; } num4 = 0; num5 = componentsInChildren2.Length; MobScanner.LogDebug("PREVIEW: filter emptied model - restored all"); } MobScanner.LogDebug($"PREVIEW: hid {num4}, showing {num5}"); Bounds val8 = CalculateBounds(val3); Vector3 val9 = ((Bounds)(ref val8)).center - val2.transform.position; val3.transform.localPosition = -val9; MobScanner.LogDebug("PREVIEW: source=" + ((Object)val).name + " " + $"renderers={val3.GetComponentsInChildren(true).Length} " + $"skinned={val3.GetComponentsInChildren(true).Length} " + $"size={((Bounds)(ref val5)).size} fitScale={num2:F2}"); GameObject val10 = new GameObject("Key Light"); val10.transform.SetParent(_root.transform, false); val10.transform.localPosition = new Vector3(2f, 2.5f, -3f); val10.layer = 31; Light val11 = val10.AddComponent(); val11.type = (LightType)2; val11.range = 40f; val11.intensity = 6f; val11.cullingMask = int.MinValue; GameObject val12 = new GameObject("Fill Light"); val12.transform.SetParent(_root.transform, false); val12.transform.localPosition = new Vector3(-2.5f, 1f, -2f); val12.layer = 31; Light val13 = val12.AddComponent(); val13.type = (LightType)2; val13.range = 40f; val13.intensity = 3f; val13.cullingMask = int.MinValue; _texture = new RenderTexture(size, size, 16); _texture.Create(); GameObject val14 = new GameObject("Preview Camera"); val14.transform.SetParent(_root.transform, false); val14.transform.localPosition = new Vector3(0f, 0f, -4f); val14.layer = 31; _camera = val14.AddComponent(); _camera.cullingMask = int.MinValue; _camera.clearFlags = (CameraClearFlags)2; _camera.backgroundColor = new Color(0.04f, 0.05f, 0.04f, 1f); _camera.targetTexture = _texture; _camera.fieldOfView = 40f; _camera.nearClipPlane = 0.05f; _camera.farClipPlane = 100f; val14.transform.LookAt(val2.transform.position); ((Behaviour)_camera).enabled = true; Object.DontDestroyOnLoad((Object)(object)_root); return true; } catch (Exception ex) { MobScanner.Logger.LogWarning((object)("PREVIEW: failed to build - " + ex.Message)); Dispose(); return false; } } private static void StripToVisualsOnly(GameObject model) { for (int i = 0; i < 4; i++) { MonoBehaviour[] componentsInChildren = model.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { try { Object.DestroyImmediate((Object)(object)val); } catch (Exception) { } } } } Component[] componentsInChildren2 = model.GetComponentsInChildren(true); foreach (Component val2 in componentsInChildren2) { if ((Object)(object)val2 == (Object)null) { continue; } string name = ((object)val2).GetType().Name; if (name.Contains("Photon") || name.Contains("NavMesh")) { try { Object.DestroyImmediate((Object)(object)val2); } catch (Exception) { } } } Collider[] componentsInChildren3 = model.GetComponentsInChildren(true); foreach (Collider val3 in componentsInChildren3) { if ((Object)(object)val3 != (Object)null) { Object.DestroyImmediate((Object)(object)val3); } } Rigidbody[] componentsInChildren4 = model.GetComponentsInChildren(true); foreach (Rigidbody val4 in componentsInChildren4) { if ((Object)(object)val4 != (Object)null) { Object.DestroyImmediate((Object)(object)val4); } } Animator[] componentsInChildren5 = model.GetComponentsInChildren(true); foreach (Animator val5 in componentsInChildren5) { if ((Object)(object)val5 != (Object)null) { ((Behaviour)val5).enabled = false; } } ParticleSystem[] componentsInChildren6 = model.GetComponentsInChildren(true); foreach (ParticleSystem val6 in componentsInChildren6) { if ((Object)(object)val6 != (Object)null) { Object.DestroyImmediate((Object)(object)val6); } } AudioSource[] componentsInChildren7 = model.GetComponentsInChildren(true); foreach (AudioSource val7 in componentsInChildren7) { if ((Object)(object)val7 != (Object)null) { Object.DestroyImmediate((Object)(object)val7); } } Light[] componentsInChildren8 = model.GetComponentsInChildren(true); foreach (Light val8 in componentsInChildren8) { if ((Object)(object)val8 != (Object)null) { Object.DestroyImmediate((Object)(object)val8); } } Renderer[] componentsInChildren9 = model.GetComponentsInChildren(true); foreach (Renderer val9 in componentsInChildren9) { val9.enabled = true; ((Component)val9).gameObject.SetActive(true); } } private static Bounds CalculateBounds(GameObject model) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = model.GetComponentsInChildren(true); if (componentsInChildren.Length == 0) { return new Bounds(model.transform.position, Vector3.one); } List list = new List(); List list2 = new List(); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Bounds bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (!(size.y < 0.02f) || (!(size.x > 5f) && !(size.z > 5f))) { float num = Mathf.Max(size.x, Mathf.Max(size.y, size.z)); if (!(num > 25f)) { list.Add(val); list2.Add(num); } } } if (list.Count == 0) { Bounds bounds2 = componentsInChildren[0].bounds; for (int j = 1; j < componentsInChildren.Length; j++) { ((Bounds)(ref bounds2)).Encapsulate(componentsInChildren[j].bounds); } return bounds2; } List list3 = new List(list2); list3.Sort(); float num2 = list3[list3.Count / 2]; float num3 = Mathf.Max(num2 * 4f, 1.5f); bool flag = false; Bounds bounds3 = default(Bounds); ((Bounds)(ref bounds3))..ctor(model.transform.position, Vector3.zero); int num4 = 0; for (int k = 0; k < list.Count; k++) { if (!(list2[k] > num3)) { if (!flag) { bounds3 = list[k].bounds; flag = true; } else { ((Bounds)(ref bounds3)).Encapsulate(list[k].bounds); } num4++; } } if (!flag) { bounds3 = list[0].bounds; for (int l = 1; l < list.Count; l++) { ((Bounds)(ref bounds3)).Encapsulate(list[l].bounds); } num4 = list.Count; } MobScanner.LogDebug($"PREVIEW: measured {num4}/{componentsInChildren.Length} parts, median={num2:F2}, limit={num3:F2}"); Vector3 size2 = ((Bounds)(ref bounds3)).size; if (size2.x < 0.1f || size2.y < 0.1f || size2.z < 0.1f) { ((Bounds)(ref bounds3)).Encapsulate(((Bounds)(ref bounds3)).center + Vector3.one * 0.25f); ((Bounds)(ref bounds3)).Encapsulate(((Bounds)(ref bounds3)).center - Vector3.one * 0.25f); } return bounds3; } private static void SetLayerRecursive(GameObject target, int layer) { target.layer = layer; Transform[] componentsInChildren = target.GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { ((Component)val).gameObject.layer = layer; } } public void Spin(float degreesPerSecond) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { Transform val = _root.transform.Find("Model"); if ((Object)(object)val != (Object)null) { val.Rotate(Vector3.up, degreesPerSecond * Time.deltaTime, (Space)0); } } } public void Dispose() { if ((Object)(object)_camera != (Object)null) { _camera.targetTexture = null; _camera = null; } if ((Object)(object)_texture != (Object)null) { _texture.Release(); Object.Destroy((Object)(object)_texture); _texture = null; } if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } } } public class ScanResult { public string Name = ""; public int Tier = 1; public int Count = 1; public Transform? EnemyTransform; public EnemyParent? Parent; public GameObject? Marker; } public class Scanner : MonoBehaviour { public static ConfigEntry ScanKey = null; public static ConfigEntry ScanRadius = null; public static ConfigEntry HoldTime = null; public static ConfigEntry ResultDuration = null; public static ConfigEntry MarkerScale = null; public static ConfigEntry Cooldown = null; public static ConfigEntry MarkerHeight = null; public static ConfigEntry ShowModel = null; public static ConfigEntry SpinSpeed = null; public static ConfigEntry ModelCycleTime = null; public static ConfigEntry UpgradePrice = null; public static ConfigEntry UsesPerLevel = null; public static ConfigEntry RequireUpgrade = null; public static ConfigEntry AlwaysInShop = null; public static ConfigEntry EyeEffect = null; public static ConfigEntry EyeFlashSpeed = null; public static ConfigEntry EyeResultTime = null; public static ConfigEntry FontName = null; private float _holdTimer; private bool _scanning; private bool _awaitingRelease; private readonly List _results = new List(); private float _resultTimer; private float _cooldownTimer; private bool _foundAnything; private static bool _hasScanner; private static int _usesLeft; private string _lastLevelName = ""; private float _messageTimer; private string _message = ""; private readonly ModelPreview _preview = new ModelPreview(); private int _previewIndex; private float _previewTimer; private string _previewName = ""; private Texture2D? _dotTexture; private static readonly Color TierGreen = new Color(0.2f, 1f, 0.2f); private static readonly Color TierOrange = new Color(1f, 0.65f, 0f); private static readonly Color TierRed = new Color(1f, 0.15f, 0.15f); private float _shopRegisterTimer; private float _eyeFlashTimer; private bool _eyeUseRed; private float _eyeResultTimer; private bool _eyeResultFound; private static Font? _gameFont; private static bool _fontSearched; private static Font? GameFont { get { EnsureFont(); return _gameFont; } } public static void GrantScanner() { _hasScanner = true; } private static Color ColourForTier(int tier) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (tier >= 3) { return TierRed; } if (tier == 2) { return TierOrange; } return TierGreen; } private void Awake() { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) _dotTexture = new Texture2D(1, 1); _dotTexture.SetPixel(0, 0, Color.white); _dotTexture.Apply(); } private void Update() { //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ShopIntegration.RegisteredItem == (Object)null) { _shopRegisterTimer -= Time.deltaTime; if (_shopRegisterTimer <= 0f) { _shopRegisterTimer = 1f; ShopIntegration.TryRegister(); } } UpdateMarkers(); if (_resultTimer > 0f) { _preview.Spin(SpinSpeed.Value); if (_previewTimer > 0f) { _previewTimer -= Time.deltaTime; if (_previewTimer <= 0f) { ShowNextPreview(); } } } if (_resultTimer > 0f) { _resultTimer -= Time.deltaTime; if (_resultTimer <= 0f) { ClearResults(); } } if (_cooldownTimer > 0f) { _cooldownTimer -= Time.deltaTime; } if (_messageTimer > 0f) { _messageTimer -= Time.deltaTime; } if ((Object)(object)Map.Instance == (Object)null || (Object)(object)PlayerController.instance == (Object)null) { _eyeResultTimer = 0f; return; } if (_eyeResultTimer > 0f) { _eyeResultTimer -= Time.deltaTime; ShowResultEyes(); } string levelKey = GetLevelKey(); if (levelKey != _lastLevelName) { MobScanner.LogDebug("SCAN: level changed '" + _lastLevelName + "' -> '" + levelKey + "'"); _lastLevelName = levelKey; _usesLeft = UsesPerLevel.Value; ClearResults(); MobScanner.LogDebug($"SCAN: uses reset to {_usesLeft}"); } if (RequireUpgrade.Value && !_hasScanner) { return; } if (_cooldownTimer > 0f) { _scanning = false; _holdTimer = 0f; } else if (UsesPerLevel.Value > 0 && _usesLeft <= 0) { if (Input.GetKeyDown(ScanKey.Value)) { _message = "NO SCANS LEFT"; _messageTimer = 2f; } _scanning = false; _holdTimer = 0f; } else if (!Input.GetKey(ScanKey.Value)) { if (_scanning) { MobScanner.LogDebug("SCAN: cancelled (key released)"); } _scanning = false; _holdTimer = 0f; _awaitingRelease = false; } else { if (_awaitingRelease) { return; } if (!_scanning) { _scanning = true; _holdTimer = 0f; MobScanner.LogDebug("SCAN: started - charging..."); return; } UpdateEyeEffect(); _holdTimer += Time.deltaTime; if (!(_holdTimer >= HoldTime.Value)) { return; } _scanning = false; _holdTimer = 0f; _awaitingRelease = true; DoScan(); _eyeResultFound = _foundAnything; _eyeResultTimer = EyeResultTime.Value; if (_foundAnything) { _cooldownTimer = Cooldown.Value; if (UsesPerLevel.Value > 0) { _usesLeft--; MobScanner.LogDebug($"SCAN: use consumed - {_usesLeft} left this level"); } else { MobScanner.LogDebug("SCAN: unlimited mode - no use consumed"); } } else { MobScanner.LogDebug("SCAN: nothing found - use NOT consumed"); } } } private static void EnsureFont() { if (_fontSearched) { return; } _fontSearched = true; Font[] array = Resources.FindObjectsOfTypeAll(); MobScanner.LogDebug($"FONT: {array.Length} font(s) loaded in memory"); Font[] array2 = array; foreach (Font val in array2) { if ((Object)(object)val != (Object)null) { MobScanner.LogDebug("FONT: available '" + ((Object)val).name + "'"); } } string text = FontName.Value ?? ""; if (text.Length > 0) { Font[] array3 = array; foreach (Font val2 in array3) { if ((Object)(object)val2 != (Object)null && ((Object)val2).name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { _gameFont = val2; MobScanner.LogDebug("FONT: using '" + ((Object)val2).name + "' (matched config)"); return; } } MobScanner.Logger.LogWarning((object)("FONT: no font matching '" + text + "' - falling back to the default")); return; } string[] array4 = new string[7] { "pixel", "silk", "vcr", "press", "arcade", "8bit", "bit" }; string[] array5 = array4; foreach (string text2 in array5) { Font[] array6 = array; foreach (Font val3 in array6) { if ((Object)(object)val3 != (Object)null && ((Object)val3).name.IndexOf(text2, StringComparison.OrdinalIgnoreCase) >= 0) { _gameFont = val3; MobScanner.LogDebug("FONT: auto-picked '" + ((Object)val3).name + "' (hint '" + text2 + "')"); return; } } } MobScanner.LogDebug("FONT: no pixel font found - using Unity's default"); } private void UpdateEyeEffect() { //IL_00a5: 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) if (!EyeEffect.Value) { return; } PlayerAvatar playerAvatarScript = PlayerController.instance.playerAvatarScript; if (!((Object)(object)playerAvatarScript == (Object)null) && !((Object)(object)playerAvatarScript.playerHealth == (Object)null)) { _eyeFlashTimer -= Time.deltaTime; if (_eyeFlashTimer <= 0f) { _eyeFlashTimer = 1f / Mathf.Max(EyeFlashSpeed.Value, 0.1f); _eyeUseRed = !_eyeUseRed; } EyeOverrideState val = (EyeOverrideState)(_eyeUseRed ? 1 : 4); playerAvatarScript.playerHealth.EyeMaterialOverride(val, 0.25f, 2); } } private void ShowResultEyes() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (EyeEffect.Value && !((Object)(object)PlayerController.instance == (Object)null)) { PlayerAvatar playerAvatarScript = PlayerController.instance.playerAvatarScript; if (!((Object)(object)playerAvatarScript == (Object)null) && !((Object)(object)playerAvatarScript.playerHealth == (Object)null)) { EyeOverrideState val = (EyeOverrideState)(_eyeResultFound ? 3 : 2); playerAvatarScript.playerHealth.EyeMaterialOverride(val, 0.25f, 3); } } } private static string GetLevelKey() { RunManager instance = RunManager.instance; if ((Object)(object)instance == (Object)null) { return "no-run"; } string arg = (((Object)(object)instance.levelCurrent != (Object)null) ? ((Object)instance.levelCurrent).name : "null"); return $"{arg}|{instance.levelsCompleted}|{instance.runLives}"; } private List UniqueResults() { List list = new List(); foreach (ScanResult result in _results) { if (result.Count > 0) { list.Add(result); } } return list; } private void ShowNextPreview() { if (ShowModel.Value) { List list = UniqueResults(); if (list.Count <= 1) { _previewTimer = ModelCycleTime.Value; return; } _previewIndex = (_previewIndex + 1) % list.Count; BuildPreviewFor(list[_previewIndex]); } } private void BuildPreviewFor(ScanResult result) { if (!((Object)(object)result.Parent == (Object)null)) { if (_preview.IsValid && _previewName == result.Name) { _previewTimer = ModelCycleTime.Value; return; } bool flag = _preview.Build(result.Parent, 220); _previewName = result.Name; _previewTimer = ModelCycleTime.Value; MobScanner.LogDebug("PREVIEW: showing " + result.Name + " (" + (flag ? "ok" : "failed") + ")"); } } private void ClearResults() { foreach (ScanResult result in _results) { if ((Object)(object)result.Marker != (Object)null) { Object.Destroy((Object)(object)result.Marker); } } _results.Clear(); _preview.Dispose(); _previewIndex = 0; _previewTimer = 0f; _previewName = ""; } private void UpdateMarkers() { //IL_006a: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Map.Instance == (Object)null) { return; } foreach (ScanResult result in _results) { if (!((Object)(object)result.Marker == (Object)null) && !((Object)(object)result.EnemyTransform == (Object)null)) { Transform transform = result.Marker.transform; Vector3 val = result.EnemyTransform.position * Map.Instance.Scale + Map.Instance.OverLayerParent.position; transform.position = new Vector3(val.x, Map.Instance.OverLayerParent.position.y + MarkerHeight.Value, val.z); float num = Mathf.PingPong(Time.time * 2.2f, 1f); Color val2 = ColourForTier(result.Tier); Color color = Color.Lerp(val2, Color.white, num * 0.55f); color.a = 0.55f + num * 0.45f; SpriteRenderer[] componentsInChildren = result.Marker.GetComponentsInChildren(true); foreach (SpriteRenderer val3 in componentsInChildren) { val3.color = color; } float num2 = MarkerScale.Value * (1f + num * 0.35f); transform.localScale = Vector3.one * num2; } } } private GameObject? CreateMarker(Transform enemyTransform, Color colour) { //IL_00ea: 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_011d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Map.Instance == (Object)null) { return null; } GameObject val = (((Object)(object)Map.Instance.ValuableObject != (Object)null) ? Map.Instance.ValuableObject : Map.Instance.EnemyObject); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = Object.Instantiate(val, Map.Instance.OverLayerParent); ((Object)val2).name = "MobScanner Marker"; val2.SetActive(true); MapValuable component = val2.GetComponent(); if ((Object)(object)component != (Object)null) { SpriteRenderer spriteRenderer = component.spriteRenderer; if ((Object)(object)spriteRenderer != (Object)null && (Object)(object)spriteRenderer.sprite == (Object)null) { spriteRenderer.sprite = (((Object)(object)component.spriteBig != (Object)null) ? component.spriteBig : component.spriteSmall); } Object.Destroy((Object)(object)component); } val2.transform.localScale = Vector3.one * MarkerScale.Value; SpriteRenderer[] componentsInChildren = val2.GetComponentsInChildren(true); foreach (SpriteRenderer val3 in componentsInChildren) { val3.color = colour; ((Renderer)val3).enabled = true; ((Renderer)val3).sortingOrder = 32000; } Transform[] componentsInChildren2 = val2.GetComponentsInChildren(true); foreach (Transform val4 in componentsInChildren2) { ((Component)val4).gameObject.SetActive(true); ((Component)val4).gameObject.layer = ((Component)Map.Instance.OverLayerParent).gameObject.layer; } MobScanner.LogDebug($"MARKER: built from {((Object)val).name}, scale={MarkerScale.Value}"); return val2; } private void DoScan() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: 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_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected I4, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) MobScanner.LogDebug("=== SCAN COMPLETE ==="); ClearResults(); _resultTimer = ResultDuration.Value; Vector3 position = ((Component)PlayerController.instance).transform.position; List list = new List(); PlayerAvatar playerAvatarScript = PlayerController.instance.playerAvatarScript; if ((Object)(object)playerAvatarScript != (Object)null && (Object)(object)playerAvatarScript.RoomVolumeCheck != (Object)null) { list.AddRange(playerAvatarScript.RoomVolumeCheck.CurrentRooms); } foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned) { if ((Object)(object)item == (Object)null || (Object)(object)item.Enemy == (Object)null || !item.Spawned || (item.Enemy.HasHealth && item.Enemy.Health.dead)) { continue; } Vector3 position2 = ((Component)item.Enemy).transform.position; float num = Vector3.Distance(position, position2); if (num > ScanRadius.Value) { continue; } bool flag = false; foreach (RoomVolume currentRoom in item.currentRooms) { if ((Object)(object)currentRoom != (Object)null && list.Contains(currentRoom)) { flag = true; break; } } int num2 = item.difficulty + 1; Color colour = ColourForTier(num2); ScanResult scanResult = null; foreach (ScanResult result in _results) { if (result.Name == item.enemyName) { scanResult = result; break; } } if (scanResult != null) { scanResult.Count++; scanResult.Marker = scanResult.Marker; GameObject val = CreateMarker(((Component)item.Enemy).transform, colour); if ((Object)(object)val != (Object)null) { _results.Add(new ScanResult { Name = item.enemyName, Tier = num2, Count = 0, EnemyTransform = ((Component)item.Enemy).transform, Parent = item, Marker = val }); } MobScanner.LogDebug($"SCAN: found {item.enemyName} | T{num2} | {num:F1}m | " + (flag ? "SAME ROOM" : "nearby room")); } else { ScanResult scanResult2 = new ScanResult { Name = item.enemyName, Tier = num2, EnemyTransform = ((Component)item.Enemy).transform, Parent = item }; scanResult2.Marker = CreateMarker(((Component)item.Enemy).transform, colour); if ((Object)(object)scanResult2.Marker == (Object)null) { MobScanner.Logger.LogWarning((object)"SCAN: could not create map marker"); } _results.Add(scanResult2); MobScanner.LogDebug($"SCAN: found {item.enemyName} | T{num2} | {num:F1}m | " + (flag ? "SAME ROOM" : "nearby room")); } } _foundAnything = _results.Count > 0; if (_foundAnything && ShowModel.Value) { List list2 = UniqueResults(); if (list2.Count > 0) { _previewIndex = 0; BuildPreviewFor(list2[0]); } } if (_results.Count == 0) { MobScanner.LogDebug("SCAN: no monsters in range"); } MobScanner.LogDebug("====================="); } private void DrawRect(float x, float y, float width, float height, Color colour) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_dotTexture == (Object)null)) { Color color = GUI.color; GUI.color = colour; GUI.DrawTexture(new Rect(x, y, width, height), (Texture)(object)_dotTexture); GUI.color = color; } } private void DrawDot(float x, float y, float size, Color colour) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_dotTexture == (Object)null)) { Color color = GUI.color; GUI.color = colour; GUI.DrawTexture(new Rect(x, y, size, size), (Texture)(object)_dotTexture); GUI.color = color; } } private void OnGUI() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006c: Expected O, but got Unknown //IL_0082: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: 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_0262: 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_0275: Expected O, but got Unknown //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Expected O, but got Unknown //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) //IL_0550: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Expected O, but got Unknown //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Unknown result type (might be due to invalid IL or missing references) //IL_061e: Expected O, but got Unknown //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Expected O, but got Unknown //IL_066f: Unknown result type (might be due to invalid IL or missing references) //IL_06bc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Map.Instance == (Object)null) { return; } if (_messageTimer > 0f && _message != "") { GUIStyle val = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = 18, fontStyle = (FontStyle)1 }; val.normal.textColor = new Color(1f, 0.4f, 0.3f); GUI.Label(new Rect(20f, (float)Screen.height * 0.44f, 320f, 26f), _message, val); } if (!RequireUpgrade.Value || _hasScanner) { GUIStyle val2 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = 14, fontStyle = (FontStyle)1 }; val2.normal.textColor = ((UsesPerLevel.Value <= 0 || _usesLeft > 0) ? new Color(0.4f, 1f, 0.5f, 0.85f) : new Color(0.7f, 0.3f, 0.3f, 0.85f)); string text = ((UsesPerLevel.Value > 0) ? $"SCANS: {_usesLeft}" : "SCANS: UNLIMITED"); GUI.Label(new Rect(20f, (float)Screen.height * 0.41f, 320f, 20f), text, val2); } float num = 20f; float num2 = (float)Screen.height * 0.44f; if (_scanning) { float num3 = _holdTimer / HoldTime.Value; float num4 = 4f + num3 * 8f; float num5 = Mathf.PingPong(Time.time * num4, 1f); float num6 = 0.35f + num5 * 0.65f; DrawDot(num, num2 + 7f, 11f, new Color(0.2f, 1f, 0.2f, num6)); GUIStyle val3 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = 18, fontStyle = (FontStyle)1 }; val3.normal.textColor = new Color(0.2f, 1f, 0.2f, num6); GUI.Label(new Rect(num + 20f, num2, 320f, 28f), "SCANNING...", val3); } else { if (_resultTimer <= 0f) { return; } GUIStyle val4 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = 18, fontStyle = (FontStyle)1 }; if (_preview.IsValid && (Object)(object)_preview.Texture != (Object)null) { float num7 = 150f; float num8 = 4f; float num9 = num2 - num7 - 12f; float x = num - num8; float y = num9 - num8; float num10 = num7 + num8 * 2f; DrawRect(x, y, num10, num10, new Color(0.58f, 0.6f, 0.57f, 0.95f)); DrawRect(num - 1f, num9 - 1f, num7 + 2f, num7 + 2f, new Color(0.08f, 0.1f, 0.08f, 1f)); DrawRect(num, num9, num7, num7, new Color(0.07f, 0.13f, 0.09f, 1f)); GUI.DrawTexture(new Rect(num, num9, num7, num7), (Texture)(object)_preview.Texture); Color colour = default(Color); ((Color)(ref colour))..ctor(0f, 0f, 0f, 0.14f); for (float num11 = 1f; num11 < num7 - 1f; num11 += 4f) { DrawRect(num, num9 + num11, num7, 2f, colour); } List list = UniqueResults(); if (list.Count > 1) { GUIStyle val5 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = 12, fontStyle = (FontStyle)1, alignment = (TextAnchor)5 }; val5.normal.textColor = new Color(0.5f, 1f, 0.6f, 0.85f); GUI.Label(new Rect(num, num9 + num7 - 18f, num7 - 5f, 16f), $"{_previewIndex + 1}/{list.Count}", val5); } } GUIStyle val6 = new GUIStyle(val4); val6.normal.textColor = (_foundAnything ? new Color(0.2f, 1f, 0.2f) : new Color(0.75f, 0.75f, 0.75f)); GUI.Label(new Rect(num, num2, 320f, 26f), _foundAnything ? "FOUND" : "NOT FOUND", val6); float num12 = 26f; float num13 = num2 + 28f; int num14 = 0; for (int i = 0; i < _results.Count; i++) { ScanResult scanResult = _results[i]; if (scanResult.Count > 0) { Color val7 = ColourForTier(scanResult.Tier); float num15 = num13 + (float)num14 * num12; num14++; DrawDot(num, num15 + 7f, 11f, val7); GUIStyle val8 = new GUIStyle(val4); val8.normal.textColor = val7; GUI.Label(new Rect(num + 20f, num15, 36f, num12), $"T{scanResult.Tier}", val8); GUIStyle val9 = new GUIStyle(val4); val9.normal.textColor = Color.white; string text2 = ((scanResult.Count > 1) ? $"{scanResult.Name} x{scanResult.Count}" : scanResult.Name); GUI.Label(new Rect(num + 54f, num15, 280f, num12), text2, val9); } } } } private void OnDestroy() { ClearResults(); } } public static class ShopIntegration { public const string ItemKey = "Item Upgrade Android Vision"; public const string DisplayName = "Android vision"; private const string TemplateKey = "Item Upgrade Player Grab Strength"; internal static Item? RegisteredItem; public static void TryRegister() { //IL_01d1: 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: Invalid comparison between Unknown and I4 if ((Object)(object)RegisteredItem != (Object)null || (Object)(object)StatsManager.instance == (Object)null) { return; } Dictionary itemDictionary = StatsManager.instance.itemDictionary; if (itemDictionary.Count == 0) { return; } if (itemDictionary.ContainsKey("Item Upgrade Android Vision")) { RegisteredItem = itemDictionary["Item Upgrade Android Vision"]; return; } MobScanner.LogDebug($"SHOP: item dictionary has {itemDictionary.Count} entries, registering..."); Item val = null; if (itemDictionary.ContainsKey("Item Upgrade Player Grab Strength")) { val = itemDictionary["Item Upgrade Player Grab Strength"]; } else { foreach (KeyValuePair item in itemDictionary) { if ((Object)(object)item.Value != (Object)null && (int)item.Value.itemType == 3) { val = item.Value; MobScanner.LogDebug("SHOP: template 'Item Upgrade Player Grab Strength' missing, using '" + item.Key + "'"); break; } } } if ((Object)(object)val == (Object)null) { MobScanner.Logger.LogWarning((object)"SHOP: no upgrade template found - cannot register"); return; } Item val2 = Object.Instantiate(val); ((Object)val2).name = "Item Upgrade Android Vision"; val2.itemName = "Android vision"; val2.itemNameLocalized = null; val2.value.valueMin = 2000f; val2.value.valueMax = 2000f; val2.maxAmountInShop = 1; Object.DontDestroyOnLoad((Object)(object)val2); itemDictionary["Item Upgrade Android Vision"] = val2; RegisteredItem = val2; MobScanner.LogDebug("SHOP: registered 'Android vision' (template=" + ((Object)val).name + ", " + $"type={val2.itemType})"); } } [HarmonyPatch(typeof(StatsManager))] internal static class StatsManagerPatch { [HarmonyPostfix] [HarmonyPatch("LoadItemsFromFolder")] private static void LoadItemsFromFolder_Postfix() { ShopIntegration.TryRegister(); } } [HarmonyPatch(typeof(ShopManager), "UpgradeValueGet")] internal static class UpgradeValueGetPatch { private static void Postfix(Item item, ref float __result) { if ((Object)(object)item != (Object)null && ((Object)item).name == "Item Upgrade Android Vision") { __result = Scanner.UpgradePrice.Value; } } } [HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")] internal static class ForceIntoPoolPatch { private static void Postfix(ShopManager __instance) { if (!Scanner.AlwaysInShop.Value) { return; } Item registeredItem = ShopIntegration.RegisteredItem; if ((Object)(object)registeredItem == (Object)null) { return; } foreach (Item potentialItemUpgrade in __instance.potentialItemUpgrades) { if ((Object)(object)potentialItemUpgrade != (Object)null && ((Object)potentialItemUpgrade).name == "Item Upgrade Android Vision") { return; } } if (SemiFunc.StatGetItemsPurchased(((Object)registeredItem).name) < registeredItem.maxAmountInShop) { __instance.potentialItemUpgrades.Add(registeredItem); MobScanner.LogDebug($"SHOP POOL: forced Android vision to front of {__instance.potentialItemUpgrades.Count} upgrades " + $"(shop shows {__instance.itemUpgradesAmount})"); } } } [HarmonyPatch(typeof(ShopManager), "GetAllItemsFromStatsManager")] internal static class ShopPoolPatch { private static void Postfix(ShopManager __instance) { int count = __instance.potentialItemUpgrades.Count; int num = 0; foreach (Item potentialItemUpgrade in __instance.potentialItemUpgrades) { if ((Object)(object)potentialItemUpgrade != (Object)null && ((Object)potentialItemUpgrade).name == "Item Upgrade Android Vision") { num++; } } MobScanner.LogDebug($"SHOP POOL: {count} upgrades available, {num} of them are Android vision"); for (int i = 0; i < __instance.potentialItemUpgrades.Count; i++) { Item val = __instance.potentialItemUpgrades[i]; if ((Object)(object)val != (Object)null && ((Object)val).name == "Item Upgrade Android Vision") { MobScanner.LogDebug($"SHOP POOL: Android vision is at position {i} " + $"(shop displays the first {__instance.itemUpgradesAmount})"); break; } } if (num == 0) { MobScanner.LogDebug("SHOP POOL: Android vision was filtered out - checking why..."); if ((Object)(object)ShopIntegration.RegisteredItem == (Object)null) { MobScanner.LogDebug("SHOP POOL: reason = item never registered"); return; } Item registeredItem = ShopIntegration.RegisteredItem; int num2 = SemiFunc.StatGetItemsPurchased(((Object)registeredItem).name); MobScanner.LogDebug($"SHOP POOL: purchased={num2} " + $"maxAmountInShop={registeredItem.maxAmountInShop} " + $"maxPurchase={registeredItem.maxPurchase} " + $"minPlayerCount={registeredItem.minPlayerCount} " + $"valueMax={registeredItem.value.valueMax} " + $"currency={__instance.totalCurrency}"); } } } [HarmonyPatch(typeof(PunManager), "SpawnShopItem")] internal static class SpawnShopItemPatch { private static void Postfix(ItemVolume itemVolume, List itemList, bool __result) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!__result) { return; } bool flag = false; foreach (Item item in itemList) { if ((Object)(object)item != (Object)null && ((Object)item).name == "Item Upgrade Android Vision") { flag = true; break; } } MobScanner.LogDebug($"SHOP SPAWN: placed an item on a '{itemVolume.itemVolume}' shelf, " + $"{itemList.Count} left in this list, ours still queued: {flag}"); } } [HarmonyPatch(typeof(PunManager), "ShopPopulateItemVolumes")] internal static class ShelfCheckPatch { private static void Prefix() { //IL_0052: 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_008d: Unknown result type (might be due to invalid IL or missing references) Item registeredItem = ShopIntegration.RegisteredItem; if ((Object)(object)registeredItem == (Object)null || (Object)(object)ShopManager.instance == (Object)null) { return; } int num = 0; foreach (ItemVolume itemVolume in ShopManager.instance.itemVolumes) { if ((Object)(object)itemVolume != (Object)null && itemVolume.itemVolume == registeredItem.itemVolume) { num++; } } MobScanner.LogDebug($"SHOP SHELVES: Android vision needs a '{registeredItem.itemVolume}' shelf; " + $"{num} of {ShopManager.instance.itemVolumes.Count} shelves match. " + "prefab=" + ((registeredItem.prefab == null) ? "NULL" : ((PrefabRef)(object)registeredItem.prefab).ResourcePath)); } } [HarmonyPatch(typeof(ItemAttributes), "Start")] internal static class ItemAttributesStartPatch { internal static int PendingSpawns; private static void Postfix(ItemAttributes __instance) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Invalid comparison between Unknown and I4 if (PendingSpawns > 0 && SemiFunc.RunIsShop()) { Item registeredItem = ShopIntegration.RegisteredItem; if (!((Object)(object)registeredItem == (Object)null) && !((Object)(object)__instance.item == (Object)null) && (!(((Object)__instance.item).name != ((Object)registeredItem).name) || (int)__instance.item.itemType == 3)) { PendingSpawns--; __instance.item = registeredItem; __instance.itemName = "Android vision"; __instance.value = (int)Scanner.UpgradePrice.Value; MobScanner.LogDebug("SHOP: converted a spawned upgrade into 'Android vision' " + $"at {__instance.value}"); } } } } [HarmonyPatch(typeof(PunManager), "ShopPopulateItemVolumes")] internal static class MarkPendingPatch { private static void Prefix() { Item registeredItem = ShopIntegration.RegisteredItem; if ((Object)(object)registeredItem == (Object)null) { ItemAttributesStartPatch.PendingSpawns = 0; return; } if (SemiFunc.StatGetItemsPurchased(((Object)registeredItem).name) >= registeredItem.maxAmountInShop) { ItemAttributesStartPatch.PendingSpawns = 0; return; } ItemAttributesStartPatch.PendingSpawns = 1; MobScanner.LogDebug("SHOP: expecting to convert 1 upgrade into Android vision"); } } [HarmonyPatch(typeof(StatsManager), "AddItemsUpgradesPurchased")] internal static class UpgradePurchasedPatch { private static void Postfix(string itemName) { if (!(itemName != "Item Upgrade Android Vision")) { Scanner.GrantScanner(); MobScanner.LogDebug("SHOP: Android vision activated"); } } } public static class UpgradeBoxModel { private static readonly Color BodyOrange = new Color(0.85f, 0.42f, 0.13f); private static readonly Color BodyDark = new Color(0.55f, 0.26f, 0.08f); private static readonly Color ScreenGreen = new Color(0.24f, 0.78f, 0.35f); private static readonly Color ScreenGlow = new Color(0.45f, 1f, 0.55f); private static readonly Color CaseGrey = new Color(0.72f, 0.74f, 0.68f); public static GameObject Build() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Android Vision Model"); GameObject val2 = MakeCube(val.transform, "Body", new Vector3(0f, 0f, 0f), new Vector3(0.55f, 0.62f, 0.3f), BodyOrange); MakeCube(val.transform, "Base", new Vector3(0f, -0.34f, 0f), new Vector3(0.62f, 0.1f, 0.36f), BodyDark); MakeCube(val.transform, "Bezel", new Vector3(0f, 0.08f, -0.16f), new Vector3(0.44f, 0.36f, 0.04f), CaseGrey); GameObject part = MakeCube(val.transform, "Screen", new Vector3(0f, 0.08f, -0.185f), new Vector3(0.36f, 0.28f, 0.02f), ScreenGreen); MakeEmissive(part, ScreenGlow, 1.4f); MakeCylinder(val.transform, "Antenna L", new Vector3(-0.16f, 0.42f, 0f), new Vector3(0.03f, 0.12f, 0.03f), CaseGrey); MakeCylinder(val.transform, "Antenna R", new Vector3(0.16f, 0.42f, 0f), new Vector3(0.03f, 0.12f, 0.03f), CaseGrey); MakeSphere(val.transform, "Antenna Tip L", new Vector3(-0.16f, 0.55f, 0f), Vector3.one * 0.07f, CaseGrey); MakeSphere(val.transform, "Antenna Tip R", new Vector3(0.16f, 0.55f, 0f), Vector3.one * 0.07f, CaseGrey); MakeSphere(val.transform, "Light T1", new Vector3(-0.12f, -0.18f, -0.17f), Vector3.one * 0.055f, new Color(0.2f, 1f, 0.2f)); MakeSphere(val.transform, "Light T2", new Vector3(0f, -0.18f, -0.17f), Vector3.one * 0.055f, new Color(1f, 0.65f, 0f)); MakeSphere(val.transform, "Light T3", new Vector3(0.12f, -0.18f, -0.17f), Vector3.one * 0.055f, new Color(1f, 0.15f, 0.15f)); return val; } private static GameObject MakeCube(Transform parent, string name, Vector3 position, Vector3 scale, Color colour) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return MakePrimitive((PrimitiveType)3, parent, name, position, scale, colour); } private static GameObject MakeCylinder(Transform parent, string name, Vector3 position, Vector3 scale, Color colour) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return MakePrimitive((PrimitiveType)2, parent, name, position, scale, colour); } private static GameObject MakeSphere(Transform parent, string name, Vector3 position, Vector3 scale, Color colour) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return MakePrimitive((PrimitiveType)0, parent, name, position, scale, colour); } private static GameObject MakePrimitive(PrimitiveType type, Transform parent, string name, Vector3 position, Vector3 scale, Color colour) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive(type); ((Object)val).name = name; val.transform.SetParent(parent, false); val.transform.localPosition = position; val.transform.localScale = scale; Collider component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { Material val2 = new Material(Shader.Find("Standard")); val2.color = colour; component2.material = val2; } return val; } private static void MakeEmissive(GameObject part, Color colour, float strength) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Renderer component = part.GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.material == (Object)null)) { Material material = component.material; material.EnableKeyword("_EMISSION"); material.SetColor("_EmissionColor", colour * strength); } } } }