Decompiled source of Loot Monitor v1.3.1

BepInEx/plugins/LootMonitor/LootMonitor.dll

Decompiled 5 days ago
using 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);
		}
	}
}