Decompiled source of CrewBoom v3.2.7

BepInEx/plugins/CrewBoom/CrewBoom.dll

Decompiled 10 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CrewBoom.Data;
using CrewBoom.Properties;
using CrewBoom.Utility;
using CrewBoomAPI;
using CrewBoomMono;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using Reptile.Phone;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.Playables;
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.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("CrewBoom")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A plugin to load custom skins and characters for Bomb Rush Cyberfunk.")]
[assembly: AssemblyFileVersion("3.2.5.0")]
[assembly: AssemblyInformationalVersion("3.2.5+f3187029eb24e0cfab10d58015f0535759e10d2f")]
[assembly: AssemblyProduct("CrewBoom")]
[assembly: AssemblyTitle("CrewBoom")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.2.5.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 CrewBoom
{
	public static class CharacterDatabase
	{
		private static readonly string ASSET_PATH = Path.Combine(Paths.ConfigPath, "CrewBoom");

		private static readonly string NO_CYPHER_PATH = Path.Combine(ASSET_PATH, "no_cypher");

		private static Dictionary<Guid, string> _characterBundlePaths;

		private static Dictionary<Guid, CustomCharacter> _customCharacters;

		private static Dictionary<Guid, bool> _cypherMapping;

		private static Dictionary<Characters, List<Guid>> _characterIds;

		private static ManualLogSource DebugLog = Logger.CreateLogSource("CrewBoom Database");

		public static int NewCharacterCount { get; private set; } = 0;


		public static bool HasCharacterOverride { get; private set; }

		public static Guid CharacterOverride { get; private set; }

		public static bool Initialize()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Invalid comparison between Unknown and I4
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Invalid comparison between Unknown and I4
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if (!Directory.Exists(ASSET_PATH))
			{
				DebugLog.LogWarning((object)("Could not find character bundle directory \"" + ASSET_PATH + "\".\nIt was created instead."));
				Directory.CreateDirectory(ASSET_PATH);
				return false;
			}
			if (!Directory.Exists(NO_CYPHER_PATH))
			{
				DebugLog.LogMessage((object)"No cypher bundle path was not found. It was created instead.");
				Directory.CreateDirectory(NO_CYPHER_PATH);
			}
			_characterBundlePaths = new Dictionary<Guid, string>();
			_customCharacters = new Dictionary<Guid, CustomCharacter>();
			_cypherMapping = new Dictionary<Guid, bool>();
			_characterIds = new Dictionary<Characters, List<Guid>>();
			Array values = Enum.GetValues(typeof(Characters));
			foreach (Characters item in values)
			{
				if ((int)item == -1 || (int)item == 26)
				{
					_characterIds.Add(item, null);
				}
				else
				{
					_characterIds.Add(item, new List<Guid>());
				}
			}
			if (!LoadAllCharacterData())
			{
				DebugLog.LogWarning((object)("There were no valid characters found in " + ASSET_PATH + ".\nMake sure your character bundles (.cbb) are in the CONFIG folder, NOT the PLUGIN folder."));
				return false;
			}
			InitializeAPI();
			return true;
		}

		private static bool LoadAllCharacterData()
		{
			bool result = false;
			string[] files = Directory.GetFiles(ASSET_PATH, "*.cbb");
			foreach (string filePath in files)
			{
				if (LoadCharacterBundle(filePath, enableCypher: true))
				{
					result = true;
				}
			}
			string[] files2 = Directory.GetFiles(NO_CYPHER_PATH, "*.cbb");
			foreach (string filePath2 in files2)
			{
				if (LoadCharacterBundle(filePath2, enableCypher: false))
				{
					result = true;
				}
			}
			return result;
		}

		private static bool LoadCharacterBundle(string filePath, bool enableCypher)
		{
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Invalid comparison between Unknown and I4
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Invalid comparison between Unknown and I4
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Invalid comparison between Unknown and I4
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			if (File.Exists(filePath) && Path.GetExtension(filePath) == ".cbb")
			{
				AssetBundle val = null;
				try
				{
					val = AssetBundle.LoadFromFile(filePath);
				}
				catch (Exception)
				{
					DebugLog.LogWarning((object)("File at " + filePath + " is not a CrewBoom character bundle, it will not be loaded"));
				}
				if ((Object)(object)val != (Object)null)
				{
					GameObject[] array = val.LoadAllAssets<GameObject>();
					CharacterDefinition val2 = null;
					GameObject[] array2 = array;
					foreach (GameObject val3 in array2)
					{
						val2 = val3.GetComponent<CharacterDefinition>();
						if ((Object)(object)val2 != (Object)null)
						{
							break;
						}
					}
					if ((Object)(object)val2 != (Object)null)
					{
						string fileName = Path.GetFileName(filePath);
						BrcCharacter val4 = (BrcCharacter)(-1);
						string path = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".json");
						if (File.Exists(path))
						{
							string text = File.ReadAllText(path);
							try
							{
								CharacterConfig val5 = JsonUtility.FromJson<CharacterConfig>(text);
								if (Enum.TryParse<BrcCharacter>(val5.CharacterToReplace, out BrcCharacter result2))
								{
									val4 = result2;
								}
								else
								{
									DebugLog.LogWarning((object)("The configured replacement character for the bundle " + fileName + " (\"" + val5.CharacterToReplace + "\") is not a valid character!"));
								}
							}
							catch (Exception)
							{
								DebugLog.LogError((object)("Failed to read JSON config for \"" + fileName + "\""));
							}
						}
						StringBuilder stringBuilder = new StringBuilder();
						stringBuilder.Append("Loading \"" + val2.CharacterName + "\"");
						if ((int)val4 == -1)
						{
							stringBuilder.Append(" (additional character");
							if (!enableCypher)
							{
								stringBuilder.Append(", disabled in cypher");
							}
							stringBuilder.Append(')');
						}
						stringBuilder.Append("...");
						DebugLog.LogMessage((object)stringBuilder.ToString());
						if (Guid.TryParse(val2.Id, out var result3))
						{
							DebugLog.LogInfo((object)$"GUID: {result3}");
							if (_characterBundlePaths.ContainsKey(result3))
							{
								DebugLog.LogWarning((object)"Character's GUID already exists. Make sure to not have duplicate character bundles.");
								return false;
							}
							result = true;
							_characterBundlePaths.Add(result3, filePath);
							SfxCollectionID sfxID = (SfxCollectionID)(-1);
							if ((int)val4 != -1)
							{
								_characterIds[(Characters)val4].Add(result3);
							}
							else
							{
								NewCharacterCount++;
								Characters key = (Characters)(26 + NewCharacterCount);
								sfxID = (SfxCollectionID)(67 + NewCharacterCount);
								if (_characterIds.ContainsKey(key))
								{
									_characterIds[key].Add(result3);
								}
								else
								{
									_characterIds.Add(key, new List<Guid> { result3 });
								}
								_cypherMapping.Add(result3, enableCypher);
							}
							CustomCharacter value = new CustomCharacter(val2, sfxID, (int)val4 != -1);
							_customCharacters.Add(result3, value);
						}
						else
						{
							DebugLog.LogError((object)("This character's GUID (\"" + val2.Id + "\") is invalid! Make sure their bundle was built correctly."));
						}
					}
					else
					{
						DebugLog.LogWarning((object)("The asset bundle at \"" + filePath + "\" does not have a CharacterDefinition. You may be trying to load a character that was made with a different version of this plugin."));
					}
				}
			}
			return result;
		}

		public static void SetOutfitShader(Shader shader)
		{
			if ((Object)(object)shader == (Object)null)
			{
				return;
			}
			foreach (CustomCharacter value in _customCharacters.Values)
			{
				value.ApplyShaderToOutfits(shader);
			}
		}

		public static void SetGraffitiShader(Shader shader)
		{
			if ((Object)(object)shader == (Object)null)
			{
				return;
			}
			foreach (CustomCharacter value in _customCharacters.Values)
			{
				value.ApplyShaderToGraffiti(shader);
			}
		}

		private static void InitializeAPI()
		{
			Dictionary<int, Guid> dictionary = new Dictionary<int, Guid>();
			int num = 26;
			for (int i = num + 1; i <= num + NewCharacterCount; i++)
			{
				if (GetFirstOrConfigCharacterId((Characters)i, out var guid))
				{
					dictionary.Add(i, guid);
				}
			}
			CrewBoomAPIDatabase.Initialize(dictionary);
			CrewBoomAPIDatabase.OnOverride += SetCharacterOverride;
		}

		private static void SetCharacterOverride(Guid id)
		{
			HasCharacterOverride = true;
			CharacterOverride = id;
			DebugLog.LogInfo((object)$"Received override for next character {id}");
		}

		public static void SetCharacterOverrideDone()
		{
			HasCharacterOverride = false;
			DebugLog.LogInfo((object)"Finished override");
		}

		public static void InitializeMissingSfxCollections(Characters character, SfxCollection collection)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!_characterIds.TryGetValue(character, out var value) || value == null || value.Count <= 0)
			{
				return;
			}
			foreach (Guid item in value)
			{
				if (GetCharacter(item, out var characterObject))
				{
					characterObject.ApplySfxCollection(collection);
				}
			}
		}

		public static bool GetCharacterNameWithId(int localizationId, out string name)
		{
			name = string.Empty;
			switch (localizationId)
			{
			case 0:
				return false;
			case 6:
				return GetCharacterName((Characters)0, out name);
			case 10:
				return GetCharacterName((Characters)1, out name);
			case 24:
				return GetCharacterName((Characters)2, out name);
			case 4:
				return GetCharacterName((Characters)3, out name);
			case 3:
				return GetCharacterName((Characters)4, out name);
			case 5:
				return GetCharacterName((Characters)5, out name);
			case 26:
				return GetCharacterName((Characters)6, out name);
			case 12:
				if (GetCharacterName((Characters)7, out name))
				{
					return true;
				}
				return GetCharacterName((Characters)24, out name);
			case 15:
				return GetCharacterName((Characters)8, out name);
			case 7:
				return GetCharacterName((Characters)9, out name);
			case 11:
				return GetCharacterName((Characters)10, out name);
			case 13:
				return GetCharacterName((Characters)11, out name);
			case 2:
				if (GetCharacterName((Characters)12, out name))
				{
					return true;
				}
				return GetCharacterName((Characters)23, out name);
			case 8:
				return GetCharacterName((Characters)13, out name);
			case 16:
				return GetCharacterName((Characters)14, out name);
			case 21:
				return GetCharacterName((Characters)15, out name);
			case 20:
				return GetCharacterName((Characters)16, out name);
			case 30:
				return GetCharacterName((Characters)17, out name);
			case 31:
				return GetCharacterName((Characters)18, out name);
			case 28:
				return GetCharacterName((Characters)19, out name);
			case 14:
				return GetCharacterName((Characters)20, out name);
			case 25:
				return GetCharacterName((Characters)21, out name);
			case 27:
				return GetCharacterName((Characters)22, out name);
			case 22:
				return GetCharacterName((Characters)25, out name);
			default:
				return false;
			}
		}

		private static bool GetCharacterName(Characters character, out string name)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			name = string.Empty;
			if (GetCharacter(character, out var characterObject))
			{
				name = characterObject.Definition.CharacterName;
				return true;
			}
			return false;
		}

		public static bool GetFirstOrConfigCharacterId(Characters character, out Guid guid)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			guid = Guid.Empty;
			if (HasCharacterOverride)
			{
				DebugLog.LogInfo((object)$"Getting override for {character} with ID {CharacterOverride}");
				if (_characterBundlePaths.ContainsKey(CharacterOverride) && _customCharacters.ContainsKey(CharacterOverride))
				{
					DebugLog.LogInfo((object)"Override was found locally.");
					guid = CharacterOverride;
					return true;
				}
			}
			if (!_characterIds.TryGetValue(character, out var value) || value == null || value.Count == 0)
			{
				return false;
			}
			if (CharacterDatabaseConfig.GetCharacterOverride(character, out var id, out var isDisabled))
			{
				if (_characterBundlePaths.ContainsKey(id) && _customCharacters.ContainsKey(id))
				{
					guid = id;
					return true;
				}
			}
			else if (isDisabled)
			{
				return false;
			}
			guid = value[0];
			return true;
		}

		public static bool GetCharacter(Guid id, out CustomCharacter characterObject)
		{
			if (!_customCharacters.TryGetValue(id, out characterObject))
			{
				return false;
			}
			return true;
		}

		public static bool GetCharacter(Characters character, out CustomCharacter characterObject)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			characterObject = null;
			if (GetFirstOrConfigCharacterId(character, out var guid))
			{
				GetCharacter(guid, out characterObject);
			}
			return characterObject != null;
		}

		public static bool GetCharacterWithGraffitiTitle(string title, out CustomCharacter characterObject)
		{
			characterObject = null;
			foreach (CustomCharacter value in _customCharacters.Values)
			{
				if (value.Graffiti != null && value.Graffiti.title == title)
				{
					characterObject = value;
					return true;
				}
			}
			return false;
		}

		public static bool HasCharacter(Characters character)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!_characterIds.TryGetValue(character, out var value))
			{
				return false;
			}
			return value != null && value.Count > 0;
		}

		public static bool HasCypherEnabledForCharacter(Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (GetFirstOrConfigCharacterId(character, out var guid) && _cypherMapping.TryGetValue(guid, out var value))
			{
				return value;
			}
			return false;
		}

		public static bool GetCharacterValueFromGuid(Guid guid, out Characters character)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected I4, but got Unknown
			character = (Characters)(-1);
			foreach (KeyValuePair<Characters, List<Guid>> characterId in _characterIds)
			{
				if (characterId.Value != null && characterId.Value.Contains(guid))
				{
					character = (Characters)(int)characterId.Key;
					return true;
				}
			}
			return false;
		}
	}
	public static class CharacterDatabaseConfig
	{
		private const string CONFIG_DESCRIPTION = "Enter a GUID of a character bundle to always load for {0} (Blank = Auto-detect, \"OFF\" = Default character for you)";

		private static ConfigEntry<string>[] _characterIdOverrides;

		public static void Initialize(ConfigFile config)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Array values = Enum.GetValues(typeof(Characters));
			_characterIdOverrides = new ConfigEntry<string>[values.Length - 2];
			foreach (Characters item in values)
			{
				if ((int)item != -1 && (int)item != 26)
				{
					BrcCharacter val2 = (BrcCharacter)item;
					_characterIdOverrides[item] = config.Bind<string>("Replacement IDs", ((object)(BrcCharacter)(ref val2)).ToString(), (string)null, $"Enter a GUID of a character bundle to always load for {val2} (Blank = Auto-detect, \"OFF\" = Default character for you)");
				}
			}
		}

		public static bool GetCharacterOverride(Characters character, out Guid id, out bool isDisabled)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			id = Guid.Empty;
			isDisabled = false;
			if ((int)character > 26)
			{
				return false;
			}
			string value = _characterIdOverrides[character].Value;
			if (value == string.Empty)
			{
				return false;
			}
			if (value == "OFF")
			{
				isDisabled = true;
				return false;
			}
			if (Guid.TryParse(value, out id))
			{
				return true;
			}
			return false;
		}
	}
	public class CharacterSaveSlots
	{
		public const int SAVE_SLOT_COUNT = 4;

		public const string SLOT_FILE_EXTENSION = ".cbs";

		public const string SAVE_FILE_EXTENSION = ".cbc";

		public static readonly string SAVE_PATH = Path.Combine(Paths.ConfigPath, "CrewBoom", "saves");

		public static CharacterSaveSlot CurrentSaveSlot;

		private static Dictionary<Guid, CharacterProgress> _progressLookup = new Dictionary<Guid, CharacterProgress>();

		public static ManualLogSource DebugLog = Logger.CreateLogSource("CrewBoom Saves");

		public static int CurrentSaveSlotId { get; private set; } = -1;


		public static void LoadSlot(int slot)
		{
			if (!Directory.Exists(SAVE_PATH))
			{
				Directory.CreateDirectory(SAVE_PATH);
				return;
			}
			string path = Path.Combine(SAVE_PATH, slot + ".cbs");
			if (File.Exists(path))
			{
				try
				{
					using FileStream input = File.OpenRead(path);
					using BinaryReader reader = new BinaryReader(input);
					CurrentSaveSlot.Read(reader);
				}
				catch (Exception)
				{
					DebugLog.LogWarning((object)$"Failed to read slot data for slot {slot}");
				}
				DebugLog.LogMessage((object)$"Loaded custom character save slot {slot}");
			}
			CurrentSaveSlotId = slot;
		}

		public static void SaveSlot()
		{
			if (CurrentSaveSlotId == -1)
			{
				return;
			}
			if (!Directory.Exists(SAVE_PATH))
			{
				Directory.CreateDirectory(SAVE_PATH);
			}
			string path = Path.Combine(SAVE_PATH, CurrentSaveSlotId + ".cbs");
			try
			{
				using FileStream output = File.OpenWrite(path);
				using BinaryWriter writer = new BinaryWriter(output);
				CurrentSaveSlot.Write(writer);
			}
			catch (Exception)
			{
				DebugLog.LogError((object)$"Failed to write slot data for slot {CurrentSaveSlotId}");
			}
		}

		public static bool GetCharacterData(Guid guid, out CharacterProgress progress)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			if (_progressLookup.TryGetValue(guid, out progress))
			{
				return true;
			}
			progress = new CharacterProgress();
			if (CurrentSaveSlotId == -1)
			{
				LogUninitialized();
				return false;
			}
			if (!EnsureSlotDirectory(out var slotPath))
			{
				return false;
			}
			string path = CharacterFilePath(slotPath, guid);
			if (!File.Exists(path))
			{
				if (CharacterDatabase.GetCharacter(guid, out var characterObject))
				{
					progress = new CharacterProgress
					{
						outfit = 0,
						moveStyle = (MoveStyle)characterObject.Definition.DefaultMovestyle,
						moveStyleSkin = 0
					};
					_progressLookup.Add(guid, progress);
					return true;
				}
				return false;
			}
			try
			{
				using (FileStream input = File.OpenRead(path))
				{
					using BinaryReader binaryReader = new BinaryReader(input);
					progress.Read(binaryReader);
				}
				_progressLookup.Add(guid, progress);
				return true;
			}
			catch (Exception)
			{
				DebugLog.LogError((object)$"Could not load character save data for character with GUID \"{guid}\".");
			}
			return false;
		}

		public static void SaveCharacterData(Guid guid)
		{
			if (CurrentSaveSlotId == -1)
			{
				LogUninitialized();
				return;
			}
			EnsureSlotDirectory(out var slotPath);
			if (!_progressLookup.TryGetValue(guid, out var value))
			{
				DebugLog.LogError((object)$"No save data made for character with GUID \"{guid}\".");
				return;
			}
			string path = CharacterFilePath(slotPath, guid);
			try
			{
				using FileStream output = File.OpenWrite(path);
				using BinaryWriter binaryWriter = new BinaryWriter(output);
				value.Write(binaryWriter);
			}
			catch (Exception)
			{
				DebugLog.LogError((object)$"Could not write character save data for character with GUID \"{guid}\".");
			}
		}

		private static bool EnsureSlotDirectory(out string slotPath)
		{
			bool result = true;
			if (!Directory.Exists(SAVE_PATH))
			{
				Directory.CreateDirectory(SAVE_PATH);
				result = false;
			}
			slotPath = Path.Combine(SAVE_PATH, CurrentSaveSlotId.ToString());
			if (!Directory.Exists(slotPath))
			{
				Directory.CreateDirectory(slotPath);
				result = false;
			}
			return result;
		}

		private static string CharacterFilePath(string slotPath, Guid guid)
		{
			return Path.Combine(slotPath, guid.ToString() + ".cbc");
		}

		private static void LogUninitialized()
		{
			DebugLog.LogWarning((object)"Can't read or write character data before slot was initialized!");
		}
	}
	public struct CharacterSaveSlot
	{
		public Guid LastPlayedCharacter;

		public void Write(BinaryWriter writer)
		{
			writer.Write(LastPlayedCharacter.ToString());
		}

		public void Read(BinaryReader reader)
		{
			Guid.TryParse(reader.ReadString(), out LastPlayedCharacter);
		}
	}
	[BepInPlugin("CrewBoom", "CrewBoom", "3.2.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string CharacterAPIGuid = "com.Viliger.CharacterAPI";

		private void Awake()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if (Chainloader.PluginInfos.ContainsKey("com.Viliger.CharacterAPI"))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"CrewBoom is incompatible with CharacterAPI (viliger) and will not load!\nUninstall CharacterAPI and restart the game if you want to use CrewBoom.");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogMessage((object)"CrewBoom v3.2.5 starting...");
			CharacterDatabaseConfig.Initialize(((BaseUnityPlugin)this).Config);
			if (CharacterDatabase.Initialize())
			{
				Harmony val = new Harmony("sgiygas.crewBoom");
				val.PatchAll();
				((BaseUnityPlugin)this).Logger.LogMessage((object)"Loaded all available characters!");
			}
		}
	}
	public static class CharUtil
	{
		public const string CHARACTER_BUNDLE = "characters";

		public const string ADD_CHARACTER_METHOD = "AddCharacterFBX";

		public const string ADD_MATERIAL_METHOD = "AddCharacterMaterial";

		public const string MATERIAL_FORMAT = "{0}Mat{1}";

		public const string SKATE_OFFSET_L = "skateOffsetL";

		public const string SKATE_OFFSET_R = "skateOffsetR";

		public const string GRAFFITI_ASSET = "charGraffiti";

		private static readonly string[] PropBones = new string[7] { "propl", "propr", "footl", "footr", "handl", "handr", "jetpackPos" };

		public static string GetOutfitMaterialName(Characters character, int outfitIndex)
		{
			return $"{((object)(Characters)(ref character)).ToString()}Mat{outfitIndex.ToString()}";
		}

		public static void ReparentAllProps(Transform originalRoot, Transform targetRoot)
		{
			string[] propBones = PropBones;
			foreach (string text in propBones)
			{
				Transform val = TransformExtentions.FindRecursive(originalRoot, text);
				Transform val2 = TransformExtentions.FindRecursive(targetRoot, text);
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
				{
					ReparentChildren(val, val2);
				}
			}
		}

		private static void ReparentChildren(Transform source, Transform target)
		{
			//IL_002b: 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)
			Transform[] componentsInChildren = ((Component)source).GetComponentsInChildren<Transform>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (!((Object)(object)componentsInChildren[i] == (Object)null))
				{
					componentsInChildren[i].SetParent(target, false);
					componentsInChildren[i].SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
				}
			}
		}

		public static bool TrySetCustomOutfit(Component source, int outfit, out SkinnedMeshRenderer firstActiveRenderer)
		{
			firstActiveRenderer = null;
			CharacterDefinition componentInChildren = source.GetComponentInChildren<CharacterDefinition>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.SetOutfit(outfit, out firstActiveRenderer);
				return true;
			}
			return false;
		}

		public static int GetSavedCharacterOutfit(Characters character)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			int result = 0;
			if ((int)character > 26 && CharacterDatabase.GetFirstOrConfigCharacterId(character, out var guid))
			{
				if (CharacterSaveSlots.GetCharacterData(guid, out var progress))
				{
					result = progress.outfit;
				}
			}
			else
			{
				result = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(character).outfit;
			}
			return result;
		}
	}
	public static class LoadUtil
	{
		public static readonly BindingFlags BindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public static Assets GetAssets(CharacterLoader instance)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			return (Assets)(((object)instance).GetType().GetField("assets", BindingFlags)?.GetValue(instance));
		}

		public static MethodInfo GetMethod(this object instance, string name)
		{
			return instance.GetType().GetMethod(name, BindingFlags);
		}

		public static void InvokeMethod(this object instance, string name, params object[] parameters)
		{
			Traverse val = Traverse.Create(instance);
			val = val.Method(name, parameters);
			val.GetValue(parameters);
		}

		public static void InvokeMethod(this object instance, string name, Type[] types, params object[] parameters)
		{
			Traverse val = Traverse.Create(instance);
			val = val.Method(name, types, (object[])null);
			val.GetValue(parameters);
		}

		public static FieldInfo GetField(this object instance, string name)
		{
			return instance.GetType().GetField(name, BindingFlags);
		}

		public static T GetComponentValue<T>(this object instance, string name) where T : Component
		{
			object? value = instance.GetField(name).GetValue(instance);
			return (T)((value is T) ? value : null);
		}

		public static T GetFieldValue<T>(this object instance, string name) where T : class
		{
			return instance.GetField(name).GetValue(instance) as T;
		}

		public static void SetField(this object instance, string name, object value)
		{
			instance.GetField(name).SetValue(instance, value);
		}
	}
	public static class VoiceUtility
	{
		public static SfxCollectionID VoiceCollectionFromCharacter(Characters character)
		{
			//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)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected I4, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_00ef: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			return (SfxCollectionID)((int)character switch
			{
				0 => 40, 
				1 => 38, 
				2 => 47, 
				3 => 44, 
				4 => 31, 
				5 => 48, 
				6 => 30, 
				7 => 36, 
				8 => 35, 
				9 => 34, 
				10 => 43, 
				11 => 32, 
				12 => 50, 
				13 => 45, 
				14 => 41, 
				15 => 42, 
				16 => -1, 
				17 => 63, 
				18 => 64, 
				19 => 49, 
				20 => 39, 
				21 => 46, 
				22 => 33, 
				23 => 51, 
				24 => 37, 
				25 => 44, 
				_ => -1, 
			});
		}

		public static Characters CharacterFromVoiceCollection(SfxCollectionID collectionID)
		{
			//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)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected I4, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			return (Characters)((collectionID - 30) switch
			{
				0 => 6, 
				1 => 4, 
				2 => 11, 
				3 => 22, 
				4 => 9, 
				5 => 8, 
				6 => 7, 
				7 => 24, 
				8 => 1, 
				9 => 20, 
				10 => 0, 
				20 => 12, 
				21 => 23, 
				11 => 14, 
				12 => 15, 
				13 => 10, 
				14 => 3, 
				15 => 13, 
				16 => 21, 
				17 => 2, 
				18 => 5, 
				19 => 19, 
				33 => 17, 
				34 => 18, 
				_ => -1, 
			});
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CrewBoom";

		public const string PLUGIN_NAME = "CrewBoom";

		public const string PLUGIN_VERSION = "3.2.5";
	}
}
namespace CrewBoom.Utility
{
	public static class CharacterDefinitionExtensions
	{
		public static bool HasVoices(this CharacterDefinition characterDefinition)
		{
			return characterDefinition.VoiceDie.Length != 0 || characterDefinition.VoiceDieFall.Length != 0 || characterDefinition.VoiceTalk.Length != 0 || characterDefinition.VoiceBoostTrick.Length != 0 || characterDefinition.VoiceCombo.Length != 0 || characterDefinition.VoiceGetHit.Length != 0 || characterDefinition.VoiceJump.Length != 0;
		}

		public static bool SetOutfit(this CharacterDefinition characterDefinition, int outfit, out SkinnedMeshRenderer firstActiveRenderer)
		{
			firstActiveRenderer = null;
			for (int i = 0; i < characterDefinition.Renderers.Length; i++)
			{
				SkinnedMeshRenderer val = characterDefinition.Renderers[i];
				((Renderer)val).sharedMaterials = characterDefinition.Outfits[outfit].MaterialContainers[i].Materials;
				((Component)val).gameObject.SetActive(characterDefinition.Outfits[outfit].EnabledRenderers[i]);
				if ((Object)(object)firstActiveRenderer == (Object)null && characterDefinition.Outfits[outfit].EnabledRenderers[i])
				{
					firstActiveRenderer = val;
				}
			}
			StoryBlinkAnimation component = ((Component)characterDefinition).GetComponent<StoryBlinkAnimation>();
			if ((Object)(object)component != (Object)null && (Object)(object)firstActiveRenderer != (Object)null)
			{
				component.mainRenderer = firstActiveRenderer;
				component.characterMesh = firstActiveRenderer.sharedMesh;
			}
			return (Object)(object)firstActiveRenderer != (Object)null;
		}
	}
	public class TextureUtil
	{
		public static Texture2D GetTextureFromBitmap(Bitmap bitmap, FilterMode filterMode = 1)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			ImageConverter val = new ImageConverter();
			byte[] array = (byte[])((TypeConverter)(object)val).ConvertTo((object?)bitmap, typeof(byte[]));
			Texture2D val2 = new Texture2D(((Image)bitmap).Width, ((Image)bitmap).Height);
			ImageConversion.LoadImage(val2, array);
			((Texture)val2).filterMode = filterMode;
			val2.Apply();
			return val2;
		}
	}
}
namespace CrewBoom.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	public class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("CrewBoom.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		public static Bitmap default_graffiti
		{
			get
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Expected O, but got Unknown
				object @object = ResourceManager.GetObject("default_graffiti", resourceCulture);
				return (Bitmap)@object;
			}
		}

		public static Bitmap logo_background
		{
			get
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Expected O, but got Unknown
				object @object = ResourceManager.GetObject("logo_background", resourceCulture);
				return (Bitmap)@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace CrewBoom.Patches
{
	[HarmonyPatch(typeof(CharacterLoader), "GetCharacterFbx")]
	public class GetFbxPatch
	{
		public static void Postfix(Characters character, ref GameObject __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.GetCharacter(character, out var characterObject))
			{
				__result = ((Component)characterObject.Definition).gameObject;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterVisual), "Init")]
	public class BlinkPatch
	{
		public static void Postfix(Characters character, ref bool ___canBlink)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.GetCharacter(character, out var characterObject))
			{
				___canBlink = characterObject.Definition.CanBlink;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterVisual), "SetInlineSkatesPropsMode")]
	public class InlineSkatesTransformPatch
	{
		private static void Postfix(MoveStylePropMode mode, Transform ___footL, Transform ___footR, PlayerMoveStyleProps ___moveStyleProps, CharacterVisual __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_009d: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if ((int)mode != 1)
			{
				return;
			}
			Player componentInParent = ((Component)__instance).GetComponentInParent<Player>(true);
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			Characters character = (Characters)componentInParent.GetField("character").GetValue(componentInParent);
			if (CharacterDatabase.HasCharacter(character))
			{
				Transform val = ___footL.Find("skateOffsetL");
				Transform val2 = ___footR.Find("skateOffsetR");
				if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
				{
					___moveStyleProps.skateL.transform.SetLocalPositionAndRotation(val.localPosition, val.localRotation);
					___moveStyleProps.skateL.transform.localScale = val.localScale;
					___moveStyleProps.skateR.transform.SetLocalPositionAndRotation(val2.localPosition, val2.localRotation);
					___moveStyleProps.skateR.transform.localScale = val2.localScale;
				}
			}
		}
	}
	internal class CharacterProgressPatches
	{
	}
	[HarmonyPatch(typeof(CharacterSelectCharacter), "Init")]
	public class CharacterSelectCharacterInitPatch
	{
		public static void Postfix(CharacterVisual ___visual, Characters setCharacter)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			CharUtil.TrySetCustomOutfit((Component)(object)___visual, CharUtil.GetSavedCharacterOutfit(setCharacter), out var _);
		}
	}
	[HarmonyPatch(typeof(CharacterSelect), "PopulateListOfSelectableCharacters")]
	public class CharacterSelectPopulateListPatch
	{
		public static void Postfix(Player player, List<Characters> ___selectableCharacters, CharacterSelect __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.NewCharacterCount == 0)
			{
				return;
			}
			Characters val = (Characters)player.GetField("character").GetValue(player);
			int num = 26;
			for (int i = num + 1; i <= num + CharacterDatabase.NewCharacterCount; i++)
			{
				Characters val2 = (Characters)i;
				if (val != val2 && CharacterDatabase.HasCypherEnabledForCharacter(val2))
				{
					___selectableCharacters.Add(val2);
				}
			}
			__instance.InvokeMethod("Shuffle", ___selectableCharacters);
		}
	}
	[HarmonyPatch(typeof(CharacterSelect), "SetPlayerToCharacter")]
	public class CharacterSelectSetPlayerPatch
	{
		public static bool Prefix(int index, out Characters __state, CharacterSelect __instance, CharacterSelectCharacter[] ___charactersInCircle, Player ___player)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			CharacterSelectCharacter val = ___charactersInCircle[index];
			__state = (Characters)(int)(Characters)val.GetField("character").GetValue(val);
			if ((int)__state > 26)
			{
				Characters val2 = (Characters)___player.GetField("character").GetValue(___player);
				Characters val3 = __state;
				___player.SetCharacter(val3, 0);
				___player.InitVisual();
				CharacterVisual fieldValue = ___player.GetFieldValue<CharacterVisual>("characterVisual");
				___player.PlayAnim((int)fieldValue.GetField("bounceAnimHash").GetValue(fieldValue), false, false, -1f);
				___player.SetCurrentMoveStyleEquipped(Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(val3).moveStyle, true, true);
				CharacterVisual fieldValue2 = val.GetFieldValue<CharacterVisual>("visual");
				___player.SetRotHard(fieldValue2.tf.forward);
				Object.Destroy((Object)(object)((Component)val).gameObject);
				__instance.InvokeMethod("CreateCharacterSelectCharacter", val2, index, (object)(CharSelectCharState)1);
				return false;
			}
			return true;
		}

		public static void Postfix(Player ___player, Characters __state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			int savedCharacterOutfit = CharUtil.GetSavedCharacterOutfit(__state);
			CharacterVisual source = (CharacterVisual)___player.GetField("characterVisual").GetValue(___player);
			CharUtil.TrySetCustomOutfit((Component)(object)source, savedCharacterOutfit, out var _);
		}
	}
	[HarmonyPatch(typeof(CharacterSelect), "CreateCharacterSelectCharacter")]
	public class CharacterSelectCreateCharacterPatch
	{
		public static bool Prefix(Characters character, int numInCircle, CharSelectCharState startState, CharacterSelect __instance, Player ___player, CharacterSelectCharacter[] ___charactersInCircle, List<Vector3> ___characterPositions, List<Vector3> ___characterDirections, Transform ___tf, GameObject ___charCollision, GameObject ___charTrigger, GameObject ___swapSequence)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if ((int)character > 26)
			{
				CharacterVisual val = ___player.CharacterConstructor.CreateNewCharacterVisual(character, ___player.animatorController, true, ___player.motor.groundDetection.groundLimit);
				___charactersInCircle[numInCircle] = ((Component)val).gameObject.AddComponent<CharacterSelectCharacter>();
				((Component)___charactersInCircle[numInCircle]).transform.position = ___characterPositions[numInCircle];
				((Component)___charactersInCircle[numInCircle]).transform.rotation = Quaternion.LookRotation(___characterDirections[numInCircle] * -1f);
				((Component)___charactersInCircle[numInCircle]).transform.parent = ___tf;
				___charactersInCircle[numInCircle].Init(__instance, character, ___charCollision, ___charTrigger, ___tf.position, Object.Instantiate<GameObject>(___swapSequence, ((Component)___charactersInCircle[numInCircle]).transform).GetComponent<PlayableDirector>());
				___charactersInCircle[numInCircle].SetState(startState);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterSelect), "GetSelectSequenceAnim")]
	public class CharacterSelectSequencePatch
	{
		public static void Prefix(ref Characters c)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected I4, but got Unknown
			if (CharacterDatabase.GetCharacter(c, out var characterObject))
			{
				c = (Characters)(int)characterObject.Definition.FreestyleAnimation;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterSelectUI), "SetCharacterInformation")]
	public class CharacterSelectUIInfoPatch
	{
		public static bool Prefix(Characters character, TextMeshProUGUI ___characterNameLabel, TextMeshProUGUI ___characterUnlockedOutfitCountLabel, CharacterSelectUI __instance)
		{
			//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_005f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)character > 26 && CharacterDatabase.GetCharacter(character, out var characterObject))
			{
				((TMP_Text)___characterNameLabel).text = characterObject.Definition.CharacterName;
				((TMP_Text)___characterUnlockedOutfitCountLabel).text = "4/4";
				if (CharacterSaveSlots.GetCharacterData(Guid.Parse(characterObject.Definition.Id), out var progress))
				{
					__instance.InvokeMethod("SetCharacterSelectUIMoveStyle", progress.moveStyle);
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterVisual), "GetCharacterFreestyleAnim")]
	public class CharacterFreestylePatch
	{
		public static void Prefix(ref Characters c)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected I4, but got Unknown
			if (CharacterDatabase.GetCharacter(c, out var characterObject))
			{
				c = (Characters)(int)characterObject.Definition.FreestyleAnimation;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterVisual), "GetCharacterBounceAnim")]
	public class CharacterBouncePatch
	{
		public static void Prefix(ref Characters c)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected I4, but got Unknown
			if (CharacterDatabase.GetCharacter(c, out var characterObject))
			{
				c = (Characters)(int)characterObject.Definition.BounceAnimation;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterConstructor), "CreateNewCharacterVisual")]
	public class ConstructorCreateVisualPatch
	{
		public static bool Prefix(Characters character, RuntimeAnimatorController controller, bool IK, float setGroundAngleLimit, ref CharacterVisual __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.GetCharacter(character, out var characterObject))
			{
				CharacterVisual val = Object.Instantiate<GameObject>(characterObject.Visual).AddComponent<CharacterVisual>();
				val.Init(character, controller, IK, setGroundAngleLimit);
				((Component)val).gameObject.SetActive(true);
				__result = val;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GraffitiLoader), "LoadGraffitiArtInfoAsync")]
	public class GraffitiLoadAsyncPatch
	{
		private static IEnumerator Postfix(IEnumerator __result, Assets assets, GraffitiLoader __instance)
		{
			AssetBundleRequest graffitiArtInfoRequest = assets.LoadAssetFromBundleASync<GraffitiArtInfo>("graffiti", "graffitiartinfo");
			yield return graffitiArtInfoRequest;
			GraffitiArtInfo info = (GraffitiArtInfo)graffitiArtInfoRequest.asset;
			GraffitiArt redGraffiti = info.graffitiArt.Find((GraffitiArt g) => g.title == "Red");
			Shader shader = redGraffiti.graffitiMaterial.shader;
			CharacterDatabase.SetGraffitiShader(shader);
			for (int i = 0; i < Enum.GetValues(typeof(Characters)).Length - 1; i++)
			{
				Characters character = (Characters)i;
				if (CharacterDatabase.GetCharacter(character, out var customCharacter) && Object.op_Implicit((Object)(object)customCharacter.Definition.Graffiti))
				{
					GraffitiArt graffiti = info.FindByCharacter(character);
					Texture mainTex = customCharacter.Definition.Graffiti.mainTexture;
					graffiti.graffitiMaterial.mainTexture = mainTex;
				}
				customCharacter = null;
			}
			__instance.SetField("graffitiArtInfo", graffitiArtInfoRequest.asset);
		}
	}
	[HarmonyPatch(typeof(GraffitiArtInfo), "FindByCharacter")]
	public class GraffitiFindCharacterPatch
	{
		public static bool Prefix(ref Characters character, ref GraffitiArt __result)
		{
			if ((int)character > 26)
			{
				if (CharacterDatabase.GetCharacter(character, out var characterObject))
				{
					__result = characterObject.Graffiti;
					return false;
				}
				character = (Characters)3;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GraffitiArtInfo), "FindByTitle")]
	public class GraffitiFindTitlePatch
	{
		public static void Postfix(ref GraffitiArt __result, string grafTitle)
		{
			if ((__result != null || !string.IsNullOrEmpty(grafTitle)) && CharacterDatabase.GetCharacterWithGraffitiTitle(grafTitle, out var characterObject))
			{
				__result = characterObject.Graffiti;
			}
		}
	}
	[HarmonyPatch(typeof(GraffitiGame), "SetStateVisual")]
	public class GraffitiVisualPatch
	{
		public static void Postfix(GraffitiGameState setState, Player ___player, GraffitiArt ___grafArt, GraffitiArtInfo ___graffitiArtInfo)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			if ((int)setState == 2)
			{
				Characters val = (Characters)___player.GetField("character").GetValue(___player);
				if (CharacterDatabase.GetCharacter(val, out var characterObject) && Object.op_Implicit((Object)(object)characterObject.Definition.Graffiti) && ___grafArt == ___graffitiArtInfo.FindByCharacter(val))
				{
					FieldInfo field = ___player.GetField("ui");
					GameplayUI val2 = (GameplayUI)field.GetValue(___player);
					((TMP_Text)val2.graffitiTitle).text = "'" + characterObject.Definition.GraffitiName + "'";
				}
			}
		}
	}
	[HarmonyPatch(typeof(MainMenuManager), "Init")]
	public class MainMenuPatch
	{
		public static void Postfix(MainMenuManager __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_004c: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			Texture2D textureFromBitmap = TextureUtil.GetTextureFromBitmap(Resources.logo_background, (FilterMode)1);
			GameObject val = new GameObject("CrewBoom Logo");
			val.transform.SetParent(((Component)__instance).transform, false);
			Image val2 = val.AddComponent<Image>();
			val2.sprite = Sprite.Create(textureFromBitmap, new Rect(0f, 0f, (float)((Texture)textureFromBitmap).width, (float)((Texture)textureFromBitmap).height), new Vector2(0.5f, 0.5f), 100f);
			RectTransform val3 = GameObjectExtensions.RectTransform(val);
			val3.sizeDelta = new Vector2((float)((Texture)textureFromBitmap).width, (float)((Texture)textureFromBitmap).height);
			val3.anchorMin = new Vector2(0f, 1f);
			val3.anchorMax = val3.anchorMin;
			val3.pivot = val3.anchorMin;
			val3.anchoredPosition = Vector2.one * 32f;
		}
	}
	[HarmonyPatch(typeof(TextMeshProGameTextLocalizer), "GetCharacterName", new Type[] { typeof(Characters) })]
	public class CharacterNamePatch
	{
		public static void Postfix(Characters character, ref string __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.GetCharacter(character, out var characterObject))
			{
				__result = characterObject.Definition.CharacterName;
			}
		}
	}
	[HarmonyPatch(typeof(TextMeshProGameTextLocalizer), "GetCharacterName", new Type[] { typeof(int) })]
	public class CharacterKeyNamePatch
	{
		public static void Postfix(int localizationKeyID, ref string __result)
		{
			if (CharacterDatabase.GetCharacterNameWithId(localizationKeyID, out var name))
			{
				__result = name;
			}
		}
	}
	[HarmonyPatch(typeof(TextMeshProGameTextLocalizer), "GetSkinText")]
	public class SkinTextPatch
	{
		public static Characters Character;

		public const string SPRING_OUTFIT = "U_SKIN_SPRING";

		public const string SUMMER_OUTFIT = "U_SKIN_SUMMER";

		public const string AUTUMN_OUTFIT = "U_SKIN_AUTUMN";

		public const string WINTER_OUTFIT = "U_SKIN_WINTER";

		public static readonly string[] OUTFIT_NAMES = new string[4] { "U_SKIN_SPRING", "U_SKIN_SUMMER", "U_SKIN_AUTUMN", "U_SKIN_WINTER" };

		public static void Postfix(string localizationKey, ref string __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.GetCharacter(Character, out var characterObject))
			{
				int num;
				switch (localizationKey)
				{
				default:
					return;
				case "U_SKIN_SPRING":
					num = 0;
					break;
				case "U_SKIN_SUMMER":
					num = 1;
					break;
				case "U_SKIN_AUTUMN":
					num = 2;
					break;
				case "U_SKIN_WINTER":
					num = 3;
					break;
				}
				string name = characterObject.Definition.Outfits[num].Name;
				if (name != null && name != string.Empty)
				{
					__result = name;
				}
			}
		}
	}
	[HarmonyPatch(typeof(NPC), "InitSceneObject")]
	public class NPCInitPatch
	{
		public static void Prefix(NPC __instance, Characters ___character)
		{
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			OutfitSwappableCharacter[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<OutfitSwappableCharacter>(true);
			if (componentsInChildren != null && componentsInChildren.Length != 0)
			{
				OutfitSwappableCharacter[] array = componentsInChildren;
				foreach (OutfitSwappableCharacter val in array)
				{
					if (CharacterDatabase.GetCharacter(val.Character, out var characterObject))
					{
						DynamicBone[] components = ((Component)val).GetComponents<DynamicBone>();
						foreach (DynamicBone val2 in components)
						{
							((Behaviour)val2).enabled = false;
						}
						CharacterDefinition val3 = Object.Instantiate<CharacterDefinition>(characterObject.Definition, ((Component)val).transform);
						Animator componentInChildren = ((Component)val).GetComponentInChildren<Animator>(true);
						Animator component = ((Component)val3).GetComponent<Animator>();
						component.runtimeAnimatorController = componentInChildren.runtimeAnimatorController;
						Transform val4 = ((Component)componentInChildren).transform.Find("root");
						if ((Object)(object)val4 != (Object)null)
						{
							CharUtil.ReparentAllProps(val4, ((Component)component).transform.Find("root"));
						}
						((Component)val3).transform.SetLocalPositionAndRotation(((Component)componentInChildren).transform.localPosition, ((Component)componentInChildren).transform.localRotation);
						SkinnedMeshRenderer val5 = val3.Renderers[0];
						val.SetField("mainRenderer", val5);
						((Component)val3).gameObject.AddComponent<LookAtIKComponent>();
						((Component)val3).gameObject.AddComponent<DummyAnimationEventRelay>();
						if (characterObject.Definition.CanBlink)
						{
							StoryBlinkAnimation val6 = ((Component)val3).gameObject.AddComponent<StoryBlinkAnimation>();
							val6.mainRenderer = val5;
							val6.characterMesh = val5.sharedMesh;
						}
						MeshCollider component2 = ((Component)componentInChildren).GetComponent<MeshCollider>();
						if (Object.op_Implicit((Object)(object)component2))
						{
							MeshCollider val7 = ((Component)val3).gameObject.AddComponent<MeshCollider>();
							val7.sharedMesh = component2.sharedMesh;
							((Collider)val7).sharedMaterial = ((Collider)component2).sharedMaterial;
							val7.convex = component2.convex;
							((Collider)val7).isTrigger = ((Collider)component2).isTrigger;
						}
						Object.DestroyImmediate((Object)(object)((Component)componentInChildren).gameObject);
					}
				}
			}
			else
			{
				ReplaceNonSwappableCharacter(__instance, ___character);
			}
		}

		private static void ReplaceNonSwappableCharacter(NPC __instance, Characters ___character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if (!CharacterDatabase.GetCharacter(___character, out var characterObject))
			{
				return;
			}
			DummyAnimationEventRelay componentInChildren = ((Component)__instance).GetComponentInChildren<DummyAnimationEventRelay>(true);
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				DynamicBone[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<DynamicBone>(true);
				foreach (DynamicBone val in componentsInChildren)
				{
					((Behaviour)val).enabled = false;
				}
				Animator component = ((Component)componentInChildren).GetComponent<Animator>();
				GameObject gameObject = Object.Instantiate<GameObject>(((Component)characterObject.Definition).gameObject, ((Component)component).transform.parent).gameObject;
				Animator component2 = gameObject.GetComponent<Animator>();
				component2.runtimeAnimatorController = component.runtimeAnimatorController;
				Transform val2 = ((Component)component).transform.Find("root");
				if ((Object)(object)val2 != (Object)null)
				{
					CharUtil.ReparentAllProps(val2, ((Component)component2).transform.Find("root"));
				}
				gameObject.transform.SetLocalPositionAndRotation(((Component)component).transform.localPosition, ((Component)component).transform.localRotation);
				gameObject.AddComponent<LookAtIKComponent>();
				gameObject.AddComponent<DummyAnimationEventRelay>();
				MeshCollider component3 = ((Component)component).GetComponent<MeshCollider>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					MeshCollider val3 = gameObject.AddComponent<MeshCollider>();
					val3.sharedMesh = component3.sharedMesh;
					((Collider)val3).sharedMaterial = ((Collider)component3).sharedMaterial;
					val3.convex = component3.convex;
					((Collider)val3).isTrigger = ((Collider)component3).isTrigger;
				}
				Object.DestroyImmediate((Object)(object)((Component)component).gameObject);
			}
		}
	}
	[HarmonyPatch(typeof(OutfitSwappableCharacter), "SetMaterialAndOutfit")]
	public class OutfitSwappablePatches
	{
		public static bool Prefix(OutfitSwappableCharacter __instance, ref SkinnedMeshRenderer ___mainRenderer, int outfitIndex)
		{
			if (CharUtil.TrySetCustomOutfit((Component)(object)__instance, outfitIndex, out var firstActiveRenderer))
			{
				___mainRenderer = firstActiveRenderer;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(OutfitSwitchMenu), "SkinButtonSelected")]
	public class OutfitSwitchSelectPatch
	{
		public static bool Prefix(OutfitSwitchMenu __instance, MenuTimelineButton ___buttonClicked, CharacterVisual ___previewCharacterVisual, int skinIndex)
		{
			if (__instance.IsTransitioning || (Object)(object)___buttonClicked != (Object)null)
			{
				return false;
			}
			if (CharUtil.TrySetCustomOutfit((Component)(object)___previewCharacterVisual, skinIndex, out var _))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(OutfitSwitchMenu), "SkinButtonClicked")]
	public class OutfitSwitchClickPatch
	{
		public static bool Prefix(OutfitSwitchMenu __instance, MenuTimelineButton clickedButton, int skinIndex, ref MenuTimelineButton ___buttonClicked, Player ___player)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			Characters val = (Characters)___player.GetField("character").GetValue(___player);
			if ((int)val > 26)
			{
				if (CharacterDatabase.GetCharacter(val, out var _))
				{
					if (__instance.IsTransitioning || (Object)(object)___buttonClicked != (Object)null)
					{
						return false;
					}
					___buttonClicked = clickedButton;
					Core.Instance.AudioManager.InvokeMethod("PlaySfxUI", (object)(SfxCollectionID)23, (object)(AudioClipID)547, 0f);
					___player.SetOutfit(skinIndex);
					WantedManager.instance.StopPlayerWantedStatus(true, true);
					OutfitSwitchBehaviour fieldValue = __instance.GetFieldValue<OutfitSwitchBehaviour>("clipBehaviour");
					((MonoBehaviour)__instance).StartCoroutine(((BaseMenuTimelineBehaviour)fieldValue).FlickerDelayedButtonPress(clickedButton, new UnityAction(((BaseMenuTimelineBehaviour)fieldValue).ExitMenu)));
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(OutfitSwitchMenu), "Activate")]
	public class OutfitSwitchActivatePatch
	{
		private static OutfitSwitchMenu _lastMenu;

		public static bool Prefix(OutfitSwitchMenu __instance, Player ___player, MenuTimelineButton[] ___buttons, TMProLocalizationAddOn[] ___texts, GameFontType ___normalGameFontType, GameFontType ___selectedGameFontType, float ___nonSelectableAlphaValue)
		{
			//IL_002a: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0043: 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)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			_lastMenu = __instance;
			Characters val = (SkinTextPatch.Character = (Characters)___player.GetField("character").GetValue(___player));
			if ((int)val > 26)
			{
				if (CharacterDatabase.GetCharacter(val, out var _))
				{
					CharacterProgress characterProgress = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(val);
					CharacterConstructor characterConstructor = ___player.CharacterConstructor;
					MenuTimelineButton val2 = null;
					for (int i = 0; i < 4; i++)
					{
						string text = null;
						if (characterProgress.outfit == i)
						{
							text = "<u>";
						}
						___texts[i].AssignAndUpdateTextWithTags(SkinTextPatch.OUTFIT_NAMES[i], (GroupOptions)5, text, (string)null, Array.Empty<string>());
						MenuTimelineButton val3 = null;
						if (i < 3)
						{
							val3 = ___buttons[i + 1];
						}
						MenuTimelineButton button = ___buttons[i];
						int skinIndex = i;
						button.SetButtonVariables((OnSelectButtonAction)delegate
						{
							__instance.InvokeMethod("SkinButtonSelected", button, skinIndex);
						}, true, (Button)(object)val2, (Button)(object)val3, ___normalGameFontType, ___selectedGameFontType, ___nonSelectableAlphaValue);
						((Selectable)button).interactable = true;
						((UnityEventBase)((Button)button).onClick).RemoveAllListeners();
						((UnityEvent)((Button)button).onClick).AddListener((UnityAction)delegate
						{
							__instance.InvokeMethod("SkinButtonClicked", button, skinIndex);
						});
						((Component)button).gameObject.SetActive(true);
						val2 = button;
					}
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "SetCharacter")]
	public class PlayerInitOverridePatch
	{
		public static void Prefix(ref Characters setChar)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected I4, but got Unknown
			if (CharacterDatabase.HasCharacterOverride && CharacterDatabase.GetCharacterValueFromGuid(CharacterDatabase.CharacterOverride, out var character) && (int)character > 26)
			{
				setChar = (Characters)(int)character;
			}
		}

		public static void Postfix(Player __instance, Characters setChar)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			if (CharacterDatabase.HasCharacterOverride)
			{
				CharacterDatabase.SetCharacterOverrideDone();
			}
			if ((Object)(object)__instance == (Object)(object)WorldHandler.instance.GetCurrentPlayer())
			{
				if (CharacterDatabase.GetCharacter(setChar, out var characterObject))
				{
					CharacterInfo val = new CharacterInfo(characterObject.Definition.CharacterName, characterObject.Definition.GraffitiName);
					CrewBoomAPIDatabase.UpdatePlayerCharacter(val);
				}
				else
				{
					CrewBoomAPIDatabase.UpdatePlayerCharacter((CharacterInfo)null);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "SetOutfit")]
	public class PlayerSetOutfitPatch
	{
		public static bool Prefix(int setOutfit, Player __instance, CharacterVisual ___characterVisual, Characters ___character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (!CharacterDatabase.HasCharacter(___character))
			{
				return true;
			}
			if (!(bool)__instance.GetField("isAI").GetValue(__instance))
			{
				Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(___character).outfit = setOutfit;
				if ((int)___character > 26 && CharacterDatabase.GetFirstOrConfigCharacterId(___character, out var guid))
				{
					CharacterSaveSlots.SaveCharacterData(guid);
				}
			}
			if (CharUtil.TrySetCustomOutfit((Component)(object)___characterVisual, setOutfit, out var firstActiveRenderer))
			{
				___characterVisual.mainRenderer = firstActiveRenderer;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "SetCurrentMoveStyleEquipped")]
	public class PlayerSetMovestyleEquipped
	{
		public static void Postfix(Player __instance, MoveStyle setMoveStyleEquipped)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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 (!(bool)__instance.GetField("isAI").GetValue(__instance))
			{
				Characters val = (Characters)__instance.GetField("character").GetValue(__instance);
				if ((int)val > 26 && CharacterDatabase.GetFirstOrConfigCharacterId(val, out var guid) && CharacterSaveSlots.GetCharacterData(guid, out var progress))
				{
					progress.moveStyle = setMoveStyleEquipped;
					CharacterSaveSlots.SaveCharacterData(guid);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "SaveSelectedCharacter")]
	public class PlayerSaveCharacterPatch
	{
		public static bool Prefix(Player __instance, ref Characters selectedCharacter)
		{
			bool result = true;
			bool flag = (bool)__instance.GetField("isAI").GetValue(__instance);
			bool flag2 = (int)selectedCharacter > 26;
			if (!flag)
			{
				CharacterSaveSlots.CurrentSaveSlot.LastPlayedCharacter = Guid.Empty;
				if (flag2)
				{
					if (CharacterDatabase.GetFirstOrConfigCharacterId(selectedCharacter, out var guid))
					{
						CharacterSaveSlots.CurrentSaveSlot.LastPlayedCharacter = guid;
					}
					result = false;
				}
				CharacterSaveSlots.SaveSlot();
			}
			else if ((int)selectedCharacter > 26)
			{
				result = false;
			}
			return result;
		}
	}
	[HarmonyPatch(typeof(Player), "PlayVoice")]
	public class PlayerVoicePatch
	{
		public static bool Prefix(AudioClipID audioClipID, VoicePriority voicePriority, bool fromPlayer, AudioManager ___audioManager, ref VoicePriority ___currentVoicePriority, Characters ___character, AudioSource ___playerGameplayVoicesAudioSource)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)___character > 26 && CharacterDatabase.GetCharacter(___character, out var characterObject) && !fromPlayer)
			{
				___audioManager.InvokeMethod("PlaySfxGameplay", new Type[3]
				{
					typeof(SfxCollectionID),
					typeof(AudioClipID),
					typeof(float)
				}, characterObject.SfxID, audioClipID, 0f);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SaveSlotData), "GetCharacterProgress")]
	public class SaveSlotGetProgressPatch
	{
		public static bool Prefix(Characters character, ref CharacterProgress __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)character > 26)
			{
				if (CharacterDatabase.GetFirstOrConfigCharacterId(character, out var guid) && CharacterSaveSlots.GetCharacterData(guid, out var progress))
				{
					__result = progress;
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SaveSlotHandler), "SetCurrentSaveSlotDataBySlotId")]
	public class SaveSlotHandlerLoadPatch
	{
		public static void Postfix(int saveSlotId)
		{
			CharacterSaveSlots.LoadSlot(saveSlotId);
		}
	}
	[HarmonyPatch(typeof(SequenceHandler), "ReplaceMaterialsOnCharactersInCutscene")]
	public class SequenceCharacterModelPatch
	{
		private static Dictionary<string, Characters> CutsceneOnlyCharacters = new Dictionary<string, Characters>
		{
			{
				"FauxNoJetpackStory",
				(Characters)23
			},
			{
				"FauxStory",
				(Characters)12
			},
			{
				"SolaceStory",
				(Characters)8
			},
			{
				"IreneStory",
				(Characters)14
			},
			{
				"DJMaskedStory",
				(Characters)9
			},
			{
				"DJNoMaskStory",
				(Characters)9
			},
			{
				"FuturismStory",
				(Characters)20
			},
			{
				"FuturismBStory",
				(Characters)20
			},
			{
				"FuturismCStory",
				(Characters)20
			},
			{
				"FuturismDStory",
				(Characters)20
			},
			{
				"EclipseAStory",
				(Characters)10
			},
			{
				"EclipseBStory",
				(Characters)10
			},
			{
				"EclipseCStory",
				(Characters)10
			},
			{
				"EclipseDStory",
				(Characters)10
			},
			{
				"DotExeEStory",
				(Characters)24
			},
			{
				"DotExeAStory",
				(Characters)7
			},
			{
				"DotExeBStory",
				(Characters)7
			},
			{
				"DotExeCStory",
				(Characters)7
			},
			{
				"DotExeDStory",
				(Characters)7
			},
			{
				"RedShatteredStory",
				(Characters)25
			},
			{
				"DemonTheoryAStory",
				(Characters)11
			},
			{
				"DemonTheoryBStory",
				(Characters)11
			},
			{
				"DemonTheoryCStory",
				(Characters)11
			},
			{
				"FelixNoJetpackStory",
				(Characters)15
			},
			{
				"FrankAStory",
				(Characters)1
			},
			{
				"FrankBStory",
				(Characters)1
			},
			{
				"FrankCStory",
				(Characters)1
			},
			{
				"FrankDStory",
				(Characters)1
			},
			{
				"FleshPrinceStory",
				(Characters)13
			}
		};

		public static void Prefix(PlayableDirector ___sequence)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			OutfitSwappableCharacter[] componentsInChildren = ((Component)___sequence).GetComponentsInChildren<OutfitSwappableCharacter>(true);
			foreach (OutfitSwappableCharacter swappable in componentsInChildren)
			{
				SwapOutfitSwappable(swappable);
			}
			Transform[] componentsInChildren2 = ((Component)___sequence).GetComponentsInChildren<Transform>(true);
			Transform[] array = componentsInChildren2;
			foreach (Transform val in array)
			{
				foreach (string key in CutsceneOnlyCharacters.Keys)
				{
					if (((Object)val).name.StartsWith(key))
					{
						SwapCutsceneOnlyCharacter(val, CutsceneOnlyCharacters[key]);
					}
				}
			}
		}

		private static void SwapOutfitSwappable(OutfitSwappableCharacter swappable)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			if (!CharacterDatabase.GetCharacter(swappable.Character, out var characterObject))
			{
				return;
			}
			DynamicBone[] components = ((Component)((Component)swappable).transform).GetComponents<DynamicBone>();
			foreach (DynamicBone val in components)
			{
				((Behaviour)val).enabled = false;
			}
			GameObject gameObject = Object.Instantiate<GameObject>(((Component)characterObject.Definition).gameObject, ((Component)swappable).transform).gameObject;
			Animator val2 = null;
			foreach (Transform item in ((Component)swappable).transform)
			{
				Transform val3 = item;
				if ((Object)(object)(val2 = ((Component)val3).GetComponent<Animator>()) != (Object)null)
				{
					break;
				}
			}
			Animator component = gameObject.GetComponent<Animator>();
			val2.avatar = component.avatar;
			SkinnedMeshRenderer componentInChildren = ((Component)component).GetComponentInChildren<SkinnedMeshRenderer>(true);
			swappable.SetField("mainRenderer", componentInChildren);
			foreach (Transform item2 in ((Component)val2).transform)
			{
				Transform val4 = item2;
				if (((Object)val4).name == "root")
				{
					((Object)val4).name = ((Object)val4).name + "_old";
					CharUtil.ReparentAllProps(val4, ((Component)component).transform.Find("root"));
				}
				else
				{
					Object.Destroy((Object)(object)((Component)val4).gameObject);
				}
			}
			gameObject.transform.SetParent(((Component)val2).transform, false);
			gameObject.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			Transform[] componentsInChildren = gameObject.GetComponentsInChildren<Transform>();
			foreach (Transform val5 in componentsInChildren)
			{
				if (!((Object)(object)val5.parent != (Object)(object)gameObject.transform))
				{
					val5.SetParent(((Component)val2).transform, false);
				}
			}
			StoryBlinkAnimation component2 = ((Component)val2).GetComponent<StoryBlinkAnimation>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				if (characterObject.Definition.CanBlink)
				{
					component2.mainRenderer = componentInChildren;
					component2.characterMesh = componentInChildren.sharedMesh;
				}
				else
				{
					((Behaviour)component2).enabled = false;
				}
			}
			Object.Destroy((Object)(object)gameObject);
			val2.Rebind(true);
		}

		private static void SwapCutsceneOnlyCharacter(Transform root, Characters character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.HasCharacter(character))
			{
				OutfitSwappableCharacter val = ((Component)root).gameObject.AddComponent<OutfitSwappableCharacter>();
				val.SetField("character", character);
				SwapOutfitSwappable(val);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterLoader), "LoadMaterialForCharacter")]
	public class OutfitShaderGrab
	{
		public static void Postfix(Characters characterToLoad, int outfitIndex, Assets ___assets, CharacterLoader __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Material val = ___assets.LoadAssetFromBundle<Material>("characters", CharUtil.GetOutfitMaterialName(characterToLoad, outfitIndex));
			CharacterDatabase.SetOutfitShader(val.shader);
			__instance.InvokeMethod("AddCharacterMaterial", characterToLoad, outfitIndex, val);
		}
	}
	[HarmonyPatch(typeof(CharacterLoader), "LoadMaterialsForCharacterASync")]
	public class OutfitShaderGrabAsync
	{
		public static IEnumerator Postfix(IEnumerator __result, Characters characterToLoad, int outfitIndex, Assets ___assets, CharacterLoader __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			AssetBundleRequest characterMaterialRequest = ___assets.LoadAssetFromBundleASync<Material>("characters", CharUtil.GetOutfitMaterialName(characterToLoad, outfitIndex));
			yield return characterMaterialRequest;
			Object asset = characterMaterialRequest.asset;
			Material material = (Material)(object)((asset is Material) ? asset : null);
			CharacterDatabase.SetOutfitShader(material.shader);
			__instance.InvokeMethod("AddCharacterMaterial", characterToLoad, outfitIndex, material);
		}
	}
	[HarmonyPatch(typeof(StageManager), "GetPlayerCharacter")]
	public class SetupPatch
	{
		public static bool Prefix(ref Characters __result)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected I4, but got Unknown
			Guid lastPlayedCharacter = CharacterSaveSlots.CurrentSaveSlot.LastPlayedCharacter;
			if (lastPlayedCharacter != Guid.Empty && CharacterDatabase.GetCharacterValueFromGuid(lastPlayedCharacter, out var character))
			{
				__result = (Characters)(int)character;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(StyleSwitchMenu), "SkinButtonClicked")]
	public class StyleSwitchMenuPatch
	{
		public static void Postfix()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			Characters val = (Characters)currentPlayer.GetField("character").GetValue(currentPlayer);
			if ((int)val > 26 && CharacterDatabase.GetFirstOrConfigCharacterId(val, out var guid))
			{
				CharacterSaveSlots.SaveCharacterData(guid);
			}
		}
	}
	[HarmonyPatch(typeof(SfxLibrary), "Init")]
	public class InitSfxLibraryPatch
	{
		public static void Postfix(SfxLibrary __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<SfxCollectionID, SfxCollection> item in __instance.sfxCollectionIDDictionary)
			{
				Characters character = VoiceUtility.CharacterFromVoiceCollection(item.Key);
				CharacterDatabase.InitializeMissingSfxCollections(character, item.Value);
			}
			int num = 26;
			for (int i = num + 1; i <= num + CharacterDatabase.NewCharacterCount; i++)
			{
				Characters character2 = (Characters)i;
				if (CharacterDatabase.GetCharacter(character2, out var characterObject) && (int)characterObject.SfxID != -1)
				{
					__instance.sfxCollectionIDDictionary.Add(characterObject.SfxID, characterObject.Sfx);
				}
			}
		}
	}
	[HarmonyPatch(typeof(SfxLibrary), "GetSfxCollectionById")]
	public class GetSfxCollectionIdPatch
	{
		public static void Postfix(SfxCollectionID sfxCollectionId, ref SfxCollection __result, SfxLibrary __instance)
		{
			//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)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Characters character = VoiceUtility.CharacterFromVoiceCollection(sfxCollectionId);
			if (CharacterDatabase.GetCharacter(character, out var characterObject))
			{
				__result = characterObject.Sfx;
			}
		}
	}
	[HarmonyPatch(typeof(AudioManager), "GetCharacterVoiceSfxCollection")]
	public class GetSfxCharacterCollectionPatch
	{
		public static bool Prefix(Characters character, ref SfxCollectionID __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected I4, but got Unknown
			if ((int)character > 26)
			{
				if (CharacterDatabase.GetCharacter(character, out var characterObject))
				{
					__result = (SfxCollectionID)(int)characterObject.SfxID;
					return false;
				}
				__result = (SfxCollectionID)(-1);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(AudioManager), "PlayVoice")]
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public class PlayVoicePatch
	{
		public static bool Prefix(ref VoicePriority currentPriority, Characters character, AudioClipID audioClipID, AudioSource audioSource, VoicePriority playbackPriority, AudioManager __instance, AudioMixerGroup[] ___mixerGroups)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected I4, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if ((int)character > 26)
			{
				if (CharacterDatabase.GetCharacter(character, out var characterObject))
				{
					if ((int)playbackPriority <= (int)currentPriority && audioSource.isPlaying)
					{
						return false;
					}
					AudioClip val = null;
					if ((Object)(object)characterObject.Sfx != (Object)null)
					{
						val = characterObject.Sfx.GetRandomAudioClipById(audioClipID);
					}
					__instance.InvokeMethod("PlayNonloopingSfx", new Type[4]
					{
						typeof(AudioSource),
						typeof(AudioClip),
						typeof(AudioMixerGroup),
						typeof(float)
					}, audioSource, val, ___mixerGroups[5], 0f);
					currentPriority = (VoicePriority)(int)playbackPriority;
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(AudioManager), "PlayVoice", new Type[]
	{
		typeof(Characters),
		typeof(AudioClipID)
	})]
	public class PlayVoiceForCharacterPatch
	{
		public static bool Prefix(Characters character, AudioClipID audioClipID, AudioManager __instance, AudioMixerGroup[] ___mixerGroups, AudioSource[] ___audioSources, ref VoicePriority __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			__result = (VoicePriority)0;
			if ((int)character > 26)
			{
				if (CharacterDatabase.GetCharacter(character, out var characterObject))
				{
					AudioClip val = null;
					if ((Object)(object)characterObject.Sfx != (Object)null)
					{
						val = characterObject.Sfx.GetRandomAudioClipById(audioClipID);
					}
					__instance.InvokeMethod("PlayNonloopingSfx", new Type[4]
					{
						typeof(AudioSource),
						typeof(AudioClip),
						typeof(AudioMixerGroup),
						typeof(float)
					}, ___audioSources[5], val, ___mixerGroups[5], 0f);
				}
				return false;
			}
			return true;
		}
	}
}
namespace CrewBoom.Data
{
	public class CustomCharacter
	{
		private GameObject _visual;

		private static readonly List<AudioClipID> VOICE_IDS = new List<AudioClipID>
		{
			(AudioClipID)484,
			(AudioClipID)485,
			(AudioClipID)486,
			(AudioClipID)498,
			(AudioClipID)487,
			(AudioClipID)488,
			(AudioClipID)489
		};

		public CharacterDefinition Definition { get; private set; }

		public SfxCollection Sfx { get; private set; }

		public SfxCollectionID SfxID { get; private set; }

		public GameObject Visual
		{
			get
			{
				if ((Object)(object)_visual == (Object)null)
				{
					CreateVisual();
				}
				return _visual;
			}
		}

		public GraffitiArt Graffiti { get; private set; }

		public CustomCharacter(CharacterDefinition definition, SfxCollectionID sfxID, bool replacement)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Definition = definition;
			CreateSfxCollection();
			SfxID = sfxID;
			if (!replacement)
			{
				CreateGraffiti();
			}
		}

		private void CreateVisual()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			GameObject val = new GameObject(Definition.CharacterName + " Visuals");
			CharacterDefinition val2 = Object.Instantiate<CharacterDefinition>(Definition);
			((Component)val2).transform.SetParent(val.transform, false);
			for (int i = 0; i < val2.Renderers.Length; i++)
			{
				SkinnedMeshRenderer val3 = val2.Renderers[i];
				((Renderer)val3).sharedMaterials = Definition.Outfits[0].MaterialContainers[i].Materials;
				((Renderer)val3).receiveShadows = false;
				((Component)val3).gameObject.layer = 15;
				((Component)val3).gameObject.SetActive(Definition.Outfits[0].EnabledRenderers[i]);
			}
			((Component)val2).GetComponentInChildren<Animator>().applyRootMotion = false;
			val.SetActive(false);
			_visual = val;
		}

		private void CreateSfxCollection()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0054: 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)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected I4, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Invalid comparison between Unknown and I4
			if (!Definition.HasVoices())
			{
				return;
			}
			SfxCollection val = ScriptableObject.CreateInstance<SfxCollection>();
			val.audioClipContainers = (RandomAudioClipContainer[])(object)new RandomAudioClipContainer[VOICE_IDS.Count];
			for (int i = 0; i < VOICE_IDS.Count; i++)
			{
				val.audioClipContainers[i] = new RandomAudioClipContainer();
				val.audioClipContainers[i].clipID = VOICE_IDS[i];
				val.audioClipContainers[i].clips = null;
				val.audioClipContainers[i].lastRandomClip = 0;
			}
			RandomAudioClipContainer[] audioClipContainers = val.audioClipContainers;
			foreach (RandomAudioClipContainer val2 in audioClipContainers)
			{
				AudioClipID clipID = val2.clipID;
				AudioClipID val3 = clipID;
				switch (val3 - 484)
				{
				default:
					if ((int)val3 == 498 && Definition.VoiceBoostTrick.Length != 0)
					{
						val2.clips = Definition.VoiceBoostTrick;
					}
					break;
				case 0:
					if (Definition.VoiceDie.Length != 0)
					{
						val2.clips = Definition.VoiceDie;
					}
					break;
				case 1:
					if (Definition.VoiceDieFall.Length != 0)
					{
						val2.clips = Definition.VoiceDieFall;
					}
					break;
				case 2:
					if (Definition.VoiceTalk.Length != 0)
					{
						val2.clips = Definition.VoiceTalk;
					}
					break;
				case 3:
					if (Definition.VoiceCombo.Length != 0)
					{
						val2.clips = Definition.VoiceCombo;
					}
					break;
				case 4:
					if (Definition.VoiceGetHit.Length != 0)
					{
						val2.clips = Definition.VoiceGetHit;
					}
					break;
				case 5:
					if (Definition.VoiceJump.Length != 0)
					{
						val2.clips = Definition.VoiceJump;
					}
					break;
				}
			}
			Sfx = val;
		}

		private void CreateGraffiti()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			Material val = Definition.Graffiti;
			string title = Definition.GraffitiName;
			string artistName = Definition.GraffitiArtist;
			if ((Object)(object)val == (Object)null)
			{
				val = new Material(Shader.Find("Standard"));
				val.mainTexture = (Texture)(object)TextureUtil.GetTextureFromBitmap(Resources.default_graffiti, (FilterMode)1);
				title = "Crew BOOM";
				artistName = "SGiygas";
			}
			GraffitiArt val2 = new GraffitiArt();
			val2.graffitiSize = (GraffitiSize)0;
			val2.graffitiMaterial = val;
			val2.title = title;
			val2.artistName = artistName;
			GraffitiAppEntry val3 = ScriptableObject.CreateInstance<GraffitiAppEntry>();
			val3.Size = (GraffitiSize)0;
			val3.GraffitiTexture = val.mainTexture;
			val3.Title = Definition.GraffitiName;
			val3.Artist = Definition.GraffitiArtist;
			val2.unlockable = val3;
			Graffiti = val2;
		}

		public void ApplySfxCollection(SfxCollection collection)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Sfx == (Object)null)
			{
				Sfx = collection;
				return;
			}
			RandomAudioClipContainer[] audioClipContainers = collection.audioClipContainers;
			foreach (RandomAudioClipContainer val in audioClipContainers)
			{
				if (!VOICE_IDS.Contains(val.clipID))
				{
					Array.Resize(ref Sfx.audioClipContainers, Sfx.audioClipContainers.Length + 1);
					Sfx.audioClipContainers[Sfx.audioClipContainers.Length - 1] = val;
				}
			}
		}

		public void ApplyShaderToOutfits(Shader shader)
		{
			CharacterOutfit[] outfits = Definition.Outfits;
			foreach (CharacterOutfit val in outfits)
			{
				CharacterOutfitRenderer[] materialContainers = val.MaterialContainers;
				foreach (CharacterOutfitRenderer val2 in materialContainers)
				{
					for (int k = 0; k < val2.Materials.Length; k++)
					{
						if (val2.UseShaderForMaterial[k])
						{
							val2.Materials[k].shader = shader;
						}
					}
				}
			}
		}

		public void ApplyShaderToGraffiti(Shader shader)
		{
			if (Graffiti != null)
			{
				Graffiti.graffitiMaterial.shader = shader;
			}
		}
	}
}

BepInEx/plugins/CrewBoom/CrewBoomAPI.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.CodeAnalysis;

[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.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("CrewBoomAPI")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("API to interact with Crew Boom.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+fe750cb15aafe2527fad60c5296f5be8aaf0403d")]
[assembly: AssemblyProduct("CrewBoomAPI")]
[assembly: AssemblyTitle("CrewBoomAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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 CrewBoomAPI
{
	public class CharacterInfo
	{
		public readonly string Name;

		public readonly string GraffitiName;

		public CharacterInfo(string name, string graffitiName)
		{
			Name = name;
			GraffitiName = graffitiName;
		}
	}
	public static class CrewBoomAPIDatabase
	{
		private static Dictionary<int, Guid> _userCharacters;

		public static bool IsInitialized { get; private set; }

		public static CharacterInfo PlayerCharacterInfo { get; private set; }

		public static event Action OnInitialized;

		public static event Action<Guid> OnOverride;

		public static event Action<CharacterInfo> OnPlayerCharacterInfoChanged;

		public static void Initialize(Dictionary<int, Guid> userCharacters)
		{
			_userCharacters = userCharacters;
			CrewBoomAPIDatabase.OnInitialized?.Invoke();
			IsInitialized = true;
		}

		public static void UpdatePlayerCharacter(CharacterInfo characterInfo)
		{
			PlayerCharacterInfo = characterInfo;
			CrewBoomAPIDatabase.OnPlayerCharacterInfoChanged?.Invoke(characterInfo);
		}

		public static bool GetUserGuidForCharacter(int character, out Guid guid)
		{
			guid = Guid.Empty;
			if (_userCharacters.TryGetValue(character, out guid))
			{
				return true;
			}
			return false;
		}

		public static void OverrideNextCharacterLoadedWithGuid(Guid guid)
		{
			CrewBoomAPIDatabase.OnOverride?.Invoke(guid);
		}
	}
}

BepInEx/plugins/CrewBoom/CrewBoomMono.dll

Decompiled 10 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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.6", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("CrewBoomMono")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Library to supply monobehaviours for Crew Boom characters.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CrewBoomMono")]
[assembly: AssemblyTitle("CrewBoomMono")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 CrewBoomMono
{
	[AddComponentMenu("Crew Boom/Character Definition")]
	public class CharacterDefinition : MonoBehaviour
	{
		public string CharacterName = "New Custom Character";

		public BrcCharacter FreestyleAnimation = BrcCharacter.Red;

		public BrcCharacter BounceAnimation = BrcCharacter.Red;

		public BrcMovestyle DefaultMovestyle = BrcMovestyle.Skateboard;

		public SkinnedMeshRenderer[] Renderers;

		public CharacterOutfit[] Outfits;

		public Material Graffiti;

		public string GraffitiName;

		public string GraffitiArtist;

		public AudioClip[] VoiceDie;

		public AudioClip[] VoiceDieFall;

		public AudioClip[] VoiceTalk;

		public AudioClip[] VoiceBoostTrick;

		public AudioClip[] VoiceCombo;

		public AudioClip[] VoiceGetHit;

		public AudioClip[] VoiceJump;

		public bool CanBlink;

		public string Id;
	}
	public class CharacterConfig
	{
		public string CharacterToReplace = "None";
	}
	public enum BrcCharacter
	{
		None = -1,
		Vinyl,
		Frank,
		Coil,
		Red,
		Tryce,
		Bel,
		Rave,
		DotExeMember,
		Solace,
		DjCyber,
		EclipseMember,
		DevilTheoryMember,
		FauxWithBoostPack,
		FleshPrince,
		Irene,
		Felix,
		OldHeadMember,
		Base,
		Jet,
		Mesh,
		FuturismMember,
		Rise,
		Shine,
		FauxWithoutBoostPack,
		DotExeBoss,
		FelixWithCyberHead
	}
	public enum BrcMovestyle
	{
		Bmx = 1,
		Skateboard,
		Skates
	}
	public class CharacterOutfit : MonoBehaviour
	{
		public string Name;

		public bool[] EnabledRenderers;

		public CharacterOutfitRenderer[] MaterialContainers;
	}
	public class CharacterOutfitRenderer : MonoBehaviour
	{
		public Material[] Materials;

		public bool[] UseShaderForMaterial;
	}
}