Decompiled source of CharacterSwapApp v1.2.3

plugins/CharacterSwapApp/CharacterSwapApp.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BombRushMP.CrewBoom;
using BombRushMP.Plugin;
using CommonAPI;
using CommonAPI.Phone;
using CrewBoom;
using CrewBoom.Data;
using CrewBoomAPI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using Reptile.Phone;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("CharacterSwapApp")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Character swap app mod for Bomb Rush Cyberfunk")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyInformationalVersion("1.2.3+5503be34be955eae7f150d8d1762788fc38f9d1e")]
[assembly: AssemblyProduct("CharacterSwapApp")]
[assembly: AssemblyTitle("CharacterSwapApp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 CharacterSwapApp
{
	public class AppCharacterSwap : CustomApp
	{
		public static AppCharacterSwap Instance;

		public static Sprite IconSprite = null;

		public static string dataDirectory = CharacterSwapPlugin.Instance.Directory;

		private static int currentMoveStyleSkin = -1;

		private static bool AddedRecentButton = false;

		public static Player Player
		{
			get
			{
				WorldHandler instance = WorldHandler.instance;
				return (instance != null) ? instance.GetCurrentPlayer() : null;
			}
		}

		public static void Initialize()
		{
			IconSprite = TextureUtility.LoadSprite(Path.Combine(dataDirectory, "CharacterSwap-icon.png"));
			PhoneAPI.RegisterApp<AppCharacterSwap>("character swap", IconSprite);
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			Instance = this;
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			((CustomApp)this).CreateTitleBar("CharacterSwap", IconSprite, 80f);
			SimplePhoneButton val = null;
			if (CharacterSwapPlugin.CrewBoomInstalled)
			{
				val = PhoneUIUtility.CreateSimpleButton("Vanilla characters...");
				SimplePhoneButton obj = val;
				((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
				{
					AppCharacterSwapList.Instance.AddVanillaCharacterButtons(customCheck: true);
					((App)this).MyPhone.OpenApp(typeof(AppCharacterSwapList));
				});
				base.ScrollView.AddButton((PhoneButton)(object)val);
				val = PhoneUIUtility.CreateSimpleButton("CrewBoom characters...");
				SimplePhoneButton obj2 = val;
				((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
				{
					AppCharacterSwapList.Instance.AddCustomCharacterButtons();
					((App)this).MyPhone.OpenApp(typeof(AppCharacterSwapList));
				});
				base.ScrollView.AddButton((PhoneButton)(object)val);
				if (CharacterSwapPlugin.BombRushMPInstalled && CharacterSwapConfig.showMPCharacters.Value && BombRushMPHelper.HasStreamedCharacters)
				{
					val = PhoneUIUtility.CreateSimpleButton("BombRushMP.CrewBoom characters...");
					SimplePhoneButton obj3 = val;
					((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
					{
						AppCharacterSwapList.Instance.AddStreamedCharacterButtons();
						((App)this).MyPhone.OpenApp(typeof(AppCharacterSwapList));
					});
					TextMeshProUGUI label = val.Label;
					((TMP_Text)label).fontSizeMin = ((TMP_Text)label).fontSizeMin - 2f;
					base.ScrollView.AddButton((PhoneButton)(object)val);
				}
			}
			else
			{
				val = PhoneUIUtility.CreateSimpleButton("Swap character...");
				SimplePhoneButton obj4 = val;
				((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
				{
					AppCharacterSwapList.Instance.AddVanillaCharacterButtons();
					((App)this).MyPhone.OpenApp(typeof(AppCharacterSwapList));
				});
				base.ScrollView.AddButton((PhoneButton)(object)val);
			}
			val = PhoneUIUtility.CreateSimpleButton("Swap outfit");
			SimplePhoneButton obj5 = val;
			((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate
			{
				SwapOutfit();
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Swap movestyle");
			SimplePhoneButton obj6 = val;
			((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate
			{
				SwapMoveStyle();
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Swap movestyle skin");
			SimplePhoneButton obj7 = val;
			((PhoneButton)obj7).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj7).OnConfirm, (Action)delegate
			{
				SwapMoveStyleSkin();
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
		}

		public override void OnAppEnable()
		{
			if (CharacterSwapPlugin.CrewBoomInstalled)
			{
				AppCharacterSwapList.Instance?.RemoveAllButtons();
			}
			if (!AddedRecentButton && CharacterSwapConfig.showRecentCharacters.Value && AppCharacterSwapList.RecentCharacters.Count > 1)
			{
				SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Recent characters...");
				((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
				{
					AppCharacterSwapList.Instance.AddRecentCharacterButtons();
					((App)this).MyPhone.OpenApp(typeof(AppCharacterSwapList));
				});
				base.ScrollView.InsertButton(0, (PhoneButton)(object)val);
				AddedRecentButton = true;
			}
		}

		public override void OnAppDisable()
		{
			((App)this).OnAppDisable();
		}

		public static void SwapOutfit()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (AppCharacterSwapList.usingStreamedCharacter)
			{
				int outfit = (AppCharacterSwapList.currentStreamedOutfit + 1) % 4;
				AppCharacterSwapList.SwapToStreamedCharacter(AppCharacterSwapList.currentStreamedCharacterGUID, outfit);
			}
			else
			{
				int outfit2 = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(Player.character).outfit;
				Player.SetOutfit((outfit2 + 1) % 4);
			}
		}

		public static void SwapMoveStyle()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected I4, but got Unknown
			int num = (Player.moveStyle + 1) % 4;
			if (num == 0)
			{
				num++;
			}
			Player.InitMovement((MoveStyle)num);
			Player.SwitchToEquippedMovestyle(true, false, true, true);
		}

		public static void SwapMoveStyleSkin()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Invalid comparison between Unknown and I4
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			if (!AppCharacterSwapList.usingStreamedCharacter)
			{
				if (currentMoveStyleSkin == -1)
				{
					currentMoveStyleSkin = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(Player.character).moveStyleSkin;
				}
				num = (currentMoveStyleSkin + 1) % 10;
			}
			else
			{
				if (AppCharacterSwapList.currentStreamedMoveStyleSkin == -1)
				{
					AppCharacterSwapList.currentStreamedMoveStyleSkin = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(Player.character).moveStyleSkin;
				}
				num = (AppCharacterSwapList.currentStreamedMoveStyleSkin + 1) % 10;
			}
			for (MoveStyle val = (MoveStyle)1; (int)val < 4; val = (MoveStyle)(val + 1))
			{
				Texture moveStyleSkinTexture = Player.CharacterConstructor.GetMoveStyleSkinTexture(val, num);
				Material[] moveStyleMaterials = MoveStyleLoader.GetMoveStyleMaterials(Player, val);
				for (int i = 0; i < moveStyleMaterials.Length; i++)
				{
					moveStyleMaterials[i].mainTexture = moveStyleSkinTexture;
				}
			}
			if (!AppCharacterSwapList.usingStreamedCharacter)
			{
				currentMoveStyleSkin = num;
				Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(Player.character).moveStyleSkin = currentMoveStyleSkin;
			}
			else
			{
				AppCharacterSwapList.currentStreamedMoveStyleSkin = num;
			}
		}
	}
	public class AppCharacterSwapList : CustomApp
	{
		public class RecentCharacterInfo
		{
			public Characters Character;

			public string Name;

			public RecentCharacterInfo(Characters character, string characterName)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				Character = character;
				Name = characterName;
				base..ctor();
			}
		}

		public static AppCharacterSwapList Instance;

		public static Dictionary<int, Sprite> tagSprites = new Dictionary<int, Sprite>();

		public static Dictionary<Guid, Sprite> tagSpritesStreamed = new Dictionary<Guid, Sprite>();

		public static bool usingStreamedCharacter = false;

		public static Guid currentStreamedCharacterGUID;

		public static int currentStreamedOutfit = 0;

		public static int currentStreamedMoveStyleSkin = -1;

		public static bool settingUpStreaming = false;

		public static List<RecentCharacterInfo> RecentCharacters = new List<RecentCharacterInfo>();

		public static Player Player => AppCharacterSwap.Player;

		public override bool Available => false;

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppCharacterSwapList>("character swap list", (Sprite)null);
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			Instance = this;
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			((CustomApp)this).CreateTitleBar("CharacterSwap", AppCharacterSwap.IconSprite, 80f);
		}

		public static void SwapToCharacter(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (character != Player.character)
			{
				bool usingEquippedMovestyle = Player.usingEquippedMovestyle;
				CharacterProgress characterProgress = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(character);
				Player.SetCharacter(character, characterProgress.outfit);
				Player.InitVisual();
				Player.SetCurrentMoveStyleEquipped(characterProgress.moveStyle, true, true);
				if (usingEquippedMovestyle)
				{
					Player.SwitchToEquippedMovestyle(true, false, true, true);
				}
				usingStreamedCharacter = false;
			}
		}

		public static void SwapToCharacter(int character)
		{
			SwapToCharacter((Characters)character);
		}

		public static void SwapToStreamedCharacter(Guid character, int outfit = 0)
		{
			settingUpStreaming = true;
			currentStreamedCharacterGUID = Guid.Empty;
			currentStreamedOutfit = outfit;
			CharacterHandle val = BombRushMPHelper.RequestCharacter(character, isAsync: true);
			if (val.Finished)
			{
				FinalizeStreamedCharacter(character, outfit);
				return;
			}
			val.OnLoadFinished = (Action)Delegate.Combine(val.OnLoadFinished, (Action)delegate
			{
				FinalizeStreamedCharacter(character, outfit);
			});
		}

		public static void FinalizeStreamedCharacter(Guid character, int outfit)
		{
			if (!(currentStreamedCharacterGUID != Guid.Empty))
			{
				BombRushMPHelper.SetStreamedCharacter(character, outfit);
				usingStreamedCharacter = true;
				currentStreamedCharacterGUID = character;
				settingUpStreaming = false;
			}
		}

		public static Dictionary<int, string> ListOfCustomCharacters()
		{
			Dictionary<int, string> dictionary = new Dictionary<int, string>();
			for (int i = 0; i <= 26 + CrewBoomHelper.NumberOfCustomCharacters; i++)
			{
				int num = i;
				if (CrewBoomHelper.IsCustomCharacter((Characters)num))
				{
					dictionary[num] = CrewBoomHelper.CustomCharacterName((Characters)num);
				}
			}
			return dictionary;
		}

		public static void AddVanillaCharacterButtons(PhoneScrollView scrollView, bool customCheck)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between I4 and Unknown
			for (int i = 0; i < 26; i++)
			{
				int num = i;
				if ((!customCheck || !CrewBoomHelper.IsCustomCharacter((Characters)num)) && IsCharacterUnlocked((Characters)num))
				{
					string vanillaCharacterName = GetVanillaCharacterName((Characters)num);
					scrollView.AddButton((PhoneButton)(object)CreateButton(num, vanillaCharacterName));
					if (CharacterSwapConfig.showRecentCharacters.Value && RecentCharacters.Count == 0 && num == (int)Player.character)
					{
						RecentCharacters.Add(new RecentCharacterInfo((Characters)num, vanillaCharacterName));
					}
				}
			}
		}

		public static void AddCustomCharacterButtons(PhoneScrollView scrollView)
		{
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Invalid comparison between I4 and Unknown
			Dictionary<int, string> dictionary = new Dictionary<int, string>();
			Dictionary<int, string> dictionary2 = new Dictionary<int, string>();
			foreach (KeyValuePair<int, string> item in ListOfCustomCharacters())
			{
				if (CrewBoomHelper.IsNoCypherCharacter((Characters)item.Key))
				{
					dictionary2[item.Key] = item.Value;
				}
				else
				{
					dictionary[item.Key] = item.Value;
				}
				Debug.Log((object)(item.Value + ": " + CrewBoomHelper.IsNoCypherCharacter((Characters)item.Key)));
			}
			foreach (Dictionary<int, string> item2 in new List<Dictionary<int, string>> { dictionary, dictionary2 })
			{
				Dictionary<string, SimplePhoneButton> dictionary3 = new Dictionary<string, SimplePhoneButton>();
				List<string> list = new List<string>();
				foreach (KeyValuePair<int, string> item3 in item2)
				{
					int key = item3.Key;
					string text = item3.Value;
					while (list.Contains(text))
					{
						text += "*";
					}
					dictionary3[text] = CreateButton(key, text.TrimEnd(new char[1] { '*' }));
					list.Add(text);
					if (CharacterSwapConfig.showRecentCharacters.Value && RecentCharacters.Count == 0 && key == (int)Player.character)
					{
						RecentCharacters.Add(new RecentCharacterInfo((Characters)key, text));
					}
				}
				list.Sort();
				foreach (string item4 in list)
				{
					scrollView.AddButton((PhoneButton)(object)dictionary3[item4]);
				}
			}
		}

		public static void AddRecentCharacterButtons(PhoneScrollView scrollView)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			foreach (RecentCharacterInfo recentCharacter in RecentCharacters)
			{
				scrollView.AddButton((PhoneButton)(object)CreateButton((int)recentCharacter.Character, recentCharacter.Name));
			}
		}

		public static void AddStreamedCharacterButtons(PhoneScrollView scrollView)
		{
			Dictionary<string, SimplePhoneButton> dictionary = new Dictionary<string, SimplePhoneButton>();
			List<string> list = new List<string>();
			foreach (Guid item in BombRushMPHelper.ListOfStreamedCharacterGUIDs())
			{
				string streamedCharacterName = BombRushMPHelper.GetStreamedCharacterName(item);
				dictionary[streamedCharacterName] = CreateStreamButton(item, streamedCharacterName);
				list.Add(streamedCharacterName);
			}
			list.Sort();
			foreach (string item2 in list)
			{
				scrollView.AddButton((PhoneButton)(object)dictionary[item2]);
			}
		}

		public static SimplePhoneButton CreateButton(int character, string characterName)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(characterName);
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				SwapToCharacter(character);
				if (CharacterSwapConfig.showRecentCharacters.Value)
				{
					RecentCharacterInfo recentCharacterInfo = new RecentCharacterInfo((Characters)character, characterName);
					RecentCharacterInfo recentCharacterInfo2 = null;
					foreach (RecentCharacterInfo recentCharacter in RecentCharacters)
					{
						if (recentCharacter.Character == recentCharacterInfo.Character)
						{
							recentCharacterInfo2 = recentCharacter;
							break;
						}
					}
					if (recentCharacterInfo2 != null)
					{
						RecentCharacters.Remove(recentCharacterInfo2);
					}
					RecentCharacters.Insert(0, recentCharacterInfo);
					if (RecentCharacters.Count > 20)
					{
						RecentCharacters.RemoveAt(RecentCharacters.Count - 1);
					}
				}
			});
			try
			{
				float num = 100f;
				float num2 = num + 5f;
				if (!tagSprites.ContainsKey(character))
				{
					tagSprites[character] = TextureUtility.CreateSpriteFromTexture(GetCharacterTag((Characters)character));
				}
				GameObject val2 = new GameObject(characterName + " Tag");
				Image val3 = val2.AddComponent<Image>();
				GameObjectExtensions.RectTransform(val2).sizeDelta = new Vector2(num, num);
				val3.sprite = tagSprites[character];
				Transform transform = ((TMP_Text)val.Label).transform;
				transform.localPosition += new Vector3(num2, 0f, 0f);
				RectTransform obj = ComponentExtensions.RectTransform((Component)(object)val.Label);
				obj.sizeDelta -= new Vector2(num2, 0f);
				val2.transform.SetParent(((Component)val.Label).gameObject.transform, false);
				RectTransform obj2 = GameObjectExtensions.RectTransform(val2);
				((Transform)obj2).localPosition = ((Transform)obj2).localPosition - new Vector3(num2 + 350f, 0f, 0f);
			}
			catch (Exception)
			{
			}
			return val;
		}

		public static SimplePhoneButton CreateStreamButton(Guid character, string characterName)
		{
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(characterName);
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				SwapToStreamedCharacter(character);
			});
			return val;
		}

		public static bool IsCharacterUnlocked(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if ((int)character == 17 || (int)character == 18)
			{
				return Core.Instance.platform.DownloadableContent.IsDownloadableContentUnlocked(Core.Instance.baseModule.characterDownloadableContent);
			}
			CharacterProgress characterProgress = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(character);
			return !CharacterSwapConfig.onlyUnlockedCharacters.Value || characterProgress.unlocked || IsHiddenCharacter(character);
		}

		public static bool IsHiddenCharacter(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			if ((int)character == 25)
			{
				return (int)Story.GetCurrentObjectiveInfo().chapter == 6;
			}
			return (int)character == 12 || (int)character == 24 || (int)character == 23;
		}

		public static Texture2D GetCharacterTag(Characters character)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			WorldHandler instance = WorldHandler.instance;
			Texture obj = ((instance != null) ? instance.graffitiArtInfo.FindByCharacter(character).graffitiMaterial.mainTexture : null);
			return (Texture2D)(object)((obj is Texture2D) ? obj : null);
		}

		public static string GetVanillaCharacterName(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((int)character == 9)
			{
				return "DJ Cyber";
			}
			if ((int)character == 7)
			{
				return "DOT EXE";
			}
			if ((int)character == 23)
			{
				return "Faux (No Boost Pack)";
			}
			if ((int)character == 24)
			{
				return "DOT EXE (Leader)";
			}
			return ToTitleCase(Core.Instance.Localizer.GetCharacterName(character));
		}

		public static string ToTitleCase(string str)
		{
			TextInfo textInfo = new CultureInfo("en-US", useUserOverride: false).TextInfo;
			return textInfo.ToTitleCase(str.ToLower());
		}

		public void AddVanillaCharacterButtons(bool customCheck = false)
		{
			AddVanillaCharacterButtons(base.ScrollView, customCheck);
		}

		public void AddCustomCharacterButtons()
		{
			AddCustomCharacterButtons(base.ScrollView);
		}

		public void AddStreamedCharacterButtons()
		{
			AddStreamedCharacterButtons(base.ScrollView);
		}

		public void AddRecentCharacterButtons()
		{
			AddRecentCharacterButtons(base.ScrollView);
		}

		public void RemoveAllButtons()
		{
			base.ScrollView.RemoveAllButtons();
		}
	}
	internal class BombRushMPHelper
	{
		public static Player Player => AppCharacterSwap.Player;

		public static bool HasStreamedCharacters => CheckIfHasStreamedCharacters();

		public static void SetStreamedCharacter(Guid guid, int outfit = 0)
		{
			ClientController.Instance.LocalPlayerComponent.SetStreamedCharacter(guid, outfit);
			ClientController.Instance.SendClientState();
		}

		public static string GetStreamedCharacterName(Guid guid)
		{
			return Path.GetFileName(BundlePathByGUID()[guid]);
		}

		public static List<Guid> ListOfStreamedCharacterGUIDs()
		{
			return BundlePathByGUID().Keys.ToList();
		}

		public static Dictionary<Guid, string> BundlePathByGUID()
		{
			Type typeFromHandle = typeof(CrewBoomStreamer);
			return typeFromHandle.GetField("BundlePathByGUID", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as Dictionary<Guid, string>;
		}

		public static List<string> Directories()
		{
			Type typeFromHandle = typeof(CrewBoomStreamer);
			return typeFromHandle.GetField("Directories", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as List<string>;
		}

		public static bool CheckIfHasStreamedCharacters()
		{
			foreach (string item in Directories())
			{
				foreach (string item2 in Directory.EnumerateFiles(item, "*.cbb", SearchOption.AllDirectories))
				{
					if (!string.IsNullOrEmpty(item2))
					{
						return true;
					}
				}
			}
			return false;
		}

		public static CharacterHandle RequestCharacter(Guid guid, bool isAsync)
		{
			return CrewBoomStreamer.RequestCharacter(guid, isAsync);
		}
	}
	internal class CrewBoomHelper
	{
		public static int NumberOfCustomCharacters => CharacterDatabase.NewCharacterCount;

		public static bool IsCustomCharacter(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			CustomCharacter val = default(CustomCharacter);
			return CharacterDatabase.GetCharacter(character, ref val);
		}

		public static bool IsNoCypherCharacter(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return !CharacterDatabase.HasCypherEnabledForCharacter(character);
		}

		public static string CustomCharacterName(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			string result = default(string);
			if (CharacterDatabase.GetCharacterName(character, ref result))
			{
				return result;
			}
			return CustomCharacterInternalName(character);
		}

		public static string CustomCharacterInternalName(Characters character)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			if (CrewBoomAPIDatabase.IsInitialized)
			{
				Guid key = default(Guid);
				if (!CrewBoomAPIDatabase.GetUserGuidForCharacter((int)character, ref key))
				{
					return "";
				}
				if (CharacterDatabase._characterBundlePaths.TryGetValue(key, out var value))
				{
					return Path.GetFileNameWithoutExtension(value);
				}
			}
			return "";
		}
	}
	[HarmonyPatch(typeof(Player))]
	public class PlayerCharacterOverridePatch
	{
		internal static bool wasUsingStreamedCharacter;

		internal static Guid streamedCharacterGUID;

		internal static int streamedOutfit;

		[HarmonyPrefix]
		[HarmonyPatch("Init")]
		public static void Prefix_OverrideWithStreamedCharacter(Player __instance)
		{
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && AppCharacterSwapList.usingStreamedCharacter)
			{
				wasUsingStreamedCharacter = true;
				streamedCharacterGUID = AppCharacterSwapList.currentStreamedCharacterGUID;
				streamedOutfit = AppCharacterSwapList.currentStreamedOutfit;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Init")]
		public static void Postfix_OverrideWithStreamedCharacter(Player __instance)
		{
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && wasUsingStreamedCharacter)
			{
				((MonoBehaviour)CharacterSwapPlugin.Instance).StartCoroutine(CharacterSwapPlugin.Instance.RefreshStreamedCharacter(streamedCharacterGUID, streamedOutfit));
				wasUsingStreamedCharacter = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetCharacter")]
		public static void Postfix_DisableStreaming(Player __instance)
		{
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && !AppCharacterSwapList.settingUpStreaming)
			{
				AppCharacterSwapList.usingStreamedCharacter = false;
			}
		}
	}
	[BepInPlugin("goatgirl.CharacterSwapApp", "CharacterSwapApp", "1.2.3")]
	[BepInProcess("Bomb Rush Cyberfunk.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class CharacterSwapPlugin : BaseUnityPlugin
	{
		internal static Harmony Harmony = new Harmony("goatgirl.CharacterSwapApp");

		public static bool CrewBoomInstalled = false;

		public static bool BombRushMPInstalled = false;

		public static CharacterSwapPlugin Instance { get; private set; }

		public string Directory => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);

		private void Awake()
		{
			Instance = this;
			CharacterSwapConfig.BindSettings(((BaseUnityPlugin)this).Config);
			AppCharacterSwap.Initialize();
			AppCharacterSwapList.Initialize();
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				if (pluginInfo.Value.Metadata.GUID.Contains("CrewBoom") || pluginInfo.Value.Metadata.GUID.Equals("CrewBoom"))
				{
					CrewBoomInstalled = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"CrewBoom found!");
				}
				if (pluginInfo.Value.Metadata.GUID.Contains("BombRushMP.Plugin") || pluginInfo.Value.Metadata.GUID.Equals("BombRushMP.Plugin"))
				{
					BombRushMPInstalled = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"BombRushMP found!");
				}
			}
			Harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin goatgirl.CharacterSwapApp is loaded!");
		}

		private void OnDestroy()
		{
			Harmony.UnpatchSelf();
		}

		public IEnumerator RefreshStreamedCharacter(Guid guid, int outfit)
		{
			yield return (object)new WaitForSeconds(0.1f);
			AppCharacterSwapList.SwapToStreamedCharacter(guid, outfit);
		}
	}
	public class CharacterSwapConfig
	{
		public static ConfigEntry<bool> onlyUnlockedCharacters;

		public static ConfigEntry<bool> showRecentCharacters;

		public static ConfigEntry<bool> showMPCharacters;

		public static void BindSettings(ConfigFile Config)
		{
			onlyUnlockedCharacters = Config.Bind<bool>("Settings", "Hide Locked Characters", true, "Whether to hide characters that have not been unlocked through the story yet.");
			showRecentCharacters = Config.Bind<bool>("Settings", "Track Recent Characters", true, "Whether to display the option to switch to your recently-used characters, sorted by how recently they were swapped to.");
			showMPCharacters = Config.Bind<bool>("Settings", "Show BombRushMP/ACN CrewBoom Characters", true, "Whether to display the option to swap to CrewBoom characters stored in BombRushMP's CrewBoom folder. Note that BombRushMP characters can only display as raw filenames within the app, and they won't show up in the Recent Characters list.");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CharacterSwapApp";

		public const string PLUGIN_NAME = "CharacterSwapApp";

		public const string PLUGIN_VERSION = "1.2.3";
	}
}