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 Loot Monitor v1.3.1
BepInEx/plugins/LootMonitor/LootMonitor.dll
Decompiled 5 days agousing System; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LootMonitor")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1")] [assembly: AssemblyProduct("LootMonitor")] [assembly: AssemblyTitle("LootMonitor")] [assembly: AssemblyVersion("1.3.1.0")] [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 LootMonitor { [BepInPlugin("com.lootmonitor.repo", "Loot Monitor", "1.3.1")] [BepInProcess("REPO.exe")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.lootmonitor.repo"; public const string PluginName = "Loot Monitor"; public const string PluginVersion = "1.3.1"; private FieldInfo? currentValueField; private FieldInfo? valueReadyField; private ConfigEntry<bool> showHud; private ConfigEntry<bool> showBackground; private ConfigEntry<float> refreshSeconds; private ConfigEntry<float> rightMargin; private ConfigEntry<float> topMargin; private ConfigEntry<float> uiScale; private GameObject? hudRoot; private RectTransform? panel; private Image? background; private TextMeshProUGUI? amountText; private Material? hudMaterial; private RectTransform? nativeAnchor; private const float HudWidth = 200f; private const float HudHeight = 36f; private float nextRefresh; private float nextErrorLog; private bool compatibilityError; private string? previousText; private void Awake() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown showHud = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Show remaining loot value during scavenging levels."); refreshSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RefreshSeconds", 0.25f, new ConfigDescription("Seconds between recounts. Reads current game values, including damage and extracted loot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>())); rightMargin = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "RightMargin", 0f, new ConfigDescription("Extra inset from the native extraction counter's right edge, in game HUD units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1500f), Array.Empty<object>())); topMargin = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "TopMargin", 0f, new ConfigDescription("Extra space below the native extraction HUD, in game HUD units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1000f), Array.Empty<object>())); uiScale = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "Scale", 1f, new ConfigDescription("Size of the counter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>())); showBackground = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "Background", false, "Optional dark backing. Off by default to match the game's HUD."); currentValueField = typeof(ValuableObject).GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); valueReadyField = typeof(ValuableObject).GetField("dollarValueSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); compatibilityError = currentValueField?.FieldType != typeof(float) || valueReadyField?.FieldType != typeof(bool); if (compatibilityError) { ((BaseUnityPlugin)this).Logger.LogError((object)"This game build changed the valuable fields. The counter is disabled to avoid displaying a false total."); } SceneManager.activeSceneChanged += OnSceneChanged; ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Game {2}, Unity {3}. Client-side, refresh {4:0.00}s.", "Loot Monitor", "1.3.1", Application.version, Application.unityVersion, refreshSeconds.Value)); } private void Update() { if (compatibilityError || Time.unscaledTime < nextRefresh) { return; } nextRefresh = Time.unscaledTime + refreshSeconds.Value; try { if (!showHud.Value || !Object.op_Implicit((Object)(object)RunManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance.levelCurrent) || !Object.op_Implicit((Object)(object)RoundDirector.instance) || !Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated || !SemiFunc.RunIsLevel()) { SetVisible(visible: false); } else if (EnsureHud()) { UpdateAmount(ReadRemainingValue()); SetVisible(visible: true); } } catch (Exception arg) { SetVisible(visible: false); if (Time.unscaledTime >= nextErrorLog) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Unable to refresh map value; retrying. {arg}"); nextErrorLog = Time.unscaledTime + 30f; } } } private void UpdateAmount(long value) { string text = "Map: $" + value.ToString("N0", CultureInfo.InvariantCulture); if (!(text == previousText)) { ((TMP_Text)amountText).text = text; previousText = text; } } private void LateUpdate() { if (Object.op_Implicit((Object)(object)hudRoot) && hudRoot.activeSelf) { ApplyDisplaySettings(); } } internal long ReadRemainingValue() { long num = 0L; ValuableObject[] array = Object.FindObjectsByType<ValuableObject>((FindObjectsSortMode)0); foreach (ValuableObject val in array) { if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeInHierarchy && (bool)valueReadyField.GetValue(val)) { num = ValueMath.Add(num, (float)currentValueField.GetValue(val)); } } ItemValuableBox[] array2 = Object.FindObjectsByType<ItemValuableBox>((FindObjectsSortMode)0); foreach (ItemValuableBox val2 in array2) { if (Object.op_Implicit((Object)(object)val2) && ((Component)val2).gameObject.activeInHierarchy) { num = ValueMath.Add(num, val2.CurrentValue); } } return num; } private bool EnsureHud() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020a: 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_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)hudRoot) && Object.op_Implicit((Object)(object)amountText) && Object.op_Implicit((Object)(object)nativeAnchor) && Object.op_Implicit((Object)(object)GoalUI.instance) && (Object)(object)nativeAnchor == (Object)(object)((Component)GoalUI.instance).GetComponent<RectTransform>()) { return true; } if (!Object.op_Implicit((Object)(object)GoalUI.instance)) { return false; } TextMeshProUGUI component = ((Component)GoalUI.instance).GetComponent<TextMeshProUGUI>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)((TMP_Text)component).font) || !Object.op_Implicit((Object)(object)((Graphic)component).canvas)) { return false; } TextMeshProUGUI val = (Object.op_Implicit((Object)(object)HaulUI.instance) ? ((Component)HaulUI.instance).GetComponent<TextMeshProUGUI>() : component); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)((TMP_Text)val).font)) { val = component; } DestroyHud(); nativeAnchor = ((TMP_Text)component).rectTransform; hudRoot = new GameObject("LootMonitor", new Type[1] { typeof(RectTransform) }); hudRoot.layer = ((Component)component).gameObject.layer; RectTransform component2 = hudRoot.GetComponent<RectTransform>(); ((Transform)component2).SetParent(((Transform)nativeAnchor).parent, false); component2.anchorMin = nativeAnchor.anchorMin; component2.anchorMax = nativeAnchor.anchorMax; component2.pivot = Vector2.one; component2.sizeDelta = new Vector2(200f, 36f); hudMaterial = new Material(((TMP_Text)val).fontSharedMaterial); GameObject val2 = new GameObject("Remaining Map Value", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val2.layer = hudRoot.layer; panel = val2.GetComponent<RectTransform>(); ((Transform)panel).SetParent(hudRoot.transform, false); RectTransform? obj = panel; RectTransform? obj2 = panel; RectTransform? obj3 = panel; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 1f); obj3.pivot = val3; Vector2 anchorMin = (obj2.anchorMax = val3); obj.anchorMin = anchorMin; panel.sizeDelta = new Vector2(200f, 36f); background = val2.GetComponent<Image>(); ((Graphic)background).raycastTarget = false; ((Graphic)background).color = new Color(0.025f, 0.045f, 0.035f, 0.78f); amountText = CreateText("Amount", (Transform)(object)panel, ((TMP_Text)val).font, hudMaterial, 26f, new Color(0.83f, 0.85f, 0.62f)); ((TMP_Text)amountText).rectTransform.anchoredPosition = Vector2.zero; ((TMP_Text)amountText).rectTransform.sizeDelta = new Vector2(200f, 36f); ((TMP_Text)amountText).enableAutoSizing = true; ((TMP_Text)amountText).fontSizeMin = 14f; ((TMP_Text)amountText).fontSizeMax = 26f; previousText = null; ApplyDisplaySettings(); return true; } private static TextMeshProUGUI CreateText(string name, Transform parent, TMP_FontAsset font, Material material, float size, Color color) { //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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); val.transform.SetParent(parent, false); val.layer = ((Component)parent).gameObject.layer; TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val2).font = font; ((TMP_Text)val2).fontSharedMaterial = material; ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = color; ((TMP_Text)val2).alignment = (TextAlignmentOptions)260; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).richText = false; RectTransform rectTransform = ((TMP_Text)val2).rectTransform; RectTransform rectTransform2 = ((TMP_Text)val2).rectTransform; RectTransform rectTransform3 = ((TMP_Text)val2).rectTransform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 1f); rectTransform3.pivot = val3; Vector2 anchorMin = (rectTransform2.anchorMax = val3); rectTransform.anchorMin = anchorMin; return val2; } private void ApplyDisplaySettings() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_0190: 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_01aa: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)panel) || !Object.op_Implicit((Object)(object)background) || !Object.op_Implicit((Object)(object)hudRoot) || !Object.op_Implicit((Object)(object)nativeAnchor) || !Object.op_Implicit((Object)(object)GoalUI.instance)) { return; } Vector3 val = ((!((SemiUI)GoalUI.instance).isHidden && Object.op_Implicit((Object)(object)((SemiUI)GoalUI.instance).uiText) && ((Behaviour)((SemiUI)GoalUI.instance).uiText).enabled) ? ((Transform)nativeAnchor).localPosition : Vector2.op_Implicit(((SemiUI)GoalUI.instance).showPosition)); float x = val.x; Rect rect = nativeAnchor.rect; float num = x + ((Rect)(ref rect)).xMax; float y = val.y; rect = nativeAnchor.rect; float num2 = y + ((Rect)(ref rect)).yMin; if (Object.op_Implicit((Object)(object)HaulUI.instance) && !((SemiUI)HaulUI.instance).isHidden && Object.op_Implicit((Object)(object)((SemiUI)HaulUI.instance).uiText) && ((Behaviour)((SemiUI)HaulUI.instance).uiText).enabled) { RectTransform rectTransform = ((TMP_Text)((SemiUI)HaulUI.instance).uiText).rectTransform; if ((Object)(object)((Transform)rectTransform).parent == (Object)(object)((Transform)nativeAnchor).parent) { float num3 = num2; float y2 = ((Transform)rectTransform).localPosition.y; rect = rectTransform.rect; num2 = Mathf.Min(num3, y2 + ((Rect)(ref rect)).yMin); } } RectTransform component = hudRoot.GetComponent<RectTransform>(); ((Transform)component).localPosition = new Vector3(num - rightMargin.Value, num2 - 8f - topMargin.Value, ((Transform)nativeAnchor).localPosition.z); ((Transform)component).localRotation = ((Transform)nativeAnchor).localRotation; ((Transform)component).localScale = Vector3.one * uiScale.Value; panel.anchoredPosition = Vector2.zero; ((Behaviour)background).enabled = showBackground.Value; } private void SetVisible(bool visible) { if (Object.op_Implicit((Object)(object)hudRoot) && hudRoot.activeSelf != visible) { hudRoot.SetActive(visible); } } private void OnSceneChanged(Scene previous, Scene next) { DestroyHud(); nextRefresh = 0f; } private void DestroyHud() { if (Object.op_Implicit((Object)(object)hudRoot)) { Object.Destroy((Object)(object)hudRoot); } hudRoot = null; amountText = null; panel = null; background = null; previousText = null; nativeAnchor = null; if (Object.op_Implicit((Object)(object)hudMaterial)) { Object.Destroy((Object)(object)hudMaterial); } hudMaterial = null; } private void OnDestroy() { SceneManager.activeSceneChanged -= OnSceneChanged; DestroyHud(); } } internal static class ValueMath { internal static long Add(long total, float value) { if (float.IsNaN(value) || float.IsInfinity(value) || value <= 0f) { return total; } if ((double)value >= (double)(long.MaxValue - total)) { return long.MaxValue; } return total + (long)Math.Truncate(value); } } }