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 Valuables Scanner v1.4.1
Kistras-Scanner.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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 JetBrains.Annotations; using Microsoft.CodeAnalysis; using Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; [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: AssemblyCompany("Kistras-Scanner")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0+ab00634a17180fc7dcde5611699c79b99bc94509")] [assembly: AssemblyProduct("REPO Scanner")] [assembly: AssemblyTitle("Kistras-Scanner")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace REPO_Scanner { public class ConfigCategory { private static readonly Color transparent = new Color(0f, 0f, 0f, 0.5f); public ConfigEntry<bool> ShouldScan { get; } public ConfigEntry<float> ScanRadius { get; } [CanBeNull] public ConfigEntry<bool> OnlyScanDiscovered { get; } [CanBeNull] public ConfigEntry<bool> MultiplayerReveal { get; } public ConfigEntry<string> CornerColorConfig { get; } public ConfigEntry<string> MiddleColorConfig { get; } public ConfigEntry<float> ScanLinger { get; } public Color CornerColor { get; private set; } public Color MiddleColor { get; private set; } public ConfigCategory(Plugin plugin, string categoryName, string cornerColor, string middleColor, bool hasDiscovered = false, bool hasReveal = false, bool hasColorSettings = true, bool hasCustomColor = false, float scanLinger = 1.5f) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) string text = "Scanning - " + categoryName.Substring(0, 1).ToUpper() + categoryName.Substring(1); ShouldScan = ((BaseUnityPlugin)plugin).Config.Bind<bool>(text, "Scan", true, new ConfigDescription("Whether to scan " + categoryName, (AcceptableValueBase)null, Array.Empty<object>())); ScanRadius = ((BaseUnityPlugin)plugin).Config.Bind<float>(text, "Radius Override", 0f, new ConfigDescription("Override scan radius for " + categoryName + " (0 to use main radius)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); ScanRadius.SettingChanged += delegate { ConfigManager.UpdateMaxScanRadius(); }; if (hasDiscovered) { OnlyScanDiscovered = ((BaseUnityPlugin)plugin).Config.Bind<bool>(text, "Discovered Only", false, new ConfigDescription("Only scan already discovered " + categoryName + " (does not reveal new ones)", (AcceptableValueBase)null, Array.Empty<object>())); } if (hasReveal) { MultiplayerReveal = ((BaseUnityPlugin)plugin).Config.Bind<bool>(text, "Multiplayer RPC", false, new ConfigDescription("Whether to reveal scan results on other players' minimaps in multiplayer", (AcceptableValueBase)null, Array.Empty<object>())); } if (hasColorSettings) { string text2 = (hasCustomColor ? "For this object this (most likely) will be ignored and only serves as fallback" : "This may be ignored if object has it's own custom color"); CornerColorConfig = ((BaseUnityPlugin)plugin).Config.Bind<string>(text, "Corner Color", cornerColor, new ConfigDescription("Corner color (in hex with #RRGGBBAA format, case-insensitive, eg. " + cornerColor + "). " + text2, (AcceptableValueBase)null, Array.Empty<object>())); MiddleColorConfig = ((BaseUnityPlugin)plugin).Config.Bind<string>(text, "Middle Color", middleColor, new ConfigDescription("Middle color (in hex with #RRGGBBAA format, case-insensitive, eg. " + middleColor + "). " + text2, (AcceptableValueBase)null, Array.Empty<object>())); ScanLinger = ((BaseUnityPlugin)plugin).Config.Bind<float>(text, "Scan Linger", scanLinger, new ConfigDescription("For how long should discovered objects be highlighted, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 8f), Array.Empty<object>())); CornerColorConfig.SettingChanged += delegate { //IL_000d: Unknown result type (might be due to invalid IL or missing references) CornerColor = GetColorFromHex(CornerColorConfig.Value); }; MiddleColorConfig.SettingChanged += delegate { //IL_000d: Unknown result type (might be due to invalid IL or missing references) MiddleColor = GetColorFromHex(MiddleColorConfig.Value); }; CornerColor = GetColorFromHex(CornerColorConfig.Value); MiddleColor = GetColorFromHex(MiddleColorConfig.Value); } } private static Color GetColorFromHex(string hex) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) if (string.IsNullOrWhiteSpace(hex)) { return transparent; } hex = hex.Trim(); if (!hex.StartsWith("#")) { hex = "#" + hex; } if (hex.Length != 9) { return transparent; } Color result = default(Color); if (ColorUtility.TryParseHtmlString(hex, ref result)) { return result; } return transparent; } } public static class ConfigManager { internal const float MaxRadius = 100f; public static InputKey scanKey = (InputKey)327; public static ConfigEntry<KeyCode> keyBind; public static ConfigEntry<float> scanRadius; public static ConfigEntry<float> cooldown; public static ConfigEntry<bool> toCreateGUI; public static ConfigEntry<string> versionGUI; private static KeyCode _storedKeybind; private static bool _initialized = false; public static bool IsLegacyVersionGUI { get; private set; } public static ConfigCategory Valuables { get; private set; } public static ConfigCategory Enemies { get; private set; } public static ConfigCategory Heads { get; private set; } public static ConfigCategory Tools { get; private set; } public static ConfigCategory Cosmetics { get; private set; } public static ConfigCategory Custom { get; private set; } private static ConfigCategory[] Configs => new ConfigCategory[6] { Valuables, Enemies, Heads, Tools, Cosmetics, Custom }; public static float MaxScanRadius { get; private set; } internal static void UpdateMaxScanRadius() { float num = 0f; ConfigCategory[] configs = Configs; foreach (ConfigCategory configCategory in configs) { if (configCategory.ShouldScan.Value) { num = Mathf.Max(num, (configCategory.ScanRadius.Value > 0f) ? configCategory.ScanRadius.Value : scanRadius.Value); } } MaxScanRadius = Mathf.Min(num, 100f); } internal static void Initialize(Plugin plugin) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; keyBind = ((BaseUnityPlugin)plugin).Config.Bind<KeyCode>("Keybinds", "Scanner Key", (KeyCode)102, new ConfigDescription("What you press to scan things", (AcceptableValueBase)null, Array.Empty<object>())); scanRadius = ((BaseUnityPlugin)plugin).Config.Bind<float>("Options", "Scan Radius", 10f, new ConfigDescription("Radius of the scanner", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 100f), Array.Empty<object>())); cooldown = ((BaseUnityPlugin)plugin).Config.Bind<float>("Options", "Cooldown", 10f, new ConfigDescription("Interval between scans", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>())); toCreateGUI = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Options", "Create GUI", true, new ConfigDescription("Whether to create cooldown GUI", (AcceptableValueBase)null, Array.Empty<object>())); versionGUI = ((BaseUnityPlugin)plugin).Config.Bind<string>("Options", "GUI Version", "New", new ConfigDescription("New version uses REPO's screen effects", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "New", "Legacy" }), Array.Empty<object>())); Valuables = new ConfigCategory(plugin, "valuables", "#FFDC00FF", "#FFDC001E", hasDiscovered: true, hasReveal: true); Enemies = new ConfigCategory(plugin, "enemies", "#FF1A11BF", "#FF00112B", hasDiscovered: false, hasReveal: false, hasColorSettings: true, hasCustomColor: false, 4f); Heads = new ConfigCategory(plugin, "heads", "#FF1A11BF", "#FF00112B"); Tools = new ConfigCategory(plugin, "tools", "#1A99E6BF", "#0080CC2B"); Cosmetics = new ConfigCategory(plugin, "cosmetics", "#33E699BF", "#1ACC802B", hasDiscovered: true, hasReveal: true, hasColorSettings: true, hasCustomColor: true); Custom = new ConfigCategory(plugin, "custom", "#FFFFFFBF", "#FFFFFF2B", hasDiscovered: false, hasReveal: false, hasColorSettings: false); IsLegacyVersionGUI = versionGUI.Value == "Legacy"; keyBind.SettingChanged += delegate { RebindScan(); }; versionGUI.SettingChanged += delegate { IsLegacyVersionGUI = versionGUI.Value == "Legacy"; if (Object.op_Implicit((Object)(object)ScannerGUI.Instance)) { Object.Destroy((Object)(object)ScannerGUI.Instance); Patches.lastGuiCheckTime = 0f; } }; UpdateMaxScanRadius(); } internal static void RebindScan() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<KeyCode> obj = keyBind; if (obj != null) { _ = obj.Value; if (0 == 0 && !((Object)(object)InputManager.instance == (Object)null) && _storedKeybind != keyBind.Value) { _storedKeybind = keyBind.Value; string text = KeyCodeToBindingPath(keyBind.Value); Plugin.Logger.LogInfo((object)("Keybind changed to: " + text)); InputManager.instance.Rebind(scanKey, text); } } } internal static string KeyCodeToBindingPath(KeyCode keyCode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Invalid comparison between Unknown and I4 //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected I4, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Invalid comparison between Unknown and I4 //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Invalid comparison between Unknown and I4 if ((int)keyCode >= 48 && (int)keyCode <= 57) { return "<keyboard>/" + ((object)(KeyCode)(ref keyCode)).ToString().Replace("Alpha", ""); } if ((int)keyCode == 323) { return "<mouse>/leftButton"; } if ((int)keyCode == 324) { return "<mouse>/rightButton"; } if ((int)keyCode == 325) { return "<mouse>/middleButton"; } if ((int)keyCode >= 326 && (int)keyCode <= 329) { return $"<mouse>/button{keyCode - 323}"; } KeyCode val = keyCode; KeyCode val2 = val; if ((int)val2 != 13) { if ((int)val2 != 305) { if ((int)val2 == 306) { return "<keyboard>/leftCtrl"; } string text = ((object)(KeyCode)(ref keyCode)).ToString(); if (text.Length > 0) { string text2 = char.ToLower(text[0]).ToString(); string text3 = text; text = text2 + text3.Substring(1, text3.Length - 1); } return "<keyboard>/" + text; } return "<keyboard>/rightCtrl"; } return "<keyboard>/enter"; } } internal interface ICustomDiscovery { bool ScanItems(Collider collider, Vector3 scanPosition, List<Vector3> scannedPositions); } internal class CustomDiscovery<T> : ICustomDiscovery where T : MonoBehaviour { [CanBeNull] public GameObject gameObject; [CanBeNull] public ValuableDiscoverCustom component; private ConfigCategory config; internal void UpdateData() { //IL_0021: 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) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)component)) { component.colorCorner = config.CornerColor; component.colorMiddle = config.MiddleColor; component.waitTime = config.ScanLinger.Value; } } public ValuableDiscoverCustom GetDiscover() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gameObject == (Object)null || !gameObject.activeSelf) { gameObject = new GameObject("ScannerCustomDiscover"); } if ((Object)(object)component == (Object)null) { component = gameObject.GetComponent<ValuableDiscoverCustom>(); if ((Object)(object)component == (Object)null) { try { Patches.shouldSuppressValuableDiscoverCustomAwake = true; component = gameObject.AddComponent<ValuableDiscoverCustom>(); } finally { Patches.shouldSuppressValuableDiscoverCustomAwake = false; } UpdateData(); Plugin.Logger.LogWarning((object)$"Created new ValuableDiscoverCustom component for {typeof(T).Name} discovery with colors {config.CornerColor} and {config.MiddleColor} and linger {config.ScanLinger.Value}"); } } return component; } [CanBeNull] private static TC GetComponentOfType<TC>(GameObject gameObject) where TC : Component { return gameObject.GetComponent<TC>() ?? gameObject.GetComponentInParent<TC>(); } [CanBeNull] private static TC GetComponentOfType<TC>(Collider collider) where TC : Component { return ((Component)collider).GetComponent<TC>() ?? ((Component)collider).GetComponentInParent<TC>(); } private static bool HasScannedItemsNearby(Vector3 itemPos, List<Vector3> scannedPositions) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) foreach (Vector3 scannedPosition in scannedPositions) { if (Vector3.Distance(scannedPosition, itemPos) < 0.1f) { return true; } } scannedPositions.Add(itemPos); return false; } public bool ScanItems(Collider collider, Vector3 scanPosition, List<Vector3> scannedPositions) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if (!config.ShouldScan.Value) { return false; } T componentOfType = GetComponentOfType<T>(collider); if ((Object)(object)componentOfType == (Object)null) { return false; } GameObject val = ((Component)(object)componentOfType).gameObject; float num = ((config.ScanRadius.Value > 0f) ? config.ScanRadius.Value : ConfigManager.scanRadius.Value); if (Vector3.Distance(((Component)(object)componentOfType).transform.position, scanPosition) > num) { return false; } if (HasScannedItemsNearby(((Component)(object)componentOfType).transform.position, scannedPositions)) { return false; } ValuableDiscoverCustom componentOfType2 = GetComponentOfType<ValuableDiscoverCustom>(val); ConfigEntry<bool> onlyScanDiscovered = config.OnlyScanDiscovered; if (onlyScanDiscovered != null && onlyScanDiscovered.Value) { object obj = componentOfType; ValuableObject val2 = (ValuableObject)((obj is ValuableObject) ? obj : null); if ((val2 != null && !val2.discovered) || ((Object)(object)componentOfType2 != (Object)null && !componentOfType2.discovered)) { return false; } } bool flag = config.MultiplayerReveal?.Value ?? false; bool flag2 = flag; bool flag3; if (flag2) { object obj2 = componentOfType; ValuableObject val2 = (ValuableObject)((obj2 is ValuableObject) ? obj2 : null); if (val2 != null) { if (!val2.discovered) { goto IL_0192; } } else { object obj3 = componentOfType; ValuableDiscoverCustom val3 = (ValuableDiscoverCustom)((obj3 is ValuableDiscoverCustom) ? obj3 : null); if (val3 != null && !val3.discovered) { goto IL_0192; } } flag3 = false; goto IL_019a; } goto IL_01b8; IL_019a: flag2 = flag3 || ((Object)(object)componentOfType2 != (Object)null && !componentOfType2.discovered); goto IL_01b8; IL_01b8: if (flag2) { if (!GameManager.Multiplayer()) { T val4 = componentOfType; T val5 = val4; object obj4 = val5; ValuableObject val6 = (ValuableObject)((obj4 is ValuableObject) ? obj4 : null); if (val6 == null) { object obj5 = val5; ValuableDiscoverCustom val7 = (ValuableDiscoverCustom)((obj5 is ValuableDiscoverCustom) ? obj5 : null); if (val7 != null) { val7.DiscoverRPC(); } else { componentOfType2.DiscoverRPC(); } } else { val6.DiscoverRPC(); } } else { T val8 = componentOfType; T val9 = val8; object obj6 = val9; ValuableObject val10 = (ValuableObject)((obj6 is ValuableObject) ? obj6 : null); PhotonView val12; if (val10 == null) { object obj7 = val9; ValuableDiscoverCustom val11 = (ValuableDiscoverCustom)((obj7 is ValuableDiscoverCustom) ? obj7 : null); val12 = ((val11 == null) ? componentOfType2.photonView : val11.photonView); } else { val12 = val10.photonView; } if (val12.ViewID == 0) { return false; } val12.RPC("DiscoverRPC", (RpcTarget)0, Array.Empty<object>()); } } PhysGrabObject componentOfType3 = GetComponentOfType<PhysGrabObject>(val); if ((Object)(object)componentOfType3 == (Object)null) { return true; } ValuableDiscover.instance.New(componentOfType3, (State)3, componentOfType2 ?? GetDiscover()); return true; IL_0192: flag3 = true; goto IL_019a; } public CustomDiscovery(ConfigCategory config) { this.config = config; if (config.CornerColorConfig != null) { config.CornerColorConfig.SettingChanged += delegate { UpdateData(); }; config.MiddleColorConfig.SettingChanged += delegate { UpdateData(); }; config.ScanLinger.SettingChanged += delegate { UpdateData(); }; } } } [HarmonyPatch] public class Patches { internal static float lastGuiCheckTime; internal static bool shouldSuppressValuableDiscoverCustomAwake; [HarmonyPatch(typeof(InputManager), "InitializeInputs")] [HarmonyPostfix] private static void InputManagerInitializeInputsPostfix(InputManager __instance) { //IL_001c: 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) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) try { Plugin.Logger.LogInfo((object)"Setting up scan input action..."); if (!InputManager.instance.inputActions.ContainsKey(ConfigManager.scanKey)) { InputAction val = new InputAction("Scan", (InputActionType)0, ConfigManager.KeyCodeToBindingPath(ConfigManager.keyBind.Value), (string)null, (string)null, (string)null); InputManager.instance.inputActions.Add(ConfigManager.scanKey, val); val.Enable(); Plugin.Logger.LogInfo((object)"Added scan input action"); } } catch (Exception ex) { Plugin.Logger.LogError((object)("Error in InputManagerInitializeInputsPostfix: " + ex.Message)); } } [HarmonyPatch(typeof(PlayerController), "Update")] [HarmonyPostfix] private static void PlayerControllerUpdatePostfix() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) Scanner.Update(); if (SemiFunc.InputDown(ConfigManager.scanKey)) { Scanner.Scan(); } EnsureScannerGUIExists(); } [HarmonyPatch(typeof(PlayerController), "Start")] [HarmonyPostfix] private static void PlayerControllerStartPostfix() { ConfigManager.RebindScan(); } private static void EnsureScannerGUIExists() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (!(Time.time - lastGuiCheckTime < 10f)) { lastGuiCheckTime = Time.time; if (!((Object)(object)ScannerGUI.Instance != (Object)null) && !((Object)(object)PlayerController.instance == (Object)null)) { GameObject val = new GameObject("ScannerGUI"); val.AddComponent<ScannerGUI>(); val.transform.SetParent(((Component)HUDCanvas.instance).transform, false); } } } [HarmonyPatch(typeof(ValuableDiscoverCustom), "Awake")] [HarmonyPrefix] private static bool SuppressValuableDiscoverCustomAwakePatch() { return !shouldSuppressValuableDiscoverCustomAwake; } } [BepInPlugin("Kistras-Scanner", "REPO Scanner", "1.2.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; private readonly Harmony harmony = new Harmony("Kistras-Scanner"); private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; ConfigManager.Initialize(this); harmony.PatchAll(typeof(Patches)); Logger.LogInfo((object)$"Patched {harmony.GetPatchedMethods().Count()} methods!"); Logger.LogInfo((object)"Plugin Kistras-Scanner (1.2.0) is loaded!"); } } public class Scanner { private static CustomDiscovery<ValuableObject> discoverValuableCustom; private static CustomDiscovery<EnemyRigidbody> discoverEnemyCustom; private static CustomDiscovery<PlayerDeathHead> discoverHeadCustom; private static CustomDiscovery<ItemAttributes> discoverToolCustom; private static CustomDiscovery<CosmeticWorldObject> discoverCosmeticCustom; private static CustomDiscovery<ValuableDiscoverCustom> discoverCustomFallback; private static float lastScanTime; private static bool isInitialized; private static ICustomDiscovery[] Discoveries => new ICustomDiscovery[6] { discoverValuableCustom, discoverEnemyCustom, discoverHeadCustom, discoverToolCustom, discoverCosmeticCustom, discoverCustomFallback }; private static void Initialize() { if (!isInitialized) { lastScanTime = ConfigManager.cooldown.Value; discoverValuableCustom = new CustomDiscovery<ValuableObject>(ConfigManager.Valuables); discoverEnemyCustom = new CustomDiscovery<EnemyRigidbody>(ConfigManager.Enemies); discoverHeadCustom = new CustomDiscovery<PlayerDeathHead>(ConfigManager.Heads); discoverToolCustom = new CustomDiscovery<ItemAttributes>(ConfigManager.Tools); discoverCosmeticCustom = new CustomDiscovery<CosmeticWorldObject>(ConfigManager.Cosmetics); discoverCustomFallback = new CustomDiscovery<ValuableDiscoverCustom>(ConfigManager.Custom); isInitialized = true; Plugin.Logger.LogInfo((object)"Scanner initialized successfully"); } } public static void Scan() { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if (Time.time - lastScanTime < ConfigManager.cooldown.Value) { return; } if ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated || SemiFunc.MenuLevel()) { Plugin.Logger.LogInfo((object)"Cannot scan: No level loaded."); return; } if (!isInitialized) { Initialize(); } PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null || (Object)(object)Camera.main == (Object)null) { Plugin.Logger.LogError((object)"Cannot scan: Player camera not found."); return; } Vector3 position = ((Component)Camera.main).transform.position; Collider[] array = Physics.OverlapSphere(position, ConfigManager.MaxScanRadius); List<Vector3> scannedPositions = new List<Vector3>(); Collider[] array2 = array; foreach (Collider val in array2) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) { continue; } ICustomDiscovery[] discoveries = Discoveries; foreach (ICustomDiscovery customDiscovery in discoveries) { if (customDiscovery.ScanItems(val, position, scannedPositions)) { break; } } } lastScanTime = Time.time; if ((Object)(object)ScannerGUI.Instance != (Object)null) { ScannerGUI.Instance.NotifyScan(); } } public static void Update() { } public static bool IsOnCooldown() { return Time.time - lastScanTime < ConfigManager.cooldown.Value; } public static float GetRemainingCooldown() { return Mathf.Max(0f, ConfigManager.cooldown.Value - (Time.time - lastScanTime)); } } public class ScannerGUI : MonoBehaviour { private GameObject uiContainer; private Image backgroundBar; private Image progressBar; private RectTransform barRect; private TextMeshProUGUI statusText; private Texture2D barTexture; private Texture2D backgroundTexture; private readonly float barWidth = 150f; private readonly float barHeight = 6f; private readonly float legacyBarWidth = 400f; private readonly float legacyBarHeight = 15f; private float lastDisplayTime; private readonly float displayDuration = 3f; private readonly Color barColor = new Color(1f, 0.6f, 0.1f, 0.8f); private readonly Color readyColor = new Color(1f, 0.8f, 0.2f, 0.8f); private CanvasGroup canvasGroup; public static ScannerGUI Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; ((Component)this).gameObject.transform.SetParent(((Component)HUDCanvas.instance).transform, false); Initialize(); } private void Initialize() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0032: 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_0056: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0252: 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_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Expected O, but got Unknown //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Expected O, but got Unknown //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) lastDisplayTime = ConfigManager.cooldown.Value; if (ConfigManager.IsLegacyVersionGUI) { barTexture = new Texture2D(1, 1); barTexture.SetPixel(0, 0, Color.white); barTexture.Apply(); backgroundTexture = new Texture2D(1, 1); backgroundTexture.SetPixel(0, 0, Color.white); backgroundTexture.Apply(); return; } RectTransform rect = HUDCanvas.instance.rect; if (!((Object)(object)rect == (Object)null)) { uiContainer = new GameObject("ScannerUI"); RectTransform val = uiContainer.AddComponent<RectTransform>(); ((Transform)val).SetParent((Transform)(object)rect, false); float num = barWidth; float num2 = barHeight; val.anchorMin = new Vector2(0.5f, 1f); val.anchorMax = new Vector2(0.5f, 1f); val.pivot = new Vector2(0.5f, 1f); val.anchoredPosition = new Vector2(0f, -5f); val.sizeDelta = new Vector2(num, num2 + 6.25f); canvasGroup = uiContainer.AddComponent<CanvasGroup>(); canvasGroup.alpha = 0f; GameObject val2 = new GameObject("Background"); RectTransform val3 = val2.AddComponent<RectTransform>(); ((Transform)val3).SetParent((Transform)(object)val, false); val3.anchorMin = new Vector2(0f, 0f); val3.anchorMax = new Vector2(1f, 0f); val3.pivot = new Vector2(0.5f, 0f); val3.sizeDelta = new Vector2(0f, num2); backgroundBar = val2.AddComponent<Image>(); ((Graphic)backgroundBar).color = new Color(0.2f, 0.2f, 0.2f, 0.6f); GameObject val4 = new GameObject("ProgressBarContainer"); RectTransform val5 = val4.AddComponent<RectTransform>(); ((Transform)val5).SetParent((Transform)(object)val3, false); val5.anchorMin = new Vector2(0f, 0f); val5.anchorMax = new Vector2(1f, 1f); val5.offsetMin = Vector2.zero; val5.offsetMax = Vector2.zero; Mask val6 = val4.AddComponent<Mask>(); val6.showMaskGraphic = false; Image val7 = val4.AddComponent<Image>(); ((Graphic)val7).color = Color.white; GameObject val8 = new GameObject("ProgressBar"); barRect = val8.AddComponent<RectTransform>(); ((Transform)barRect).SetParent((Transform)(object)val5, false); barRect.anchorMin = new Vector2(0f, 0f); barRect.anchorMax = new Vector2(1f, 1f); barRect.offsetMin = Vector2.zero; barRect.offsetMax = Vector2.zero; progressBar = val8.AddComponent<Image>(); ((Graphic)progressBar).color = barColor; GameObject val9 = new GameObject("StatusText"); RectTransform val10 = val9.AddComponent<RectTransform>(); ((Transform)val10).SetParent((Transform)(object)val, false); val10.anchorMin = new Vector2(0f, 0f); val10.anchorMax = new Vector2(1f, 0f); val10.pivot = new Vector2(0.5f, 0f); val10.anchoredPosition = new Vector2(0f, -12f); val10.sizeDelta = new Vector2(0f, 10f); statusText = val9.AddComponent<TextMeshProUGUI>(); ((TMP_Text)statusText).alignment = (TextAlignmentOptions)514; ((TMP_Text)statusText).fontSize = 6f; ((TMP_Text)statusText).fontStyle = (FontStyles)1; ((Graphic)statusText).color = Color.white; } } private void OnGUI() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_01b5: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) if (!ConfigManager.IsLegacyVersionGUI || !ShouldShowGUI()) { return; } float remainingCooldown = Scanner.GetRemainingCooldown(); float num = remainingCooldown / ConfigManager.cooldown.Value; bool flag = Scanner.IsOnCooldown(); float num2; if (flag) { num2 = 1f; lastDisplayTime = Time.time; } else { float num3 = Time.time - lastDisplayTime; num2 = Mathf.Clamp01(1f - num3 / displayDuration); } if (!(num2 <= 0.01f)) { float num4 = ((float)Screen.width - legacyBarWidth) / 2f; float num5 = 30f; GUI.color = new Color(0.2f, 0.2f, 0.2f, 0.6f * num2); GUI.DrawTexture(new Rect(num4, num5, legacyBarWidth, legacyBarHeight), (Texture)(object)backgroundTexture); if (flag) { GUI.color = new Color(barColor.r, barColor.g, barColor.b, barColor.a * num2); GUI.DrawTexture(new Rect(num4, num5, legacyBarWidth * (1f - num), legacyBarHeight), (Texture)(object)barTexture); } else { GUI.color = new Color(readyColor.r, readyColor.g, readyColor.b, readyColor.a * num2); GUI.DrawTexture(new Rect(num4, num5, legacyBarWidth, legacyBarHeight), (Texture)(object)barTexture); } GUI.color = Color.white; GUIStyle val = new GUIStyle(GUI.skin.label); val.font = GUI.skin.font; val.fontSize = 14; val.alignment = (TextAnchor)4; val.fontStyle = (FontStyle)1; val.normal.textColor = new Color(1f, 1f, 1f, num2); string text = (flag ? $"Scanner: {remainingCooldown:F1}s" : "Scanner Ready"); GUI.Label(new Rect(num4, num5 + legacyBarHeight + 5f, legacyBarWidth, 20f), text, val); } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } if ((Object)(object)uiContainer != (Object)null) { Object.Destroy((Object)(object)uiContainer); } if ((Object)(object)barTexture != (Object)null) { Object.Destroy((Object)(object)barTexture); } if ((Object)(object)backgroundTexture != (Object)null) { Object.Destroy((Object)(object)backgroundTexture); } } private void Update() { //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (!ShouldShowGUI() || (Object)(object)uiContainer == (Object)null || ConfigManager.IsLegacyVersionGUI) { if ((Object)(object)uiContainer != (Object)null) { uiContainer.SetActive(false); } return; } uiContainer.SetActive(true); float remainingCooldown = Scanner.GetRemainingCooldown(); float num = remainingCooldown / ConfigManager.cooldown.Value; bool flag = Scanner.IsOnCooldown(); float alpha; if (flag) { alpha = 1f; lastDisplayTime = Time.time; } else { float num2 = Time.time - lastDisplayTime; alpha = Mathf.Clamp01(1f - num2 / displayDuration); } canvasGroup.alpha = alpha; if (flag) { float num3 = 1f - num; barRect.anchorMax = new Vector2(num3, 1f); ((Graphic)progressBar).color = barColor; ((TMP_Text)statusText).text = $"Scanner: {remainingCooldown:F1}s"; } else { barRect.anchorMax = new Vector2(1f, 1f); ((Graphic)progressBar).color = readyColor; ((TMP_Text)statusText).text = "Scanner Ready"; } } private bool ShouldShowGUI() { return ConfigManager.toCreateGUI.Value && (Object)(object)PlayerController.instance != (Object)null && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated && !SemiFunc.MenuLevel(); } public void NotifyScan() { lastDisplayTime = Time.time; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Kistras-Scanner"; public const string PLUGIN_NAME = "REPO Scanner"; public const string PLUGIN_VERSION = "1.2.0"; } }