using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("ProfileSwitcher")]
[assembly: AssemblyTitle("ProfileSwitcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[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;
}
}
}
[BepInPlugin("sparroh.profileswitcher", "ProfileSwitcher", "1.0.1")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class ProfileSwitcherPlugin : BaseUnityPlugin
{
public const string PluginGUID = "sparroh.profileswitcher";
public const string PluginName = "ProfileSwitcher";
public const string PluginVersion = "1.0.1";
internal static ManualLogSource Log;
private Harmony _harmony;
private void Awake()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
_harmony = new Harmony("sparroh.profileswitcher");
_harmony.PatchAll(typeof(StartMenuProfilePatches));
Log.LogInfo((object)"ProfileSwitcher v1.0.1 loaded — profiles can be swapped from the main menu without restarting.");
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
internal static class ProfileReloader
{
private static readonly FieldInfo InstanceField = AccessTools.Field(typeof(PlayerData), "_instance");
private static readonly FieldInfo SavePathField = AccessTools.Field(typeof(PlayerData), "savePath");
private static readonly FieldInfo BinaryFormatterField = AccessTools.Field(typeof(PlayerData), "binaryFormatter");
private static readonly FieldInfo ProfileIndexField = AccessTools.Field(typeof(ProfileConfig), "profileIndex");
private static readonly MethodInfo TryLoadSaveMethod = AccessTools.Method(typeof(PlayerData), "TryLoadSave", (Type[])null, (Type[])null);
private static readonly MethodInfo OnCreatedMethod = AccessTools.Method(typeof(PlayerData), "OnCreated", (Type[])null, (Type[])null);
private static readonly MethodInfo InitializeMethod = AccessTools.Method(typeof(PlayerData), "Initialize", (Type[])null, (Type[])null);
private static readonly MethodInfo PlayerLevelMethod = AccessTools.Method(typeof(PlayerData), "GetPlayerLevel", Type.EmptyTypes, (Type[])null);
private static readonly FieldInfo InWorldUpgradesField = AccessTools.Field(typeof(PlayerData), "inWorldUpgrades");
private static readonly FieldInfo FloatingInstancesField = AccessTools.Field(typeof(PlayerData), "floatingInstances");
private static readonly FieldInfo RecentUnchosenField = AccessTools.Field(typeof(PlayerData), "recentUnchosenUpgrades");
private static readonly FieldInfo DamagePropertiesField = AccessTools.Field(typeof(PlayerData), "damageProperties");
private static readonly FieldInfo KillPropertiesField = AccessTools.Field(typeof(PlayerData), "killProperties");
private static readonly FieldInfo MissionPropertiesField = AccessTools.Field(typeof(PlayerData), "missionProperties");
private static readonly FieldInfo FixedUpdatePropertiesField = AccessTools.Field(typeof(PlayerData), "fixedUpdateProperties");
private static readonly FieldInfo DiePropertiesField = AccessTools.Field(typeof(PlayerData), "dieProperties");
private static readonly FieldInfo OuroPropertiesField = AccessTools.Field(typeof(PlayerData), "ouroProperties");
private static readonly FieldInfo ActiveDefaultDirectiveField = AccessTools.Field(typeof(PlayerData), "activeDefaultDirective");
private static readonly FieldInfo TaskObjectiveField = AccessTools.Field(typeof(PlayerData), "taskObjective");
private static readonly FieldInfo ProfileNameField = AccessTools.Field(typeof(PlayerData), "profile");
private static readonly FieldInfo DataField = AccessTools.Field(typeof(PlayerData), "data");
private static readonly FieldInfo InvalidUpgradesField = AccessTools.Field(typeof(PlayerData), "invalidUpgrades");
private static readonly FieldInfo DiscoveredModifiersField = AccessTools.Field(typeof(PlayerData), "discoveredModifiers");
private static readonly MethodInfo MergeUpgradeListsMethod = AccessTools.Method(typeof(PlayerData), "MergeUpgradeLists", (Type[])null, (Type[])null);
private static readonly MethodInfo GiveMissingGunTokensMethod = AccessTools.Method(typeof(PlayerData), "GiveMissingGunTokens", (Type[])null, (Type[])null);
private static readonly MethodInfo QueryUpgradesMethod = AccessTools.Method(typeof(PlayerData), "QueryUpgrades", (Type[])null, (Type[])null);
private static readonly FieldInfo OnResourcesUpdatedField = AccessTools.DeclaredField(typeof(PlayerData), "OnResourcesUpdated");
private static readonly FieldInfo OnXPAddedField = AccessTools.DeclaredField(typeof(PlayerData), "OnXPAdded");
private static readonly FieldInfo OnUpgradeCollectedOrDestroyedField = AccessTools.DeclaredField(typeof(PlayerData), "OnUpgradeCollectedOrDestroyed");
internal static int GetCurrentProfileIndex()
{
ProfileConfig instance = ProfileConfig.Instance;
if (instance == null || ProfileIndexField == null)
{
return 0;
}
return (int)ProfileIndexField.GetValue(instance);
}
public static bool TrySwapProfile(int newIndex, out string error)
{
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Expected O, but got Unknown
error = null;
if (InstanceField == null || SavePathField == null || TryLoadSaveMethod == null || InitializeMethod == null || ProfileIndexField == null)
{
error = "Could not access required PlayerData internals. The game may have updated.";
return false;
}
ProfileConfig instance = ProfileConfig.Instance;
if (instance == null)
{
error = "Profile configuration is missing.";
return false;
}
int num = (int)ProfileIndexField.GetValue(instance);
PlayerData instance2 = PlayerData.Instance;
string text = SavePathField.GetValue(null) as string;
try
{
UpdateProfileLevelMetadata(num);
PlayerData.SaveData(false);
SaveProfileConfig();
instance.SetProfile(newIndex);
SaveProfileConfig();
string text2 = BuildSavePathForCurrentProfile();
SavePathField.SetValue(null, text2);
string text3 = text2 + "/PlayerData.saxon";
object[] array = new object[2] { text3, null };
int num2 = (int)TryLoadSaveMethod.Invoke(null, array);
object obj = array[1];
PlayerData val = (PlayerData)((obj is PlayerData) ? obj : null);
if (num2 != 0 || val == null)
{
string path = text2 + "/Backups";
if (Directory.Exists(path))
{
string[] files = Directory.GetFiles(path);
Array.Sort(files);
for (int num3 = files.Length - 1; num3 >= 0; num3--)
{
array[0] = files[num3];
array[1] = null;
num2 = (int)TryLoadSaveMethod.Invoke(null, array);
object obj2 = array[1];
val = (PlayerData)((obj2 is PlayerData) ? obj2 : null);
if (num2 == 0 && val != null)
{
break;
}
}
}
}
if (num2 != 0 || val == null)
{
ProfileSwitcherPlugin.Log.LogInfo((object)$"No existing save for profile {newIndex}; creating a new PlayerData instance.");
val = new PlayerData();
OnCreatedMethod?.Invoke(val, null);
}
ClearStaticRuntimeCaches();
RemovePlayerDataEventHandlers(instance2);
ResetProcessLifetimeCounters();
InstanceField.SetValue(null, val);
int gameLaunchCount = val.gameLaunchCount;
InitializeMethod.Invoke(val, null);
val.gameLaunchCount = gameLaunchCount;
RebindGearAndFinalize(val);
ProfileNameField?.SetValue(val, GetSteamBranchFolderName());
UpdateProfileLevelMetadata(newIndex);
SaveProfileConfig();
return true;
}
catch (Exception ex)
{
error = ex.Message;
ProfileSwitcherPlugin.Log.LogError((object)ex);
try
{
if (instance2 != null)
{
InstanceField.SetValue(null, instance2);
}
if (text != null)
{
SavePathField.SetValue(null, text);
}
instance.SetProfile(num);
SaveProfileConfig();
}
catch (Exception arg)
{
ProfileSwitcherPlugin.Log.LogError((object)$"Rollback after failed swap also failed: {arg}");
}
return false;
}
}
private static void UpdateProfileLevelMetadata(int index)
{
try
{
if (index >= 1)
{
int level = 1;
if (PlayerLevelMethod != null && PlayerData.Instance != null)
{
level = (int)PlayerLevelMethod.Invoke(null, null);
}
ProfileConfig.Instance.GetProfile(index).Level = level;
}
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("Could not update profile level metadata: " + ex.Message));
}
}
private static string GetSteamBranchFolderName()
{
string text = default(string);
if (SteamManager.Initialized && Online.GetProfileName(ref text) && !string.IsNullOrEmpty(text))
{
return text;
}
return "default";
}
private static string BuildSavePathForCurrentProfile()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
string text = Application.persistentDataPath + "/Profiles/" + GetSteamBranchFolderName();
string name = ProfileConfig.Instance.CurrentProfile.Name;
if (!string.IsNullOrEmpty(name))
{
return text + "/" + name;
}
return text;
}
private static void SaveProfileConfig()
{
try
{
if (ProfileConfig.Instance == null || string.IsNullOrEmpty(ProfileConfig.SavePath))
{
return;
}
BinaryFormatter binaryFormatter = (BinaryFormatterField?.GetValue(null) as BinaryFormatter) ?? new BinaryFormatter();
string directoryName = Path.GetDirectoryName(ProfileConfig.SavePath);
if (!string.IsNullOrEmpty(directoryName))
{
Directory.CreateDirectory(directoryName);
}
using FileStream serializationStream = new FileStream(ProfileConfig.SavePath, FileMode.Create);
binaryFormatter.Serialize(serializationStream, ProfileConfig.Instance);
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogWarning((object)("Failed to save Profiles.poop: " + ex.Message));
}
}
private static void ClearStaticRuntimeCaches()
{
ClearListField(InWorldUpgradesField);
ClearDictionaryField(FloatingInstancesField);
ClearListField(RecentUnchosenField);
ClearListField(DamagePropertiesField);
ClearListField(KillPropertiesField);
ClearListField(MissionPropertiesField);
ClearListField(FixedUpdatePropertiesField);
ClearListField(DiePropertiesField);
ClearListField(OuroPropertiesField);
ActiveDefaultDirectiveField?.SetValue(null, null);
TaskObjectiveField?.SetValue(null, null);
}
private static void RemovePlayerDataEventHandlers(PlayerData oldInstance)
{
if (oldInstance != null)
{
RemoveHandlersTargeting(OnResourcesUpdatedField, oldInstance);
RemoveHandlersTargeting(OnXPAddedField, oldInstance);
RemoveHandlersTargeting(OnUpgradeCollectedOrDestroyedField, oldInstance);
}
}
private static void RemoveHandlersTargeting(FieldInfo eventField, object oldTarget)
{
if (eventField == null)
{
return;
}
try
{
if (!(eventField.GetValue(null) is Delegate obj) || (object)obj == null)
{
return;
}
Delegate obj2 = null;
Delegate[] invocationList = obj.GetInvocationList();
foreach (Delegate obj3 in invocationList)
{
if (obj3.Target != oldTarget)
{
obj2 = (((object)obj2 == null) ? obj3 : Delegate.Combine(obj2, obj3));
}
}
eventField.SetValue(null, obj2);
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("Could not prune event field " + eventField.Name + ": " + ex.Message));
}
}
private static void ResetProcessLifetimeCounters()
{
PlayerData.goobers = 0;
PlayerData.hoops = 0;
PlayerData.tempSaxitosPunchedCounter = 0;
}
private static void ClearListField(FieldInfo field)
{
if (!(field == null) && field.GetValue(null) is IList list)
{
list.Clear();
}
}
private static void ClearDictionaryField(FieldInfo field)
{
if (!(field == null) && field.GetValue(null) is IDictionary dictionary)
{
dictionary.Clear();
}
}
private static void RebindGearAndFinalize(PlayerData instance)
{
if ((Object)(object)Global.Instance == (Object)null)
{
ProfileSwitcherPlugin.Log.LogWarning((object)"Global.Instance is null during profile rebind; gear refs may be incomplete until next scene.");
return;
}
for (int i = 0; i < Global.Instance.AllGear.Length; i++)
{
AddGear(Global.Instance.AllGear[i]);
}
for (int j = 0; j < Global.Instance.Characters.Length; j++)
{
AddGear((IUpgradable)(object)Global.Instance.Characters[j]);
}
AddGear((IUpgradable)(object)Global.Instance);
RepairInvalidAndNullUpgrades(instance);
try
{
MergeUpgradeListsMethod?.Invoke(instance, null);
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("MergeUpgradeLists: " + ex.Message));
}
List<int> list = null;
foreach (KeyValuePair<int, GearData> item in instance.collectedGear)
{
if (item.Value.Gear == null)
{
if (list == null)
{
list = new List<int>();
}
list.Add(item.Key);
}
else
{
try
{
item.Value.DeepCleanup();
}
catch (Exception ex2)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("DeepCleanup: " + ex2.Message));
}
}
}
if (list != null)
{
for (int k = 0; k < list.Count; k++)
{
instance.collectedGear.Remove(list[k]);
}
}
foreach (KeyValuePair<int, GearData> item2 in instance.collectedGear)
{
try
{
IUpgradable gear = item2.Value.Gear;
if (gear != null)
{
gear.InitializeOnLoad();
}
item2.Value.RestoreSavedUpgrades(true);
}
catch (Exception ex3)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("InitializeOnLoad/RestoreSavedUpgrades: " + ex3.Message));
}
}
try
{
if (instance.GetFlag("mxp") == 0)
{
instance.SetFlag("mxp", 1);
foreach (KeyValuePair<int, GearData> item3 in instance.collectedGear)
{
try
{
item3.Value.GiveMissedXP();
}
catch (Exception ex4)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("GiveMissedXP: " + ex4.Message));
}
}
}
if (instance.GetFlag("freeupgrades") <= 0 && QueryUpgradesMethod != null)
{
instance.SetFlag("freeupgrades", 1);
QueryUpgradesMethod.Invoke(null, new object[1] { (Action<UpgradeInstance>)delegate(UpgradeInstance upgrade)
{
try
{
upgrade.UnlockIfFree();
}
catch (Exception ex7)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("UnlockIfFree: " + ex7.Message));
}
} });
}
}
catch (Exception ex5)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("OnAwake one-shot fixes skipped: " + ex5.Message));
}
ScrubInvalidDiscoveredModifiers(instance);
try
{
GiveMissingGunTokensMethod?.Invoke(null, null);
}
catch (Exception ex6)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("GiveMissingGunTokens: " + ex6.Message));
}
void AddGear(IUpgradable val)
{
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Invalid comparison between Unknown and I4
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Invalid comparison between Unknown and I4
if (!((Object)(object)((val != null) ? val.Info : null) == (Object)null))
{
if (instance.collectedGear.TryGetValue(val.Info.ID, out var value))
{
value.Gear = val;
if ((int)val.Info.UnlockState >= 1 && !value.IsCollected)
{
value.Collect();
}
if ((int)val.Info.UnlockState == 2 && !value.IsUnlocked)
{
value.Unlock();
}
}
else
{
instance.collectedGear.Add(val.Info.ID, new GearData(val, val.Info.UnlockState));
}
}
}
}
private static void RepairInvalidAndNullUpgrades(PlayerData instance)
{
if (DataField == null || InvalidUpgradesField == null)
{
return;
}
try
{
IDictionary dictionary = DataField.GetValue(instance) as IDictionary;
IList list = InvalidUpgradesField.GetValue(instance) as IList;
if (dictionary == null || list == null)
{
return;
}
Type type = null;
if (InvalidUpgradesField.FieldType.IsGenericType)
{
type = InvalidUpgradesField.FieldType.GetGenericArguments()[0];
}
FieldInfo fieldInfo = type?.GetField("info", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo fieldInfo2 = type?.GetField("gearID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (fieldInfo == null || fieldInfo2 == null)
{
return;
}
PropertyInfo property = typeof(UpgradeInfo).GetProperty("Upgrade", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PropertyInfo property2 = typeof(UpgradeInfo).GetProperty("SourceID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int num = list.Count - 1; num >= 0; num--)
{
object obj = list[num];
if (obj == null)
{
list.RemoveAt(num);
}
else
{
object value = fieldInfo.GetValue(obj);
if (value == null)
{
list.RemoveAt(num);
}
else
{
object? obj2 = property?.GetValue(value);
int num2 = (int)fieldInfo2.GetValue(obj);
if (obj2 != null && dictionary.Contains(num2) && dictionary[num2] is IList list2)
{
object obj3 = property2?.GetValue(value);
bool flag = false;
for (int i = 0; i < list2.Count; i++)
{
object obj4 = list2[i];
if (obj4 != null)
{
object obj5 = property2?.GetValue(obj4);
if (obj3 != null && obj5 != null && obj3.Equals(obj5))
{
flag = true;
break;
}
}
}
if (!flag)
{
list2.Add(value);
}
list.RemoveAt(num);
}
}
}
}
ArrayList arrayList = new ArrayList();
foreach (object key in dictionary.Keys)
{
arrayList.Add(key);
}
FieldInfo field = typeof(UpgradeID).GetField("Mod", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (object item in arrayList)
{
if (!(dictionary[item] is IList list3))
{
continue;
}
for (int num3 = list3.Count - 1; num3 >= 0; num3--)
{
object obj6 = list3[num3];
if (obj6 == null)
{
list3.RemoveAt(num3);
}
else if (property?.GetValue(obj6) == null)
{
object obj7 = property2?.GetValue(obj6);
string value2 = null;
if (obj7 != null && field != null)
{
value2 = field.GetValue(obj7) as string;
}
if (!string.IsNullOrEmpty(value2) && type != null)
{
for (int num4 = list.Count - 1; num4 >= 0; num4--)
{
object obj8 = list[num4];
if (obj8 != null && object.Equals(fieldInfo2.GetValue(obj8), item))
{
object value3 = fieldInfo.GetValue(obj8);
object obj9 = ((value3 == null) ? null : property2?.GetValue(value3));
if (obj7 != null && obj9 != null && obj7.Equals(obj9))
{
list.RemoveAt(num4);
}
}
}
object obj10 = Activator.CreateInstance(type);
fieldInfo.SetValue(obj10, obj6);
fieldInfo2.SetValue(obj10, item);
list.Add(obj10);
}
list3.RemoveAt(num3);
}
}
}
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("RepairInvalidAndNullUpgrades: " + ex.Message));
}
}
private static void ScrubInvalidDiscoveredModifiers(PlayerData instance)
{
if (DiscoveredModifiersField == null)
{
return;
}
try
{
if (!(DiscoveredModifiersField.GetValue(instance) is IDictionary { Count: not 0 } dictionary))
{
return;
}
MethodInfo method = typeof(UpgradeID).GetMethod("IsValid", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
object obj = Activator.CreateInstance(typeof(UpgradeID));
bool flag = false;
foreach (object key in dictionary.Keys)
{
if (key == null || key.Equals(obj))
{
flag = true;
break;
}
if (method != null && !(bool)method.Invoke(key, null))
{
flag = true;
break;
}
}
if (!flag)
{
return;
}
IDictionary dictionary2;
try
{
Type type = AccessTools.TypeByName("UpgradeIDComparer");
object obj2 = ((!(type != null)) ? null : AccessTools.Field(type, "Instance")?.GetValue(null));
dictionary2 = ((obj2 != null) ? ((IDictionary)Activator.CreateInstance(dictionary.GetType(), obj2)) : ((IDictionary)Activator.CreateInstance(dictionary.GetType())));
}
catch
{
dictionary2 = (IDictionary)Activator.CreateInstance(dictionary.GetType());
}
foreach (DictionaryEntry item in dictionary)
{
if (item.Key != null && !item.Key.Equals(obj) && (!(method != null) || (bool)method.Invoke(item.Key, null)))
{
dictionary2.Add(item.Key, item.Value);
}
}
DiscoveredModifiersField.SetValue(instance, dictionary2);
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("ScrubInvalidDiscoveredModifiers: " + ex.Message));
}
}
}
[HarmonyPatch(typeof(StartMenu))]
internal static class StartMenuProfilePatches
{
private static readonly FieldInfo ProfileSelectField = AccessTools.Field(typeof(StartMenu), "profileSelect");
private static readonly FieldInfo ProfileTextField = AccessTools.Field(typeof(StartMenu), "profileText");
private static readonly FieldInfo ProfileRestartTextField = AccessTools.Field(typeof(StartMenu), "profileRestartText");
private static readonly FieldInfo PatchNotesBlinkerField = AccessTools.Field(typeof(StartMenu), "patchNotesBlinker");
private static bool _isSwapping;
[HarmonyPatch("SelectProfile")]
[HarmonyPrefix]
private static bool SelectProfile_Prefix(StartMenu __instance, int index)
{
if (_isSwapping)
{
return false;
}
try
{
if (!CanSwapSafely(out var reason))
{
ProfileSwitcherPlugin.Log.LogWarning((object)("Profile swap blocked: " + reason));
ShowInfo("Profile Swap", reason);
ApplyVanillaSelectionUi(__instance, index, showRestartPrompt: true);
return false;
}
int currentProfileIndex = ProfileReloader.GetCurrentProfileIndex();
if (index == currentProfileIndex)
{
ApplyVanillaSelectionUi(__instance, index, showRestartPrompt: false);
return false;
}
_isSwapping = true;
string error;
bool num = ProfileReloader.TrySwapProfile(index, out error);
_isSwapping = false;
if (!num)
{
ProfileSwitcherPlugin.Log.LogError((object)("Profile swap failed: " + error));
ShowInfo("Profile Swap Failed", error ?? "Unknown error while loading the selected profile.");
ApplyVanillaSelectionUi(__instance, ProfileReloader.GetCurrentProfileIndex(), showRestartPrompt: true);
return false;
}
ApplyVanillaSelectionUi(__instance, index, showRestartPrompt: false);
RefreshMenuAfterSwap(__instance);
ProfileSwitcherPlugin.Log.LogInfo((object)$"Swapped to profile index {index} without restart.");
return false;
}
catch (Exception arg)
{
_isSwapping = false;
ProfileSwitcherPlugin.Log.LogError((object)$"Unhandled profile swap exception: {arg}");
ShowInfo("Profile Swap Failed", "An unexpected error occurred. The game may need a restart.");
return false;
}
}
private static bool CanSwapSafely(out string reason)
{
if ((Object)(object)GameManager.Instance != (Object)null)
{
reason = "Leave the hub/mission and return to the main menu before swapping profiles.";
return false;
}
if (JoinFriendsWindow.JoiningInProgress)
{
reason = "Cannot swap profiles while joining a lobby.";
return false;
}
if ((Object)(object)StartMenu.Instance == (Object)null)
{
reason = "Main menu is not active.";
return false;
}
reason = null;
return true;
}
private static void ApplyVanillaSelectionUi(StartMenu menu, int index, bool showRestartPrompt)
{
ProfileConfig.Instance.SetProfile(index);
object? obj = ProfileSelectField?.GetValue(menu);
object? obj2 = ((obj is GameObject) ? obj : null);
if (obj2 != null)
{
((GameObject)obj2).SetActive(false);
}
object? obj3 = ProfileRestartTextField?.GetValue(menu);
TextMeshProUGUI val = (TextMeshProUGUI)((obj3 is TextMeshProUGUI) ? obj3 : null);
if ((Object)(object)val != (Object)null)
{
((Component)val).gameObject.SetActive(showRestartPrompt);
}
object? obj4 = ProfileTextField?.GetValue(menu);
TextMeshProUGUI val2 = (TextMeshProUGUI)((obj4 is TextMeshProUGUI) ? obj4 : null);
if ((Object)(object)val2 != (Object)null)
{
((TMP_Text)val2).text = ((index == 0) ? "default" : ProfileConfig.Instance.GetProfile(index).Name);
((Component)val2).gameObject.SetActive(true);
}
}
private static void RefreshMenuAfterSwap(StartMenu menu)
{
try
{
object? obj = PatchNotesBlinkerField?.GetValue(menu);
Component val = (Component)((obj is Component) ? obj : null);
if ((Object)(object)val != (Object)null)
{
val.gameObject.SetActive(Global.Version != PlayerData.Instance.lastViewedPatchNotes);
}
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("Patch notes blinker refresh skipped: " + ex.Message));
}
}
private static void ShowInfo(string title, string body)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!((Object)(object)StartMenu.Instance == (Object)null) && !((Object)(object)Global.Instance == (Object)null) && !((Object)(object)Global.Instance.InfoWindow == (Object)null))
{
((InfoWindow)((Window)StartMenu.Instance).WindowSystem.OpenWindowFromPrefab((Window)(object)Global.Instance.InfoWindow, false)).SetInfo(title, body);
}
}
catch (Exception ex)
{
ProfileSwitcherPlugin.Log.LogDebug((object)("Could not show info window: " + ex.Message));
}
}
}
namespace ProfileSwitcher
{
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "ProfileSwitcher";
public const string PLUGIN_NAME = "ProfileSwitcher";
public const string PLUGIN_VERSION = "1.0.1";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}