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();
}
}
}