public static List <ExtractableItem> OpenDirectory(string rootDir, AudioType audioType) { string liveDir = Path.Join(rootDir, "live"); string patchableFilesDir = Path.Join(liveDir, "PatcherData", "PatchableFiles"); string audioDir = Path.Join(patchableFilesDir, "Audio"); string cardProfilesDir = Path.Join(patchableFilesDir, "AssetBundles"); if (!Directory.Exists(rootDir) || !Directory.Exists(liveDir) || !Directory.Exists(patchableFilesDir) || !Directory.Exists(audioDir) || !Directory.Exists(cardProfilesDir)) { throw new Exception("This is not a valid LoR directory"); } string[] files = Directory.GetFiles(audioDir); string[] assetBundles = DirUtils.RecursivelyList(cardProfilesDir, "*.bbq"); if (assetBundles.Length == 0) { throw new Exception("No AssetBundles found in this directory, please make sure it is a valid LoR directory."); } List <string> audioEvents = new (); HashSet <string> soundBanks = new (); AssetsManager assetsManager = new (); assetsManager.LoadFiles(assetBundles); foreach (var serializedFile in assetsManager.assetsFileList) { List <Object> objects = serializedFile.Objects; foreach (var objectObj in objects.Where(objectObj => objectObj is MonoBehaviour)) { var monoBehaviour = (MonoBehaviour)objectObj; var nodes = monoBehaviour.serializedType.m_Type; OrderedDictionary data = TypeTreeHelper.ReadType(nodes, monoBehaviour.reader); TypeTraversalUtil.FindSoundEvents(audioEvents, soundBanks, monoBehaviour.m_Name, data); } } assetsManager.Clear(); List <ExtractableItem> items = new (); switch (audioType) { case AudioType.VO: foreach (string file in files) { LoadVO(file, items, audioEvents); } break; case AudioType.SFX: foreach (string file in files) { LoadSFX(file, items, audioEvents, soundBanks); } break; default: throw new ArgumentNullException(nameof(audioType)); } return(items); }