Decompiled source of LD CrewBoom v4.0.0

CrewBoom.dll

Decompiled 14 hours 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.Linq;
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.Compatibility;
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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("CrewBoom")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A plugin to load custom skins and characters for Bomb Rush Cyberfunk.")]
[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.0.0+e76adb901edfab6f31e4754e79cf57fda5d4e00c")]
[assembly: AssemblyProduct("CrewBoom")]
[assembly: AssemblyTitle("CrewBoom")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.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 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Invalid comparison between Unknown and I4
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Invalid comparison between Unknown and I4
			//IL_00c4: 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>>();
			foreach (Characters value in Enum.GetValues(typeof(Characters)))
			{
				if ((int)value == -1 || (int)value == 26)
				{
					_characterIds.Add(value, null);
				}
				else
				{
					_characterIds.Add(value, 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");
			for (int i = 0; i < files.Length; i++)
			{
				if (LoadCharacterBundle(files[i], enableCypher: true))
				{
					result = true;
				}
			}
			files = Directory.GetFiles(NO_CYPHER_PATH, "*.cbb");
			for (int i = 0; i < files.Length; i++)
			{
				if (LoadCharacterBundle(files[i], enableCypher: false))
				{
					result = true;
				}
			}
			files = Directory.GetFiles(Paths.PluginPath, "*.cbb", SearchOption.AllDirectories);
			for (int i = 0; i < files.Length; i++)
			{
				if (LoadCharacterBundle(files[i], enableCypher: true))
				{
					result = true;
				}
			}
			return result;
		}

		private static bool LoadCharacterBundle(string filePath, bool enableCypher)
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Invalid comparison between Unknown and I4
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Invalid comparison between Unknown and I4
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			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;
					for (int i = 0; i < array2.Length; i++)
					{
						val2 = array2[i].GetComponent<CharacterDefinition>();
						if ((Object)(object)val2 != (Object)null)
						{
							break;
						}
					}
					if ((Object)(object)val2 != (Object)null)
					{
						string fileName = Path.GetFileName(filePath);
						BrcCharacter val3 = (BrcCharacter)(-1);
						string path = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".json");
						if (File.Exists(path))
						{
							string text = File.ReadAllText(path);
							try
							{
								CharacterConfig val4 = JsonUtility.FromJson<CharacterConfig>(text);
								if (Enum.TryParse<BrcCharacter>(val4.CharacterToReplace, out BrcCharacter result2))
								{
									val3 = result2;
								}
								else
								{
									DebugLog.LogWarning((object)("The configured replacement character for the bundle " + fileName + " (\"" + val4.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)val3 == -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)val3 != -1)
							{
								_characterIds[(Characters)val3].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)val3 != -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_0005: 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_0007: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0003: 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_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!_characterIds.TryGetValue(character, out var value))
			{
				return false;
			}
			if (value != null)
			{
				return value.Count > 0;
			}
			return false;
		}

		public static bool HasCypherEnabledForCharacter(Characters character)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			if (!GetFirstOrConfigCharacterId(character, out var guid))
			{
				return false;
			}
			if (GetCharacter(character, out var characterObject))
			{
				if ((int)characterObject.Definition.UnlockType == 2)
				{
					return false;
				}
				if ((int)characterObject.Definition.UnlockType == 1 && CharacterSaveSlots.GetCharacterData(guid, out var progress))
				{
					return progress.unlocked;
				}
			}
			if (_cypherMapping.TryGetValue(guid, out var value))
			{
				return value;
			}
			return false;
		}

		public static bool GetCharacterValueFromGuid(Guid guid, out Characters character)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_002f: 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_0037: Invalid comparison between Unknown and I4
			//IL_0039: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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)
			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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_001a: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0060: 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_006c: 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_0079: Expected O, but got Unknown
			if (_progressLookup.TryGetValue(guid, out progress))
			{
				return true;
			}
			progress = new CharacterProgress();
			progress.unlocked = false;
			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", "4.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string CharacterAPIGuid = "com.Viliger.CharacterAPI";

		private void Awake()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if (Chainloader.PluginInfos.ContainsKey("com.Viliger.CharacterAPI"))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"LD CrewBoom is incompatible with CharacterAPI (viliger) and will not load!\nUninstall CharacterAPI and restart the game if you want to use LD CrewBoom.");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogMessage((object)"LD CrewBoom v4.0.0 starting...");
			CharacterDatabaseConfig.Initialize(((BaseUnityPlugin)this).Config);
			if (CharacterDatabase.Initialize())
			{
				new Harmony("softGoat.crewBoom").PatchAll();
				((BaseUnityPlugin)this).Logger.LogMessage((object)"Loaded all available characters!");
			}
			if (Chainloader.PluginInfos.ContainsKey("com.Dragsun.BunchOfEmotes"))
			{
				BunchOfEmotesSupport.Initialize();
				StageManager.OnStagePostInitialization += new OnStageInitializedDelegate(BoE_StageManager_OnStagePostInitialization);
			}
		}

		private void BoE_StageManager_OnStagePostInitialization()
		{
			BunchOfEmotesSupport.CacheAnimations();
		}
	}
	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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_0033: 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)
			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 VoiceUtility
	{
		public static SfxCollectionID VoiceCollectionFromCharacter(Characters character)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected I4, but got Unknown
			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_0000: 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_0095: Expected I4, but got Unknown
			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 = "4.0.0";
	}
}
namespace CrewBoom.Utility
{
	public static class CharacterDefinitionExtensions
	{
		public static bool HasVoices(this CharacterDefinition characterDefinition)
		{
			if (characterDefinition.VoiceDie.Length == 0 && characterDefinition.VoiceDieFall.Length == 0 && characterDefinition.VoiceTalk.Length == 0 && characterDefinition.VoiceBoostTrick.Length == 0 && characterDefinition.VoiceCombo.Length == 0 && characterDefinition.VoiceGetHit.Length == 0)
			{
				return characterDefinition.VoiceJump.Length != 0;
			}
			return true;
		}

		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 static class ReflectionUtility
	{
		public static Type GetTypeByName(string name)
		{
			foreach (Assembly item in AppDomain.CurrentDomain.GetAssemblies().Reverse())
			{
				Type type = item.GetType(name);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}
	}
	public class TextureUtil
	{
		public static Texture2D GetTextureFromBitmap(Bitmap bitmap, FilterMode filterMode = 1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			byte[] array = (byte[])((TypeConverter)new ImageConverter()).ConvertTo((object?)bitmap, typeof(byte[]));
			Texture2D val = new Texture2D(((Image)bitmap).Width, ((Image)bitmap).Height);
			ImageConversion.LoadImage(val, array);
			((Texture)val).filterMode = filterMode;
			val.Apply();
			return val;
		}
	}
}
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)
				{
					resourceMan = new ResourceManager("CrewBoom.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

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

		public static Bitmap default_graffiti => (Bitmap)ResourceManager.GetObject("default_graffiti", resourceCulture);

		public static Bitmap logo_background => (Bitmap)ResourceManager.GetObject("logo_background", resourceCulture);

		internal Resources()
		{
		}
	}
}
namespace CrewBoom.Patches
{
	[HarmonyPatch(typeof(CharacterLoader), "GetCharacterFbx")]
	public class GetFbxPatch
	{
		public static void Postfix(Characters character, ref GameObject __result)
		{
			//IL_0000: 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_0000: 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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0019: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00ac: 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) && CharacterDatabase.HasCharacter(componentInParent.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;
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterSelectCharacter), "Init")]
	public class CharacterSelectCharacterInitPatch
	{
		public static void Postfix(CharacterVisual ___visual, Characters setCharacter)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			CharUtil.TrySetCustomOutfit((Component)(object)___visual, CharUtil.GetSavedCharacterOutfit(setCharacter), out var _);
		}
	}
	[HarmonyPatch(typeof(CharacterSelectCharacter), "SetState")]
	public class CharacterSelectCharacterSetStatePatch
	{
		public static void Prefix(CharacterSelectCharacter __instance, CharSelectCharState setState)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			if (BunchOfEmotesSupport.Installed && BunchOfEmotesSupport.IsCustomAnimation(__instance.visual.bounceAnimHash) && ((int)setState == 5 || (int)setState == 1))
			{
				__instance.visual.anim.runtimeAnimatorController = BunchOfEmotesSupport.AnimatorController;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterSelect), "PopulateListOfSelectableCharacters")]
	public class CharacterSelectPopulateListPatch
	{
		public static void Postfix(Player player, List<Characters> ___selectableCharacters, CharacterSelect __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//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_001c: 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)
			if (CharacterDatabase.NewCharacterCount == 0)
			{
				return;
			}
			int num = 26;
			for (int i = num + 1; i <= num + CharacterDatabase.NewCharacterCount; i++)
			{
				Characters val = (Characters)i;
				if (player.character != val && CharacterDatabase.HasCypherEnabledForCharacter(val))
				{
					___selectableCharacters.Add(val);
				}
			}
			__instance.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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected I4, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0023: 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_0061: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			CharacterSelectCharacter val = ___charactersInCircle[index];
			__state = (Characters)(int)val.character;
			if ((int)__state > 26)
			{
				Characters character = ___player.character;
				Characters character2 = val.character;
				___player.SetCharacter(character2, 0);
				___player.InitVisual();
				CharacterVisual characterVisual = ___player.characterVisual;
				___player.PlayAnim(characterVisual.bounceAnimHash, false, false, -1f);
				___player.SetCurrentMoveStyleEquipped(Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(character2).moveStyle, true, true);
				CharacterVisual visual = val.visual;
				___player.SetRotHard(visual.tf.forward);
				Object.Destroy((Object)(object)((Component)val).gameObject);
				__instance.CreateCharacterSelectCharacter(character, index, (CharSelectCharState)1);
				return false;
			}
			return true;
		}

		public static void Postfix(Player ___player, Characters __state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			int savedCharacterOutfit = CharUtil.GetSavedCharacterOutfit(__state);
			CharUtil.TrySetCustomOutfit((Component)(object)___player.characterVisual, 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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_000f: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0095: 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)
			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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: 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)
			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.SetCharacterSelectUIMoveStyle(progress.moveStyle);
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterVisual), "GetCharacterFreestyleAnim")]
	public class CharacterFreestylePatch
	{
		public static void Prefix(ref Characters c)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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 bool Prefix(ref Characters c, ref int __result)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected I4, but got Unknown
			if (CharacterDatabase.GetCharacter(c, out var characterObject))
			{
				if (!string.IsNullOrWhiteSpace(characterObject.Definition.BoEBounceAnimation) && BunchOfEmotesSupport.Installed && BunchOfEmotesSupport.TryGetGameAnimationForCustomAnimationName(characterObject.Definition.BoEBounceAnimation, out var gameAnim))
				{
					__result = gameAnim;
					return false;
				}
				c = (Characters)(int)characterObject.Definition.BounceAnimation;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterConstructor), "CreateNewCharacterVisual")]
	public class ConstructorCreateVisualPatch
	{
		public static bool Prefix(Characters character, RuntimeAnimatorController controller, bool IK, float setGroundAngleLimit, ref CharacterVisual __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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
	{
		[CompilerGenerated]
		private sealed class <Postfix>d__0 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Assets assets;

			public GraffitiLoader __instance;

			private AssetBundleRequest <graffitiArtInfoRequest>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Postfix>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<graffitiArtInfoRequest>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Expected O, but got Unknown
				//IL_009d: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<graffitiArtInfoRequest>5__2 = assets.LoadAssetFromBundleASync<GraffitiArtInfo>("graffiti", "graffitiartinfo");
					<>2__current = <graffitiArtInfoRequest>5__2;
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					GraffitiArtInfo val = (GraffitiArtInfo)<graffitiArtInfoRequest>5__2.asset;
					CharacterDatabase.SetGraffitiShader(val.graffitiArt.Find((GraffitiArt g) => g.title == "Red").graffitiMaterial.shader);
					for (int i = 0; i < Enum.GetValues(typeof(Characters)).Length - 1; i++)
					{
						Characters val2 = (Characters)i;
						if (CharacterDatabase.GetCharacter(val2, out var characterObject) && Object.op_Implicit((Object)(object)characterObject.Definition.Graffiti))
						{
							GraffitiArt obj = val.FindByCharacter(val2);
							Texture mainTexture = characterObject.Definition.Graffiti.mainTexture;
							obj.graffitiMaterial.mainTexture = mainTexture;
						}
					}
					ref GraffitiArtInfo graffitiArtInfo = ref __instance.graffitiArtInfo;
					Object asset = <graffitiArtInfoRequest>5__2.asset;
					graffitiArtInfo = (GraffitiArtInfo)(object)((asset is GraffitiArtInfo) ? asset : null);
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[IteratorStateMachine(typeof(<Postfix>d__0))]
		private static IEnumerator Postfix(IEnumerator __result, Assets assets, GraffitiLoader __instance)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Postfix>d__0(0)
			{
				assets = assets,
				__instance = __instance
			};
		}
	}
	[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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((int)setState == 2 && CharacterDatabase.GetCharacter(___player.character, out var characterObject) && Object.op_Implicit((Object)(object)characterObject.Definition.Graffiti) && ___grafArt == ___graffitiArtInfo.FindByCharacter(___player.character))
			{
				((TMP_Text)___player.ui.graffitiTitle).text = "'" + characterObject.Definition.GraffitiName + "'";
			}
		}
	}
	[HarmonyPatch(typeof(MainMenuManager), "Init")]
	public class MainMenuPatch
	{
		public static void Postfix(MainMenuManager __instance)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_006f: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00ab: 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_00bf: 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);
			val.AddComponent<Image>().sprite = Sprite.Create(textureFromBitmap, new Rect(0f, 0f, (float)((Texture)textureFromBitmap).width, (float)((Texture)textureFromBitmap).height), new Vector2(0.5f, 0.5f), 100f);
			RectTransform obj = GameObjectExtensions.RectTransform(val);
			obj.sizeDelta = new Vector2((float)((Texture)textureFromBitmap).width, (float)((Texture)textureFromBitmap).height);
			obj.anchorMin = new Vector2(0f, 1f);
			obj.anchorMax = obj.anchorMin;
			obj.pivot = obj.anchorMin;
			obj.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_0000: 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_0000: 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_01ae: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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>();
						for (int j = 0; j < components.Length; j++)
						{
							((Behaviour)components[j]).enabled = false;
						}
						CharacterDefinition val2 = Object.Instantiate<CharacterDefinition>(characterObject.Definition, ((Component)val).transform);
						Animator componentInChildren = ((Component)val).GetComponentInChildren<Animator>(true);
						Animator component = ((Component)val2).GetComponent<Animator>();
						component.runtimeAnimatorController = componentInChildren.runtimeAnimatorController;
						Transform val3 = ((Component)componentInChildren).transform.Find("root");
						if ((Object)(object)val3 != (Object)null)
						{
							CharUtil.ReparentAllProps(val3, ((Component)component).transform.Find("root"));
						}
						((Component)val2).transform.SetLocalPositionAndRotation(((Component)componentInChildren).transform.localPosition, ((Component)componentInChildren).transform.localRotation);
						SkinnedMeshRenderer val4 = (val.mainRenderer = val2.Renderers[0]);
						((Component)val2).gameObject.AddComponent<LookAtIKComponent>();
						((Component)val2).gameObject.AddComponent<DummyAnimationEventRelay>();
						if (characterObject.Definition.CanBlink)
						{
							StoryBlinkAnimation obj = ((Component)val2).gameObject.AddComponent<StoryBlinkAnimation>();
							obj.mainRenderer = val4;
							obj.characterMesh = val4.sharedMesh;
						}
						MeshCollider component2 = ((Component)componentInChildren).GetComponent<MeshCollider>();
						if (Object.op_Implicit((Object)(object)component2))
						{
							MeshCollider obj2 = ((Component)val2).gameObject.AddComponent<MeshCollider>();
							obj2.sharedMesh = component2.sharedMesh;
							((Collider)obj2).sharedMaterial = ((Collider)component2).sharedMaterial;
							obj2.convex = component2.convex;
							((Collider)obj2).isTrigger = ((Collider)component2).isTrigger;
						}
						Object.DestroyImmediate((Object)(object)((Component)componentInChildren).gameObject);
					}
				}
			}
			else
			{
				ReplaceNonSwappableCharacter(__instance, ___character);
			}
		}

		private static void ReplaceNonSwappableCharacter(NPC __instance, Characters ___character)
		{
			//IL_0000: 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_00ce: 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);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Behaviour)componentsInChildren[i]).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 val = ((Component)component).transform.Find("root");
				if ((Object)(object)val != (Object)null)
				{
					CharUtil.ReparentAllProps(val, ((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 obj = gameObject.AddComponent<MeshCollider>();
					obj.sharedMesh = component3.sharedMesh;
					((Collider)obj).sharedMaterial = ((Collider)component3).sharedMaterial;
					obj.convex = component3.convex;
					((Collider)obj).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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if ((int)___player.character > 26)
			{
				if (CharacterDatabase.GetCharacter(___player.character, out var _))
				{
					if (__instance.IsTransitioning || (Object)(object)___buttonClicked != (Object)null)
					{
						return false;
					}
					___buttonClicked = clickedButton;
					Core.Instance.AudioManager.PlaySfxUI((SfxCollectionID)23, (AudioClipID)547, 0f);
					___player.SetOutfit(skinIndex);
					WantedManager.instance.StopPlayerWantedStatus(true, true);
					((MonoBehaviour)__instance).StartCoroutine(((BaseMenuTimelineBehaviour)__instance.clipBehaviour).FlickerDelayedButtonPress(clickedButton, new UnityAction(((BaseMenuTimelineBehaviour)__instance.clipBehaviour).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_0019: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_00f2: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			_lastMenu = __instance;
			SkinTextPatch.Character = ___player.character;
			if ((int)___player.character > 26)
			{
				if (CharacterDatabase.GetCharacter(___player.character, out var _))
				{
					CharacterProgress characterProgress = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(___player.character);
					_ = ___player.CharacterConstructor;
					MenuTimelineButton val = 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 val2 = null;
						if (i < 3)
						{
							val2 = ___buttons[i + 1];
						}
						MenuTimelineButton button = ___buttons[i];
						int skinIndex = i;
						button.SetButtonVariables((OnSelectButtonAction)delegate
						{
							__instance.SkinButtonSelected(button, skinIndex);
						}, true, (Button)(object)val, (Button)(object)val2, ___normalGameFontType, ___selectedGameFontType, ___nonSelectableAlphaValue);
						((Selectable)button).interactable = true;
						((UnityEventBase)((Button)button).onClick).RemoveAllListeners();
						((UnityEvent)((Button)button).onClick).AddListener((UnityAction)delegate
						{
							__instance.SkinButtonSelected(button, skinIndex);
						});
						((Component)button).gameObject.SetActive(true);
						val = button;
					}
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "SetCharacter")]
	public class PlayerInitOverridePatch
	{
		public static void Prefix(ref Characters setChar)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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))
				{
					CrewBoomAPIDatabase.UpdatePlayerCharacter(new CharacterInfo(characterObject.Definition.CharacterName, characterObject.Definition.GraffitiName));
				}
				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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!CharacterDatabase.HasCharacter(___character))
			{
				return true;
			}
			if (!__instance.isAI)
			{
				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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.isAI && (int)__instance.character > 26 && CharacterDatabase.GetFirstOrConfigCharacterId(__instance.character, 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 = (int)selectedCharacter > 26;
			if (!__instance.isAI)
			{
				CharacterSaveSlots.CurrentSaveSlot.LastPlayedCharacter = Guid.Empty;
				if (flag)
				{
					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), "PlayAnim")]
	public class PlayerPlayAnimPatch
	{
		public static bool Prefix(Player __instance, int newAnim)
		{
			if (BunchOfEmotesSupport.Installed && BunchOfEmotesSupport.IsCustomAnimation(__instance.curAnim) && __instance.curAnim == __instance.characterVisual.bounceAnimHash && (newAnim == __instance.idleHash || newAnim == __instance.idleFidget1Hash || newAnim == __instance.stopRunHash))
			{
				return false;
			}
			return true;
		}
	}
	[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_0000: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)___character > 26 && CharacterDatabase.GetCharacter(___character, out var characterObject) && !fromPlayer)
			{
				___audioManager.PlaySfxGameplay(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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			OutfitSwappableCharacter[] componentsInChildren = ((Component)___sequence).GetComponentsInChildren<OutfitSwappableCharacter>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				SwapOutfitSwappable(componentsInChildren[i]);
			}
			Transform[] componentsInChildren2 = ((Component)___sequence).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren2)
			{
				foreach (string key in CutsceneOnlyCharacters.Keys)
				{
					if (((Object)val).name.StartsWith(key))
					{
						SwapCutsceneOnlyCharacter(val, CutsceneOnlyCharacters[key]);
					}
				}
			}
		}

		private static void SwapOutfitSwappable(OutfitSwappableCharacter swappable)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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>();
			for (int i = 0; i < components.Length; i++)
			{
				((Behaviour)components[i]).enabled = false;
			}
			GameObject gameObject = Object.Instantiate<GameObject>(((Component)characterObject.Definition).gameObject, ((Component)swappable).transform).gameObject;
			Animator val = null;
			IEnumerator enumerator = ((Component)swappable).transform.GetEnumerator();
			try
			{
				while (enumerator.MoveNext() && !((Object)(object)(val = ((Component)(Transform)enumerator.Current).GetComponent<Animator>()) != (Object)null))
				{
				}
			}
			finally
			{
				IDisposable disposable = enumerator as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
			Animator component = gameObject.GetComponent<Animator>();
			val.avatar = component.avatar;
			SkinnedMeshRenderer val2 = (swappable.mainRenderer = ((Component)component).GetComponentInChildren<SkinnedMeshRenderer>(true));
			foreach (Transform item in ((Component)val).transform)
			{
				Transform val3 = item;
				if (((Object)val3).name == "root")
				{
					((Object)val3).name = ((Object)val3).name + "_old";
					CharUtil.ReparentAllProps(val3, ((Component)component).transform.Find("root"));
				}
				else
				{
					Object.Destroy((Object)(object)((Component)val3).gameObject);
				}
			}
			gameObject.transform.SetParent(((Component)val).transform, false);
			gameObject.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			Transform[] componentsInChildren = gameObject.GetComponentsInChildren<Transform>();
			foreach (Transform val4 in componentsInChildren)
			{
				if (!((Object)(object)val4.parent != (Object)(object)gameObject.transform))
				{
					val4.SetParent(((Component)val).transform, false);
				}
			}
			StoryBlinkAnimation component2 = ((Component)val).GetComponent<StoryBlinkAnimation>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				if (characterObject.Definition.CanBlink)
				{
					component2.mainRenderer = val2;
					component2.characterMesh = val2.sharedMesh;
				}
				else
				{
					((Behaviour)component2).enabled = false;
				}
			}
			Object.Destroy((Object)(object)gameObject);
			val.Rebind(true);
		}

		private static void SwapCutsceneOnlyCharacter(Transform root, Characters character)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.HasCharacter(character))
			{
				OutfitSwappableCharacter obj = ((Component)root).gameObject.AddComponent<OutfitSwappableCharacter>();
				obj.character = character;
				SwapOutfitSwappable(obj);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterLoader), "LoadMaterialForCharacter")]
	public class OutfitShaderGrab
	{
		public static void Postfix(Characters characterToLoad, int outfitIndex, Assets ___assets, CharacterLoader __instance)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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.AddCharacterMaterial(characterToLoad, outfitIndex, val);
		}
	}
	[HarmonyPatch(typeof(CharacterLoader), "LoadMaterialsForCharacterASync")]
	public class OutfitShaderGrabAsync
	{
		[CompilerGenerated]
		private sealed class <Postfix>d__0 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Assets ___assets;

			public Characters characterToLoad;

			public int outfitIndex;

			public CharacterLoader __instance;

			private AssetBundleRequest <characterMaterialRequest>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Postfix>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<characterMaterialRequest>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<characterMaterialRequest>5__2 = ___assets.LoadAssetFromBundleASync<Material>("characters", CharUtil.GetOutfitMaterialName(characterToLoad, outfitIndex));
					<>2__current = <characterMaterialRequest>5__2;
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Object asset = <characterMaterialRequest>5__2.asset;
					Material val = (Material)(object)((asset is Material) ? asset : null);
					CharacterDatabase.SetOutfitShader(val.shader);
					__instance.AddCharacterMaterial(characterToLoad, outfitIndex, val);
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[IteratorStateMachine(typeof(<Postfix>d__0))]
		public static IEnumerator Postfix(IEnumerator __result, Characters characterToLoad, int outfitIndex, Assets ___assets, CharacterLoader __instance)
		{
			//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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Postfix>d__0(0)
			{
				characterToLoad = characterToLoad,
				outfitIndex = outfitIndex,
				___assets = ___assets,
				__instance = __instance
			};
		}
	}
	[HarmonyPatch(typeof(StageManager), "GetPlayerCharacter")]
	public class SetupPatch
	{
		public static bool Prefix(ref Characters __result)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			if ((int)currentPlayer.character > 26 && CharacterDatabase.GetFirstOrConfigCharacterId(currentPlayer.character, out var guid))
			{
				CharacterSaveSlots.SaveCharacterData(guid);
			}
		}
	}
	[HarmonyPatch(typeof(SfxLibrary), "Init")]
	public class InitSfxLibraryPatch
	{
		public static void Postfix(SfxLibrary __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0062: Invalid comparison between Unknown and I4
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<SfxCollectionID, SfxCollection> item in __instance.sfxCollectionIDDictionary)
			{
				CharacterDatabase.InitializeMissingSfxCollections(VoiceUtility.CharacterFromVoiceCollection(item.Key), item.Value);
			}
			int num = 26;
			for (int i = num + 1; i <= num + CharacterDatabase.NewCharacterCount; i++)
			{
				if (CharacterDatabase.GetCharacter((Characters)i, 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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (CharacterDatabase.GetCharacter(VoiceUtility.CharacterFromVoiceCollection(sfxCollectionId), out var characterObject))
			{
				__result = characterObject.Sfx;
			}
		}
	}
	[HarmonyPatch(typeof(AudioManager), "GetCharacterVoiceSfxCollection")]
	public class GetSfxCharacterCollectionPatch
	{
		public static bool Prefix(Characters character, ref SfxCollectionID __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: 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)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected I4, but got Unknown
			//IL_0035: 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.PlayNonloopingSfx(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_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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.PlayNonloopingSfx(___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_0014: Unknown result type (might be due to invalid IL or missing references)
			Definition = definition;
			CreateSfxCollection();
			SfxID = sfxID;
			if (!replacement)
			{
				CreateGraffiti();
			}
		}

		private void CreateVisual()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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 obj = val2.Renderers[i];
				((Renderer)obj).sharedMaterials = Definition.Outfits[0].MaterialContainers[i].Materials;
				((Renderer)obj).receiveShadows = false;
				((Component)obj).gameObject.layer = 15;
				((Component)obj).gameObject.SetActive(Definition.Outfits[0].EnabledRenderers[i]);
			}
			((Component)val2).GetComponentInChildren<Animator>().applyRootMotion = false;
			val.SetActive(false);
			_visual = val;
		}

		private void CreateSfxCollection()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected I4, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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;
				switch (clipID - 484)
				{
				default:
					if ((int)clipID == 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0062: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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 = "Capry";
			}
			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_002b: 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;
			for (int i = 0; i < outfits.Length; i++)
			{
				CharacterOutfitRenderer[] materialContainers = outfits[i].MaterialContainers;
				foreach (CharacterOutfitRenderer val in materialContainers)
				{
					for (int k = 0; k < val.Materials.Length; k++)
					{
						if (val.UseShaderForMaterial[k])
						{
							val.Materials[k].shader = shader;
						}
					}
				}
			}
		}

		public void ApplyShaderToGraffiti(Shader shader)
		{
			if (Graffiti != null)
			{
				Graffiti.graffitiMaterial.shader = shader;
			}
		}
	}
}
namespace CrewBoom.Compatibility
{
	public static class BunchOfEmotesSupport
	{
		private static object BoEPluginInstance = null;

		private static Type BoEPluginType = null;

		private static FieldInfo CustomAnimsField = null;

		private static FieldInfo CustomAnimControllerField = null;

		private static bool Cached = false;

		private static Dictionary<string, int> GameAnimationByCustomAnimationName = new Dictionary<string, int>();

		private static HashSet<int> GameAnimations = new HashSet<int>();

		public static bool Installed { get; private set; } = false;


		public static RuntimeAnimatorController AnimatorController
		{
			get
			{
				object? value = CustomAnimControllerField.GetValue(BoEPluginInstance);
				return (RuntimeAnimatorController)((value is RuntimeAnimatorController) ? value : null);
			}
		}

		public static void Initialize()
		{
			Installed = true;
			BoEPluginInstance = Chainloader.PluginInfos["com.Dragsun.BunchOfEmotes"].Instance;
			BoEPluginType = ReflectionUtility.GetTypeByName("BunchOfEmotes.BunchOfEmotesPlugin");
			CustomAnimsField = BoEPluginType.GetField("myCustomAnims2");
			CustomAnimControllerField = BoEPluginType.GetField("myAnim");
		}

		public static bool IsCustomAnimation(int animHash)
		{
			if (!Installed)
			{
				return false;
			}
			CacheAnimationsIfNecessary();
			return GameAnimations.Contains(animHash);
		}

		public static void CacheAnimations()
		{
			Cached = true;
			foreach (KeyValuePair<int, string> item in CustomAnimsField.GetValue(BoEPluginInstance) as Dictionary<int, string>)
			{
				int key = item.Key;
				GameAnimationByCustomAnimationName[item.Value] = key;
				GameAnimations.Add(key);
			}
		}

		public static void CacheAnimationsIfNecessary()
		{
			if (!Cached)
			{
				CacheAnimations();
			}
		}

		public static bool TryGetGameAnimationForCustomAnimationName(string name, out int gameAnim)
		{
			if (!Installed)
			{
				gameAnim = 0;
				return false;
			}
			CacheAnimationsIfNecessary();
			if (GameAnimationByCustomAnimationName.TryGetValue(name, out gameAnim))
			{
				return true;
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

CrewBoomAPI.dll

Decompiled 14 hours 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);
		}
	}
}

CrewBoomMono.dll

Decompiled 14 hours 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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("CrewBoomMono")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Library to supply monobehaviours for Crew Boom characters.")]
[assembly: AssemblyFileVersion("1.8.0.0")]
[assembly: AssemblyInformationalVersion("1.8.0+d558781e48ea5bc493a660f5dc05fed20cbe2b9c")]
[assembly: AssemblyProduct("CrewBoomMono")]
[assembly: AssemblyTitle("CrewBoomMono")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.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 bool OverrideBundleFilename;

		public string BundleFilename = "";

		public string CharacterName = "New Custom Character";

		public BrcCharacter FreestyleAnimation = BrcCharacter.Red;

		public BrcCharacter BounceAnimation = BrcCharacter.Red;

		public BrcMovestyle DefaultMovestyle = BrcMovestyle.Skateboard;

		public UnlockType UnlockType;

		public string BoEBounceAnimation = "";

		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 enum UnlockType
	{
		AlwaysUnlocked,
		Unlockable,
		Locked
	}
	public class CharacterOutfit : MonoBehaviour
	{
		public string Name;

		public bool[] EnabledRenderers;

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

		public bool[] UseShaderForMaterial;
	}
}