Example #1
0
        private bool UpdateSongConfig(AssetsManager manager, BeatSaberSong song, CustomLevelLoader loader)
        {
            var songsAssetFile           = manager.GetAssetsFile(BSConst.KnownFiles.SongsAssetsFilename);
            BeatmapLevelDataObject level = null;

            if (!string.IsNullOrWhiteSpace(song.SongID))
            {
                var levels = songsAssetFile.FindAssets <BeatmapLevelDataObject>(x => x.Object.LevelID == song.SongID).Select(x => x.Object).ToList();
                if (levels.Count() > 0)
                {
                    if (levels.Count() > 1)
                    {
                        Log.LogErr($"Song ID {song.SongID} already has more than one entry in the assets, this may cause problems!");
                    }
                    else
                    {
                        Log.LogMsg($"Song ID {song.SongID} exists already and won't be loaded");
                    }
                    level          = levels.First();
                    song.LevelData = level;
                    return(true);
                }
                else
                {
                    Log.LogMsg($"Song ID '{song.SongID}' does not exist and will be created");
                }
            }
            if (level != null && !string.IsNullOrWhiteSpace(song.CustomSongFolder))
            {
                Log.LogErr("SongID and CustomSongsFolder are both set and the level already exists.  The existing one will be used and CustomSongsFolder won'tbe imported again.");
                return(false);
            }

            //load new song
            if (!string.IsNullOrWhiteSpace(song.CustomSongFolder))
            {
                try
                {
                    string oggPath;
                    var    deser = loader.DeserializeFromJson(song.CustomSongFolder, song.SongID);
                    var    found = songsAssetFile.FindAssets <BeatmapLevelDataObject>(x => x.Object.LevelID == deser.LevelID).Select(x => x.Object).FirstOrDefault();
                    if (found != null)
                    {
                        Log.LogErr($"No song id was specified, but the level {found.LevelID} is already in the assets, skipping it.");
                        song.LevelData = found;
                        return(true);
                    }
                    level          = loader.LoadSongToAsset(deser, song.CustomSongFolder, out oggPath, true);
                    song.SourceOgg = oggPath;
                }
                catch (Exception ex)
                {
                    Log.LogErr($"Exception loading custom song folder '{song.CustomSongFolder}', skipping it", ex);
                    return(false);
                }

                if (level == null)
                {
                    Log.LogErr($"Song at folder '{song.CustomSongFolder}' failed to load, skipping it");
                    return(false);
                }

                song.LevelData = level;
                return(true);
            }
            //level == null && string.IsNullOrWhiteSpace(song.CustomSongFolder)

            Log.LogErr($"Song ID '{song.SongID}' either was not specified or could not be found and no CustomSongFolder was specified, skipping it.");
            return(false);
        }
        internal override void PerformOp(OpContext context)
        {
            if (string.IsNullOrEmpty(Song.SongID))
            {
                throw new InvalidOperationException("SongID must be set on the song!");
            }
            if (string.IsNullOrEmpty(Song.CustomSongPath))
            {
                throw new InvalidOperationException("CustomSongPath must be set on the song!");
            }
            if (!context.Cache.PlaylistCache.ContainsKey(PlaylistID))
            {
                throw new KeyNotFoundException($"PlaylistID {PlaylistID} not found in the cache!");
            }
            bool exists = context.Cache.SongCache.ContainsKey(Song.SongID);

            if (exists && !OverwriteIfExists)
            {
                throw new AddSongException(AddSongFailType.SongExists, $"SongID {Song.SongID} already exists!");
            }

            if (exists && OverwriteIfExists)
            {
                OpCommon.DeleteSong(context, Song.SongID);
            }

            if (context.Cache.SongCache.ContainsKey(Song.SongID))
            {
                throw new AddSongException(AddSongFailType.SongExists, $"SongID {Song.SongID} already exists, even though it should have been deleted to be replaced!");
            }

            BeatmapLevelDataObject level = null;

            try
            {
                var songsAssetFile       = context.Engine.GetSongsAssetsFile();
                CustomLevelLoader loader = new CustomLevelLoader(songsAssetFile, context.Config);
                var deser = loader.DeserializeFromJson(Song.CustomSongPath, Song.SongID);
                level = loader.LoadSongToAsset(deser, Song.CustomSongPath, true);
            }
            catch (Exception ex)
            {
                throw new Exception($"Exception loading custom song folder '{Song.CustomSongPath}' for SongID {Song.SongID}", ex);
            }

            if (level == null)
            {
                throw new AddSongException(AddSongFailType.InvalidFormat, $"Song at folder '{Song.CustomSongPath}' for SongID {Song.SongID} failed to load");
            }

            Song.LevelData       = level;
            Song.LevelAuthorName = level.LevelAuthorName;
            Song.SongAuthorName  = level.SongAuthorName;
            Song.SongName        = level.SongName;
            Song.SongSubName     = level.SongSubName;
            var playlist = context.Cache.PlaylistCache[PlaylistID];

            playlist.Playlist.BeatmapLevelCollection.Object.BeatmapLevels.Add(Song.LevelData.PtrFrom(playlist.Playlist.BeatmapLevelCollection.Object));
            playlist.Songs.Add(Song.SongID, new OrderedSong()
            {
                Song = Song.LevelData, Order = playlist.Songs.Count
            });
            context.Cache.SongCache.Add(Song.SongID, new SongAndPlaylist()
            {
                Playlist = playlist.Playlist, Song = Song.LevelData
            });
            var qfos = context.Engine.QueuedFileOperations.Where(x => x.Tag == Song.SongID && x.Type == QueuedFileOperationType.DeleteFolder || x.Type == QueuedFileOperationType.DeleteFile).ToList();

            foreach (var q in qfos)
            {
                context.Engine.QueuedFileOperations.Remove(q);
            }
        }