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 Observe v1.1.1
Observe.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Observe.Patches; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("headclef")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1+fb16e3c1316d6f39cd4649ac84ad34188bad4448")] [assembly: AssemblyProduct("Observe")] [assembly: AssemblyTitle("Observe")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.1.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 Observe { internal static class MapReveal { private struct Marker { public GameObject Go; public float Expire; } private static readonly Dictionary<ValuableObject, Marker> _markers = new Dictionary<ValuableObject, Marker>(); private static readonly HashSet<ValuableObject> _onMap = new HashSet<ValuableObject>(); internal static void RefreshOnMapSet() { _onMap.Clear(); MapValuable[] array = Object.FindObjectsOfType<MapValuable>(); foreach (MapValuable val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.target != (Object)null) { _onMap.Add(val.target); } } } internal static void AddOrRefresh(ValuableObject valuable, float duration) { Map instance = Map.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)valuable == (Object)null) { return; } float expire = Time.time + duration; if (_markers.TryGetValue(valuable, out var value)) { value.Expire = expire; _markers[valuable] = value; } else if (!_onMap.Contains(valuable)) { Transform overLayerParent = instance.OverLayerParent; int childCountBefore = (((Object)(object)overLayerParent != (Object)null) ? overLayerParent.childCount : (-1)); instance.AddValuable(valuable); GameObject val = CaptureNewMarker(overLayerParent, childCountBefore, valuable); if (!((Object)(object)val == (Object)null)) { _markers[valuable] = new Marker { Go = val, Expire = expire }; _onMap.Add(valuable); } } } private static GameObject? CaptureNewMarker(Transform? parent, int childCountBefore, ValuableObject valuable) { if ((Object)(object)parent == (Object)null || parent.childCount <= childCountBefore) { return null; } MapValuable component = ((Component)parent.GetChild(parent.childCount - 1)).GetComponent<MapValuable>(); if ((Object)(object)component != (Object)null && (Object)(object)component.target == (Object)(object)valuable) { return ((Component)component).gameObject; } int num = parent.childCount - 1; while (num >= 0 && num >= childCountBefore) { MapValuable component2 = ((Component)parent.GetChild(num)).GetComponent<MapValuable>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.target == (Object)(object)valuable) { return ((Component)component2).gameObject; } num--; } if (!((Object)(object)component != (Object)null)) { return null; } return ((Component)component).gameObject; } internal static void Tick() { if (_markers.Count == 0) { return; } if ((Object)(object)Map.Instance == (Object)null || !SemiFunc.RunIsLevel()) { _markers.Clear(); _onMap.Clear(); return; } float time = Time.time; List<ValuableObject> list = null; foreach (KeyValuePair<ValuableObject, Marker> marker in _markers) { if ((Object)(object)marker.Value.Go == (Object)null || (Object)(object)marker.Key == (Object)null || time >= marker.Value.Expire) { (list ?? (list = new List<ValuableObject>())).Add(marker.Key); if ((Object)(object)marker.Value.Go != (Object)null) { Object.Destroy((Object)(object)marker.Value.Go); } } } if (list == null) { return; } foreach (ValuableObject item in list) { _markers.Remove(item); _onMap.Remove(item); } } internal static void ClearAll() { foreach (KeyValuePair<ValuableObject, Marker> marker in _markers) { if ((Object)(object)marker.Value.Go != (Object)null) { Object.Destroy((Object)(object)marker.Value.Go); } } _markers.Clear(); _onMap.Clear(); } } [BepInPlugin("headclef.Observe", "Observe", "1.1.1")] public class Observe : BaseUnityPlugin { private const string PluginGuid = "headclef.Observe"; private const string PluginName = "Observe"; private const string PluginVersion = "1.1.1"; internal static ConfigEntry<KeyboardShortcut> ObserveKey; internal static ConfigEntry<float> Radius; internal static ConfigEntry<float> Cooldown; internal static ConfigEntry<bool> ShowCooldownBar; internal static ConfigEntry<bool> ShowOnMap; internal static ConfigEntry<float> MapMarkerDuration; private GUIStyle? _hudStyle; internal static Observe Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { //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_004a: Expected O, but got Unknown //IL_004f: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; BindConfiguration(); if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } private void OnDestroy() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void BindConfiguration() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown ObserveKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Observe", "Observe Key", new KeyboardShortcut((KeyCode)102, Array.Empty<KeyCode>()), "Key to press to reveal nearby valuables."); Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Observe", "Radius", 10f, new ConfigDescription("Radius in meters around you within which valuables are revealed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Observe", "Cooldown", 10f, new ConfigDescription("Cooldown in seconds between uses.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); ShowCooldownBar = ((BaseUnityPlugin)this).Config.Bind<bool>("Observe", "Show Cooldown Bar", true, "Show an on-screen bar and countdown while Observe is on cooldown."); ShowOnMap = ((BaseUnityPlugin)this).Config.Bind<bool>("Observe", "Show On Map", true, "Also mark revealed valuables on the Map tool when you scan (in addition to the through-wall world marker). Client-side only — just you see them."); MapMarkerDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Observe", "Map Marker Duration", 10f, new ConfigDescription("How long (seconds) revealed valuables stay marked on the map after a scan. Independent of the cooldown. Valuables you genuinely discover stay on the map as usual — this only governs the temporary markers Observe adds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); } private void OnGUI() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_00a1: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown if (!ShowCooldownBar.Value || !SemiFunc.RunIsLevel()) { return; } float num = ObservePatch.CooldownRemaining(); if (!(num <= 0f)) { float num2 = Mathf.Max(Cooldown.Value, 0.0001f); float num3 = Mathf.Clamp01(num / num2); float num4 = ((float)Screen.width - 280f) / 2f; float num5 = (float)Screen.height - 200f; Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.6f); GUI.DrawTexture(new Rect(num4 - 2f, num5 - 2f, 284f, 26f), (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(0.12f, 0.12f, 0.12f, 0.9f); GUI.DrawTexture(new Rect(num4, num5, 280f, 22f), (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(1f, 0.82f, 0.1f, 0.95f); GUI.DrawTexture(new Rect(num4, num5, 280f * num3, 22f), (Texture)(object)Texture2D.whiteTexture); if (_hudStyle == null) { _hudStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontStyle = (FontStyle)1, fontSize = 14 }; } string text = $"Observe {num:0.0}s"; GUI.color = new Color(0f, 0f, 0f, 0.85f); GUI.Label(new Rect(num4 + 1f, num5 + 1f, 280f, 22f), text, _hudStyle); GUI.color = Color.white; GUI.Label(new Rect(num4, num5, 280f, 22f), text, _hudStyle); GUI.color = color; } } } } namespace Observe.Patches { [HarmonyPatch] internal static class ObservePatch { private static float _lastObserveTime = -999f; private static Coroutine? _revealRoutine; private const int RevealsPerFrame = 4; private static bool _prewarmStarted; internal static float CooldownRemaining() { float num = Observe.Cooldown.Value - (Time.time - _lastObserveTime); return Mathf.Max(num, 0f); } [HarmonyPatch(typeof(PlayerController), "Update")] [HarmonyPostfix] private static void PlayerController_Update_Postfix(PlayerController __instance) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)__instance != (Object)(object)PlayerController.instance) { return; } MapReveal.Tick(); TryLazyPrewarm(); if (!ObserveKeyPressed() || !SemiFunc.RunIsLevel()) { return; } float value = Observe.Cooldown.Value; if (Time.time - _lastObserveTime < value) { Observe.Logger.LogDebug((object)$"Observe on cooldown ({value - (Time.time - _lastObserveTime):F1}s remaining)"); return; } _lastObserveTime = Time.time; if (_revealRoutine != null) { ((MonoBehaviour)Observe.Instance).StopCoroutine(_revealRoutine); } _revealRoutine = ((MonoBehaviour)Observe.Instance).StartCoroutine(RevealNearbyValuables(((Component)__instance).transform.position)); } catch (Exception ex) { Observe.Logger.LogError((object)("Observe exception: " + ex.Message)); } } private static IEnumerator RevealNearbyValuables(Vector3 origin) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) ValuableDiscover discover = ValuableDiscover.instance; if ((Object)(object)discover == (Object)null) { Observe.Logger.LogWarning((object)"ValuableDiscover.instance is null — cannot reveal."); _revealRoutine = null; yield break; } float value = Observe.Radius.Value; float sqrRadius = value * value; int revealed = 0; int thisFrame = 0; bool showOnMap = Observe.ShowOnMap.Value; float mapDuration = Observe.MapMarkerDuration.Value; if (showOnMap) { MapReveal.RefreshOnMapSet(); } ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>(); ValuableObject[] array2 = array; foreach (ValuableObject val in array2) { if ((Object)(object)val == (Object)null || (Object)(object)val.physGrabObject == (Object)null) { continue; } Vector3 val2 = ((Component)val).transform.position - origin; if (!(((Vector3)(ref val2)).sqrMagnitude > sqrRadius)) { discover.New(val.physGrabObject, (State)0, (ValuableDiscoverCustom)null); if (showOnMap) { MapReveal.AddOrRefresh(val, mapDuration); } revealed++; int num = thisFrame + 1; thisFrame = num; if (num >= 4) { thisFrame = 0; yield return null; } } } _revealRoutine = null; } private static bool ObserveKeyPressed() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Observe.ObserveKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } private static void TryLazyPrewarm() { if (!_prewarmStarted && SemiFunc.RunIsLevel()) { _prewarmStarted = true; ((MonoBehaviour)Observe.Instance).StartCoroutine(PrewarmDelayed()); } } private static IEnumerator PrewarmDelayed() { yield return (object)new WaitForSeconds(2f); ValuableDiscover instance = ValuableDiscover.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.graphicPrefab == (Object)null) { yield break; } try { GameObject val = Object.Instantiate<GameObject>(instance.graphicPrefab, ((Component)instance).transform); val.SetActive(false); Object.Destroy((Object)(object)val); Observe.Logger.LogDebug((object)"Observe pre-warmed the discovery graphic."); } catch (Exception ex) { Observe.Logger.LogDebug((object)("Observe pre-warm skipped: " + ex.Message)); } } } }