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 list = null; foreach (KeyValuePair item in instance.collectedGear) { if (item.Value.Gear == null) { if (list == null) { list = new List(); } 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 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 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)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) { } } }