Decompiled source of HistoryExtension v1.1.0

HistoryExtension.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 Loading;
using Map;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using On;
using On.Loading;
using On.Map;
using On.PeglinUI.Encirclepedia;
using On.PeglinUI.MainMenu;
using On.PeglinUI.RunSummary;
using PeglinUI.ControllerSupport;
using PeglinUI.Encirclepedia;
using PeglinUI.MainMenu;
using PeglinUI.RunSummary;
using Saving;
using Stats;
using TMPro;
using ToolBox.Serialization;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
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("HistoryExtension")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Store more than the past 20 runs along with other run history improvements")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+3d4dd5fec1a25308bcbbb395f3a41d0468b0a44f")]
[assembly: AssemblyProduct("HistoryExtension")]
[assembly: AssemblyTitle("HistoryExtension")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 HistoryExtension
{
	public class AuxiliaryRunStatsBehavior : MonoBehaviour
	{
		public class AuxiliaryRunStats
		{
			[JsonProperty("runs")]
			private Dictionary<Guid, AuxiliaryRunStatsData> _runs = new Dictionary<Guid, AuxiliaryRunStatsData>();

			public int Count()
			{
				return _runs.Count;
			}

			public void StartRun(RunStats runStats)
			{
				_runs.Add(runStats.runId, new AuxiliaryRunStatsData
				{
					RunStats = runStats
				});
			}

			public void ContinueRun(Guid guid)
			{
				AuxiliaryRunStatsData run;
				AuxiliaryRunStatsData auxiliaryRunStatsData = (run = GetRun(guid));
				if (run.Continues == null)
				{
					List<int> list2 = (run.Continues = new List<int>());
				}
				auxiliaryRunStatsData.Continues.Add(StaticGameData.chosenNextNodeIndex);
			}

			public bool IsRunContinued(Guid guid)
			{
				if (!_runs.ContainsKey(guid))
				{
					return true;
				}
				if (_runs.TryGetValue(guid, out var value))
				{
					List<int> continues = value.Continues;
					if (continues == null)
					{
						return false;
					}
					return continues.Count > 0;
				}
				return false;
			}

			private AuxiliaryRunStatsData GetRun(Guid guid)
			{
				AuxiliaryRunStatsData valueOrDefault = _runs.GetValueOrDefault(guid, new AuxiliaryRunStatsData());
				_runs[guid] = valueOrDefault;
				return valueOrDefault;
			}
		}

		public class AuxiliaryRunStatsData
		{
			public List<int> Continues { get; set; }

			public RunStats RunStats { get; set; }
		}

		public static AuxiliaryRunStats RunStats { get; private set; }

		public void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			RunStats = LoadRunStats();
			PlayButton.ConfirmRunConfigAndStartGame += new hook_ConfirmRunConfigAndStartGame(PlayButtonOnConfirmRunConfigAndStartGame);
			MapController.LoadRunStats += new hook_LoadRunStats(MapControllerOnLoadRunStats);
			SaveManager.OnSaveRequested = (SaveRequested)Delegate.Combine((Delegate?)(object)SaveManager.OnSaveRequested, (Delegate?)new SaveRequested(Save));
			PauseMenu.QuitToMenu += new hook_QuitToMenu(PauseMenuOnQuitToMenu);
		}

		public void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			PlayButton.ConfirmRunConfigAndStartGame -= new hook_ConfirmRunConfigAndStartGame(PlayButtonOnConfirmRunConfigAndStartGame);
			MapController.LoadRunStats -= new hook_LoadRunStats(MapControllerOnLoadRunStats);
			SaveManager.OnSaveRequested = (SaveRequested)Delegate.Remove((Delegate?)(object)SaveManager.OnSaveRequested, (Delegate?)new SaveRequested(Save));
			PauseMenu.QuitToMenu -= new hook_QuitToMenu(PauseMenuOnQuitToMenu);
		}

		public void OnApplicationQuit()
		{
			Save();
		}

		private void PauseMenuOnQuitToMenu(orig_QuitToMenu orig, PauseMenu self)
		{
			orig.Invoke(self);
			Save();
		}

		private void PlayButtonOnConfirmRunConfigAndStartGame(orig_ConfirmRunConfigAndStartGame orig, PlayButton self)
		{
			orig.Invoke(self);
			RunStats.StartRun(StaticGameData.CurrentRunStats);
		}

		private RunStats MapControllerOnLoadRunStats(orig_LoadRunStats orig, MapController self)
		{
			RunStats obj = orig.Invoke(self);
			Guid runId = obj.runId;
			RunStats.ContinueRun(runId);
			return obj;
		}

		private AuxiliaryRunStats LoadRunStats()
		{
			AuxiliaryRunStats auxiliaryRunStats = new AuxiliaryRunStats();
			try
			{
				Debug.Log((object)"Loading auxiliary run stats");
				JsonConvert.PopulateObject(File.ReadAllText(GetFilePath()), (object)auxiliaryRunStats);
				Debug.Log((object)$"Populated {auxiliaryRunStats.Count()} runs from auxiliary run stats file");
			}
			catch (Exception arg)
			{
				Debug.LogWarning((object)$"Couldn't populate stats from existing file: {arg}");
			}
			return auxiliaryRunStats;
		}

		public void Save()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Debug.Log((object)"Saving...");
				string filePath = GetFilePath();
				Debug.Log((object)("Saving Run Stats to: " + filePath));
				using StreamWriter streamWriter = File.CreateText(filePath);
				new JsonSerializer().Serialize((TextWriter)streamWriter, (object)RunStats);
			}
			catch (Exception arg)
			{
				Debug.LogWarning((object)$"Couldn't save aux stats: {arg}");
			}
		}

		private string GetFilePath()
		{
			return Path.Combine(Application.persistentDataPath, $"auxiliaryRunStats-{DataSerializer.CurrentProfileIndex}.json");
		}
	}
	public class EncirclepediaHighlight : MonoBehaviour
	{
		public Color highlightColor = new Color(0.35f, 0.35f, 1f);

		private int _itemsPerPage = 20;

		private int _currentPage;

		private Button _prevButton;

		private Button _nextButton;

		private RunStatsSaveData[] _allRuns;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			RunStatisticsDetails.Initialize += new hook_Initialize(RunStatisticsDetailsOnInitialize);
			RunSummaryList.Awake += new hook_Awake(RunSummaryListOnAwake);
			EncirclepediaManager.OnEnable += new hook_OnEnable(EncirclepediaManagerOnOnEnable);
		}

		private void RunStatisticsDetailsOnInitialize(orig_Initialize orig, RunStatisticsDetails self, RunStats stats)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, stats);
			bool flag = AuxiliaryRunStatsBehavior.RunStats.IsRunContinued(stats.runId);
			Transform val = self.headerParent.Find("PeglinContainer/StickerBackground");
			Image val2 = default(Image);
			if (Object.op_Implicit((Object)(object)val) && ((Component)val).TryGetComponent<Image>(ref val2))
			{
				((Graphic)val2).color = (flag ? Color.white : highlightColor);
			}
		}

		public void Destroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			RunStatisticsDetails.Initialize -= new hook_Initialize(RunStatisticsDetailsOnInitialize);
			RunSummaryList.Awake -= new hook_Awake(RunSummaryListOnAwake);
			EncirclepediaManager.OnEnable -= new hook_OnEnable(EncirclepediaManagerOnOnEnable);
		}

		private void EncirclepediaManagerOnOnEnable(orig_OnEnable orig, EncirclepediaManager self)
		{
			orig.Invoke(self);
			Canvas val = default(Canvas);
			if (((Component)self).TryGetComponent<Canvas>(ref val))
			{
				val.pixelPerfect = false;
			}
			else
			{
				Debug.Log((object)"Couldn't find encirclepedia manager canvas to disable pixel perfect.");
			}
		}

		private void RunSummaryListOnAwake(orig_Awake orig, RunSummaryList self)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_02bf: Expected O, but got Unknown
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Expected O, but got Unknown
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			if (AssetLoading.Instance.RunStats.Count == 0)
			{
				AssetLoading.Instance.LoadRunStats();
			}
			_allRuns = AssetLoading.Instance.RunStats.Reverse().ToArray();
			List<Button> list = new List<Button>();
			for (int i = 0; i < _itemsPerPage; i++)
			{
				RunSummaryLine component = Object.Instantiate<GameObject>(self.runSummaryLinePrefab, self.runSummaryLineContainer).GetComponent<RunSummaryLine>();
				list.Add(((Component)component).GetComponentInChildren<Button>());
			}
			for (int j = 0; j < list.Count; j++)
			{
				Navigation val = default(Navigation);
				((Navigation)(ref val)).mode = (Mode)4;
				Navigation navigation = val;
				if (list.Count > j + 1)
				{
					((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)list[j + 1];
				}
				if (j > 0)
				{
					((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)list[j - 1];
				}
				((Selectable)list[j]).navigation = navigation;
			}
			EventSystem.current.SetSelectedGameObject(((Component)list[0]).gameObject);
			((UnityEvent)self.moveCameraButton.onClick).AddListener(new UnityAction(self.MoveCameraToLoadout));
			_currentPage = 0;
			RectTransform component2 = ((Component)self).GetComponent<RectTransform>();
			_prevButton = Object.Instantiate<Button>(self.moveCameraButton, (Transform)(object)component2);
			((Object)_prevButton).name = "Previous Runs";
			MapButtonToInput val2 = default(MapButtonToInput);
			if (((Component)_prevButton).TryGetComponent<MapButtonToInput>(ref val2))
			{
				Object.Destroy((Object)(object)val2);
				Transform obj = ((Component)_prevButton).transform.Find("ControllerButton");
				Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null));
			}
			_prevButton.onClick = new ButtonClickedEvent();
			((UnityEvent)_prevButton.onClick).AddListener((UnityAction)delegate
			{
				ShowPage(_currentPage - 1, self);
			});
			RectTransform component3 = ((Component)_prevButton).GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(0f, 0f);
			component3.anchoredPosition = new Vector2(30f, 0f);
			TextMeshProUGUI componentInChildren = ((Component)_prevButton).GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((TMP_Text)componentInChildren).text = self.MOVE_LEFT_ARROW;
			}
			_nextButton = Object.Instantiate<Button>(self.moveCameraButton, (Transform)(object)component2);
			((Object)_nextButton).name = "Next Runs";
			if (((Component)_nextButton).TryGetComponent<MapButtonToInput>(ref val2))
			{
				Object.Destroy((Object)(object)val2);
				Transform obj2 = ((Component)_nextButton).transform.Find("ControllerButton");
				Object.Destroy((Object)(object)((obj2 != null) ? ((Component)obj2).gameObject : null));
			}
			_nextButton.onClick = new ButtonClickedEvent();
			((UnityEvent)_nextButton.onClick).AddListener((UnityAction)delegate
			{
				ShowPage(_currentPage + 1, self);
			});
			RectTransform component4 = ((Component)_nextButton).GetComponent<RectTransform>();
			component4.anchorMin = new Vector2(1f, 0f);
			component4.anchorMax = new Vector2(1f, 0f);
			component4.anchoredPosition = new Vector2(-30f, 0f);
			ShowPage(0, self);
		}

		private void ShowPage(int page, RunSummaryList runSummaryList)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			_currentPage = page;
			int num = page * _itemsPerPage;
			int num2 = Mathf.Min(num + _itemsPerPage, _allRuns.Length);
			RunSummaryLine[] componentsInChildren = ((Component)runSummaryList.runSummaryLineContainer).GetComponentsInChildren<RunSummaryLine>(true);
			RunSummaryLine component = runSummaryList.runSummaryLinePrefab.GetComponent<RunSummaryLine>();
			object obj;
			if (component == null)
			{
				obj = null;
			}
			else
			{
				Image backgroundImage = component.backgroundImage;
				obj = ((backgroundImage != null) ? backgroundImage.sprite : null);
			}
			Sprite val = (Sprite)obj;
			for (int i = 0; i < _itemsPerPage; i++)
			{
				RunSummaryLine val2 = componentsInChildren[i];
				if (i + num < _allRuns.Length)
				{
					((Component)val2).gameObject.SetActive(true);
					RunStatsSaveData val3 = _allRuns[i + num];
					val2.Initialize(new RunStats(val3), runSummaryList.classInfos[val3.selectedClass], runSummaryList.runStatsDetails, runSummaryList);
					val2.backgroundImage.sprite = (val3.hasWon ? val : val2.lossSprite);
				}
				else
				{
					((Component)val2).gameObject.SetActive(false);
				}
			}
			RunSummaryLine[] array = componentsInChildren;
			Image val6 = default(Image);
			foreach (RunSummaryLine val4 in array)
			{
				Guid runId = val4._stats.runId;
				if (!AuxiliaryRunStatsBehavior.RunStats.IsRunContinued(runId))
				{
					Transform val5 = ((Component)val4).transform.Find("Parent/PeglinContainer/StickerBackground");
					if (Object.op_Implicit((Object)(object)val5) && ((Component)val5).TryGetComponent<Image>(ref val6))
					{
						((Graphic)val6).color = highlightColor;
					}
				}
			}
			((Component)_prevButton).gameObject.SetActive(page > 0);
			((Component)_nextButton).gameObject.SetActive(num2 < _allRuns.Length);
		}
	}
	[BepInPlugin("HistoryExtension", "HistoryExtension", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		private ConfigEntry<int> _historyLimit;

		public void Awake()
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin HistoryExtension is loaded!");
			try
			{
				_historyLimit = ((BaseUnityPlugin)this).Config.Bind<int>("General", "History Limit", -1, "Number of history entries to store, -1 for infinite.");
				string filePath = DataSerializer.GetFilePath(DataSerializer.CurrentProfileIndex, (SaveType)4);
				FileInfo fileInfo = new FileInfo(filePath);
				FileInfo fileInfo2 = new FileInfo(filePath + ".bak");
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Checking save file existence: {fileInfo.Exists}");
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Backup file existence: {fileInfo2.Exists}");
				((BaseUnityPlugin)this).Logger.LogInfo((object)("History file age: " + fileInfo2.LastWriteTime.ToLongDateString()));
				if (fileInfo.Exists && (!fileInfo2.Exists || DateTime.Now > fileInfo2.LastWriteTime.AddDays(30.0)))
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Backing up stats file");
					fileInfo.CopyTo(fileInfo2.FullName, overwrite: true);
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Couldn't read config file: {arg}");
			}
			AssetLoading.AddRunStats += new hook_AddRunStats(AssetLoadingOnAddRunStats);
			((Component)this).gameObject.AddComponent<AuxiliaryRunStatsBehavior>();
			EncirclepediaHighlight encirclepediaHighlight = ((Component)this).gameObject.AddComponent<EncirclepediaHighlight>();
			try
			{
				ConfigEntry<Color> val = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "Encirclepedia Highlight", encirclepediaHighlight.highlightColor, "Color to highlight non-continued runs in the encirclepedia.");
				encirclepediaHighlight.highlightColor = val.Value;
			}
			catch (Exception arg2)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Couldn't read encirclepedia highlight color from config: {arg2}");
			}
		}

		private void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			AssetLoading.AddRunStats -= new hook_AddRunStats(AssetLoadingOnAddRunStats);
		}

		private void AssetLoadingOnAddRunStats(orig_AddRunStats orig, AssetLoading self, RunStats stats)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			foreach (RunStatsSaveData runStat in self.RunStats)
			{
				if (runStat.runId.Equals(stats.runId.ToString()))
				{
					return;
				}
			}
			int value = _historyLimit.Value;
			((BaseUnityPlugin)this).Logger.LogDebug((object)"Checking history limit");
			((BaseUnityPlugin)this).Logger.LogDebug((object)$"Run Stats Count: {self.RunStats.Count}");
			((BaseUnityPlugin)this).Logger.LogDebug((object)$"Limit: {value}");
			while (value >= 0 && self.RunStats.Count >= value && self.RunStats.Count > 0)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)"Run stats count >= history limit. Dequeueing");
				self.RunStats.Dequeue();
			}
			PersistentPlayerData.Instance.PermanentStats.AddStatsToPermanent(stats);
			self.RunStats.Enqueue(new RunStatsSaveData(stats));
			self.SaveRunStats();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "HistoryExtension";

		public const string PLUGIN_NAME = "HistoryExtension";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}