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 MobScanner v1.0.3
BepInEx/plugin/MobScanner.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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 ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; 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<bool> 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<bool>("Debug", "DebugLogging", false, "Write detailed scan, marker, preview and shop diagnostics to the log."); Scanner.ScanKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ScanKey", (KeyCode)122, "Hold this key to scan."); Scanner.HoldTime = ((BaseUnityPlugin)this).Config.Bind<float>("Scanning", "HoldTime", 3f, "How many seconds you must hold the key without moving."); Scanner.ScanRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Scanning", "ScanRadius", 20f, "How far the scan reaches, in meters. Lower = shorter range."); Scanner.ResultDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "ResultDuration", 15f, "How many seconds the scan results stay on screen."); Scanner.MarkerScale = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "MarkerScale", 1f, "Size of the dot drawn on the map. Raise this if you cannot see it."); Scanner.MarkerHeight = ((BaseUnityPlugin)this).Config.Bind<float>("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<bool>("Display", "ShowModel", true, "Show a spinning 3D model of the monster that was found."); Scanner.SpinSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "SpinSpeed", 55f, "How fast the 3D model spins, in degrees per second."); Scanner.ModelCycleTime = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "ModelCycleTime", 2f, "Seconds each monster is shown before switching to the next one."); Scanner.UpgradePrice = ((BaseUnityPlugin)this).Config.Bind<float>("Shop", "UpgradePrice", 5f, "Android vision price. The shop displays thousands, so 5 shows as $5K."); Scanner.UsesPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Shop", "UsesPerLevel", 2, "How many successful scans you get per level. Set to 0 for unlimited."); Scanner.RequireUpgrade = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "RequireUpgrade", true, "If false, scanning works without buying the upgrade (useful for testing)."); Scanner.AlwaysInShop = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "AlwaysInShop", false, "Force Android vision into every shop. Off by default so it turns up at random like any other upgrade."); Scanner.EyeEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "EyeEffect", true, "Make your eyes glow while scanning. Other players can see this too."); Scanner.EyeFlashSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "EyeFlashSpeed", 4f, "How many times per second the eyes switch between orange and red."); Scanner.EyeResultTime = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "EyeResultTime", 3f, "Seconds your eyes stay pink (found) or green (clear) after a scan."); Scanner.FontName = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "FontName", "RobotoMono", "Font for the scanner text. Tries the game's own fonts first, then fonts installed on your PC (e.g. Impact, Consolas). Leave empty to auto-pick."); Scanner.TextSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "TextSize", 22, "Size of the scanner text on screen. Raise it if the readout is hard to see."); Scanner.OutlineThickness = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "OutlineThickness", 1.5f, "Thickness of the dark outline behind the text. Set to 0 to turn it off."); Scanner.UseCustomCardArt = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop", "UseCustomCardArt", true, "Paint the mod's own artwork onto the Android vision shop card."); Scanner.HudX = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "HudX", 0.015f, "Left edge of the scanner readout, as a fraction of screen width. 0 = far left, 0.5 = centre."); Scanner.HudY = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "HudY", 0.44f, "Top of the scanner readout, as a fraction of screen height. 0 = top, 1 = bottom."); Scanner.ExportCardTemplate = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ExportCardTemplate", false, "Developer tool: save the shop card's texture to disk so it can be used as a painting template."); Scanner.Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Scanning", "Cooldown", 3f, "Seconds you must wait after a scan before you can scan again."); ((Component)this).gameObject.AddComponent<Scanner>(); Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); bool flag = false; foreach (MethodBase patchedMethod in Harmony.GetPatchedMethods()) { if (patchedMethod != null && patchedMethod.DeclaringType != null && patchedMethod.DeclaringType.Name == "ItemUpgradePlayerGrabStrength") { flag = true; break; } } Logger.LogInfo((object)$"PATCH CHECK: ItemUpgradePlayerGrabStrength.Upgrade hooked = {flag}"); } 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_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: 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_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: 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_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_043e: 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_0454: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Expected O, but got Unknown //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Expected O, but got Unknown //IL_05b0: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Unknown result type (might be due to invalid IL or missing references) //IL_060d: Expected O, but got Unknown //IL_061e: Unknown result type (might be due to invalid IL or missing references) //IL_0625: Expected O, but got Unknown //IL_0654: Unknown result type (might be due to invalid IL or missing references) //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_070c: 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<GameObject>(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); int num = 0; Transform[] componentsInChildren = val3.GetComponentsInChildren<Transform>(true); foreach (Transform val4 in componentsInChildren) { if (!((Component)val4).gameObject.activeSelf) { num++; } } if (num > 0) { MobScanner.LogDebug($"PREVIEW: left {num} hidden part(s) hidden"); } Bounds val5 = CalculateBounds(val3); float num2 = Mathf.Max(new float[3] { ((Bounds)(ref val5)).size.x, ((Bounds)(ref val5)).size.y, ((Bounds)(ref val5)).size.z }); if (num2 <= 0.001f) { num2 = 1f; } float num3 = 2f / num2; if (num3 < 0.25f || num3 > 6f) { MobScanner.Logger.LogWarning((object)($"PREVIEW: measured size {((Bounds)(ref val5)).size} gives an unusable scale " + $"{num3:F2} - clamping. The model may look off.")); num3 = Mathf.Clamp(num3, 0.25f, 6f); } Renderer[] componentsInChildren2 = val3.GetComponentsInChildren<Renderer>(true); Vector3 size2 = ((Bounds)(ref val5)).size; float num4 = Mathf.Max(((Vector3)(ref size2)).magnitude * 3f, 6f); int num5 = 0; int num6 = 0; Renderer[] array = componentsInChildren2; foreach (Renderer val6 in array) { Bounds bounds = val6.bounds; Vector3 size3 = ((Bounds)(ref bounds)).size; float num7 = 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) > num4; bool flag2 = num7 > 25f; if (flag || flag2) { val6.enabled = false; num5++; } else { num6++; } } if (num6 == 0) { Renderer[] array2 = componentsInChildren2; foreach (Renderer val7 in array2) { val7.enabled = true; } num5 = 0; num6 = componentsInChildren2.Length; MobScanner.LogDebug("PREVIEW: filter emptied model - restored all"); } MobScanner.LogDebug($"PREVIEW: hid {num5}, showing {num6}"); int num8 = 0; Renderer[] array3 = componentsInChildren2; foreach (Renderer val8 in array3) { if (val8.enabled) { num8++; } } if (num8 == 0) { MobScanner.Logger.LogWarning((object)"PREVIEW: nothing is visible - the preview box will be empty"); } else { MobScanner.LogDebug($"PREVIEW: {num8} part(s) actually visible"); } val3.transform.localScale = Vector3.one * num3; Bounds val9 = CalculateBounds(val3); Vector3 val10 = ((Bounds)(ref val9)).center - val2.transform.position; val3.transform.localPosition = -val10; MobScanner.LogDebug("PREVIEW: source=" + ((Object)val).name + " " + $"renderers={val3.GetComponentsInChildren<Renderer>(true).Length} " + $"skinned={val3.GetComponentsInChildren<SkinnedMeshRenderer>(true).Length} " + $"size={((Bounds)(ref val5)).size} fitScale={num3:F2}"); GameObject val11 = new GameObject("Key Light"); val11.transform.SetParent(_root.transform, false); val11.transform.localPosition = new Vector3(2f, 2.5f, -3f); val11.layer = 31; Light val12 = val11.AddComponent<Light>(); val12.type = (LightType)2; val12.range = 40f; val12.intensity = 6f; val12.cullingMask = int.MinValue; GameObject val13 = new GameObject("Fill Light"); val13.transform.SetParent(_root.transform, false); val13.transform.localPosition = new Vector3(-2.5f, 1f, -2f); val13.layer = 31; Light val14 = val13.AddComponent<Light>(); val14.type = (LightType)2; val14.range = 40f; val14.intensity = 3f; val14.cullingMask = int.MinValue; _texture = new RenderTexture(size, size, 16); _texture.Create(); GameObject val15 = new GameObject("Preview Camera"); val15.transform.SetParent(_root.transform, false); val15.transform.localPosition = new Vector3(0f, 0f, -4f); val15.layer = 31; _camera = val15.AddComponent<Camera>(); _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; val15.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<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { try { Object.DestroyImmediate((Object)(object)val); } catch (Exception) { } } } } Component[] componentsInChildren2 = model.GetComponentsInChildren<Component>(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<Collider>(true); foreach (Collider val3 in componentsInChildren3) { if ((Object)(object)val3 != (Object)null) { Object.DestroyImmediate((Object)(object)val3); } } Rigidbody[] componentsInChildren4 = model.GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val4 in componentsInChildren4) { if ((Object)(object)val4 != (Object)null) { Object.DestroyImmediate((Object)(object)val4); } } Animator[] componentsInChildren5 = model.GetComponentsInChildren<Animator>(true); foreach (Animator val5 in componentsInChildren5) { if ((Object)(object)val5 != (Object)null) { ((Behaviour)val5).enabled = false; } } ParticleSystem[] componentsInChildren6 = model.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val6 in componentsInChildren6) { if ((Object)(object)val6 != (Object)null) { Object.DestroyImmediate((Object)(object)val6); } } AudioSource[] componentsInChildren7 = model.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val7 in componentsInChildren7) { if ((Object)(object)val7 != (Object)null) { Object.DestroyImmediate((Object)(object)val7); } } Light[] componentsInChildren8 = model.GetComponentsInChildren<Light>(true); foreach (Light val8 in componentsInChildren8) { if ((Object)(object)val8 != (Object)null) { Object.DestroyImmediate((Object)(object)val8); } } } 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_0616: 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_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_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: 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) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_030f: 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_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0610: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_05cd: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e1: Unknown result type (might be due to invalid IL or missing references) //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_05f5: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = model.GetComponentsInChildren<Renderer>(true); if (componentsInChildren.Length == 0) { return new Bounds(model.transform.position, Vector3.one); } List<Renderer> list = new List<Renderer>(); List<float> list2 = new List<float>(); Renderer[] array = componentsInChildren; Bounds bounds; foreach (Renderer val in array) { 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<float> list3 = new List<float>(list2); list3.Sort(); float num2 = list3[list3.Count / 2]; float num3 = Mathf.Max(num2 * 4f, 1.5f); Renderer val2 = list[0]; int num4 = -1; for (int k = 0; k < list.Count; k++) { bounds = list[k].bounds; Vector3 center = ((Bounds)(ref bounds)).center; int num5 = 0; for (int l = 0; l < list.Count; l++) { bounds = list[l].bounds; if (Vector3.Distance(((Bounds)(ref bounds)).center, center) <= 3f) { num5++; } } if (num5 > num4) { num4 = num5; val2 = list[k]; } } bounds = val2.bounds; Vector3 center2 = ((Bounds)(ref bounds)).center; MobScanner.LogDebug("PREVIEW: anchored on '" + ((Object)((Component)val2).gameObject).name + "' " + $"with {num4} neighbour(s) of {list.Count} candidates"); bool flag = false; Bounds bounds3 = default(Bounds); ((Bounds)(ref bounds3))..ctor(model.transform.position, Vector3.zero); int num6 = 0; int num7 = 0; for (int m = 0; m < list.Count; m++) { if (list2[m] > num3) { continue; } bounds = list[m].bounds; if (Vector3.Distance(((Bounds)(ref bounds)).center, center2) > 3f) { num7++; continue; } if (!flag) { bounds3 = list[m].bounds; flag = true; } else { ((Bounds)(ref bounds3)).Encapsulate(list[m].bounds); } num6++; } if (num6 < list.Count / 3 && list.Count >= 12) { MobScanner.LogDebug($"PREVIEW: cluster too small ({num6}/{list.Count}) - measuring all parts"); bounds3 = list[0].bounds; for (int n = 1; n < list.Count; n++) { ((Bounds)(ref bounds3)).Encapsulate(list[n].bounds); } num6 = list.Count; num7 = 0; } if (num7 > 0) { MobScanner.LogDebug($"PREVIEW: ignored {num7} scattered parts"); string text = ""; string text2 = ""; int num8 = 0; int num9 = 0; for (int num10 = 0; num10 < list.Count; num10++) { int num11; if (list2[num10] <= num3) { bounds = list[num10].bounds; num11 = ((Vector3.Distance(((Bounds)(ref bounds)).center, center2) <= 3f) ? 1 : 0); } else { num11 = 0; } bool flag2 = (byte)num11 != 0; if (flag2 && num8 < 5) { text = text + ((Object)((Component)list[num10]).gameObject).name + ", "; num8++; } else if (!flag2 && num9 < 5) { text2 = text2 + ((Object)((Component)list[num10]).gameObject).name + ", "; num9++; } } MobScanner.LogDebug("PREVIEW: kept e.g. " + text); MobScanner.LogDebug("PREVIEW: dropped e.g. " + text2); } if (!flag) { bounds3 = list[0].bounds; for (int num12 = 1; num12 < list.Count; num12++) { ((Bounds)(ref bounds3)).Encapsulate(list[num12].bounds); } num6 = list.Count; } MobScanner.LogDebug($"PREVIEW: measured {num6}/{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<Transform>(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<KeyCode> ScanKey = null; public static ConfigEntry<float> ScanRadius = null; public static ConfigEntry<float> HoldTime = null; public static ConfigEntry<float> ResultDuration = null; public static ConfigEntry<float> MarkerScale = null; public static ConfigEntry<float> Cooldown = null; public static ConfigEntry<float> MarkerHeight = null; public static ConfigEntry<bool> ShowModel = null; public static ConfigEntry<float> SpinSpeed = null; public static ConfigEntry<float> ModelCycleTime = null; public static ConfigEntry<float> UpgradePrice = null; public static ConfigEntry<int> UsesPerLevel = null; public static ConfigEntry<bool> RequireUpgrade = null; public static ConfigEntry<bool> AlwaysInShop = null; public static ConfigEntry<bool> EyeEffect = null; public static ConfigEntry<float> EyeFlashSpeed = null; public static ConfigEntry<float> EyeResultTime = null; public static ConfigEntry<string> FontName = null; public static ConfigEntry<int> TextSize = null; public static ConfigEntry<bool> UseCustomCardArt = null; public static ConfigEntry<bool> ExportCardTemplate = null; public static ConfigEntry<float> HudX = null; public static ConfigEntry<float> HudY = null; public static ConfigEntry<float> OutlineThickness = null; private float _holdTimer; private bool _scanning; private bool _awaitingRelease; private readonly List<ScanResult> _results = new List<ScanResult>(); private float _resultTimer; private float _cooldownTimer; private bool _foundAnything; private static bool _hasScanner; private static int _usesLeft; private readonly ModelPreview _preview = new ModelPreview(); private int _previewIndex; private float _previewTimer; private string _previewName = ""; private float _eyeFlashTimer; private bool _eyeUseRed; private float _eyeResultTimer; private bool _eyeResultFound; private float _shopRegisterTimer; private float _networkSyncTimer; 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 string _lastLevelName = ""; private float _messageTimer; private string _message = ""; private static Font? _gameFont; private static bool _fontSearched; private static Font? GameFont { get { EnsureFont(); return _gameFont; } } public static void GrantScanner() { _hasScanner = true; } public static bool HasScanner() { if (_hasScanner) { return true; } Dictionary<string, int> dictionary = ShopIntegration.Ownership(); if (dictionary == null) { return false; } PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null || string.IsNullOrEmpty(instance.steamID)) { return false; } int value; return dictionary.TryGetValue(instance.steamID, out value) && value > 0; } 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_032f: 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) if ((Object)(object)ShopIntegration.RegisteredItem == (Object)null) { _shopRegisterTimer -= Time.deltaTime; if (_shopRegisterTimer <= 0f) { _shopRegisterTimer = 1f; ShopIntegration.TryRegister(); } } _networkSyncTimer -= Time.deltaTime; if (_networkSyncTimer <= 0f) { _networkSyncTimer = 1f; ShopIntegration.SyncNetworkedItems(); } 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; ShopIntegration.ResetNetworkList(); 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<Font>(); 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 + "' (loaded in game)"); return; } } try { string[] oSInstalledFontNames = Font.GetOSInstalledFontNames(); MobScanner.LogDebug($"FONT: {oSInstalledFontNames.Length} font(s) installed on this machine"); string[] array4 = oSInstalledFontNames; foreach (string text2 in array4) { if (text2 != null && text2.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { Font val3 = Font.CreateDynamicFontFromOSFont(text2, 18); if ((Object)(object)val3 != (Object)null) { _gameFont = val3; MobScanner.Logger.LogInfo((object)("FONT: using '" + text2 + "' from this PC. Players without it will see the default font instead.")); return; } } } } catch (Exception ex) { MobScanner.Logger.LogWarning((object)("FONT: could not read installed fonts - " + ex.Message)); } MobScanner.Logger.LogWarning((object)("FONT: nothing matching '" + text + "' - falling back to the default")); return; } string[] array5 = new string[7] { "pixel", "silk", "vcr", "press", "arcade", "8bit", "bit" }; string[] array6 = array5; foreach (string text3 in array6) { Font[] array7 = array; foreach (Font val4 in array7) { if ((Object)(object)val4 != (Object)null && ((Object)val4).name.IndexOf(text3, StringComparison.OrdinalIgnoreCase) >= 0) { _gameFont = val4; MobScanner.LogDebug("FONT: auto-picked '" + ((Object)val4).name + "' (hint '" + text3 + "')"); 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<ScanResult> UniqueResults() { List<ScanResult> list = new List<ScanResult>(); foreach (ScanResult result in _results) { if (result.Count > 0) { list.Add(result); } } return list; } private void ShowNextPreview() { if (ShowModel.Value) { List<ScanResult> 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<SpriteRenderer>(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<GameObject>(val, Map.Instance.OverLayerParent); ((Object)val2).name = "MobScanner Marker"; val2.SetActive(true); MapValuable component = val2.GetComponent<MapValuable>(); 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<SpriteRenderer>(true); foreach (SpriteRenderer val3 in componentsInChildren) { val3.color = colour; ((Renderer)val3).enabled = true; ((Renderer)val3).sortingOrder = 32000; } Transform[] componentsInChildren2 = val2.GetComponentsInChildren<Transform>(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<RoomVolume> list = new List<RoomVolume>(); 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<ScanResult> 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 static Vector2 HudOrigin() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) return new Vector2((float)Screen.width * HudX.Value, (float)Screen.height * HudY.Value); } private static float LineHeight() { return (float)TextSize.Value * 1.8f; } private void DrawLabel(Rect rect, string text, GUIStyle style, Color colour) { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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) float value = OutlineThickness.Value; if (value > 0f) { GUIStyle val = new GUIStyle(style); val.normal.textColor = new Color(0f, 0f, 0f, 0.85f * colour.a); GUI.Label(new Rect(((Rect)(ref rect)).x - value, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, val); GUI.Label(new Rect(((Rect)(ref rect)).x + value, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, val); GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y - value, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, val); GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + value, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, val); } GUIStyle val2 = new GUIStyle(style); val2.normal.textColor = colour; GUI.Label(rect, text, val2); } 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_006b: 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_007c: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00b5: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_022e: 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_0130: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: 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_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Expected O, but got Unknown //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0634: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Expected O, but got Unknown //IL_0461: 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_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04d9: 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_0659: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_058f: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_05a1: Expected O, but got Unknown //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_06fe: Unknown result type (might be due to invalid IL or missing references) //IL_0703: Unknown result type (might be due to invalid IL or missing references) //IL_072e: Unknown result type (might be due to invalid IL or missing references) //IL_0737: Unknown result type (might be due to invalid IL or missing references) //IL_073e: Expected O, but got Unknown //IL_0745: Unknown result type (might be due to invalid IL or missing references) //IL_075e: Unknown result type (might be due to invalid IL or missing references) //IL_077b: Unknown result type (might be due to invalid IL or missing references) //IL_0784: Unknown result type (might be due to invalid IL or missing references) //IL_078b: Expected O, but got Unknown //IL_0792: Unknown result type (might be due to invalid IL or missing references) //IL_07e0: Unknown result type (might be due to invalid IL or missing references) //IL_07e9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Map.Instance == (Object)null || (Object)(object)PlayerController.instance == (Object)null || SemiFunc.MenuLevel()) { return; } if (_messageTimer > 0f && _message != "") { GUIStyle val = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = TextSize.Value, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; val.normal.textColor = new Color(1f, 0.4f, 0.3f); Vector2 val2 = HudOrigin(); DrawLabel(new Rect(val2.x, val2.y, 360f, LineHeight()), _message, val, new Color(1f, 0.4f, 0.3f)); } if (!RequireUpgrade.Value || HasScanner()) { GUIStyle val3 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = TextSize.Value - 2, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; val3.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"); Vector2 val4 = HudOrigin(); DrawLabel(new Rect(val4.x, val4.y - LineHeight(), 360f, LineHeight()), text, val3, val3.normal.textColor); } Vector2 val5 = HudOrigin(); float x = val5.x; float y = val5.y; if (_scanning) { float num = _holdTimer / HoldTime.Value; float num2 = 4f + num * 8f; float num3 = Mathf.PingPong(Time.time * num2, 1f); float num4 = 0.35f + num3 * 0.65f; DrawDot(x, y + LineHeight() * 0.5f - 5f, 11f, new Color(0.2f, 1f, 0.2f, num4)); GUIStyle val6 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = TextSize.Value, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; val6.normal.textColor = new Color(0.2f, 1f, 0.2f, num4); DrawLabel(new Rect(x + 20f, y, 360f, LineHeight()), "SCANNING...", val6, new Color(0.2f, 1f, 0.2f, num4)); } else { if (_resultTimer <= 0f) { return; } GUIStyle val7 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = TextSize.Value, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; if (_preview.IsValid && (Object)(object)_preview.Texture != (Object)null) { float num5 = Mathf.Clamp((float)Screen.height * 0.16f, 110f, 320f); float num6 = Mathf.Max(3f, num5 * 0.027f); float num7 = y - num5 - 12f; float x2 = x - num6; float y2 = num7 - num6; float num8 = num5 + num6 * 2f; DrawRect(x2, y2, num8, num8, new Color(0.58f, 0.6f, 0.57f, 0.95f)); DrawRect(x - 1f, num7 - 1f, num5 + 2f, num5 + 2f, new Color(0.08f, 0.1f, 0.08f, 1f)); DrawRect(x, num7, num5, num5, new Color(0.07f, 0.13f, 0.09f, 1f)); GUI.DrawTexture(new Rect(x, num7, num5, num5), (Texture)(object)_preview.Texture); Color colour = default(Color); ((Color)(ref colour))..ctor(0f, 0f, 0f, 0.14f); for (float num9 = 1f; num9 < num5 - 1f; num9 += 4f) { DrawRect(x, num7 + num9, num5, 2f, colour); } List<ScanResult> list = UniqueResults(); if (list.Count > 1) { GUIStyle val8 = new GUIStyle(GUI.skin.label) { font = GameFont, fontSize = TextSize.Value - 4, fontStyle = (FontStyle)1, alignment = (TextAnchor)5 }; val8.normal.textColor = new Color(0.5f, 1f, 0.6f, 0.85f); float num10 = LineHeight(); DrawLabel(new Rect(x, num7 + num5 - num10 - 4f, num5 - 6f, num10), $"{_previewIndex + 1}/{list.Count}", val8, new Color(0.5f, 1f, 0.6f, 0.85f)); } } GUIStyle val9 = new GUIStyle(val7); val9.normal.textColor = (_foundAnything ? new Color(0.2f, 1f, 0.2f) : new Color(0.75f, 0.75f, 0.75f)); float num11 = LineHeight(); DrawLabel(new Rect(x, y, 360f, num11), _foundAnything ? "FOUND" : "NOT FOUND", val9, val9.normal.textColor); float num12 = y + num11 + 2f; int num13 = 0; for (int i = 0; i < _results.Count; i++) { ScanResult scanResult = _results[i]; if (scanResult.Count > 0) { Color val10 = ColourForTier(scanResult.Tier); float num14 = num12 + (float)num13 * num11; num13++; DrawDot(x, num14 + num11 * 0.5f - 5f, 11f, val10); GUIStyle val11 = new GUIStyle(val7); val11.normal.textColor = val10; DrawLabel(new Rect(x + 22f, num14, 44f, num11), $"T{scanResult.Tier}", val11, val10); GUIStyle val12 = new GUIStyle(val7); val12.normal.textColor = Color.white; string text2 = ((scanResult.Count > 1) ? $"{scanResult.Name} x{scanResult.Count}" : scanResult.Name); DrawLabel(new Rect(x + 66f, num14, 300f, num11), text2, val12, Color.white); } } } } private void OnDestroy() { ClearResults(); } } public class MobScannerItemTag : MonoBehaviour { } 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 const string NetworkKey = "MobScannerItems"; private static readonly List<int> _publishedIDs = new List<int>(); public const string OwnershipKey = "playerUpgradeAndroidVision"; private static Texture2D? _cardArt; private static bool _cardArtChecked; internal static void PublishOurItem(ItemAttributes attributes) { if (SemiFunc.IsMultiplayer() && PhotonNetwork.IsMasterClient) { PhotonView component = ((Component)attributes).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null || component.ViewID == 0) { MobScanner.LogDebug("NET: converted item has no network ID yet - not published"); } else if (!_publishedIDs.Contains(component.ViewID)) { _publishedIDs.Add(component.ViewID); SemiFunc.SetCurrentRoomProperty("MobScannerItems", (object)_publishedIDs.ToArray()); MobScanner.LogDebug($"NET: published item {component.ViewID} ({_publishedIDs.Count} total this level)"); } } } internal static void SyncNetworkedItems() { if (!SemiFunc.IsMultiplayer() || PhotonNetwork.CurrentRoom == null) { return; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; if (customProperties == null || !((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"MobScannerItems") || !(customProperties[(object)"MobScannerItems"] is int[] array)) { return; } Item registeredItem = RegisteredItem; if ((Object)(object)registeredItem == (Object)null) { return; } int[] array2 = array; foreach (int num in array2) { PhotonView val = PhotonView.Find(num); if (!((Object)(object)val == (Object)null)) { ItemAttributes component = ((Component)val).GetComponent<ItemAttributes>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)((Component)component).GetComponent<MobScannerItemTag>() != (Object)null)) { ((Component)component).gameObject.AddComponent<MobScannerItemTag>(); component.item = registeredItem; component.itemName = "Android vision"; component.value = (int)Scanner.UpgradePrice.Value; ApplyCardArt(((Component)component).gameObject); MobScanner.LogDebug($"NET: applied host's Android vision to item {num}"); } } } } internal static void ResetNetworkList() { _publishedIDs.Clear(); } private static Texture2D? CardArt() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown if (_cardArtChecked) { return _cardArt; } _cardArtChecked = true; try { string location = Assembly.GetExecutingAssembly().Location; string path = Path.GetDirectoryName(location) ?? ""; string text = Path.Combine(path, "card.png"); if (!File.Exists(text)) { MobScanner.Logger.LogWarning((object)("CARD ART: no card.png next to the mod (" + text + ") - keeping the default art")); return null; } byte[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val, array)) { MobScanner.Logger.LogWarning((object)"CARD ART: card.png could not be read as an image"); Object.Destroy((Object)(object)val); return null; } ((Object)val).name = "MobScanner Card Art"; Object.DontDestroyOnLoad((Object)(object)val); _cardArt = val; MobScanner.Logger.LogInfo((object)$"CARD ART: loaded card.png ({((Texture)val).width}x{((Texture)val).height})"); } catch (Exception ex) { MobScanner.Logger.LogWarning((object)("CARD ART: could not load card.png - " + ex.Message)); } return _cardArt; } internal static void ApplyCardArt(GameObject card) { if (!Scanner.UseCustomCardArt.Value) { return; } Texture2D val = CardArt(); if ((Object)(object)val == (Object)null) { return; } int num = 0; Renderer[] componentsInChildren = card.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { Material[] materials = val2.materials; foreach (Material val3 in materials) { if (!((Object)(object)val3 == (Object)null) && val3.HasProperty("_MainTex")) { Texture texture = val3.GetTexture("_MainTex"); if (!((Object)(object)texture == (Object)null) && ((Object)texture).name.StartsWith("Upgrade_")) { val3.SetTexture("_MainTex", (Texture)(object)val); num++; } } } } if (num > 0) { MobScanner.LogDebug($"CARD ART: painted {num} surface(s)"); } else { MobScanner.Logger.LogWarning((object)"CARD ART: found no card face to paint"); } } public static Dictionary<string, int>? Ownership() { StatsManager instance = StatsManager.instance; if ((Object)(object)instance == (Object)null) { return null; } if (!instance.dictionaryOfDictionaries.TryGetValue("playerUpgradeAndroidVision", out var value)) { value = new Dictionary<string, int>(); instance.dictionaryOfDictionaries.Add("playerUpgradeAndroidVision", value); MobScanner.LogDebug("SHOP: created Android vision ownership store"); } return value; } 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<string, Item> 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<string, Item> 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<Item>(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)) { int num = __instance.potentialItemUpgrades.RemoveAll((Item x) => (Object)(object)x != (Object)null && ((Object)x).name == "Item Upgrade Android Vision"); __instance.potentialItemUpgrades.Add(registeredItem); MobScanner.LogDebug("SHOP POOL: moved Android vision to the end of the queue " + $"(removed {num} stray copies, {__instance.potentialItemUpgrades.Count} upgrades total, " + $"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<Item> 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<GameObject>)(object)registeredItem.prefab).ResourcePath)); } } [HarmonyPatch(typeof(ItemAttributes), "Start")] internal static class ItemAttributesStartPatch { internal static int PendingSpawns; internal static bool CardInspected; private static void InspectCard(GameObject card) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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) MobScanner.Logger.LogInfo((object)"=== CARD INSPECTION ==="); Renderer[] componentsInChildren = card.GetComponentsInChildren<Renderer>(true); MobScanner.Logger.LogInfo((object)$"CARD: {componentsInChildren.Length} renderer(s)"); for (int i = 0; i < componentsInChildren.Length; i++) { Renderer val = componentsInChildren[i]; Bounds bounds = val.bounds; Vector3 size = ((Bounds)(ref bounds)).size; MobScanner.Logger.LogInfo((object)($"CARD[{i}] object='{((Object)((Component)val).gameObject).name}' " + $"type={((object)val).GetType().Name} size=({size.x:F2},{size.y:F2},{size.z:F2}) " + $"materials={val.materials.Length}")); for (int j = 0; j < val.materials.Length; j++) { Material val2 = val.materials[j]; if ((Object)(object)val2 == (Object)null) { continue; } string text = (((Object)(object)val2.shader != (Object)null) ? ((Object)val2.shader).name : "none"); string text2 = "none"; if (val2.HasProperty("_MainTex")) { Texture texture = val2.GetTexture("_MainTex"); text2 = (((Object)(object)texture != (Object)null) ? $"{((Object)texture).name} ({texture.width}x{texture.height})" : "empty"); } MobScanner.Logger.LogInfo((object)$"CARD[{i}] material[{j}]='{((Object)val2).name}' shader='{text}' mainTex={text2}"); if (Scanner.ExportCardTemplate.Value && val2.HasProperty("_MainTex")) { Texture texture2 = val2.GetTexture("_MainTex"); if ((Object)(object)texture2 != (Object)null && texture2.width > 64) { DumpTexture(texture2, $"CardTemplate_{i}_{j}"); } } } } ItemAttributes component = card.GetComponent<ItemAttributes>(); if ((Object)(object)component != (Object)null) { MobScanner.Logger.LogInfo((object)("CARD: icon=" + (((Object)(object)component.icon != (Object)null) ? ((Object)component.icon).name : "none") + " " + $"hasIcon={component.hasIcon}")); } MobScanner.Logger.LogInfo((object)"======================="); } private static void DumpTexture(Texture source, string label) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) try { RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0); Graphics.Blit(source, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)5, false); val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); string text = Path.Combine(Paths.PluginPath, "MobScanner"); Directory.CreateDirectory(text); string text2 = Path.Combine(text, label + "_" + ((Object)source).name + ".png"); File.WriteAllBytes(text2, ImageConversion.EncodeToPNG(val)); Object.Destroy((Object)(object)val); MobScanner.Logger.LogInfo((object)("CARD: saved texture to " + text2)); } catch (Exception ex) { MobScanner.Logger.LogWarning((object)("CARD: could not save texture - " + ex.Message)); } } private static void Postfix(ItemAttributes __instance) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 Item registeredItem = ShopIntegration.RegisteredItem; if ((Object)(object)registeredItem == (Object)null || (Object)(object)__instance.item == (Object)null) { return; } if ((int)__instance.item.itemType == 3) { PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); int num = (((Object)(object)component != (Object)null) ? component.ViewID : (-1)); MobScanner.LogDebug($"UPGRADE SPAWN: item='{((Object)__instance.item).name}' viewID={num} " + $"value={__instance.value} pending={PendingSpawns} " + $"master={SemiFunc.IsMasterClientOrSingleplayer()}"); } if (!((Object)(object)((Component)__instance).GetComponent<MobScannerItemTag>() == (Object)null)) { __instance.item = registeredItem; __instance.itemName = "Android vision"; __instance.value = (int)Scanner.UpgradePrice.Value; ShopIntegration.ApplyCardArt(((Component)__instance).gameObject); ShopIntegration.PublishOurItem(__instance); if (!CardInspected) { CardInspected = true; InspectCard(((Component)__instance).gameObject); } PhotonView component2 = ((Component)__instance).GetComponent<PhotonView>(); MobScanner.LogDebug($"SHOP: CONVERTED viewID={(((Object)(object)component2 != (Object)null) ? component2.ViewID : (-1))} " + string.Format("into '{0}' at value {1}", "Android vision", __instance.value)); } } } [HarmonyPatch(typeof(PunManager), "SpawnShopItem")] internal static class ShopSpawnMarkPatch { private static void Prefix(ItemVolume itemVolume, List<Item> itemList) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ShopIntegration.RegisteredItem == (Object)null || (Object)(object)itemVolume == (Object)null) { return; } for (int num = itemList.Count - 1; num >= 0; num--) { Item val = itemList[num]; if (!((Object)(object)val == (Object)null) && val.itemVolume == itemVolume.itemVolume) { if (((Object)val).name == "Item Upgrade Android Vision") { ItemAttributesStartPatch.PendingSpawns++; MobScanner.LogDebug("SPAWN MARK: Android vision is the next shop spawn"); } break; } } } } [HarmonyPatch(typeof(ItemAttributes), "Awake")] internal static class ItemAttributesAwakePatch { private static void Postfix(ItemAttributes __instance) { if (ItemAttributesStartPatch.PendingSpawns > 0) { ItemAttributesStartPatch.PendingSpawns--; if ((Object)(object)((Component)__instance).GetComponent<MobScannerItemTag>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<MobScannerItemTag>(); } MobScanner.LogDebug("SPAWN CLAIM: tagged '" + ((Object)((Component)__instance).gameObject).name + "' as Android vision"); } } } [HarmonyPatch(typeof(PunManager), "SpawnItem")] internal static class TruckSpawnMarkPatch { private static void Prefix(Item item) { if ((Object)(object)item != (Object)null && ((Object)item).name == "Item Upgrade Android Vision") { ItemAttributesStartPatch.PendingSpawns++; MobScanner.LogDebug("SPAWN MARK: Android vision is the next truck spawn"); } } } [HarmonyPatch(typeof(ItemUpgradePlayerGrabStrength), "Upgrade")] internal static class GrabStrengthUpgradePatch { private static bool Prefix(ItemUpgradePlayerGrabStrength __instance) { ItemAttributes component = ((Component)__instance).GetComponent<ItemAttributes>(); bool flag = (Object)(object)((Component)__instance).GetComponent<MobScannerItemTag>() != (Object)null; string text = (((Object)(object)component != (Object)null && (Object)(object)component.item != (Object)null) ? ((Object)component.item).name : "none"); MobScanner.Logger.LogInfo((object)$"UPGRADE HOOK: grab-strength upgrade used. tagged={flag} item='{text}'"); if (!flag && text != "Item Upgrade Android Vision") { return true; } ItemToggle component2 = ((Component)__instance).GetComponent<ItemToggle>(); PlayerAvatar val = (((Object)(object)component2 != (Object)null) ? SemiFunc.PlayerAvatarGetFromPhotonID(component2.playerTogglePhotonID) : null); if ((Object)(object)val == (Object)null || string.IsNullOrEmpty(val.steamID)) { MobScanner.LogDebug("UPGRADE: Android vision used but the player is unknown"); return false; } Dictionary<string, int> dictionary = ShopIntegration.Ownership(); if (dictionary != null) { dictionary[val.steamID] = 1; } if (val.isLocal) { Scanner.GrantScanner(); } MobScanner.LogDebug("UPGRADE: Android vision granted to " + val.playerName + " " + $"({val.steamID}), local={val.isLocal} - grab strength skipped"); return false; } } [HarmonyPatch(typeof(StatsManager), "AddItemsUpgradesPurchased")] internal static class UpgradePurchasedPatch { private static void Postfix(string itemName) { if (!(itemName != "Item Upgrade Android Vision")) { MobScanner.LogDebug("SHOP: Android vision purchase recorded"); } } } }