Decompiled source of ExpandedWinTracker v0.0.1

plugins/ExpandedWinTracker.Plugin.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
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: AssemblyCompany("ExpandedWinTracker.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: AssemblyInformationalVersion("0.0.1+04db90a217b61f64020e47044550e36ca413dff6")]
[assembly: AssemblyProduct("ExpandedWinTracker.Plugin")]
[assembly: AssemblyTitle("ExpandedWinTracker.Plugin")]
[assembly: AssemblyVersion("0.0.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 ExpandedWinTracker.Plugin
{
	internal class ConfigDescriptionBuilder
	{
		public string English { get; set; } = "";

		public string French { get; set; } = "";

		public string German { get; set; } = "";

		public string Russian { get; set; } = "";

		public string Portuguese { get; set; } = "";

		public string Chinese { get; set; } = "";

		public string Spanish { get; set; } = "";

		public string ChineseTraditional { get; set; } = "";

		public string Korean { get; set; } = "";

		public string Japanese { get; set; } = "";

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (!string.IsNullOrEmpty(English))
			{
				stringBuilder.AppendLine(English);
			}
			if (!string.IsNullOrEmpty(French))
			{
				stringBuilder.AppendLine(French);
			}
			if (!string.IsNullOrEmpty(German))
			{
				stringBuilder.AppendLine(German);
			}
			if (!string.IsNullOrEmpty(Russian))
			{
				stringBuilder.AppendLine(Russian);
			}
			if (!string.IsNullOrEmpty(Portuguese))
			{
				stringBuilder.AppendLine(Portuguese);
			}
			if (!string.IsNullOrEmpty(Chinese))
			{
				stringBuilder.AppendLine(Chinese);
			}
			if (!string.IsNullOrEmpty(Spanish))
			{
				stringBuilder.AppendLine(Spanish);
			}
			if (!string.IsNullOrEmpty(ChineseTraditional))
			{
				stringBuilder.AppendLine(ChineseTraditional);
			}
			if (!string.IsNullOrEmpty(Korean))
			{
				stringBuilder.AppendLine(Korean);
			}
			if (!string.IsNullOrEmpty(Japanese))
			{
				stringBuilder.AppendLine(Japanese);
			}
			return stringBuilder.ToString().TrimEnd();
		}
	}
	[Serializable]
	public sealed class SoulSaviorClassCombination
	{
		[JsonProperty("classID")]
		public string ClassID { get; set; } = "";

		[JsonProperty("subclassID")]
		public string SubclassID { get; set; } = "";

		[JsonProperty("championIndex")]
		public int ChampionIndex { get; set; }

		[JsonProperty("highestGameLevel")]
		public int HighestGameLevel { get; set; }
	}
	[Serializable]
	public class SoulSaviorSoulWin
	{
		[JsonProperty("name")]
		public string Name { get; set; } = "";

		[JsonProperty("tier")]
		public int Tier { get; set; }

		[JsonProperty("highestGameLevel")]
		public int HighestGameLevel { get; set; }
	}
	[Serializable]
	public class ExtraMetagameSaveData
	{
		[JsonProperty("soulSaviorClassWins")]
		public List<SoulSaviorClassCombination> SoulSaviorClassWins { get; set; } = new List<SoulSaviorClassCombination>();

		[JsonProperty("soulWins")]
		public List<SoulSaviorSoulWin> SoulWins { get; set; } = new List<SoulSaviorSoulWin>();
	}
	[BepInPlugin("ExpandedWinTracker.Plugin", "ExpandedWinTracker.Plugin", "0.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger = new ManualLogSource("ExpandedWinTracker.Plugin");

		public static ConfigEntry<bool>? soulSaviorWinTracker;

		public static ConfigEntry<bool>? scanRunHistory;

		public static ExtraMetagameSaveData SaveData = new ExtraMetagameSaveData();

		public static string SaveFilePath = string.Empty;

		public static string ModConfigDir = string.Empty;

		public void Awake()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			ModConfigDir = Path.Combine(Paths.ConfigPath, "ExpandedWinTracker.Plugin");
			SaveFilePath = Path.Combine(ModConfigDir, "extraMetagameSave.json");
			ReadSaveData();
			scanRunHistory = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "Scan Run History", true, new ConfigDescription(new ConfigDescriptionBuilder
			{
				English = "Scan the Run History JSON to populate unrecorded wins. This option will re-set itself to false the next time the game is ran.",
				Chinese = ""
			}.ToString(), (AcceptableValueBase)null, Array.Empty<object>()));
			Logger.LogInfo((object)"Plugin ExpandedWinTracker.Plugin is loaded!");
			new Harmony("ExpandedWinTracker.Plugin").PatchAll();
		}

		public static void ReadSaveData()
		{
			CreateSaveDir();
			if (!File.Exists(SaveFilePath))
			{
				Logger.LogWarning((object)("No save data found at " + SaveFilePath));
				WriteSaveData();
				return;
			}
			ExtraMetagameSaveData extraMetagameSaveData = JsonConvert.DeserializeObject<ExtraMetagameSaveData>(File.ReadAllText(SaveFilePath));
			if (extraMetagameSaveData == null)
			{
				Logger.LogWarning((object)("Failed to read save data at " + SaveFilePath));
				extraMetagameSaveData = new ExtraMetagameSaveData();
			}
			SaveData = extraMetagameSaveData;
		}

		public static void CreateSaveDir()
		{
			if (!Directory.Exists(ModConfigDir))
			{
				Directory.CreateDirectory(ModConfigDir);
			}
		}

		public static void WriteSaveData()
		{
			CreateSaveDir();
			string contents = JsonConvert.SerializeObject((object)SaveData, (Formatting)1);
			Logger.LogDebug((object)("Writing to " + SaveFilePath));
			File.WriteAllText(SaveFilePath, contents);
		}

		internal static SoulSaviorSoulWin FindSoulWin(string name)
		{
			return SaveData.SoulWins.Find((SoulSaviorSoulWin x) => x.Name == name);
		}

		internal static void AddOrUpdateSoulWin(string name, int tier, int regionLevel)
		{
			SoulSaviorSoulWin soulSaviorSoulWin = FindSoulWin(name);
			if (soulSaviorSoulWin != null)
			{
				if (soulSaviorSoulWin.HighestGameLevel < regionLevel)
				{
					soulSaviorSoulWin.HighestGameLevel = regionLevel;
					Logger.LogInfo((object)$"Updated {name}({tier}) win to {regionLevel}");
				}
				if (soulSaviorSoulWin.Tier < tier)
				{
					soulSaviorSoulWin.Tier = tier;
					Logger.LogInfo((object)$"Updated {name} win to {tier} level");
				}
			}
			else
			{
				SaveData.SoulWins.Add(new SoulSaviorSoulWin
				{
					Name = name,
					Tier = tier,
					HighestGameLevel = regionLevel
				});
				Logger.LogInfo((object)$"Added {name}({tier}) win at {regionLevel}");
			}
		}

		internal static SoulSaviorClassCombination FindSoulSaviorWin(string classID, string subclassID, int championIndex)
		{
			return SaveData.SoulSaviorClassWins.Find((SoulSaviorClassCombination x) => x.ClassID == classID && x.SubclassID == subclassID && x.ChampionIndex == championIndex);
		}

		internal static void AddOrUpdateSoulSaviorWin(string classID, string subclassID, int championIndex, int regionLevel)
		{
			SoulSaviorClassCombination soulSaviorClassCombination = FindSoulSaviorWin(classID, subclassID, championIndex);
			if (soulSaviorClassCombination != null)
			{
				if (soulSaviorClassCombination.HighestGameLevel < regionLevel)
				{
					soulSaviorClassCombination.HighestGameLevel = regionLevel;
					Logger.LogInfo((object)$"Updated {classID}-({championIndex})/{subclassID} win to {regionLevel}");
				}
			}
			else
			{
				SaveData.SoulSaviorClassWins.Add(new SoulSaviorClassCombination
				{
					ClassID = classID,
					SubclassID = subclassID,
					ChampionIndex = championIndex,
					HighestGameLevel = regionLevel
				});
				Logger.LogInfo((object)$"Added {classID}-({championIndex})/{subclassID} win at {regionLevel}");
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ExpandedWinTracker.Plugin";

		public const string PLUGIN_NAME = "ExpandedWinTracker.Plugin";

		public const string PLUGIN_VERSION = "0.0.1";
	}
}
namespace ExpandedWinTracker.Plugin.patches
{
	[HarmonyPatch(typeof(RunHistoryDataJson), "InitUserAsync")]
	public static class RunHistoryDataJson_InitUserAsync_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(RunHistoryDataJson __instance, ref Task __result)
		{
			__result = AfterInit(__result, __instance);
		}

		private static async Task AfterInit(Task originalTask, RunHistoryDataJson instance)
		{
			await originalTask;
			if (Plugin.scanRunHistory.Value && AccessTools.Field(typeof(RunHistoryDataJson), "_runEntries").GetValue(instance) is List<RunEntry> runEntries)
			{
				ScanRunHistory(runEntries);
				Plugin.scanRunHistory.Value = false;
			}
		}

		private static void ScanRunHistory(List<RunEntry> runEntries)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			foreach (RunEntry runEntry in runEntries)
			{
				RunAggregateData run = runEntry.GetRun();
				Plugin.Logger.LogDebug((object)("Scanning run: " + runEntry.runId));
				if ((int)((BaseSaveData)run).GetRunTypeEnum() != 6 || !run.GetVictory())
				{
					continue;
				}
				IReadonly startingConditions = ((BaseSaveData)run).GetStartingConditions();
				string classId = startingConditions.ClassId;
				string subclassId = startingConditions.SubclassId;
				int mainChampionIndex = startingConditions.MainChampionIndex;
				int regionRunDifficultyTier = startingConditions.GetRegionRunDifficultyTier();
				Plugin.AddOrUpdateSoulSaviorWin(classId, subclassId, mainChampionIndex, regionRunDifficultyTier);
				foreach (SoulState soul in run.GetSouls())
				{
					int tierLevel = soul.TierLevel;
					string name = ((Object)soul.GetSoulData()).name;
					Plugin.AddOrUpdateSoulWin(name.Substring(0, name.Length - 2), tierLevel, regionRunDifficultyTier);
				}
			}
			Plugin.WriteSaveData();
		}
	}
	[HarmonyPatch(typeof(SaveManager), "TrackClassVictory")]
	public class TrackClassVictoryPatch
	{
		public static void Postfix(SaveManager __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			RunType runType = __instance.GetRunType();
			string iD = ((GameData)__instance.GetMainClass()).GetID();
			string iD2 = ((GameData)__instance.GetSubClass()).GetID();
			int mainChampionIndex = __instance.GetMainChampionIndex();
			int regionRunDifficultyTier = __instance.GetStartingConditions().GetRegionRunDifficultyTier();
			if ((int)runType == 6)
			{
				Plugin.AddOrUpdateSoulSaviorWin(iD, iD2, mainChampionIndex, regionRunDifficultyTier);
				foreach (SoulState selectedSoul in __instance.GetSelectedSouls())
				{
					string name = ((Object)selectedSoul.GetSoulData()).name;
					Plugin.AddOrUpdateSoulWin(name.Substring(0, name.Length - 2), selectedSoul.TierLevel, regionRunDifficultyTier);
				}
			}
			Plugin.WriteSaveData();
		}
	}
}