Decompiled source of Session Stats v1.0.0

Session_Stats/SessionStats.dll

Decompiled 9 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
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("SessionStats")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SessionStats")]
[assembly: AssemblyTitle("SessionStats")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Ocewen.SessionStats
{
	internal class DragHandler : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		private RectTransform? _rect;

		private Vector2 _dragOffset;

		private void Awake()
		{
			_rect = ((Component)this).GetComponent<RectTransform>();
		}

		public void OnBeginDrag(PointerEventData data)
		{
			//IL_0020: 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)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_rect == (Object)null))
			{
				Transform parent = ((Transform)_rect).parent;
				Vector2 val = default(Vector2);
				RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), data.position, data.pressEventCamera, ref val);
				_dragOffset = _rect.anchoredPosition - val;
			}
		}

		public void OnDrag(PointerEventData data)
		{
			//IL_0020: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_rect == (Object)null))
			{
				Transform parent = ((Transform)_rect).parent;
				Vector2 val = default(Vector2);
				RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), data.position, data.pressEventCamera, ref val);
				_rect.anchoredPosition = val + _dragOffset;
			}
		}

		public void OnEndDrag(PointerEventData data)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_rect == (Object)null))
			{
				Vector2 anchoredPosition = _rect.anchoredPosition;
				ModConfig.PosX.Value = anchoredPosition.x;
				ModConfig.PosY.Value = 0f - anchoredPosition.y;
			}
		}
	}
	internal static class HudDisplay
	{
		private static GameObject? _root;

		private static RectTransform? _rootRect;

		private static Image? _borderImage;

		private static Image? _bgImage;

		private static RectTransform? _bgRect;

		private static TextMeshProUGUI? _label;

		internal static void Create()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_root != (Object)null))
			{
				GameObject val = new GameObject("SessionStatsCanvas");
				Object.DontDestroyOnLoad((Object)(object)val);
				Canvas obj = val.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 100;
				val.AddComponent<CanvasScaler>();
				val.AddComponent<GraphicRaycaster>();
				_root = new GameObject("SessionStatsPanel");
				_root.transform.SetParent(val.transform, false);
				_borderImage = _root.AddComponent<Image>();
				_root.AddComponent<DragHandler>();
				_rootRect = _root.GetComponent<RectTransform>();
				_rootRect.anchorMin = new Vector2(0f, 1f);
				_rootRect.anchorMax = new Vector2(0f, 1f);
				_rootRect.pivot = new Vector2(0f, 1f);
				GameObject val2 = new GameObject("BG");
				val2.transform.SetParent(_root.transform, false);
				_bgImage = val2.AddComponent<Image>();
				_bgRect = val2.GetComponent<RectTransform>();
				_bgRect.anchorMin = Vector2.zero;
				_bgRect.anchorMax = Vector2.one;
				GameObject val3 = new GameObject("Label");
				val3.transform.SetParent(_root.transform, false);
				_label = val3.AddComponent<TextMeshProUGUI>();
				((TMP_Text)_label).enableWordWrapping = false;
				((TMP_Text)_label).overflowMode = (TextOverflowModes)0;
				RectTransform component = val3.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				UpdateLayout();
				UpdateStyle();
			}
		}

		internal static void Destroy()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_root.transform.parent).gameObject);
			}
			_root = null;
			_rootRect = null;
			_borderImage = null;
			_bgImage = null;
			_bgRect = null;
			_label = null;
		}

		internal static void UpdateLayout()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_rootRect == (Object)null))
			{
				_rootRect.anchoredPosition = new Vector2(ModConfig.PosX.Value, 0f - ModConfig.PosY.Value);
			}
		}

		internal static void UpdateStyle()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_borderImage != (Object)null)
			{
				((Graphic)_borderImage).color = ModConfig.BorderColor.Value;
			}
			float value = ModConfig.BorderSize.Value;
			if ((Object)(object)_bgRect != (Object)null)
			{
				_bgRect.offsetMin = new Vector2(value, value);
				_bgRect.offsetMax = new Vector2(0f - value, 0f - value);
			}
			if ((Object)(object)_bgImage != (Object)null)
			{
				((Graphic)_bgImage).color = ModConfig.BgColor.Value;
			}
			if ((Object)(object)_label != (Object)null)
			{
				((TMP_Text)_label).fontSize = ModConfig.FontSize.Value;
			}
			float num = ModConfig.BgPadding.Value + value;
			if ((Object)(object)_label != (Object)null)
			{
				RectTransform component = ((Component)_label).GetComponent<RectTransform>();
				component.offsetMin = new Vector2(num, num);
				component.offsetMax = new Vector2(0f - num, 0f - num);
			}
			Refresh();
		}

		internal static void Refresh()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_label == (Object)null || (Object)(object)_rootRect == (Object)null)
			{
				return;
			}
			string text = "#" + ColorUtility.ToHtmlStringRGBA(ModConfig.LabelColor.Value);
			string text2 = "#" + ColorUtility.ToHtmlStringRGBA(ModConfig.ValueColor.Value);
			bool value = ModConfig.ShowTotals.Value;
			StringBuilder stringBuilder = new StringBuilder();
			if (ModConfig.ShowSession.Value)
			{
				TimeSpan elapsed = SessionData.Elapsed;
				stringBuilder.AppendLine($"<color={text}>Session </color><color={text2}>{(int)elapsed.TotalHours:D2}:{elapsed.Minutes:D2}:{elapsed.Seconds:D2}</color>");
			}
			if (ModConfig.ShowXph.Value)
			{
				string text3 = $"<color={text}>XP/h    </color><color={text2}>{SessionData.XpPerHour:N0}</color>";
				if (value)
				{
					text3 += $"<color={text}>  ({SessionData.XpGained:N0})</color>";
				}
				stringBuilder.AppendLine(text3);
			}
			if (ModConfig.ShowKph.Value)
			{
				string text4 = $"<color={text}>KPH     </color><color={text2}>{SessionData.Kph:N0}</color>";
				if (value)
				{
					text4 += $"<color={text}>  ({SessionData.KillCount:N0})</color>";
				}
				stringBuilder.AppendLine(text4);
			}
			if (ModConfig.ShowGoldph.Value)
			{
				string text5 = $"<color={text}>Gold/h  </color><color={text2}>{SessionData.GoldPerHour:N0}</color>";
				if (value)
				{
					text5 += $"<color={text}>  ({SessionData.GoldGained:N0})</color>";
				}
				stringBuilder.AppendLine(text5);
			}
			((TMP_Text)_label).text = stringBuilder.ToString().TrimEnd();
			int num = (ModConfig.ShowSession.Value ? 1 : 0) + (ModConfig.ShowXph.Value ? 1 : 0) + (ModConfig.ShowKph.Value ? 1 : 0) + (ModConfig.ShowGoldph.Value ? 1 : 0);
			float num2 = ModConfig.BgPadding.Value + ModConfig.BorderSize.Value;
			float num3 = ModConfig.FontSize.Value * 1.4f;
			float num4 = (ModConfig.ShowTotals.Value ? 220f : 160f);
			_rootRect.sizeDelta = new Vector2(num4, (float)num * num3 + num2 * 2f);
		}
	}
	internal static class ModConfig
	{
		internal static ConfigEntry<KeyCode> ResetKey { get; private set; }

		internal static ConfigEntry<float> PosX { get; private set; }

		internal static ConfigEntry<float> PosY { get; private set; }

		internal static ConfigEntry<float> FontSize { get; private set; }

		internal static ConfigEntry<Color> LabelColor { get; private set; }

		internal static ConfigEntry<Color> ValueColor { get; private set; }

		internal static ConfigEntry<Color> BgColor { get; private set; }

		internal static ConfigEntry<float> BgPadding { get; private set; }

		internal static ConfigEntry<Color> BorderColor { get; private set; }

		internal static ConfigEntry<float> BorderSize { get; private set; }

		internal static ConfigEntry<bool> ShowSession { get; private set; }

		internal static ConfigEntry<bool> ShowXph { get; private set; }

		internal static ConfigEntry<bool> ShowKph { get; private set; }

		internal static ConfigEntry<bool> ShowGoldph { get; private set; }

		internal static ConfigEntry<bool> ShowTotals { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			//IL_0096: 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)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			ResetKey = config.Bind<KeyCode>("General", "ResetKey", (KeyCode)286, "Key to reset session stats");
			PosX = config.Bind<float>("Display", "PosX", 20f, "Horizontal position from left edge (also updated by drag)");
			PosY = config.Bind<float>("Display", "PosY", 200f, "Vertical position from top edge (also updated by drag)");
			FontSize = config.Bind<float>("Display", "FontSize", 13f, "Font size");
			LabelColor = config.Bind<Color>("Display", "LabelColor", new Color(0.67f, 0.67f, 0.67f), "Color of the row labels");
			ValueColor = config.Bind<Color>("Display", "ValueColor", Color.white, "Color of the stat values");
			BgColor = config.Bind<Color>("Display", "BgColor", new Color(0f, 0f, 0f, 0.6f), "Background color");
			BgPadding = config.Bind<float>("Display", "BgPadding", 6f, "Inner padding in pixels");
			BorderColor = config.Bind<Color>("Display", "BorderColor", Color.clear, "Border color");
			BorderSize = config.Bind<float>("Display", "BorderSize", 0f, "Border thickness in pixels");
			ShowSession = config.Bind<bool>("Display", "ShowSession", true, "Show session time");
			ShowXph = config.Bind<bool>("Display", "ShowXph", true, "Show XP/hour");
			ShowKph = config.Bind<bool>("Display", "ShowKph", true, "Show kills/hour");
			ShowGoldph = config.Bind<bool>("Display", "ShowGoldph", true, "Show gold/hour");
			ShowTotals = config.Bind<bool>("Display", "ShowTotals", false, "Show total accumulated values next to rates");
			PosX.SettingChanged += delegate
			{
				HudDisplay.UpdateLayout();
			};
			PosY.SettingChanged += delegate
			{
				HudDisplay.UpdateLayout();
			};
			FontSize.SettingChanged += delegate
			{
				HudDisplay.UpdateStyle();
			};
			LabelColor.SettingChanged += delegate
			{
				HudDisplay.Refresh();
			};
			ValueColor.SettingChanged += delegate
			{
				HudDisplay.Refresh();
			};
			BgColor.SettingChanged += delegate
			{
				HudDisplay.UpdateStyle();
			};
			BgPadding.SettingChanged += delegate
			{
				HudDisplay.UpdateStyle();
			};
			BorderColor.SettingChanged += delegate
			{
				HudDisplay.UpdateStyle();
			};
			BorderSize.SettingChanged += delegate
			{
				HudDisplay.UpdateStyle();
			};
			ShowTotals.SettingChanged += delegate
			{
				HudDisplay.Refresh();
			};
		}
	}
	[BepInPlugin("Ocewen.Session_Stats", "Session Stats", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony? _harmony;

		private float _refreshTimer;

		private int _lastGold;

		private bool _hudReady;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("Ocewen.Session_Stats");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Session Stats 1.0.0 loaded.");
		}

		private void Update()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			bool flag = ((Scene)(ref activeScene)).name == "Hidden";
			if (!_hudReady && flag)
			{
				_hudReady = true;
				HudDisplay.Create();
				SessionData.Reset();
				_lastGold = GameData.PlayerInv?.Gold ?? 0;
			}
			else if (_hudReady && !flag)
			{
				_hudReady = false;
				HudDisplay.Destroy();
			}
			if (Input.GetKeyDown(ModConfig.ResetKey.Value))
			{
				SessionData.Reset();
				_lastGold = GameData.PlayerInv?.Gold ?? 0;
			}
			Inventory playerInv = GameData.PlayerInv;
			if ((Object)(object)playerInv != (Object)null)
			{
				int gold = playerInv.Gold;
				int num = gold - _lastGold;
				if (num > 0)
				{
					SessionData.GoldGained += num;
				}
				_lastGold = gold;
			}
			_refreshTimer += Time.deltaTime;
			if (_refreshTimer >= 1f)
			{
				_refreshTimer = 0f;
				HudDisplay.Refresh();
			}
		}

		private void OnDestroy()
		{
			HudDisplay.Destroy();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchAll("Ocewen.Session_Stats");
			}
		}
	}
	internal static class SessionData
	{
		internal static DateTime Start = DateTime.Now;

		internal static int XpGained = 0;

		internal static int KillCount = 0;

		internal static int GoldGained = 0;

		internal static TimeSpan Elapsed => DateTime.Now - Start;

		private static double Hours => Math.Max(Elapsed.TotalHours, 0.0002777777777777778);

		internal static int XpPerHour => (int)((double)XpGained / Hours);

		internal static int Kph => (int)((double)KillCount / Hours);

		internal static int GoldPerHour => (int)((double)GoldGained / Hours);

		internal static void Reset()
		{
			Start = DateTime.Now;
			XpGained = 0;
			KillCount = 0;
			GoldGained = 0;
		}
	}
}
namespace Ocewen.SessionStats.Patches
{
	[HarmonyPatch(typeof(GameData), "AddExperience")]
	internal static class AddExperience_Patch
	{
		private static void Prefix(int xp)
		{
			if (xp > 0)
			{
				SessionData.XpGained += xp;
			}
		}
	}
	[HarmonyPatch(typeof(Character), "DoDeath")]
	internal static class DoDeath_Patch
	{
		private static void Prefix(Character __instance)
		{
			if (__instance.isNPC && __instance.Alive && Traverse.Create((object)__instance).Field<bool>("damagedByPlayerEver").Value)
			{
				SessionData.KillCount++;
			}
		}
	}
}