/// <summary> /// Get a handle to the view controllers we are going to add elements to. /// </summary> public 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); } // Append our own event to appropriate events so we can refresh the song list before the user sees it. MainFlowCoordinator mainFlow = Resources.FindObjectsOfTypeAll <MainFlowCoordinator>().First(); Button soloFreePlayButton = Resources.FindObjectsOfTypeAll <Button>().First(x => x.name == "SoloFreePlayButton"); Button partyFreePlayButton = Resources.FindObjectsOfTypeAll <Button>().First(x => x.name == "PartyFreePlayButton"); soloFreePlayButton.onClick.AddListener(HandleSoloModeSelection); partyFreePlayButton.onClick.AddListener(HandlePartyModeSelection); } catch (Exception e) { Logger.Exception("Exception AcquireUIElements(): ", e); } }
/// <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> /// Handle Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleModeSelection(MainMenuViewController.MenuButton mode) { Logger.Trace("HandleModeSelection()"); this._songBrowserUI.CreateUI(mode); this._songBrowserUI.UpdateSongList(); this._songBrowserUI.RefreshSongList(); }
/// <summary> /// Awake. /// </summary> private void Awake() { Logger.Trace("Awake()"); if (Instance == null) { Instance = this; } }
/// <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()"); AcquireUIElements(); StartCoroutine(ScrappedData.Instance.DownloadScrappedData((List <ScrappedSong> songs) => { })); StartCoroutine(WaitForSongListUI()); }
/// <summary> /// Awake. /// </summary> private void Awake() { Logger.Trace("Awake-ScoreSaberDatabaseDownloader()"); if (Instance == null) { Instance = this; } }
/// <summary> /// It has awaken! /// </summary> private void Awake() { Logger.Trace("Awake()"); Instance = this; _songBrowserUI = gameObject.AddComponent <SongBrowserUI>(); _ppDownloader = gameObject.AddComponent <ScoreSaberDatabaseDownloader>(); _ppDownloader.onScoreSaberDataDownloaded += OnScoreSaberDataDownloaded; }
/// <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"); try { _songBrowserUI.UpdateSongList(); } 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> /// 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> /// 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> /// Inform browser score saber data is available. /// </summary> /// <param name="loader"></param> /// <param name="levels"></param> private void OnScoreSaberDataDownloaded() { Logger.Trace("OnScoreSaberDataDownloaded"); try { // TODO - this should be in the SongBrowserUI which is acting like the view controller for the SongBrowser _songBrowserUI.Model.UpdateScoreSaberDataMapping(); //_songBrowserUI.RefreshScoreSaberData(null); if (_songBrowserUI.Model.Settings.sortMode == SongSortMode.PP) { _songBrowserUI.Model.ProcessSongList(); _songBrowserUI.RefreshSongList(); } } catch (Exception e) { Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e); } }
/// <summary> /// Wait for the song list to be visible to draw it. /// </summary> /// <returns></returns> private IEnumerator WaitForSongListUI() { Logger.Trace("WaitForSongListUI()"); yield return(new WaitUntil(delegate() { return Resources.FindObjectsOfTypeAll <SoloFreePlayFlowCoordinator>().Any() && Resources.FindObjectsOfTypeAll <SoloFreePlayFlowCoordinator>().Any(); })); Logger.Debug("Found Solo and Party FreePlayFlowCoordinators..."); if (SongLoaderPlugin.SongLoader.AreSongsLoaded) { OnSongLoaderLoadedSongs(null, SongLoader.CustomLevels); } else { SongLoader.SongsLoadedEvent += OnSongLoaderLoadedSongs; } _songBrowserUI.RefreshSongList(); }
/// <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("Cannot fetch song difficulty for score saber data..."); 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() { Logger.Trace("ProcessSongList()"); // This has come in handy many times for debugging issues with Newest. /*foreach (LevelSO 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); * } * }*/ if (_directoryStack.Count <= 0) { Logger.Debug("Cannot process songs yet, songs infos have not been processed..."); return; } // Playlist filter will load the original songs. if (this._settings.filterMode == SongFilterMode.Playlist && this.CurrentPlaylist != null) { _originalSongs = null; } else { Logger.Debug("Showing songs for directory: {0}", _directoryStack.Peek().Key); _originalSongs = _directoryStack.Peek().Levels; } // filter Logger.Debug("Starting filtering songs..."); Stopwatch stopwatch = Stopwatch.StartNew(); switch (_settings.filterMode) { case SongFilterMode.Favorites: FilterFavorites(); break; case SongFilterMode.Search: FilterSearch(_originalSongs); break; case SongFilterMode.Playlist: FilterPlaylist(); break; case SongFilterMode.None: default: Logger.Info("No song filter selected..."); _filteredSongs = _originalSongs; 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); //_sortedSongs.ForEach(x => Logger.Debug(x.levelID)); }
/// <summary> /// Handle Party Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandlePartyModeSelection() { Logger.Trace("HandlePartyModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.Party); this._songBrowserUI.Show(); }
/// <summary> /// Handle Party Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleCampaignModeSelection() { Logger.Trace("HandleCampaignModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.SoloCampaign); this._songBrowserUI.Hide(); }
/// <summary> /// Handle Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleModeSelection(MainMenuViewController.MenuButton mode) { Logger.Trace("HandleModeSelection()"); this._songBrowserUI.CreateUI(mode); StartCoroutine(this.UpdateBrowserUI()); }
/// <summary> /// Handle Party Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandlePartyModeSelection() { Logger.Trace("HandlePartyModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.Party); }
/// <summary> /// Handle Solo Mode /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> private void HandleSoloModeSelection() { Logger.Trace("HandleSoloModeSelection()"); HandleModeSelection(MainMenuViewController.MenuButton.SoloFreePlay); }
/// <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() { 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)); }