using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Events;
using Events.OptionsMenu;
using ProfileFixer.MonoBehaviors;
using ProfileFixer.Utils;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ProfileFixer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ProfileFixer")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2d8469ad-b4b8-484f-96f3-c5be348cf004")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace ProfileFixer
{
[BepInPlugin("com.Californ1a.ProfileFixer", "ProfileFixer", "1.1.0")]
public class ProfileFixerPlugin : BaseUnityPlugin
{
internal static bool isChecking = false;
public static string KeyComboKey = "Shortcut";
public static string MinFPSKey = "Min fps";
public static ConfigEntry<KeyboardShortcut> KeyCombo;
public static ConfigEntry<int> MinFPS;
internal static ManualLogSource Log;
private void Awake()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
Log = Logger.CreateLogSource("ProfileFixer");
KeyCode[] array = (KeyCode[])(object)new KeyCode[2]
{
(KeyCode)306,
(KeyCode)303
};
KeyCombo = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", KeyComboKey, new KeyboardShortcut((KeyCode)112, array), "Key combo to start the profile checker. By default is intentionally hard to press.");
MinFPS = ((BaseUnityPlugin)this).Config.Bind<int>("General", MinFPSKey, 100, new ConfigDescription("The minimum FPS to target while scanning local leaderboards", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), new object[0]));
KeyCombo.SettingChanged += ConfigSettingChanged;
MinFPS.SettingChanged += ConfigSettingChanged;
Log.LogInfo((object)"Loaded");
}
private void RunProfileChecker()
{
if (!isChecking && GameManager.IsInMainMenuScene_)
{
ProfileProgress currentProfileProgress_ = G.Sys.ProfileManager_.CurrentProfileProgress_;
isChecking = true;
Ask.UseAchievements(currentProfileProgress_);
}
}
private void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
KeyboardShortcut value = KeyCombo.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
RunProfileChecker();
}
}
private void ConfigSettingChanged(object sender, EventArgs e)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
if (val != null)
{
if (val.ChangedSetting.Definition.Key == MinFPSKey)
{
int num = (int)val.ChangedSetting.BoxedValue;
}
if (val.ChangedSetting.Definition.Key == KeyComboKey)
{
KeyboardShortcut val2 = (KeyboardShortcut)val.ChangedSetting.BoxedValue;
}
}
}
}
}
namespace ProfileFixer.Utils
{
internal static class Ask
{
internal static void TOS(ProfileProgress progress)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0041: Expected O, but got Unknown
G.Sys.MenuPanelManager_.ShowYesNo("Restore The Other Side?\n\n(Requires having The Other Side achievement)", "The Other Side", (OnButtonClicked)delegate
{
if (G.Sys.Achievements_.HasAchieved((EAchievements)30))
{
Unlock.TOS(progress);
}
else
{
ProfileFixerPlugin.Log.LogInfo((object)"Player does not have The Other Side achievement.");
}
LBCheck.Check(progress);
}, (OnButtonClicked)delegate
{
LBCheck.Check(progress);
}, false, (Pivot)4);
}
internal static void Nexus(ProfileProgress progress)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0041: Expected O, but got Unknown
G.Sys.MenuPanelManager_.ShowYesNo("Restore Nexus?\n\n(No achievement required)", "Nexus", (OnButtonClicked)delegate
{
Unlock.Nexus(progress);
TOS(progress);
}, (OnButtonClicked)delegate
{
TOS(progress);
}, false, (Pivot)4);
}
internal static void LtE(ProfileProgress progress)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0041: Expected O, but got Unknown
G.Sys.MenuPanelManager_.ShowYesNo("Restore Lost to Echoes?\n\n(Requires having the Blast from the Past achievement)", "Lost to Echoes", (OnButtonClicked)delegate
{
if (G.Sys.Achievements_.HasAchieved((EAchievements)28))
{
Unlock.LtE(progress);
}
else
{
ProfileFixerPlugin.Log.LogInfo((object)"Player does not have the Blast from the Past achievement.");
}
Nexus(progress);
}, (OnButtonClicked)delegate
{
Nexus(progress);
}, false, (Pivot)4);
}
internal static void Adventure(ProfileProgress progress)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0041: Expected O, but got Unknown
G.Sys.MenuPanelManager_.ShowYesNo("Restore Adventure?\n\n(Requires having the Adventurer achievement)", "Adventure", (OnButtonClicked)delegate
{
if (G.Sys.Achievements_.HasAchieved((EAchievements)4))
{
Unlock.Adventure(progress);
}
else
{
ProfileFixerPlugin.Log.LogInfo((object)"Player does not have the Adventurer achievement.");
}
LtE(progress);
}, (OnButtonClicked)delegate
{
LtE(progress);
}, false, (Pivot)4);
}
internal static void UseAchievements(ProfileProgress progress)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0041: Expected O, but got Unknown
G.Sys.MenuPanelManager_.ShowYesNo("Use achievements to automatically restore campaigns?", "Use Achievements?", (OnButtonClicked)delegate
{
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: 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_00b8: Invalid comparison between Unknown and I4
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Invalid comparison between Unknown and I4
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Invalid comparison between Unknown and I4
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Invalid comparison between Unknown and I4
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Invalid comparison between Unknown and I4
bool flag = G.Sys.Achievements_.HasAchieved((EAchievements)4);
bool flag2 = G.Sys.Achievements_.HasAchieved((EAchievements)28);
bool flag3 = G.Sys.Achievements_.HasAchieved((EAchievements)30);
if (flag)
{
Unlock.Adventure(progress);
}
if (flag2)
{
Unlock.LtE(progress);
}
if (flag3)
{
Unlock.TOS(progress);
}
LevelSet nexusSet = G.Sys.LevelSets_.GetNexusSet();
List<LevelNameAndPathPair> allLevelNameAndPathPairs = nexusSet.GetAllLevelNameAndPathPairs();
bool flag4 = false;
foreach (LevelNameAndPathPair item in allLevelNameAndPathPairs)
{
MedalStatus medalStatusBasedOnLeaderboard = Status.GetMedalStatusBasedOnLeaderboard(item.levelPath_, (GameModeID)1);
if ((int)medalStatusBasedOnLeaderboard == 2 || (int)medalStatusBasedOnLeaderboard == 3 || (int)medalStatusBasedOnLeaderboard == 4 || (int)medalStatusBasedOnLeaderboard == 5 || (int)medalStatusBasedOnLeaderboard == 6)
{
flag4 = true;
break;
}
}
if (flag4)
{
Unlock.Nexus(progress);
}
LBCheck.Check(progress);
}, (OnButtonClicked)delegate
{
Adventure(progress);
}, false, (Pivot)4);
}
}
internal static class Unlock
{
private static void Set(LevelSet levelSet, GameModeID gameModeID, ProfileProgress progress)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
List<LevelNameAndPathPair> allLevelNameAndPathPairs = levelSet.GetAllLevelNameAndPathPairs();
foreach (LevelNameAndPathPair item in allLevelNameAndPathPairs)
{
progress.UpdateMedal(item.levelPath_, DateTime.Now, gameModeID, (MedalStatus)2);
}
}
internal static void Adventure(ProfileProgress progress)
{
LevelSet adventureSet = G.Sys.LevelSets_.GetAdventureSet();
Set(adventureSet, (GameModeID)9, progress);
}
internal static void LtE(ProfileProgress progress)
{
LevelSet echoesModeFinalSet = G.Sys.LevelSets_.GetEchoesModeFinalSet();
Set(echoesModeFinalSet, (GameModeID)14, progress);
}
internal static void Nexus(ProfileProgress progress)
{
LevelSet nexusSet = G.Sys.LevelSets_.GetNexusSet();
Set(nexusSet, (GameModeID)15, progress);
}
internal static void TOS(ProfileProgress progress)
{
for (int i = 0; i < 8; i++)
{
progress.SetCrabAsFound(i);
}
LevelSet theOtherSideSet = G.Sys.LevelSets_.GetTheOtherSideSet();
Set(theOtherSideSet, (GameModeID)16, progress);
}
}
internal class LBCheck
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static OnButtonClicked <>9__0_2;
internal void <Check>b__0_2()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
int index_ = G.Sys.ProfileManager_.CurrentProfile_.Index_;
G.Sys.ProfileManager_.SetDefaultLocalProfileIndexAndCreatePlayer(index_);
bool flag = false;
G.Sys.GameManager_.GoToMainMenu((OpenOnMainMenuInit)0);
StaticEvent<Data>.Broadcast(new Data(flag));
ProfileFixerPlugin.isChecking = false;
ProfileFixerPlugin.Log.LogInfo((object)"Profile Fixer complete");
}
}
internal static void Check(ProfileProgress progress)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
G.Sys.MenuPanelManager_.ShowError("This will now check local leaderboard files for matching profile name and attempt to restore obtained medals.\n\nIt may take a while, just wait.", "Check Local Leaderboards", (OnButtonClicked)delegate
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
ProfileFixerPlugin.Log.LogInfo((object)"Checking profile...");
G.Sys.MenuPanelManager_.MenuInputEnabled_ = false;
GameObject progressBarObject = new GameObject("LBProgressBarObject");
LBProgressBar lBProgressBar = progressBarObject.AddComponent<LBProgressBar>();
ProfileFixerPlugin.Log.LogInfo((object)"Initialized");
GameObject loadingGameObject = Resource.LoadPrefabInstance("SteamWorkshopLoadingText", true);
SteamWorkshopLoadingText component = loadingGameObject.GetComponent<SteamWorkshopLoadingText>();
lBProgressBar.StartProcessing(progress, component, delegate
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
Object.Destroy((Object)(object)loadingGameObject);
G.Sys.MenuPanelManager_.MenuInputEnabled_ = true;
ProfileFixerPlugin.Log.LogInfo((object)"Done profile check");
MenuPanelManager menuPanelManager_ = G.Sys.MenuPanelManager_;
object obj = <>c.<>9__0_2;
if (obj == null)
{
OnButtonClicked val = delegate
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
int index_ = G.Sys.ProfileManager_.CurrentProfile_.Index_;
G.Sys.ProfileManager_.SetDefaultLocalProfileIndexAndCreatePlayer(index_);
bool flag = false;
G.Sys.GameManager_.GoToMainMenu((OpenOnMainMenuInit)0);
StaticEvent<Data>.Broadcast(new Data(flag));
ProfileFixerPlugin.isChecking = false;
ProfileFixerPlugin.Log.LogInfo((object)"Profile Fixer complete");
};
<>c.<>9__0_2 = val;
obj = (object)val;
}
menuPanelManager_.ShowError("Done checking local leaderboard files for missing medals.\n\nYour profile will be reloaded now.", "Profile Progress Restored", (OnButtonClicked)obj, (Pivot)4);
Object.Destroy((Object)(object)progressBarObject);
});
}, (Pivot)4);
}
}
internal static class Status
{
internal static MedalStatus GetMedalStatusBasedOnLeaderboard(string levelPath, GameModeID modeID)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
MedalStatus result = (MedalStatus)0;
Profile currentProfile_ = G.Sys.ProfileManager_.CurrentProfile_;
LevelInfo levelInfo = G.Sys.LevelSets_.GetLevelInfo(levelPath);
List<ResultInfo> list = null;
LocalLeaderboard val = LocalLeaderboard.Load(levelPath, modeID);
if ((Object)(object)val != (Object)null)
{
list = new List<ResultInfo>(val.Results_);
}
if (list != null && list.Count > 0)
{
bool flag = false;
if (GameModeIDEx.IsTimeBased(modeID))
{
int num = int.MaxValue;
foreach (ResultInfo item in list)
{
if (item.ProfileID_ == currentProfile_.ProfileID_ || item.ProfileName_ == currentProfile_.Name_)
{
flag = true;
if (item.Value_ < num)
{
num = item.Value_;
}
}
}
if (flag)
{
result = GameMode.EvaluateMedalStatus(modeID, levelInfo, (double)num);
}
}
else if (GameModeIDEx.IsPointsBased(modeID))
{
int num2 = -2;
foreach (ResultInfo item2 in list)
{
if (item2.ProfileID_ == currentProfile_.ProfileID_ || item2.ProfileName_ == currentProfile_.Name_)
{
flag = true;
if (item2.Value_ > num2)
{
num2 = item2.Value_;
}
}
}
if (flag)
{
result = GameMode.EvaluateMedalStatus(modeID, levelInfo, (double)num2);
}
}
}
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)((Component)val).gameObject);
}
return result;
}
}
}
namespace ProfileFixer.Properties
{
internal class ModInfo
{
public const string MyGUID = "com.Californ1a.ProfileFixer";
public const string PluginName = "ProfileFixer";
public const string Version = "1.1.0";
}
}
namespace ProfileFixer.MonoBehaviors
{
public class LBProgressBar : MonoBehaviour
{
private Action onProcessComplete;
private GameManager gameManager;
private List<string> levelPathsList;
private MethodInfo updateMedalStatus;
private ProfileProgress progress;
private SteamWorkshopLoadingText progressText;
private int currentIndex = 0;
private int total = 0;
private int maxChecksPerFrame = 200;
private float targetFrameRate = 60f;
private float minFrameTime = 1f / (float)ProfileFixerPlugin.MinFPS.Value;
private int maxChecksIncrement = 20;
private float decreaseRate = 0.1f;
public void StartProcessing(ProfileProgress progress, SteamWorkshopLoadingText progressText, Action onProcessComplete)
{
ProfileFixerPlugin.Log.LogInfo((object)"StartProcessing");
this.onProcessComplete = onProcessComplete;
this.progress = progress;
this.progressText = progressText;
this.progressText.steamWorkshopProgressTextLabel_.text = "Loading...";
this.progressText.steamWorkshopProgressBar_.value = 0f;
gameManager = G.Sys.GameManager_;
LevelSetsManager levelSets_ = G.Sys.LevelSets_;
updateMedalStatus = ((object)this.progress).GetType().GetMethod("UpdateMedalStatusBasedOnLeaderboard", BindingFlags.Instance | BindingFlags.NonPublic);
levelPathsList = new List<string>(levelSets_.AllLevelPaths_);
ProfileFixerPlugin.Log.LogInfo((object)("ModeIDs count: " + gameManager.ModeIDs_.Count));
ProfileFixerPlugin.Log.LogInfo((object)("LevelPaths count: " + levelPathsList.Count));
total = gameManager.ModeIDs_.Count * levelPathsList.Count;
((MonoBehaviour)this).StartCoroutine(ProcessMedalStatus());
}
private string GetNewLabel(int index, int count)
{
string text = "\n[c][AAAAAA]Checking leaderboards...[-][/c]";
string text2 = string.Concat(new object[4]
{
"Progress ",
(index + 1).ToString("N0"),
" / ",
count.ToString("N0")
});
int num = (int)((float)index / (float)count * 100f);
return text2 + " : " + num + "%[-][/c]" + text;
}
private void UpdateProgress(float value, string labelText)
{
progressText.steamWorkshopProgressBar_.value = value;
progressText.steamWorkshopProgressTextLabel_.text = labelText;
}
private IEnumerator ProcessMedalStatus()
{
ProfileFixerPlugin.Log.LogInfo((object)"ProcessMedalStatus");
while (currentIndex < total)
{
float frameStartTime = Time.realtimeSinceStartup;
for (int checksThisFrame = 0; checksThisFrame < maxChecksPerFrame; checksThisFrame++)
{
if (currentIndex >= total)
{
break;
}
GameModeID modeID = gameManager.ModeIDs_[currentIndex / levelPathsList.Count];
string levelPath = levelPathsList[currentIndex % levelPathsList.Count];
object[] methodParams = new object[2] { levelPath, modeID };
updateMedalStatus.Invoke(progress, methodParams);
float progressValue = (float)(currentIndex + 1) / (float)total;
UpdateProgress(progressValue, GetNewLabel(currentIndex + 1, total));
currentIndex++;
}
float frameTime = Time.realtimeSinceStartup - frameStartTime;
if (frameTime < minFrameTime)
{
maxChecksPerFrame += maxChecksIncrement;
}
else if (frameTime > 1f / targetFrameRate && maxChecksPerFrame > 1)
{
maxChecksPerFrame -= maxChecksIncrement;
}
if (maxChecksIncrement > 1)
{
maxChecksIncrement = Mathf.Max(1, Mathf.RoundToInt((float)maxChecksIncrement * (1f - decreaseRate)));
}
yield return null;
}
progress.UpdateUnlockedLevels();
progress.Save();
onProcessComplete?.Invoke();
}
}
}