public BeatmapLevelDataObject LoadSongToAsset(BeatmapLevelDataObject beatmapLevel, string songPath, out string oggFileName, bool includeCovers = true) { oggFileName = null; try { beatmapLevel.Name = $"{beatmapLevel.LevelID}Level"; //cover art Texture2DObject coverImage = null; if (includeCovers) { coverImage = LoadSongCover(songPath, beatmapLevel); } //audio var audioAsset = LoadSongAudioAsset(songPath, beatmapLevel); if (audioAsset == null) { Log.LogErr($"failed to get audio for song at path {songPath}"); return(null); } oggFileName = Path.Combine(songPath, beatmapLevel.SongFilename);; foreach (var difficultySet in beatmapLevel.DifficultyBeatmapSets) { difficultySet.BeatmapCharacteristic = GetCharacteristicAsset(difficultySet.BeatmapCharacteristicName).PtrFrom(beatmapLevel); List <DifficultyBeatmap> toRemove = new List <DifficultyBeatmap>(); foreach (var difficultyBeatmap in difficultySet.DifficultyBeatmaps) { var dataFile = Path.Combine(songPath, $"{difficultyBeatmap.Difficulty.ToString()}.dat"); if (!File.Exists(dataFile)) { Log.LogErr(dataFile + " is missing, skipping this difficulty"); toRemove.Add(difficultyBeatmap); continue; } string jsonData; using (var sr = new StreamReader(dataFile)) { jsonData = sr.ReadToEnd(); } if (_assetsFile != null) { difficultyBeatmap.BeatmapData = new BeatmapDataObject(_assetsFile); } difficultyBeatmap.BeatmapData.Name = beatmapLevel.LevelID + ((difficultySet.BeatmapCharacteristicName == Characteristic.Standard) ? "" : difficultySet.BeatmapCharacteristicName.ToString()) + difficultyBeatmap.Difficulty.ToString() + "BeatmapData"; difficultyBeatmap.BeatmapData.BeatsPerMinute = beatmapLevel.BeatsPerMinute; difficultyBeatmap.BeatmapData.Shuffle = beatmapLevel.Shuffle; difficultyBeatmap.BeatmapData.ShufflePeriod = beatmapLevel.ShufflePeriod; difficultyBeatmap.BeatmapData.JsonData = jsonData; difficultyBeatmap.BeatmapData.TransformToProjectedData(); difficultyBeatmap.BeatmapData.JsonData = null; _assetsFile.AddObject(difficultyBeatmap.BeatmapData, true); difficultyBeatmap.BeatmapDataPtr = difficultyBeatmap.BeatmapData.PtrFrom(beatmapLevel); } toRemove.ForEach(x => difficultySet.DifficultyBeatmaps.Remove(x)); if (difficultySet.DifficultyBeatmaps.Count < 1) { Log.LogErr($"Song at path {songPath} has no valid beatmaps for any difficulty, skipping song"); return(null); } } _assetsFile.AddObject(audioAsset, true); if (coverImage != null) { _assetsFile.AddObject(coverImage); } beatmapLevel.AudioClip = audioAsset.PtrFrom(beatmapLevel); if (coverImage == null) { beatmapLevel.CoverImageTexture2D = _assetsFile.FindAsset <Texture2DObject>(x => x.Object.Name == "BeatSaberCover").PtrFrom(beatmapLevel); } else { beatmapLevel.CoverImageTexture2D = coverImage.PtrFrom(beatmapLevel); } var environment = _assetsFile.Manager.MassFirstOrDefaultAsset <MonoBehaviourObject>(x => x.Object.Name == $"{beatmapLevel.EnvironmentName}SceneInfo"); if (environment == null) { Log.LogMsg($"Unknown environment name '{beatmapLevel.EnvironmentName}' on '{beatmapLevel.SongName}', falling back to default."); environment = _assetsFile.Manager.MassFirstAsset <MonoBehaviourObject>(x => x.Object.Name == "DefaultEnvironmentSceneInfo"); } beatmapLevel.EnvironmentSceneInfo = environment.PtrFrom(beatmapLevel); _assetsFile.AddObject(beatmapLevel, true); return(beatmapLevel); } catch (Exception ex) { Log.LogErr($"Error loading song from path {songPath}", ex); return(null); } }
public BeatmapLevelDataObject LoadSongToAsset(BeatmapLevelDataObject beatmapLevel, string songPath, bool includeCovers = true) { try { beatmapLevel.Name = $"{beatmapLevel.LevelID}Level"; //cover art Texture2DObject coverImage = null; if (includeCovers) { coverImage = LoadSongCover(songPath, beatmapLevel); } //audio var audioAsset = LoadSongAudioAsset(songPath, beatmapLevel); if (audioAsset == null) { Log.LogErr($"failed to get audio for song at path {songPath}"); return(null); } var toRemoveSet = new List <DifficultyBeatmapSet>(); foreach (var difficultySet in beatmapLevel.DifficultyBeatmapSets) { var characteristic = GetCharacteristicAsset(difficultySet.BeatmapCharacteristicName)?.PtrFrom(beatmapLevel); if (characteristic == null) { Log.LogErr($"Characteristic {difficultySet.BeatmapCharacteristicName} couldn't be found. Set will be removed."); toRemoveSet.Add(difficultySet); continue; } difficultySet.BeatmapCharacteristic = characteristic; List <DifficultyBeatmap> toRemove = new List <DifficultyBeatmap>(); foreach (var difficultyBeatmap in difficultySet.DifficultyBeatmaps) { string dataFile = null; if (!string.IsNullOrWhiteSpace(difficultyBeatmap.BeatmapFilename)) { dataFile = songPath.CombineFwdSlash(difficultyBeatmap.BeatmapFilename); if (!_config.SongFileProvider.FileExists(dataFile)) { Log.LogErr($"BeatmapFilename was set to {dataFile} but the file didn't exist, will try to fall back to difficulty name."); dataFile = null; } } if (dataFile == null) { dataFile = songPath.CombineFwdSlash($"{difficultyBeatmap.Difficulty.ToString()}.dat"); } if (!_config.SongFileProvider.FileExists(dataFile)) { Log.LogErr(dataFile + " is missing, skipping this difficulty"); toRemove.Add(difficultyBeatmap); continue; } string jsonData = _config.SongFileProvider.ReadToString(dataFile); if (_assetsFile != null) { difficultyBeatmap.BeatmapData = new BeatmapDataObject(_assetsFile); } difficultyBeatmap.BeatmapData.Name = beatmapLevel.LevelID + ((difficultySet.BeatmapCharacteristicName == Characteristic.Standard) ? "" : difficultySet.BeatmapCharacteristicName.ToString()) + difficultyBeatmap.Difficulty.ToString() + "BeatmapData"; difficultyBeatmap.BeatmapData.BeatsPerMinute = beatmapLevel.BeatsPerMinute; difficultyBeatmap.BeatmapData.Shuffle = beatmapLevel.Shuffle; difficultyBeatmap.BeatmapData.ShufflePeriod = beatmapLevel.ShufflePeriod; difficultyBeatmap.BeatmapData.JsonData = jsonData; _assetsFile.AddObject(difficultyBeatmap.BeatmapData, true); difficultyBeatmap.BeatmapDataPtr = difficultyBeatmap.BeatmapData.PtrFrom(beatmapLevel); } toRemove.ForEach(x => difficultySet.DifficultyBeatmaps.Remove(x)); if (difficultySet.DifficultyBeatmaps.Count < 1) { Log.LogErr($"Song at path {songPath} has no valid beatmaps for any difficulty on set {difficultySet.BeatmapCharacteristicName}, removing it"); toRemoveSet.Add(difficultySet); continue; } } toRemoveSet.ForEach(x => beatmapLevel.DifficultyBeatmapSets.Remove(x)); if (beatmapLevel.DifficultyBeatmapSets.Count < 1) { Log.LogErr($"Song at path {songPath} has no valid characterstics, it will not be imported"); return(null); } _assetsFile.AddObject(audioAsset, true); if (coverImage != null) { _assetsFile.AddObject(coverImage); } beatmapLevel.AudioClip = audioAsset.PtrFrom(beatmapLevel); if (coverImage == null) { var bsCover = _assetsFile.FindAsset <Texture2DObject>(x => x.Object.Name == "BeatSaberCover"); if (bsCover == null) { Log.LogErr("Unable to find BeatSaberCover in assets! How is that gone?"); throw new Exception("Could not find beat saber cover in assets! That should never be missing."); } var cover = bsCover.Clone(); _assetsFile.AddObject(cover, true); beatmapLevel.CoverImageTexture2D = cover.PtrFrom(beatmapLevel); } else { beatmapLevel.CoverImageTexture2D = coverImage.PtrFrom(beatmapLevel); } var environment = GetEnvironment(beatmapLevel.EnvironmentName); if (environment == null) { Log.LogMsg($"Unknown environment name '{beatmapLevel.EnvironmentName}' on '{beatmapLevel.SongName}', falling back to default."); environment = GetEnvironment("DefaultEnvironment"); if (environment == null) { throw new Exception("Unable to find the default environment!"); } } beatmapLevel.EnvironmentInfo = environment.PtrFrom(beatmapLevel); _assetsFile.AddObject(beatmapLevel, true); return(beatmapLevel); } catch (Exception ex) { Log.LogErr($"Error loading song from path {songPath}", ex); return(null); } }
private void UpdatePlaylistConfig(AssetsFile songsAssetFile, BeatSaberPlaylist playlist) { Log.LogMsg($"Processing playlist ID {playlist.PlaylistID}..."); CustomLevelLoader loader = new CustomLevelLoader(songsAssetFile, _config); BeatmapLevelPackObject levelPack = songsAssetFile.FindAsset <BeatmapLevelPackObject>(x => x.Object.PackID == playlist.PlaylistID)?.Object; //create a new level pack if one waasn't found if (levelPack == null) { Log.LogMsg($"Level pack for playlist '{playlist.PlaylistID}' was not found and will be created"); levelPack = new BeatmapLevelPackObject(songsAssetFile) { Enabled = 1, GameObject = null, IsPackAlwaysOwned = true, PackID = playlist.PlaylistID, Name = playlist.PlaylistID + BSConst.NameSuffixes.LevelPack, PackName = playlist.PlaylistName }; songsAssetFile.AddObject(levelPack, true); var col = new BeatmapLevelCollectionObject(songsAssetFile) { Name = playlist.PlaylistID + BSConst.NameSuffixes.LevelCollection }; songsAssetFile.AddObject(col, true); levelPack.BeatmapLevelCollection = col.PtrFrom(levelPack); } playlist.LevelPackObject = levelPack; levelPack.PackName = playlist.PlaylistName ?? levelPack.PackName; //todo: allow for editing cover art if (!string.IsNullOrWhiteSpace(playlist.CoverArtFilename)) { Log.LogMsg($"Loading cover art for playlist ID '{playlist.PlaylistID}'"); var oldCoverImage = playlist?.LevelPackObject?.CoverImage; var oldTex = playlist?.LevelPackObject?.CoverImage?.Object?.Texture; //todo: verify this is a good place to delete stuff playlist.CoverArtSprite = loader.LoadPackCover(playlist.PlaylistID, playlist.CoverArtFilename); playlist.LevelPackObject.CoverImage = playlist.CoverArtSprite.PtrFrom(playlist.LevelPackObject); if (oldCoverImage != null) { if (oldCoverImage.Object != null) { songsAssetFile.DeleteObject(oldCoverImage.Object); } oldCoverImage.Dispose(); } if (oldTex != null) { if (oldTex?.Object != null) { songsAssetFile.DeleteObject(oldTex.Object); } oldTex.Dispose(); } } else { if (playlist.LevelPackObject.CoverImage != null) { playlist.CoverArtSprite = playlist.LevelPackObject.CoverImage.Object; } else { playlist.CoverArtSprite = loader.LoadPackCover(playlist.PlaylistID, null); } playlist.LevelPackObject.CoverImage = playlist.CoverArtSprite.PtrFrom(playlist.LevelPackObject); } //clear out any levels, we'll add them back var levelCollection = levelPack.BeatmapLevelCollection.Object; levelCollection.BeatmapLevels.ForEach(x => x.Dispose()); levelCollection.BeatmapLevels.Clear(); int songCount = 0; Log.LogMsg($"Processing songs for playlist ID {playlist.PlaylistID}..."); var totalSongs = playlist.SongList.Count(); var songMod = Math.Ceiling((double)totalSongs / (double)10); if (songMod < 1) { songMod = 1; } foreach (var song in playlist.SongList.ToList()) { songCount++; if (songCount % songMod == 0) { Console.WriteLine($"{songCount.ToString().PadLeft(5)} of {totalSongs}..."); } if (UpdateSongConfig(songsAssetFile, song, loader)) { if (levelCollection.BeatmapLevels.Any(x => x.Object.LevelID == song.LevelData.LevelID)) { Log.LogErr($"Playlist ID '{playlist.PlaylistID}' already contains song ID '{song.SongID}' once, removing the second link"); } else { levelCollection.BeatmapLevels.Add(song.LevelData.PtrFrom(levelCollection)); continue; } } playlist.SongList.Remove(song); } Console.WriteLine($"Proccessed {totalSongs} for playlist ID {playlist.PlaylistID}"); }