Exemple #1
0
        private void ApplyQuickFilterPressed(QuickFilter quickFilter)
        {
            FilterList.ApplyQuickFilter(quickFilter);

            IPreviewBeatmapLevel[] unfilteredLevels = null;
            if (_lastPack == null)
            {
                _lastPack = LevelSelectionNavigationController.GetPrivateField <IBeatmapLevelPack>("_levelPack");
            }
            if (_lastPack == null)
            {
                unfilteredLevels = _levelCollectionTableView.GetPrivateField <IPreviewBeatmapLevel[]>("_previewBeatmapLevels");
            }
            else
            {
                unfilteredLevels = _lastPack.beatmapLevelCollection.beatmapLevels;
            }

            if (unfilteredLevels == null)
            {
                Logger.log.Warn("Unable to apply quick filter (could not find songs to filter)");
                return;
            }

            _filteredLevelPack.SetupFromUnfilteredLevels(unfilteredLevels);
            LevelSelectionNavigationController.SetData(
                _filteredLevelPack,
                true,
                LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"));

            ButtonPanel.instance.SetFilterStatus(true);
        }
Exemple #2
0
        private void DismissFilterFlowCoordinator()
        {
            _freePlayFlowCoordinator.InvokeMethod("DismissFlowCoordinator", _filterFlowCoordinator, null, false);
            ButtonPanel.instance.ShowPanel();

            // instead of applying filters inside the filter flow coordinator, apply the filters when the flow coordinator is dismissed
            // that way, we don't get the unity complaining about the LevelSelectionNavigationController being not active
            if (SongBrowserTweaks.Initialized && FilterList.AnyApplied)
            {
                SongBrowserTweaks.ApplyFilters();
            }
            else if (_levelsToApply != null)
            {
                // NOTE: levels should already be sorted
                LevelSelectionNavigationController.SetData(
                    _levelsToApply,
                    true,
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"),
                    null);
                _levelsToApply = null;

                if (_uiAdditions != null)
                {
                    _uiAdditions.RefreshPageButtons();
                }
            }
        }
Exemple #3
0
        private void SortButtonPressed()
        {
            if (_lastPack == null)
            {
                _lastPack = LevelSelectionNavigationController.GetPrivateField <IBeatmapLevelPack>("_levelPack");
            }

            if (FilterList.AnyApplied)
            {
                _filteredLevelPack.SetupFromUnfilteredLevels(_lastPack.beatmapLevelCollection.beatmapLevels, _lastPack.coverImage, false);
                LevelSelectionNavigationController.SetData(_filteredLevelPack,
                                                           true,
                                                           LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                                                           LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"));
            }
            else
            {
                if (_lastPack != null && _lastPack is IBeatmapLevelPack beatmapLevelPack)
                {
                    LevelSelectionNavigationController.SetData(
                        _sortedLevelsLevelPack.SetupFromLevelPack(beatmapLevelPack),
                        true,
                        LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                        LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"));
                }
                else
                {
                    var lastLevels = _levelCollectionTableView.GetPrivateField <IPreviewBeatmapLevel[]>("_previewBeatmapLevels");

                    if (lastLevels != null)
                    {
                        // if using default sort on a playlist, just show it as a playlist instead of creating a new level pack
                        if (SongSortModule.IsDefaultSort)
                        {
                            LevelSelectionNavigationController.SetData(
                                new BeatmapLevelCollection(lastLevels),
                                LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                                LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"),
                                null);
                        }
                        else
                        {
                            LevelSelectionNavigationController.SetData(
                                _sortedLevelsLevelPack.SetupFromLevels(lastLevels),
                                true,
                                LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                                LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"));
                        }
                    }
                    else
                    {
                        Logger.log.Warn("Unable to find songs to sort");
                    }
                }
            }
        }
Exemple #4
0
        private void ConfirmDeleteButtonPressed(CustomBeatmapLevel level)
        {
            // scrolling back to the previous position is done by SongListUIAdditions
            // just need to deal with setting up the current pack here
            var currentPack = LevelSelectionNavigationController.GetPrivateField <IBeatmapLevelPack>("_levelPack", typeof(LevelSelectionNavigationController));

            // if the current list of levels does not belong to a level pack, just provide the same levels minus the deleted song
            if (currentPack == null)
            {
                IPreviewBeatmapLevel[] levels            = _levelCollectionTableView.GetPrivateField <IPreviewBeatmapLevel[]>("_previewBeatmapLevels", typeof(LevelCollectionTableView));
                BeatmapLevelCollection replacementLevels = new BeatmapLevelCollection(levels.Where(x => x.levelID != level.levelID).ToArray());

                Loader.Instance.DeleteSong(level.customLevelPath);

                LevelSelectionNavigationController.SetData(
                    replacementLevels,
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView", typeof(LevelSelectionNavigationController)),
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView", typeof(LevelSelectionNavigationController)),
                    null);
            }
            // check if the current level pack is this mod's filtered/sorted level pack
            // if it is, just remove the song from the level pack and show it again
            else if (currentPack.packID == FilteredLevelsLevelPack.PackID || currentPack.packID.Contains(SortedLevelsLevelPack.PackIDSuffix))
            {
                // remove the song from the pack
                var replacementPack = new BeatmapLevelPack(
                    currentPack.packID,
                    currentPack.packName,
                    currentPack.shortPackName,
                    currentPack.coverImage,
                    new BeatmapLevelCollection(currentPack.beatmapLevelCollection.beatmapLevels.Where(x => x.levelID != level.levelID).ToArray()));

                try
                {
                    _isDeletingSongInModOwnedLevelPack = true;
                    Loader.Instance.DeleteSong(level.customLevelPath);
                }
                finally
                {
                    _isDeletingSongInModOwnedLevelPack = false;
                }

                LevelSelectionNavigationController.SetData(
                    replacementPack,
                    true,
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView", typeof(LevelSelectionNavigationController)),
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView", typeof(LevelSelectionNavigationController)));
            }
            // if the current level pack is not from this mod, just delete
            // SongCore should automatically reload the pack
            else
            {
                Loader.Instance.DeleteSong(level.customLevelPath);
            }
        }
Exemple #5
0
        public void ClearButtonPressed()
        {
            if (FilterList.AnyApplied)
            {
                UnapplyFilters();
            }
            else
            {
                return;
            }

            if (SongBrowserTweaks.Initialized)
            {
                Logger.log.Debug("'Clear Filter' button pressed.");
                return;
            }

            if (_lastPack == null)
            {
                var levelCollectionsViewController = Resources.FindObjectsOfTypeAll <AnnotatedBeatmapLevelCollectionsViewController>().FirstOrDefault();

                if (levelCollectionsViewController != null)
                {
                    _lastPack = levelCollectionsViewController.selectedAnnotatedBeatmapLevelCollection;
                }
            }

            if (_lastPack != null)
            {
                if (SongSortModule.IsDefaultSort)
                {
                    LevelSelectionNavigationController.SetData(_lastPack,
                                                               true,
                                                               LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                                                               LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"),
                                                               null);
                }
                else
                {
                    LevelSelectionNavigationController.SetData(_sortedLevelsLevelPack.SetupFromLevelCollection(_lastPack),
                                                               true,
                                                               LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                                                               LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"));
                }
            }
            else
            {
                Logger.log.Warn("Unable to find the last level pack");
            }

            if (ButtonPanel.IsSingletonAvailable && ButtonPanel.instance.Initialized)
            {
                ButtonPanel.instance.SetFilterStatus(false);
            }
        }
Exemple #6
0
        private void ApplySearchFilter(string searchQuery)
        {
            if (string.IsNullOrEmpty(searchQuery))
            {
                _freePlayFlowCoordinator.InvokeMethod("DismissFlowCoordinator", _searchFlowCoordinator, null, false);
                return;
            }

            SearchFilter filter = FilterList.SearchFilter;

            if (filter == null)
            {
                // this should never happen
                Logger.log.Error("Unable to apply search filter (SearchFilter object doesn't exist)");
                return;
            }

            filter.QueryStagingValue        = searchQuery;
            filter.SplitQueryStagingValue   = PluginConfig.SplitQueryByWords;
            filter.SongFieldsStagingValue   = PluginConfig.SongFieldsToSearch;
            filter.StripSymbolsStagingValue = PluginConfig.StripSymbols;
            filter.ApplyStagingValues();

            if (_filterFlowCoordinator != null)
            {
                _filterFlowCoordinator.RefreshUI();
            }

            _freePlayFlowCoordinator.InvokeMethod("DismissFlowCoordinator", _searchFlowCoordinator, null, false);

            if (SongBrowserTweaks.Initialized)
            {
                SongBrowserTweaks.ApplyFilters();
            }
            else
            {
                ButtonPanel.instance.SetFilterStatus(true);
                ButtonPanel.instance.ShowPanel();

                _filteredLevelPack.SetupFromUnfilteredLevels(_lastPack.beatmapLevelCollection.beatmapLevels, _lastPack.coverImage, false);
                LevelSelectionNavigationController.SetData(
                    _filteredLevelPack,
                    true,
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                    LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"));

                _uiAdditions.RefreshPageButtons();
            }
        }
        /// <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));
        }
Exemple #8
0
        private void LevelPackSelected(LevelFilteringNavigationController navController, IAnnotatedBeatmapLevelCollection levelPack, GameObject noDataInfoPrefab, BeatmapCharacteristicSO preferredCharacteristic)
        {
            // ignore the first select event that's fired immediately after the user select the free play mode
            // this is done so we can select the saved last pack later
            // when the saved pack is selected, it will then call this function again for sorting/storing
            if (_isSelectingInitialLevelPack)
            {
                _lastPack = levelPack;
                _isSelectingInitialLevelPack = false;
                return;
            }

            // in ConfirmDeleteButtonClicked, the call to SongCore.Loader.Instance.DeleteSong will reload the level packs
            // which causes the custom level pack to be re-selected. but, if filters are applied or level pack is sorted,
            // we want to reshow our own filtered/sorted level pack and not reset our UI, so we don't have to handle this event
            // this code is kinda smelly tbh, but can't do anything about it unless there are changes to SongCore
            if (_isDeletingSongInModOwnedLevelPack)
            {
                return;
            }

            if (levelPack.collectionName != FilteredLevelsLevelPack.CollectionName)
            {
                _lastPack = levelPack;

                // store level pack to PluginConfig
                var tabBarVC    = LevelFilteringNavigationController.GetPrivateField <TabBarViewController>("_tabBarViewController");
                var tabBarItems = tabBarVC.GetPrivateField <TabBarViewController.TabBarItem[]>("_items");

                string lastLevelPackString = tabBarItems[tabBarVC.selectedCellNumber].title + PluginConfig.LastLevelPackIDSeparator;
                if (levelPack is IBeatmapLevelPack beatmapLevelPack)
                {
                    lastLevelPackString += beatmapLevelPack.packID;
                    Logger.log.Debug($"Storing '{beatmapLevelPack.packName}' (id = '{beatmapLevelPack.packID}') level pack as last pack");
                }
                else
                {
                    lastLevelPackString += levelPack.collectionName;
                    Logger.log.Debug($"Storing '{levelPack.collectionName}' level collection as last pack");
                }
                PluginConfig.LastLevelPackID = lastLevelPackString;

                // reapply sort mode
                if (!SongSortModule.IsDefaultSort)
                {
                    if (levelPack is IBeatmapLevelPack beatmapLevelPack2)
                    {
                        _sortedLevelsLevelPack.SetupFromLevelPack(beatmapLevelPack2);
                    }
                    else
                    {
                        _sortedLevelsLevelPack.SetupFromLevels(levelPack.beatmapLevelCollection.beatmapLevels);
                    }

                    // since the level selection navigation controller shows a level pack using the same event that calls this function
                    // and it technically isn't a guarantee that this function will run after it is set,
                    // delay setting our level pack
                    StartCoroutine(UIUtilities.DelayedAction(() =>
                                                             LevelSelectionNavigationController.SetData(
                                                                 _sortedLevelsLevelPack,
                                                                 true,
                                                                 LevelSelectionNavigationController.GetPrivateField <bool>("_showPlayerStatsInDetailView"),
                                                                 LevelSelectionNavigationController.GetPrivateField <bool>("_showPracticeButtonInDetailView"))));
                }
            }

            // SongBrowser can now apply filters to OST levels and switch between different level packs
            // so our old behaviour of cancelling the filters is no longer needed
            // that being said, without SongBrowser, we are still going to cancel filters upon switching level packs
            // because i'd rather the player have to go into the FilterViewController,
            // so that it can check if all the beatmap details have been loaded
            if (FilterList.AnyApplied)
            {
                Logger.log.Debug("Another level pack has been selected, unapplying filters");
            }
            UnapplyFilters();

            if (_uiAdditions != null)
            {
                StartCoroutine(UIUtilities.DelayedAction(_uiAdditions.RefreshPageButtons));
            }
        }