public IEnumerator MatchKey() { if (!string.IsNullOrEmpty(key) || level == null || !(level is CustomPreviewBeatmapLevel)) { yield break; } string songHash = null; if (!string.IsNullOrEmpty(hash)) { songHash = hash; } else if (!string.IsNullOrEmpty(levelId)) { songHash = CustomHelpers.GetSongHash(level.levelID); } if (songHash != null && SongDataCore.Plugin.BeatSaver.Data.Songs.ContainsKey(hash)) { var song = SongDataCore.Plugin.BeatSaver.Data.Songs[hash]; key = song.key; } else { // no more hitting api just to match a key. We know the song hash. //yield return SongDownloader.Instance.RequestSongByLevelIDCoroutine(level.levelID.Split('_')[2], (Song bsSong) => { if (bsSong != null) key = bsSong.key; }); } }
/// <summary> /// Add Song to Editing Playlist /// </summary> /// <param name="songInfo"></param> public void AddSongToEditingPlaylist(IBeatmapLevel songInfo) { if (this.CurrentEditingPlaylist == null) { return; } this.CurrentEditingPlaylist.songs.Add(new PlaylistSong() { songName = songInfo.songName, levelId = songInfo.levelID, hash = CustomHelpers.GetSongHash(songInfo.levelID), }); this.CurrentEditingPlaylistLevelIds.Add(songInfo.levelID); this.CurrentEditingPlaylist.SavePlaylist(); }
/// <summary> /// Filter songs based on ranked or unranked status. /// </summary> /// <param name="levels"></param> /// <param name="includeRanked"></param> /// <param name="includeUnranked"></param> /// <returns></returns> private List <IPreviewBeatmapLevel> FilterRanked(List <IPreviewBeatmapLevel> levels, bool includeRanked, bool includeUnranked) { return(levels.Where(x => { var hash = CustomHelpers.GetSongHash(x.levelID); double maxPP = 0.0; if (SongDataCore.Plugin.ScoreSaber.Data.Songs.ContainsKey(hash)) { maxPP = SongDataCore.Plugin.ScoreSaber.Data.Songs[hash].diffs.Max(y => y.pp); } if (maxPP > 0f) { return includeRanked; } else { return includeUnranked; } }).ToList()); }
/// <summary> /// Sorting by star rating. /// </summary> /// <param name="levels"></param> /// <returns></returns> private List <IPreviewBeatmapLevel> SortStars(List <IPreviewBeatmapLevel> levels) { Logger.Info("Sorting song list by star points..."); if (!SongDataCore.Plugin.ScoreSaber.IsDataAvailable()) { return(levels); } return(levels .OrderByDescending(x => { var hash = CustomHelpers.GetSongHash(x.levelID); var stars = 0.0; if (SongDataCore.Plugin.ScoreSaber.Data.Songs.ContainsKey(hash)) { var diffs = SongDataCore.Plugin.ScoreSaber.Data.Songs[hash].diffs; stars = diffs.Max(y => y.star); } //Logger.Debug("Stars={0}", stars); if (stars != 0) { return stars; } if (_settings.invertSortResults) { return double.MaxValue; } else { return double.MinValue; } }) .ToList()); }
/// <summary> /// Sorting by BeatSaver heat stat. /// </summary> /// <param name="levelIds"></param> /// <returns></returns> private List <IPreviewBeatmapLevel> SortBeatSaverHeat(List <IPreviewBeatmapLevel> levelIds) { Logger.Info("Sorting song list by BeatSaver Heat!"); // Do not always have data when trying to sort by heat if (!SongDataCore.Plugin.BeatSaver.IsDataAvailable()) { return(levelIds); } return(levelIds .OrderByDescending(x => { var hash = CustomHelpers.GetSongHash(x.levelID); if (SongDataCore.Plugin.BeatSaver.Data.Songs.ContainsKey(hash)) { return SongDataCore.Plugin.BeatSaver.Data.Songs[hash].stats.heat; } else { return int.MinValue; } }) .ToList()); }
/// <summary> /// Sorting by PP. /// </summary> /// <param name="levels"></param> /// <returns></returns> private List <IPreviewBeatmapLevel> SortPerformancePoints(List <IPreviewBeatmapLevel> levels) { Logger.Info("Sorting song list by performance points..."); if (!SongDataCore.Plugin.ScoreSaber.IsDataAvailable()) { return(levels); } return(levels .OrderByDescending(x => { var hash = CustomHelpers.GetSongHash(x.levelID); if (SongDataCore.Plugin.ScoreSaber.Data.Songs.ContainsKey(hash)) { return SongDataCore.Plugin.ScoreSaber.Data.Songs[hash].diffs.Max(y => y.pp); } else { return 0; } }) .ToList()); }
/// <summary> /// Favorites used to exist as part of the song_browser_settings.xml /// This makes little sense now. This is the upgrade path. /// Convert all existing favorites to the best of our effort into a playlist. /// </summary> /// <param name="levelIdToCustomLevel"></param> /// <param name="levelIdToSongVersion"></param> public void ConvertFavoritesToPlaylist(Dictionary <String, CustomPreviewBeatmapLevel> customSongsMap) { // map songs in case we are converting a huge list Dictionary <String, CustomPreviewBeatmapLevel> levelIdToCustomLevel = new Dictionary <string, CustomPreviewBeatmapLevel>(StringComparer.OrdinalIgnoreCase); foreach (var kp in customSongsMap) { if (levelIdToCustomLevel.ContainsKey(kp.Value.levelID)) { continue; } levelIdToCustomLevel.Add(kp.Value.levelID, kp.Value); } // Check if we have favorites to convert to the playlist if (this.Favorites.Count <= 0) { return; } // check if the playlist exists String playlistPath = Path.Combine(Environment.CurrentDirectory, "Playlists", DefaultConvertedFavoritesPlaylistName); bool playlistExists = false; if (File.Exists(playlistPath)) { playlistExists = true; } // abort here if playlist already exits. if (playlistExists) { Logger.Info("Not converting song_browser_setting.xml favorites because {0} already exists...", playlistPath); return; } Logger.Info("Converting {0} Favorites in song_browser_settings.xml to {1}...", this.Favorites.Count, playlistPath); // written like this in case we ever want to support adding to this playlist Playlist p = null; if (playlistExists) { p = Playlist.LoadPlaylist(playlistPath); } else { p = new Playlist { playlistTitle = "Song Browser Favorites", playlistAuthor = "SongBrowser", fileLoc = "", image = Base64Sprites.SpriteToBase64(Base64Sprites.BeastSaberLogo), songs = new List <PlaylistSong>(), }; } List <String> successfullyRemoved = new List <string>(); this.Favorites.RemoveWhere(levelId => { PlaylistSong playlistSong = new PlaylistSong { levelId = levelId }; if (levelIdToCustomLevel.ContainsKey(levelId)) { playlistSong.songName = levelIdToCustomLevel[levelId].songName; playlistSong.levelId = levelId; playlistSong.hash = CustomHelpers.GetSongHash(levelId); } else { // No easy way to look up original songs... They will still work but have wrong song name in playlist. playlistSong.levelId = levelId; playlistSong.hash = CustomHelpers.GetSongHash(levelId); playlistSong.key = ""; } p.songs.Add(playlistSong); return(true); }); p.SavePlaylist(playlistPath); if (String.IsNullOrEmpty(this.currentEditingPlaylistFile)) { this.currentEditingPlaylistFile = playlistPath; } this.Save(); }
public static void MatchSongsForPlaylist(Playlist playlist, bool matchAll = false) { if (!SongCore.Loader.AreSongsLoaded || SongCore.Loader.AreSongsLoading || playlist.playlistTitle == "All songs" || playlist.playlistTitle == "Your favorite songs") { return; } Dictionary <string, CustomPreviewBeatmapLevel> songMap = new Dictionary <string, CustomPreviewBeatmapLevel>(StringComparer.OrdinalIgnoreCase); foreach (var kp in SongCore.Loader.CustomLevels) { var songHash = CustomHelpers.GetSongHash(kp.Value.levelID); if (songMap.ContainsKey(songHash)) { continue; } songMap.Add(songHash, kp.Value); } if (!playlist.songs.All(x => x.level != null) || matchAll) { playlist.songs.AsParallel().ForAll(x => { if (x.level == null || matchAll) { try { // try to use levelID if (!string.IsNullOrEmpty(x.levelId)) { string songHash = CustomHelpers.GetSongHash(x.levelId); if (songMap.ContainsKey(songHash)) { x.level = songMap[songHash]; x.hash = songHash; } } // failed, try again using hash if (x.level == null && !string.IsNullOrEmpty(x.hash)) { // fix broken playlists from a bug in song browser if (x.hash.Contains("custom_level")) { x.hash = CustomHelpers.GetSongHash(x.hash); } if (songMap.ContainsKey(x.hash)) { x.level = songMap[x.hash]; } } if (x.level == null && !string.IsNullOrEmpty(x.key)) { x.level = SongCore.Loader.CustomLevels.FirstOrDefault(y => y.Value.customLevelPath.Contains(x.key)).Value; if (x.level != null && !String.IsNullOrEmpty(x.level.levelID)) { x.hash = CustomHelpers.GetSongHash(x.level.levelID); } } } catch (Exception e) { Logger.Warning($"Unable to match song with {(string.IsNullOrEmpty(x.key) ? " unknown key!" : ("key " + x.key + " !"))}"); } } }); } }