Decompiled source of LD CrewBoom v4.2.0
CrewBoom.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
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 BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CommonAPI; using CrewBoom.Behaviours; using CrewBoom.Compatibility; using CrewBoom.Data; using CrewBoom.Database; using CrewBoom.Mono; 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.2.0.0")] [assembly: AssemblyInformationalVersion("4.2.0+dabe070583f8c672c6e79d8343dd7bc3c6980984")] [assembly: AssemblyProduct("CrewBoom")] [assembly: AssemblyTitle("CrewBoom")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("4.2.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; public static Shader GraffitiShader = null; private static ManualLogSource DebugLog = Logger.CreateLogSource("CrewBoom Database"); private static bool _appliedGrafShaders = false; 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() { int num = 0; bool result = false; string[] files = Directory.GetFiles(ASSET_PATH, "*.cbb"); for (int i = 0; i < files.Length; i++) { if (LoadCharacterBundle(files[i], enableCypher: true, out var generatedStream)) { result = true; if (generatedStream) { num++; } } } files = Directory.GetFiles(NO_CYPHER_PATH, "*.cbb"); for (int i = 0; i < files.Length; i++) { if (LoadCharacterBundle(files[i], enableCypher: false, out var generatedStream2)) { result = true; if (generatedStream2) { num++; } } } files = Directory.GetFiles(Paths.PluginPath, "*.cbb", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { if (LoadCharacterBundle(files[i], enableCypher: true, out var generatedStream3)) { result = true; if (generatedStream3) { num++; } } } if (num > 0) { if (CrewBoomSettings.UpdateCBBs) { DebugLog.LogInfo((object)$"Updated {num} .cbb files with stream data!"); } else { DebugLog.LogInfo((object)$"Created stream files (.ldcs) for {num} .cbb files!"); } } return result; } private static bool LoadCharacterBundle(string filePath, bool enableCypher) { bool generatedStream; return LoadCharacterBundle(filePath, enableCypher, out generatedStream); } private static bool SafelyAppendEmbedded(string filePath, EmbeddedBundle embedded, CharacterStreamData streamData) { string text = filePath + ".bak"; if (File.Exists(text)) { File.Delete(text); } File.Copy(filePath, text); try { embedded.OpenWrite(); embedded.AppendStreamData(streamData); } catch (Exception arg) { embedded.Close(); File.Replace(text, filePath, null); DebugLog.LogError((object)("Failed to update CBB for \"" + filePath + "\"")); DebugLog.LogError((object)$"{arg}"); return false; } File.Delete(text); return true; } private static bool LoadCharacterBundle(string filePath, bool enableCypher, out bool generatedStream) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Invalid comparison between Unknown and I4 //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Invalid comparison between Unknown and I4 //IL_0346: Unknown result type (might be due to invalid IL or missing references) generatedStream = false; string fileName = Path.GetFileName(filePath); string path = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".json"); string path2 = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".ldcs"); BrcCharacter val = (BrcCharacter)(-1); if (File.Exists(path)) { string text = File.ReadAllText(path); try { CharacterConfig val2 = JsonUtility.FromJson<CharacterConfig>(text); if (Enum.TryParse<BrcCharacter>(val2.CharacterToReplace, out BrcCharacter result)) { val = result; } else { DebugLog.LogWarning((object)("The configured replacement character for the bundle " + fileName + " (\"" + val2.CharacterToReplace + "\") is not a valid character!")); } } catch (Exception) { DebugLog.LogError((object)("Failed to read JSON config for \"" + fileName + "\"")); } } CharacterDefinition val3 = null; CharacterStreamData val4 = null; try { EmbeddedBundle val5 = new EmbeddedBundle(filePath); try { val5.OpenRead(); if (!val5.TryRetrieveStreamData(ref val4)) { if (File.Exists(path2)) { val4 = new CharacterStreamData(); using (FileStream input = new FileStream(path2, FileMode.Open, FileAccess.Read)) { using BinaryReader binaryReader = new BinaryReader(input); val4.Read(binaryReader, CrewBoomSettings.UpdateCBBs); } if (CrewBoomSettings.UpdateCBBs) { generatedStream = SafelyAppendEmbedded(filePath, val5, val4); } } else { AssetBundle val6 = val5.LoadAssetBundle(); GameObject[] array = val6.LoadAllAssets<GameObject>(); for (int i = 0; i < array.Length; i++) { val3 = array[i].GetComponent<CharacterDefinition>(); if (!((Object)(object)val3 != (Object)null)) { continue; } val4 = new CharacterStreamData(); val4.FromCharacter(val3); if (CrewBoomSettings.UpdateCBBs) { generatedStream = SafelyAppendEmbedded(filePath, val5, val4); break; } using (FileStream output = new FileStream(path2, FileMode.Create, FileAccess.Write)) { using BinaryWriter binaryWriter = new BinaryWriter(output); val4.Write(binaryWriter); } generatedStream = true; break; } val6.Unload(true); } } } finally { ((IDisposable)val5)?.Dispose(); } } catch (Exception arg) { DebugLog.LogError((object)("Failed to load bundle for \"" + fileName + "\"")); DebugLog.LogError((object)$"{arg}"); if (val4 != null) { val4.Release(); } return false; } if (val4 == null) { return false; } Guid guid = Guid.Parse(val4.Id); if (_characterBundlePaths.ContainsKey(guid)) { DebugLog.LogError((object)$"Failed to load \"{fileName}\" - there already is a character with the same GUID ({guid})"); val4.Release(); return false; } _characterBundlePaths[guid] = filePath; SfxCollectionID sfxID = (SfxCollectionID)(-1); if ((int)val != -1) { _characterIds[(Characters)val].Add(guid); } else { NewCharacterCount++; Characters key = (Characters)(26 + NewCharacterCount); sfxID = (SfxCollectionID)(67 + NewCharacterCount); if (_characterIds.ContainsKey(key)) { _characterIds[key].Add(guid); } else { _characterIds.Add(key, new List<Guid> { guid }); } _cypherMapping.Add(guid, enableCypher); } bool replacement = (int)val != -1; bool forceLoad = false; if (!CrewBoomSettings.StreamCharacters) { forceLoad = true; } CustomCharacter value = new CustomCharacter(val4, sfxID, filePath, replacement, forceLoad); _customCharacters.Add(guid, value); return true; } public static void RefreshShaders() { _appliedGrafShaders = false; foreach (CustomCharacter value in _customCharacters.Values) { if (value.Loaded) { value.FixCharacterShader(); } } } public static void SetGraffitiShader(Shader shader) { if (_appliedGrafShaders || (Object)(object)shader == (Object)null) { return; } foreach (CustomCharacter value in _customCharacters.Values) { value.ApplyShaderToGraffiti(shader); } _appliedGrafShaders = true; } 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.StreamData.Name; 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.StreamData.UnlockType == 2) { return false; } if ((int)characterObject.StreamData.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.StreamData.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.2.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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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.2.0 starting..."); CrewBoomSettings.Initialize(((BaseUnityPlugin)this).Config); 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); } StageManager.OnStagePostInitialization += new OnStageInitializedDelegate(StageManager_OnStagePostInitialization); } private void Update() { CharacterStreamer.Update(Time.deltaTime); } private void BoE_StageManager_OnStagePostInitialization() { BunchOfEmotesSupport.CacheAnimations(); } private void StageManager_OnStagePostInitialization() { CharacterDatabase.RefreshShaders(); Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); if ((Object)(object)currentPlayer != (Object)null) { PlayerStreamingComponent.GetOrCreate(currentPlayer).WaitForLoadSync(); } } } 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.2.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, CharacterLoader __instance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (CharacterDatabase.GetCharacter(character, out var characterObject)) { if (characterObject.Loaded) { __result = ((Component)characterObject.Definition).gameObject; } else { __result = __instance.loadedCharacterFbxAssets[3]; } } } } [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)) { if (characterObject.Loaded) { ___canBlink = characterObject.Definition.CanBlink; } else { ___canBlink = false; } } } } [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_000a: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if ((int)character > 26) { CustomCharacter characterObject = null; if (CharacterDatabase.GetCharacter(character, out characterObject)) { characterObject.WaitForLoadSync(); } 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); if (characterObject != null) { GenericCharacterStreamer.Create(((Component)val).gameObject, characterObject); } return false; } return true; } } [HarmonyPatch(typeof(CharacterSelect), "GetSelectSequenceAnim")] public class CharacterSelectSequencePatch { public static void Prefix(ref Characters c) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown if (CharacterDatabase.GetCharacter(c, out var characterObject)) { if (characterObject.Loaded) { c = (Characters)(int)characterObject.Definition.FreestyleAnimation; } else { c = (Characters)3; } } } } [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.StreamData.Name; ((TMP_Text)___characterUnlockedOutfitCountLabel).text = "4/4"; if (CharacterSaveSlots.GetCharacterData(Guid.Parse(characterObject.StreamData.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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown if (CharacterDatabase.GetCharacter(c, out var characterObject)) { if (characterObject.Loaded) { c = (Characters)(int)characterObject.Definition.FreestyleAnimation; } else { c = (Characters)3; } } } } [HarmonyPatch(typeof(CharacterVisual), "GetCharacterBounceAnim")] public class CharacterBouncePatch { public static bool Prefix(ref Characters c, ref int __result) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected I4, but got Unknown if (CharacterDatabase.GetCharacter(c, out var characterObject)) { if (!string.IsNullOrWhiteSpace(characterObject.StreamData.BoEIdleDance)) { if (!characterObject.StreamData.BoEIdleDanceVanilla && BunchOfEmotesSupport.Installed) { if (BunchOfEmotesSupport.TryGetGameAnimationForCustomAnimationName(characterObject.StreamData.BoEIdleDance, out var gameAnim)) { __result = gameAnim; return false; } } else if (characterObject.StreamData.BoEIdleDanceVanilla) { __result = Animator.StringToHash(characterObject.StreamData.BoEIdleDance); return false; } } c = (Characters)(int)characterObject.StreamData.IdleDance; } return true; } } [HarmonyPatch(typeof(CharacterConstructor), "CreateNewCharacterVisual")] public class ConstructorCreateVisualPatch { public static bool Prefix(Characters character, RuntimeAnimatorController controller, bool IK, float setGroundAngleLimit, CharacterConstructor __instance, ref CharacterVisual __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (CharacterDatabase.GetCharacter(character, out var characterObject)) { CharacterVisual val = null; val = ((!characterObject.Loaded) ? Object.Instantiate<GameObject>(CharacterStreamer.StreamingVisuals).AddComponent<CharacterVisual>() : 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_00b7: 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) && characterObject.StreamData.HasGraffiti) { GraffitiArt obj = val.FindByCharacter(val2); Texture2D graffitiTexture = characterObject.StreamData.GraffitiTexture; obj.graffitiMaterial.mainTexture = (Texture)(object)graffitiTexture; } } 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_001e: Unknown result type (might be due to invalid IL or missing references) if ((int)setState == 2 && CharacterDatabase.GetCharacter(___player.character, out var characterObject) && characterObject.Graffiti != null && ___grafArt == ___graffitiArtInfo.FindByCharacter(___player.character)) { ((TMP_Text)___player.ui.graffitiTitle).text = "'" + characterObject.Graffiti.title + "'"; } } } [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.StreamData.Name; } } } [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; } characterObject.WaitForLoadSync(); 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_01b5: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) 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)) { characterObject.WaitForLoadSync(); 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (!CharacterDatabase.GetCharacter(___character, out var characterObject)) { return; } DummyAnimationEventRelay componentInChildren = ((Component)__instance).GetComponentInChildren<DummyAnimationEventRelay>(true); if (!((Object)(object)componentInChildren == (Object)null)) { characterObject.WaitForLoadSync(); 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.SkinButtonClicked(button, skinIndex); }); ((Component)button).gameObject.SetActive(true); val = button; } } return false; } return true; } } [HarmonyPatch(typeof(Player), "SetCharacter")] public class PlayerInitOverridePatch { public static void Prefix(Player __instance, ref Characters setChar, int setOutfit) { //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; } bool preloaded = false; if (CharacterDatabase.GetCharacter(setChar, out var characterObject)) { if (characterObject.Loaded) { preloaded = true; } else if (!CrewBoomSettings.LoadCharactersAsync) { characterObject.WaitForLoadSync(); preloaded = true; } } PlayerStreamingComponent.GetOrCreate(__instance).SetCharacter(setChar, setOutfit, preloaded); } public static void Postfix(Player __instance, Characters setChar) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown if (CharacterDatabase.HasCharacterOverride) { CharacterDatabase.SetCharacterOverrideDone(); } if (!((Object)(object)__instance == (Object)(object)WorldHandler.instance.GetCurrentPlayer())) { return; } if (CharacterDatabase.GetCharacter(setChar, out var characterObject)) { string text = ""; if (characterObject.Graffiti != null) { text = characterObject.Graffiti.title; } CrewBoomAPIDatabase.UpdatePlayerCharacter(new CharacterInfo(characterObject.StreamData.Name, text)); } 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_000c: 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_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) PlayerStreamingComponent.GetOrCreate(__instance).SetOutfit(setOutfit); 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; } } public struct UpdateAnimState { public int originalAnim; public int newAnim; public bool doingBoEDance; } [HarmonyPatch(typeof(Player), "UpdateAnim")] public class PlayerUpdateAnimPatch { public static void Prefix(Player __instance, ref UpdateAnimState __state) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) __state.originalAnim = __instance.curAnim; __state.doingBoEDance = false; if (CharacterDatabase.GetCharacter(__instance.character, out var characterObject)) { if (characterObject.StreamData.BoEIdleDanceVanilla && __instance.curAnim == __instance.characterVisual.bounceAnimHash) { __state.doingBoEDance = true; } else if (!characterObject.StreamData.BoEIdleDanceVanilla && BunchOfEmotesSupport.Installed && BunchOfEmotesSupport.IsCustomAnimation(__instance.curAnim) && __instance.curAnim == __instance.characterVisual.bounceAnimHash) { __state.doingBoEDance = true; } } if (__state.doingBoEDance) { __state.newAnim = __instance.softBounce1Hash; __instance.curAnim = __state.newAnim; } } public static void Postfix(Player __instance, UpdateAnimState __state) { if (__state.doingBoEDance && __state.newAnim == __instance.curAnim) { __instance.curAnim = __state.originalAnim; } } } [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(PublicToilet), "DoSequence")] public class PublicToiletDoSequencePatch { public static void Prefix() { Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); if ((Object)(object)currentPlayer != (Object)null) { PlayerStreamingComponent.GetOrCreate(currentPlayer).WaitForLoadSync(); } } } [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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) if (!CharacterDatabase.GetCharacter(swappable.Character, out var characterObject)) { return; } characterObject.WaitForLoadSync(); 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(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 static readonly List<AudioClipID> VOICE_IDS = new List<AudioClipID> { (AudioClipID)484, (AudioClipID)485, (AudioClipID)486, (AudioClipID)498, (AudioClipID)487, (AudioClipID)488, (AudioClipID)489 }; private string _path; private AssetBundle _bundle; public AssetBundleCreateRequest BundleRequest; public int References; public Action<CustomCharacter> OnLoadedCallback; private static Texture2D _defaultGraffitiTexture = null; public CharacterDefinition Definition { get; private set; } public CharacterStreamData StreamData { get; private set; } public SfxCollectionID SfxID { get; private set; } public SfxCollection Sfx { get; private set; } public GameObject Visual { get; private set; } public bool Loaded { get; private set; } public bool KeepLoaded { get; private set; } public GraffitiArt Graffiti { get; private set; } public Texture2D DefaultGraffitiTexture { get { if ((Object)(object)_defaultGraffitiTexture == (Object)null) { _defaultGraffitiTexture = TextureUtil.GetTextureFromBitmap(Resources.default_graffiti, (FilterMode)1); } return _defaultGraffitiTexture; } } public CustomCharacter(CharacterStreamData streamData, SfxCollectionID sfxID, string path, bool replacement, bool forceLoad) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) StreamData = streamData; InitializeSfxCollection(); SfxID = sfxID; _path = path; KeepLoaded = replacement || forceLoad; if (KeepLoaded) { LoadSyncFromStartup(); } if (!replacement) { CreateGraffiti(); } } private void CreateGraffiti() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(Shader.Find("Standard")); val.mainTexture = (Texture)(object)StreamData.GraffitiTexture; string title = StreamData.GrafTitle; string text = StreamData.GrafAuthor; if (!StreamData.HasGraffiti) { val.mainTexture = (Texture)(object)DefaultGraffitiTexture; title = "Crew BOOM"; text = "Capry"; } GraffitiArt val2 = new GraffitiArt(); val2.graffitiSize = (GraffitiSize)0; val2.graffitiMaterial = val; val2.title = title; val2.artistName = text; GraffitiAppEntry val3 = ScriptableObject.CreateInstance<GraffitiAppEntry>(); val3.Size = (GraffitiSize)0; val3.GraffitiTexture = val.mainTexture; val3.Title = title; val3.Artist = text; val2.unlockable = val3; Graffiti = val2; } public void AddReference() { if (!KeepLoaded) { References++; if (CrewBoomSettings.LoadCharactersAsync && CrewBoomSettings.StreamCharacters) { LoadAsync(); } else { LoadSync(); } } } public void RemoveReference() { if (CrewBoomSettings.UnloadCharacters && !KeepLoaded) { References--; if (References <= 0 && CrewBoomSettings.StreamCharacters) { Unload(); } } } public void WaitForLoadSync() { if (Loaded) { return; } if (BundleRequest != null) { while (((AsyncOperation)BundleRequest).progress < 0.9f) { } BundleRequest.assetBundle.Unload(true); BundleRequest = null; } LoadSync(); } private void CancelAsyncLoad() { if (!Loaded && BundleRequest != null) { CharacterStreamer.CancelBundleLoadRequest(this); _bundle = null; } } private void LoadAsync() { if (!Loaded) { if (BundleRequest == null) { BundleRequest = AssetBundle.LoadFromFileAsync(_path); } CharacterStreamer.AddToStreamQueue(this); } } private void LoadSyncFromStartup() { OnBundleLoaded(AssetBundle.LoadFromFile(_path), fixShaders: false); } private void LoadSync() { if (!Loaded) { CancelAsyncLoad(); OnBundleLoaded(AssetBundle.LoadFromFile(_path)); } } public bool UpdateAsyncLoad() { if (Loaded) { return true; } if (BundleRequest == null) { return true; } if (((AsyncOperation)BundleRequest).isDone) { OnBundleLoaded(BundleRequest.assetBundle); return true; } return false; } private void OnBundleLoaded(AssetBundle bundle, bool fixShaders = true) { _bundle = bundle; Loaded = true; BundleRequest = null; GameObject[] array = bundle.LoadAllAssets<GameObject>(); foreach (GameObject val in array) { Definition = val.GetComponent<CharacterDefinition>(); if ((Object)(object)Definition != (Object)null) { break; } } if (fixShaders) { FixCharacterShader(); } CreateVisual(); LoadSfxCollection(); OnLoadedCallback?.Invoke(this); } private void Unload() { CancelAsyncLoad(); if (Loaded) { _bundle.Unload(true); _bundle = null; BundleRequest = null; Loaded = false; Definition = null; DestroyVisual(); UnloadSfxCollection(); } } private void DestroyVisual() { if (!((Object)(object)Visual == (Object)null)) { Object.Destroy((Object)(object)Visual); Visual = null; } } private void CreateVisual() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (!((Object)(object)Visual != (Object)null)) { GameObject val = new GameObject(Definition.CharacterName + " Visuals"); Object.DontDestroyOnLoad((Object)(object)val); 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 InitializeSfxCollection() { Sfx = ScriptableObject.CreateInstance<SfxCollection>(); UnloadSfxCollection(); } private void UnloadSfxCollection() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) if ((Object)(object)Sfx != (Object)null) { Sfx.audioClipContainers = (RandomAudioClipContainer[])(object)new RandomAudioClipContainer[VOICE_IDS.Count]; for (int i = 0; i < VOICE_IDS.Count; i++) { Sfx.audioClipContainers[i] = new RandomAudioClipContainer(); Sfx.audioClipContainers[i].clipID = VOICE_IDS[i]; Sfx.audioClipContainers[i].clips = null; Sfx.audioClipContainers[i].lastRandomClip = 0; } } } private void LoadSfxCollection() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected I4, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Invalid comparison between Unknown and I4 if (!Definition.HasVoices()) { return; } SfxCollection val = Sfx; if ((Object)
CrewBoomAPI.dll
Decompiled a month agousing 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 a month agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using CrewBoomMono; 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.10.0.0")] [assembly: AssemblyInformationalVersion("1.10.0+905ea7ff42b19009cf72f409d144f6bc9dad7f19")] [assembly: AssemblyProduct("CrewBoomMono")] [assembly: AssemblyTitle("CrewBoomMono")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.10.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.Mono { public class EmbeddedBundle : IDisposable { private const string Magic = "STREAM"; private const byte Version = 0; private string _path; private FileStream _stream; public EmbeddedBundle(string bundlePath) { _path = bundlePath; } public void OpenRead() { Close(); _stream = new FileStream(_path, FileMode.Open, FileAccess.Read); } public void OpenWrite() { Close(); _stream = new FileStream(_path, FileMode.Open, FileAccess.Write); } public void Close() { if (_stream != null) { _stream.Dispose(); } _stream = null; } public void Dispose() { if (_stream != null) { _stream.Dispose(); } } public AssetBundle LoadAssetBundle() { Close(); return AssetBundle.LoadFromFile(_path); } public void AppendStreamData(CharacterStreamData streamData) { if (_stream == null) { throw new IOException("There isn't any stream open to write!"); } if (!_stream.CanWrite) { throw new IOException("The FileStream can't write!"); } _stream.Seek(0L, SeekOrigin.End); int value = (int)_stream.Position; using BinaryWriter binaryWriter = new BinaryWriter(_stream); streamData.Write(binaryWriter); binaryWriter.Write(value); binaryWriter.Write(Encoding.ASCII.GetBytes("STREAM")); binaryWriter.Write((byte)0); } public bool TryRetrieveStreamData(out CharacterStreamData streamData) { if (_stream == null) { throw new IOException("There isn't any stream open to read!"); } if (!_stream.CanRead) { throw new IOException("The FileStream can't read!"); } streamData = null; int num = "STREAM".Length + 1; _stream.Seek(-num, SeekOrigin.End); byte[] array = new byte[num]; _stream.Read(array, 0, num); if (Encoding.ASCII.GetString(array, 0, "STREAM".Length) != "STREAM") { return false; } byte b = array[6]; if (b < 0 || b > 0) { throw new IOException($"Unrecognized Stream Data version {b}"); } _stream.Seek(-num - 4, SeekOrigin.End); byte[] array2 = new byte[4]; _stream.Read(array2, 0, 4); int num2 = BitConverter.ToInt32(array2, 0); _stream.Seek(num2, SeekOrigin.Begin); using (BinaryReader reader = new BinaryReader(_stream)) { streamData = new CharacterStreamData(); streamData.Read(reader); } return true; } } } 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 bool BoEBounceAnimationVanilla; 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; } public class CharacterStreamData { private const byte Version = 0; public string Id; public UnlockType UnlockType; public BrcMovestyle DefaultMoveStyle; public string Name; public string GrafTitle; public string GrafAuthor; public bool HasGraffiti; public BrcCharacter IdleDance; public string BoEIdleDance; public bool BoEIdleDanceVanilla; public Texture2D GraffitiTexture; public void FromCharacter(CharacterDefinition character) { Id = character.Id; UnlockType = character.UnlockType; DefaultMoveStyle = character.DefaultMovestyle; Name = character.CharacterName; HasGraffiti = (Object)(object)character.Graffiti != (Object)null; GrafTitle = character.GraffitiName; GrafAuthor = character.GraffitiArtist; IdleDance = character.BounceAnimation; BoEIdleDance = character.BoEBounceAnimation; BoEIdleDanceVanilla = character.BoEBounceAnimationVanilla; if (HasGraffiti) { Texture mainTexture = character.Graffiti.mainTexture; CopyGraffitiTexture((Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null)); } } public void Write(BinaryWriter writer) { writer.Write((byte)0); writer.Write(Id); writer.Write((int)UnlockType); writer.Write((int)DefaultMoveStyle); writer.Write(Name); writer.Write(HasGraffiti); writer.Write(GrafTitle); writer.Write(GrafAuthor); writer.Write((int)IdleDance); writer.Write(BoEIdleDance); writer.Write(BoEIdleDanceVanilla); if (HasGraffiti) { byte[] array = ImageConversion.EncodeToPNG(GraffitiTexture); writer.Write(array.Length); writer.Write(array); } } public void Read(BinaryReader reader, bool grafreadable = false) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown reader.ReadByte(); Id = reader.ReadString(); UnlockType = (UnlockType)reader.ReadInt32(); DefaultMoveStyle = (BrcMovestyle)reader.ReadInt32(); Name = reader.ReadString(); HasGraffiti = reader.ReadBoolean(); GrafTitle = reader.ReadString(); GrafAuthor = reader.ReadString(); IdleDance = (BrcCharacter)reader.ReadInt32(); BoEIdleDance = reader.ReadString(); BoEIdleDanceVanilla = reader.ReadBoolean(); if (HasGraffiti) { int count = reader.ReadInt32(); byte[] array = reader.ReadBytes(count); GraffitiTexture = new Texture2D(2, 2); ImageConversion.LoadImage(GraffitiTexture, array, !grafreadable); } } private void CopyGraffitiTexture(Texture2D source) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); Graphics.Blit((Texture)(object)source, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; GraffitiTexture = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)5, false); GraffitiTexture.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0); GraffitiTexture.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } public void Release() { if ((Object)(object)GraffitiTexture != (Object)null) { Object.DestroyImmediate((Object)(object)GraffitiTexture); } } } }