Beispiel #1
0
        public static BeatmapLevelPackObject CreatePlaylist(OpContext context, BeatSaberPlaylist playlist, AssetsFile songsAssetFile)
        {
            Log.LogMsg($"Playlist {playlist.PlaylistID} will be created");
            var 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;
            var mainCol = context.Engine.GetMainLevelPack();
            var aoPacks = context.Engine.GetAlwaysOwnedModel();

            mainCol.BeatmapLevelPacks.Add(levelPack.PtrFrom(mainCol));
            aoPacks.AlwaysOwnedPacks.Add(levelPack.PtrFrom(aoPacks));
            context.Cache.PlaylistCache.Add(playlist.PlaylistID, new PlaylistAndSongs()
            {
                Playlist = levelPack, Order = context.Cache.PlaylistCache.Count
            });
            UpdateCoverImage(playlist, context, songsAssetFile);
            return(levelPack);
        }
        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);
            }
        }
        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);
            }
        }
Beispiel #4
0
        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}");
        }