/// <summary> /// Select a level pack. /// </summary> /// <param name="levelPackId"></param> public void SelectLevelPack(String levelPackId) { Logger.Trace("SelectLevelPack({0})", levelPackId); try { //var levelPacks = GetLevelPackCollection(); IBeatmapLevelPack pack = GetLevelPackByPackId(levelPackId); if (pack == null) { Logger.Debug("Could not locate requested level pack..."); return; } Logger.Info("Selecting level pack: {0}", pack.packID); LevelFilteringNavigationController.SelectBeatmapLevelPackOrPlayList(pack, null); LevelFilteringNavigationController.TabBarDidSwitch(); Logger.Debug("Done selecting level pack!"); } catch (Exception e) { Logger.Exception(e); } }
/// <summary> /// Acquire any UI elements from Beat saber that we need. Wait for the song list to be loaded. /// </summary> public void Start() { Logger.Trace("Start-SongBrowserApplication()"); InstallHandlers(); SongDataCore.Plugin.Songs.OnDataFinishedProcessing += OnScoreSaberDataDownloaded; if (SongCore.Loader.AreSongsLoaded) { OnSongLoaderLoadedSongs(null, SongCore.Loader.CustomLevels); } else { SongCore.Loader.SongsLoadedEvent += OnSongLoaderLoadedSongs; } // Useful to dump game objects. /*foreach (RectTransform rect in Resources.FindObjectsOfTypeAll<RectTransform>()) * { * Logger.Debug("RectTransform: {0}", rect.name); * }*/ /*foreach (Sprite sprite in Resources.FindObjectsOfTypeAll<Sprite>()) * { * Logger.Debug("Adding Icon: {0}", sprite.name); * }*/ }
/// <summary> /// Get a handle to the view controllers we are going to add elements to. /// </summary> private void AcquireUIElements() { Logger.Trace("AcquireUIElements()"); try { CachedIcons = new Dictionary <String, Sprite>(); foreach (Sprite sprite in Resources.FindObjectsOfTypeAll <Sprite>()) { if (CachedIcons.ContainsKey(sprite.name)) { continue; } //Logger.Debug("Adding Icon: {0}", sprite.name); CachedIcons.Add(sprite.name, sprite); } /*foreach (RectTransform rect in Resources.FindObjectsOfTypeAll<RectTransform>()) * { * Logger.Debug("RectTransform: {0}", rect.name); * }*/ } catch (Exception e) { Logger.Exception("Exception AcquireUIElements(): ", e); } }
/// <summary> /// Select a level pack. /// </summary> /// <param name="levelPackId"></param> public void SelectLevelPack(String levelPackId) { Logger.Trace("SelectLevelPack({0})", levelPackId); try { var levelPacks = GetLevelPackCollection(); var index = GetLevelPackIndexByPackId(levelPackId); var pack = GetLevelPackByPackId(levelPackId); if (index < 0) { Logger.Debug("Cannot select level packs yet..."); return; } Logger.Info("Selecting level pack index: {0}", pack.packName); var tableView = LevelPacksTableView.GetPrivateField <TableView>("_tableView"); LevelPacksTableView.SelectCellWithIdx(index); tableView.SelectCellWithIdx(index, true); tableView.ScrollToCellWithIdx(0, TableViewScroller.ScrollPositionType.Beginning, false); for (int i = 0; i < index; i++) { tableView.GetPrivateField <TableViewScroller>("_scroller").PageScrollDown(); } Logger.Debug("Done selecting level pack!"); } catch (Exception e) { Logger.Exception(e); } }
/// <summary> /// Handle Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleModeSelection(MainMenuViewController.MenuButton mode) { Logger.Trace("HandleModeSelection()"); _songBrowserUI.UpdateLevelPackModel(true); this._songBrowserUI.CreateUI(mode); StartCoroutine(this.UpdateBrowserUI()); }
/// <summary> /// Handle Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleModeSelection(MainMenuViewController.MenuButton mode) { Logger.Trace("HandleModeSelection()"); _songBrowserUI.CreateUI(mode); SongBrowserApplication.MainProgressBar.ShowMessage(""); StartCoroutine(UpdateBrowserUI()); }
/// <summary> /// Select a level collection. /// </summary> /// <param name="levelCollectionName"></param> public void SelectLevelCollection(String levelCollectionName) { Logger.Trace("SelectLevelCollection({0})", levelCollectionName); try { IAnnotatedBeatmapLevelCollection collection = GetLevelCollectionByName(levelCollectionName); if (collection == null) { Logger.Debug("Could not locate requested level collection..."); return; } Logger.Info("Selecting level collection: {0}", collection.collectionName); LevelFilteringNavigationController.SelectBeatmapLevelPackOrPlayList(collection as IBeatmapLevelPack, collection as IPlaylist); LevelFilteringNavigationController.TabBarDidSwitch(); Logger.Debug("Done selecting level collection!"); } catch (Exception e) { Logger.Exception(e); } }
/// <summary> /// Awake. /// </summary> private void Awake() { Logger.Trace("Awake-ScoreSaberDatabaseDownloader()"); if (Instance == null) { Instance = this; } }
/// <summary> /// Load the settings file for this plugin. /// If we fail to load return Default settings. /// </summary> /// <returns>SongBrowserSettings</returns> public static SongBrowserSettings Load() { Logger.Trace("Load()"); SongBrowserSettings retVal = null; // No Settings file. String settingsFilePath = SongBrowserSettings.SettingsPath(); if (File.Exists(settingsFilePath)) { // Deserialization from JSON FileStream fs = null; try { fs = File.OpenRead(settingsFilePath); XmlSerializer serializer = new XmlSerializer(typeof(SongBrowserSettings)); retVal = (SongBrowserSettings)serializer.Deserialize(fs); // Success loading, sane time to make a backup retVal.SaveBackup(); } catch (Exception e) { Logger.Exception("Unable to deserialize song browser settings file, using default settings: ", e); retVal = new SongBrowserSettings { DisableSavingSettings = true }; } finally { if (fs != null) { fs.Close(); } } } else { Logger.Debug("Settings file does not exist, returning defaults: " + settingsFilePath); retVal = new SongBrowserSettings(); } // check if the playlist directory exists, make it otherwise. String playlistDirPath = Path.Combine(Environment.CurrentDirectory, "Playlists"); if (!Directory.Exists(playlistDirPath)) { Directory.CreateDirectory(playlistDirPath); } MigrateFavorites(); ApplyFixes(retVal); return(retVal); }
/// <summary> /// It has awaken! /// </summary> private void Awake() { Logger.Trace("Awake-SongBrowserApplication()"); Instance = this; _songBrowserUI = gameObject.AddComponent <SongBrowserUI>(); _ppDownloader = gameObject.AddComponent <ScoreSaberDatabaseDownloader>(); _ppDownloader.onScoreSaberDataDownloaded += OnScoreSaberDataDownloaded; }
/// <summary> /// Inform browser score saber data is available. /// </summary> /// <param name="loader"></param> /// <param name="levels"></param> private void OnScoreSaberDataDownloaded() { Logger.Trace("OnScoreSaberDataDownloaded"); try { StartCoroutine(_songBrowserUI.AsyncWaitForSongUIUpdate()); } catch (Exception e) { Logger.Exception("Exception during OnScoreSaberDataDownloaded: ", e); } }
public bool SelectLevelCategory(String levelCategoryName) { Logger.Trace("SelectLevelCategory({0})", levelCategoryName); try { if (String.IsNullOrEmpty(levelCategoryName)) { // hack for now, just assume custom levels if a user has an old settings file, corrects itself first time they change level packs. levelCategoryName = SelectLevelCategoryViewController.LevelCategory.CustomSongs.ToString(); } SelectLevelCategoryViewController.LevelCategory category; try { category = (SelectLevelCategoryViewController.LevelCategory)Enum.Parse(typeof(SelectLevelCategoryViewController.LevelCategory), levelCategoryName, true); } catch (Exception) { // invalid input return(false); } if (category == LevelFilteringNavigationController.selectedLevelCategory) { Logger.Debug($"Level category [{category}] is already selected"); return(false); } Logger.Info("Selecting level category: {0}", levelCategoryName); var selectLeveCategoryViewController = LevelFilteringNavigationController.GetComponentInChildren <SelectLevelCategoryViewController>(); var iconSegementController = selectLeveCategoryViewController.GetComponentInChildren <IconSegmentedControl>(); int selectCellNumber = (from x in selectLeveCategoryViewController.GetField <SelectLevelCategoryViewController.LevelCategoryInfo[], SelectLevelCategoryViewController>("_levelCategoryInfos") select x.levelCategory).ToList().IndexOf(category); iconSegementController.SelectCellWithNumber(selectCellNumber); selectLeveCategoryViewController.LevelFilterCategoryIconSegmentedControlDidSelectCell(iconSegementController, selectCellNumber); LevelFilteringNavigationController.UpdateSecondChildControllerContent(category); //AnnotatedBeatmapLevelCollectionsViewController.RefreshAvailability(); Logger.Debug("Done selecting level category."); return(true); } catch (Exception e) { Logger.Exception(e); } return(false); }
/// <summary> /// Only gets called once during boot of BeatSaber. /// </summary> /// <param name="loader"></param> /// <param name="levels"></param> private void OnSongLoaderLoadedSongs(SongCore.Loader loader, ConcurrentDictionary <string, CustomPreviewBeatmapLevel> levels) { Logger.Trace("OnSongLoaderLoadedSongs-SongBrowserApplication()"); try { _songBrowserUI.UpdateLevelDataModel(); _songBrowserUI.RefreshSongList(); } catch (Exception e) { Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e); } }
/// <summary> /// Only gets called once during boot of BeatSaber. /// </summary> /// <param name="loader"></param> /// <param name="levels"></param> private void OnSongLoaderLoadedSongs(SongLoader loader, List <CustomLevel> levels) { Logger.Trace("OnSongLoaderLoadedSongs-SongBrowserApplication()"); try { _songBrowserUI.UpdateLevelPackModel(); _songBrowserUI.UpdateLevelDataModel(); _songBrowserUI.RefreshSongList(); } catch (Exception e) { Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e); } }
/// <summary> /// It has awaken! /// </summary> private void Awake() { Logger.Trace("Awake-SongBrowserApplication()"); Instance = this; // Init Model, load settings _songBrowserModel = new SongBrowserModel(); _songBrowserModel.Init(); // Init browser UI _songBrowserUI = gameObject.AddComponent <SongBrowserUI>(); _songBrowserUI.Model = _songBrowserModel; }
/// <summary> /// Inform browser score saber data is available. /// </summary> /// <param name="loader"></param> /// <param name="levels"></param> private void OnScoreSaberDataDownloaded() { Logger.Trace("OnScoreSaberDataDownloaded"); try { _songBrowserUI.Model.UpdateScoreSaberDataMapping(); if (_songBrowserUI.Model.Settings.sortMode == SongSortMode.PP) { _songBrowserUI.Model.ProcessSongList(); _songBrowserUI.RefreshSongList(); } } catch (Exception e) { Logger.Exception("Exception during OnScoreSaberDataDownloaded: ", e); } }
/// <summary> /// Inform browser score saber data is available. /// </summary> /// <param name="loader"></param> /// <param name="levels"></param> private void OnScoreSaberDataDownloaded() { Logger.Trace("OnScoreSaberDataDownloaded"); try { // It is okay if SongDataCore beats us to initialization if (_songBrowserUI == null) { return; } StartCoroutine(_songBrowserUI.AsyncWaitForSongUIUpdate()); } catch (Exception e) { Logger.Exception("Exception during OnScoreSaberDataDownloaded: ", e); } }
/// <summary> /// Acquire any UI elements from Beat saber that we need. Wait for the song list to be loaded. /// </summary> public void Start() { Logger.Trace("Start-SongBrowserApplication()"); AcquireUIElements(); InstallHandlers(); StartCoroutine(ScrappedData.Instance.DownloadScrappedData((List <ScrappedSong> songs) => { })); if (SongLoaderPlugin.SongLoader.AreSongsLoaded) { OnSongLoaderLoadedSongs(null, SongLoader.CustomLevels); } else { SongLoader.SongsLoadedEvent += OnSongLoaderLoadedSongs; _songBrowserUI.UpdateLevelPackModel(); } }
/// <summary> /// Update mapping of scrapped song data. /// </summary> private void OnBeatSaverDataDownloaded() { Logger.Trace("OnBeatSaverDataDownloaded"); try { if (_songBrowserModel.Settings.sortMode.NeedsBeatSaverData()) { _songBrowserUI.ProcessSongList(); _songBrowserUI.RefreshSongUI(); } else { _songBrowserUI.RefreshSortButtonUI(); } } catch (Exception e) { Logger.Exception("Exception during OnDownloaderScrappedDataDownloaded: ", e); } }
/// <summary> /// Parse the current pp data file. /// Public so controllers can decide when to update it. /// </summary> public void UpdateScoreSaberDataMapping() { Logger.Trace("UpdateScoreSaberDataMapping()"); ScoreSaberDataFile scoreSaberDataFile = ScoreSaberDatabaseDownloader.ScoreSaberDataFile; // bail if (scoreSaberDataFile == null) { Logger.Warning("Score saber data is not ready yet..."); return; } foreach (var level in SongLoader.CustomLevels) { // Skip if (_levelIdToScoreSaberData.ContainsKey(level.levelID)) { continue; } ScoreSaberData scoreSaberData = null; // try to version match first if (_levelIdToSongVersion.ContainsKey(level.levelID)) { String version = _levelIdToSongVersion[level.levelID]; if (scoreSaberDataFile.SongVersionToScoreSaberData.ContainsKey(version)) { scoreSaberData = scoreSaberDataFile.SongVersionToScoreSaberData[version]; } } if (scoreSaberData != null) { //Logger.Debug("{0} = {1}pp", level.songName, pp); _levelIdToScoreSaberData.Add(level.levelID, scoreSaberData); } } }
/// <summary> /// Sort the song list based on the settings. /// </summary> public void ProcessSongList(IAnnotatedBeatmapLevelCollection selectedBeatmapCollection, LevelSelectionNavigationController navController) { Logger.Trace("ProcessSongList()"); List <IPreviewBeatmapLevel> unsortedSongs = null; List <IPreviewBeatmapLevel> filteredSongs = null; List <IPreviewBeatmapLevel> sortedSongs = null; // Abort if (selectedBeatmapCollection == null) { Logger.Debug("Cannot process songs yet, no level collection selected..."); return; } Logger.Debug($"Using songs from level collection: {selectedBeatmapCollection.collectionName} [num={selectedBeatmapCollection.beatmapLevelCollection.beatmapLevels.Length}"); unsortedSongs = selectedBeatmapCollection.beatmapLevelCollection.beatmapLevels.ToList(); // filter Logger.Debug($"Starting filtering songs by {_settings.filterMode}"); Stopwatch stopwatch = Stopwatch.StartNew(); switch (_settings.filterMode) { case SongFilterMode.Favorites: filteredSongs = FilterFavorites(unsortedSongs); break; case SongFilterMode.Search: filteredSongs = FilterSearch(unsortedSongs); break; case SongFilterMode.Ranked: filteredSongs = FilterRanked(unsortedSongs, true, false); break; case SongFilterMode.Unranked: filteredSongs = FilterRanked(unsortedSongs, false, true); break; case SongFilterMode.Custom: Logger.Info("Song filter mode set to custom. Deferring filter behaviour to another mod."); filteredSongs = CustomFilterHandler != null?CustomFilterHandler.Invoke(selectedBeatmapCollection) : unsortedSongs; break; case SongFilterMode.None: default: Logger.Info("No song filter selected..."); filteredSongs = unsortedSongs; break; } stopwatch.Stop(); Logger.Info("Filtering songs took {0}ms", stopwatch.ElapsedMilliseconds); // sort Logger.Debug($"Starting to sort songs by {_settings.sortMode}"); stopwatch = Stopwatch.StartNew(); SortWasMissingData = false; switch (_settings.sortMode) { case SongSortMode.Original: sortedSongs = SortOriginal(filteredSongs); break; case SongSortMode.Newest: sortedSongs = SortNewest(filteredSongs); break; case SongSortMode.Author: sortedSongs = SortAuthor(filteredSongs); break; case SongSortMode.UpVotes: sortedSongs = SortUpVotes(filteredSongs); break; case SongSortMode.PlayCount: sortedSongs = SortBeatSaverPlayCount(filteredSongs); break; case SongSortMode.Rating: sortedSongs = SortBeatSaverRating(filteredSongs); break; case SongSortMode.Heat: sortedSongs = SortBeatSaverHeat(filteredSongs); break; case SongSortMode.YourPlayCount: sortedSongs = SortPlayCount(filteredSongs); break; case SongSortMode.PP: sortedSongs = SortPerformancePoints(filteredSongs); break; case SongSortMode.Stars: sortedSongs = SortStars(filteredSongs); break; case SongSortMode.Random: sortedSongs = SortRandom(filteredSongs); break; case SongSortMode.Custom: sortedSongs = CustomSortHandler != null?CustomSortHandler.Invoke(filteredSongs) : filteredSongs; break; case SongSortMode.Default: default: sortedSongs = SortSongName(filteredSongs); break; } if (this.Settings.invertSortResults && _settings.sortMode != SongSortMode.Random) { sortedSongs.Reverse(); } stopwatch.Stop(); Logger.Info("Sorting songs took {0}ms", stopwatch.ElapsedMilliseconds); // Still hacking in a custom level pack // Asterisk the pack name so it is identifable as filtered. var packName = selectedBeatmapCollection.collectionName; if (packName == null) { packName = ""; } if (!packName.EndsWith("*") && _settings.filterMode != SongFilterMode.None) { packName += "*"; } // Some level categories have a null cover image, supply something, it won't show it anyway var coverImage = selectedBeatmapCollection.coverImage; if (coverImage == null) { coverImage = BeatSaberMarkupLanguage.Utilities.ImageResources.BlankSprite; } Logger.Debug("Creating filtered level pack..."); BeatmapLevelPack levelPack = new BeatmapLevelPack(SongBrowserModel.FilteredSongsCollectionName, packName, selectedBeatmapCollection.collectionName, coverImage, new BeatmapLevelCollection(sortedSongs.ToArray())); /* * public virtual void SetData( * IAnnotatedBeatmapLevelCollection annotatedBeatmapLevelCollection, * bool showPackHeader, bool showPlayerStats, bool showPracticeButton, * string actionButtonText, * GameObject noDataInfoPrefab, BeatmapDifficultyMask allowedBeatmapDifficultyMask, BeatmapCharacteristicSO[] notAllowedCharacteristics); */ Logger.Debug("Acquiring necessary fields to call SetData(pack)..."); LevelCollectionNavigationController lcnvc = navController.GetField <LevelCollectionNavigationController, LevelSelectionNavigationController>("_levelCollectionNavigationController"); var _showPlayerStatsInDetailView = navController.GetField <bool, LevelSelectionNavigationController>("_showPlayerStatsInDetailView"); var _hidePracticeButton = navController.GetField <bool, LevelSelectionNavigationController>("_hidePracticeButton"); var _actionButtonText = navController.GetField <string, LevelSelectionNavigationController>("_actionButtonText"); var _allowedBeatmapDifficultyMask = navController.GetField <BeatmapDifficultyMask, LevelSelectionNavigationController>("_allowedBeatmapDifficultyMask"); var _notAllowedCharacteristics = navController.GetField <BeatmapCharacteristicSO[], LevelSelectionNavigationController>("_notAllowedCharacteristics"); Logger.Debug("Calling lcnvc.SetData..."); lcnvc.SetData(levelPack, true, _showPlayerStatsInDetailView, !_hidePracticeButton, _actionButtonText, null, _allowedBeatmapDifficultyMask, _notAllowedCharacteristics); //_sortedSongs.ForEach(x => Logger.Debug(x.levelID)); }
/// <summary> /// Handle Solo Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleSoloModeSelection() { Logger.Trace("HandleSoloModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.SoloFreePlay); _songBrowserUI.Show(); }
/// <summary> /// Sort the song list based on the settings. /// </summary> public void ProcessSongList(IBeatmapLevelPack selectedLevelPack, LevelCollectionViewController levelCollectionViewController, LevelSelectionNavigationController navController) { Logger.Trace("ProcessSongList()"); List <IPreviewBeatmapLevel> unsortedSongs = null; List <IPreviewBeatmapLevel> filteredSongs = null; List <IPreviewBeatmapLevel> sortedSongs = null; // Abort if (selectedLevelPack == null) { Logger.Debug("Cannot process songs yet, no level pack selected..."); return; } Logger.Debug("Using songs from level pack: {0}", selectedLevelPack.packID); unsortedSongs = selectedLevelPack.beatmapLevelCollection.beatmapLevels.ToList(); // filter Logger.Debug($"Starting filtering songs by {_settings.filterMode}"); Stopwatch stopwatch = Stopwatch.StartNew(); switch (_settings.filterMode) { case SongFilterMode.Favorites: filteredSongs = FilterFavorites(unsortedSongs); break; case SongFilterMode.Search: filteredSongs = FilterSearch(unsortedSongs); break; case SongFilterMode.Ranked: filteredSongs = FilterRanked(unsortedSongs, true, false); break; case SongFilterMode.Unranked: filteredSongs = FilterRanked(unsortedSongs, false, true); break; case SongFilterMode.Custom: Logger.Info("Song filter mode set to custom. Deferring filter behaviour to another mod."); filteredSongs = CustomFilterHandler != null?CustomFilterHandler.Invoke(selectedLevelPack) : unsortedSongs; break; case SongFilterMode.None: default: Logger.Info("No song filter selected..."); filteredSongs = unsortedSongs; break; } stopwatch.Stop(); Logger.Info("Filtering songs took {0}ms", stopwatch.ElapsedMilliseconds); // sort Logger.Debug("Starting to sort songs..."); stopwatch = Stopwatch.StartNew(); SortWasMissingData = false; switch (_settings.sortMode) { case SongSortMode.Original: sortedSongs = SortOriginal(filteredSongs); break; case SongSortMode.Newest: sortedSongs = SortNewest(filteredSongs); break; case SongSortMode.Author: sortedSongs = SortAuthor(filteredSongs); break; case SongSortMode.UpVotes: sortedSongs = SortUpVotes(filteredSongs); break; case SongSortMode.PlayCount: sortedSongs = SortBeatSaverPlayCount(filteredSongs); break; case SongSortMode.Rating: sortedSongs = SortBeatSaverRating(filteredSongs); break; case SongSortMode.Heat: sortedSongs = SortBeatSaverHeat(filteredSongs); break; case SongSortMode.YourPlayCount: sortedSongs = SortPlayCount(filteredSongs); break; case SongSortMode.PP: sortedSongs = SortPerformancePoints(filteredSongs); break; case SongSortMode.Stars: sortedSongs = SortStars(filteredSongs); break; case SongSortMode.Random: sortedSongs = SortRandom(filteredSongs); break; case SongSortMode.Default: default: sortedSongs = SortSongName(filteredSongs); break; } if (this.Settings.invertSortResults && _settings.sortMode != SongSortMode.Random) { sortedSongs.Reverse(); } stopwatch.Stop(); Logger.Info("Sorting songs took {0}ms", stopwatch.ElapsedMilliseconds); // Asterisk the pack name so it is identifable as filtered. var packName = selectedLevelPack.packName; if (!packName.EndsWith("*") && _settings.filterMode != SongFilterMode.None) { packName += "*"; } BeatmapLevelPack levelPack = new BeatmapLevelPack(SongBrowserModel.FilteredSongsPackId, packName, selectedLevelPack.shortPackName, selectedLevelPack.coverImage, new BeatmapLevelCollection(sortedSongs.ToArray())); GameObject _noDataGO = levelCollectionViewController.GetPrivateField <GameObject>("_noDataInfoGO"); //string _headerText = tableView.GetPrivateField<string>("_headerText"); //Sprite _headerSprite = tableView.GetPrivateField<Sprite>("_headerSprite"); bool _showPlayerStatsInDetailView = navController.GetPrivateField <bool>("_showPlayerStatsInDetailView"); bool _showPracticeButtonInDetailView = navController.GetPrivateField <bool>("_showPracticeButtonInDetailView"); navController.SetData(levelPack, true, _showPlayerStatsInDetailView, _showPracticeButtonInDetailView, _noDataGO); //_sortedSongs.ForEach(x => Logger.Debug(x.levelID)); }
/// <summary> /// Acquire any UI elements from Beat saber that we need. Wait for the song list to be loaded. /// </summary> public void Start() { Logger.Trace("Start()"); StartCoroutine(WaitForDownload()); }
/// <summary> /// Sort the song list based on the settings. /// </summary> public void ProcessSongList(LevelPackLevelsViewController levelsViewController) { Logger.Trace("ProcessSongList()"); List <IPreviewBeatmapLevel> unsortedSongs = null; List <IPreviewBeatmapLevel> filteredSongs = null; List <IPreviewBeatmapLevel> sortedSongs = null; // Abort if (levelsViewController.levelPack == null) { Logger.Debug("Cannot process songs yet, no level pack selected..."); return; } // fetch unsorted songs. // playlists always use customsongs if (this._settings.filterMode == SongFilterMode.Playlist && this.CurrentPlaylist != null) { unsortedSongs = null; } else { Logger.Debug("Using songs from level pack: {0}", levelsViewController.levelPack.packID); unsortedSongs = levelsViewController.levelPack.beatmapLevelCollection.beatmapLevels.ToList(); } // filter Logger.Debug($"Starting filtering songs by {_settings.filterMode}"); Stopwatch stopwatch = Stopwatch.StartNew(); switch (_settings.filterMode) { case SongFilterMode.Favorites: filteredSongs = FilterFavorites(); break; case SongFilterMode.Search: filteredSongs = FilterSearch(unsortedSongs); break; case SongFilterMode.Playlist: filteredSongs = FilterPlaylist(); break; case SongFilterMode.Ranked: filteredSongs = FilterRanked(unsortedSongs, true, false); break; case SongFilterMode.Unranked: filteredSongs = FilterRanked(unsortedSongs, false, true); break; case SongFilterMode.Custom: Logger.Info("Song filter mode set to custom. Deferring filter behaviour to another mod."); filteredSongs = CustomFilterHandler != null?CustomFilterHandler.Invoke(levelsViewController.levelPack) : unsortedSongs; break; case SongFilterMode.None: default: Logger.Info("No song filter selected..."); filteredSongs = unsortedSongs; break; } stopwatch.Stop(); Logger.Info("Filtering songs took {0}ms", stopwatch.ElapsedMilliseconds); // sort Logger.Debug("Starting to sort songs..."); stopwatch = Stopwatch.StartNew(); switch (_settings.sortMode) { case SongSortMode.Original: sortedSongs = SortOriginal(filteredSongs); break; case SongSortMode.Newest: sortedSongs = SortNewest(filteredSongs); break; case SongSortMode.Author: sortedSongs = SortAuthor(filteredSongs); break; case SongSortMode.UpVotes: sortedSongs = SortUpVotes(filteredSongs); break; case SongSortMode.PlayCount: sortedSongs = SortBeatSaverPlayCount(filteredSongs); break; case SongSortMode.Rating: sortedSongs = SortBeatSaverRating(filteredSongs); break; case SongSortMode.Heat: sortedSongs = SortBeatSaverHeat(filteredSongs); break; case SongSortMode.YourPlayCount: sortedSongs = SortPlayCount(filteredSongs); break; case SongSortMode.PP: sortedSongs = SortPerformancePoints(filteredSongs); break; case SongSortMode.Stars: sortedSongs = SortStars(filteredSongs); break; case SongSortMode.Difficulty: sortedSongs = SortDifficulty(filteredSongs); break; case SongSortMode.Random: sortedSongs = SortRandom(filteredSongs); break; case SongSortMode.Default: default: sortedSongs = SortSongName(filteredSongs); break; } if (this.Settings.invertSortResults && _settings.sortMode != SongSortMode.Random) { sortedSongs.Reverse(); } stopwatch.Stop(); Logger.Info("Sorting songs took {0}ms", stopwatch.ElapsedMilliseconds); // Asterisk the pack name so it is identifable as filtered. var packName = levelsViewController.levelPack.packName; if (!packName.EndsWith("*") && _settings.filterMode != SongFilterMode.None) { packName += "*"; } BeatmapLevelPack levelPack = new BeatmapLevelPack(SongBrowserModel.FilteredSongsPackId, packName, levelsViewController.levelPack.coverImage, new BeatmapLevelCollection(sortedSongs.ToArray())); levelsViewController.SetData(levelPack); //_sortedSongs.ForEach(x => Logger.Debug(x.levelID)); }
/// <summary> /// Sort the song list based on the settings. /// </summary> public void ProcessSongList() { Logger.Trace("ProcessSongList()"); // This has come in handy many times for debugging issues with Newest. /*foreach (BeatmapLevelSO level in _originalSongs) * { * if (_levelIdToCustomLevel.ContainsKey(level.levelID)) * { * Logger.Debug("HAS KEY {0}: {1}", _levelIdToCustomLevel[level.levelID].customSongInfo.path, level.levelID); * } * else * { * Logger.Debug("Missing KEY: {0}", level.levelID); * } * }*/ // TODO - remove as part of unifying song list interface if (_isPreviewLevelPack) { return; } if (_levelPackToSongs.Count == 0) { Logger.Debug("Cannot process songs yet, level packs have not been processed..."); return; } if (this._currentLevelPack == null || !this._levelPackToSongs.ContainsKey(this._currentLevelPack.packName)) { Logger.Debug("Cannot process songs yet, no level pack selected..."); return; } // Playlist filter will load the original songs. List <BeatmapLevelSO> unsortedSongs = null; List <BeatmapLevelSO> filteredSongs = null; if (this._settings.filterMode == SongFilterMode.Playlist && this.CurrentPlaylist != null) { unsortedSongs = null; } else { Logger.Debug("Using songs from level pack: {0}", this._currentLevelPack.packName); unsortedSongs = new List <BeatmapLevelSO>(_levelPackToSongs[this._currentLevelPack.packName]); } // filter Logger.Debug("Starting filtering songs..."); Stopwatch stopwatch = Stopwatch.StartNew(); switch (_settings.filterMode) { case SongFilterMode.Favorites: filteredSongs = FilterFavorites(); break; case SongFilterMode.Search: filteredSongs = FilterSearch(unsortedSongs); break; case SongFilterMode.Playlist: filteredSongs = FilterPlaylist(); break; case SongFilterMode.None: default: Logger.Info("No song filter selected..."); filteredSongs = unsortedSongs; break; } stopwatch.Stop(); Logger.Info("Filtering songs took {0}ms", stopwatch.ElapsedMilliseconds); // sort Logger.Debug("Starting to sort songs..."); stopwatch = Stopwatch.StartNew(); switch (_settings.sortMode) { case SongSortMode.Original: SortOriginal(filteredSongs); break; case SongSortMode.Newest: SortNewest(filteredSongs); break; case SongSortMode.Author: SortAuthor(filteredSongs); break; case SongSortMode.PlayCount: SortPlayCount(filteredSongs); break; case SongSortMode.PP: SortPerformancePoints(filteredSongs); break; case SongSortMode.Difficulty: SortDifficulty(filteredSongs); break; case SongSortMode.Random: SortRandom(filteredSongs); break; case SongSortMode.Default: default: SortSongName(filteredSongs); break; } if (this.Settings.invertSortResults && _settings.sortMode != SongSortMode.Random) { _sortedSongs.Reverse(); } stopwatch.Stop(); Logger.Info("Sorting songs took {0}ms", stopwatch.ElapsedMilliseconds); this.OverwriteCurrentLevelPack(); //_sortedSongs.ForEach(x => Logger.Debug(x.levelID)); }
/// <summary> /// Handle Multiplayer Mode. /// Triggers when level select is clicked inside a host lobby. /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleMultiplayerModeSelection() { Logger.Trace("HandleCampaignModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.Multiplayer); _songBrowserUI.Hide(); }
/// <summary> /// Handle Party Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> public void HandleCampaignModeSelection() { Logger.Trace("HandleCampaignModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.SoloCampaign); _songBrowserUI.Hide(); }
/// <summary> /// Handle Party Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandlePartyModeSelection() { Logger.Trace("HandlePartyModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.Party); _songBrowserUI.Show(); }