Пример #1
0
        /// <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);
            }
        }
Пример #2
0
        public void SetSongs(IBeatmapLevelPack selectedPack, SortMode sortMode, string searchRequest)
        {
            _lastSortMode      = sortMode;
            _lastSearchRequest = searchRequest;
            _lastSelectedPack  = selectedPack;

            List <BeatmapLevelSO> levels = new List <BeatmapLevelSO>();

            if (_lastSelectedPack != null)
            {
                levels = _lastSelectedPack.beatmapLevelCollection.beatmapLevels.Where(x => x is BeatmapLevelSO).Cast <BeatmapLevelSO>().ToList();

                if (string.IsNullOrEmpty(searchRequest))
                {
                    switch (sortMode)
                    {
                    case SortMode.Newest: { levels = SortLevelsByCreationTime(levels); }; break;

                    case SortMode.Difficulty:
                    {
                        levels = levels.AsParallel().OrderBy(x => { int index = ScrappedData.Songs.FindIndex(y => x.levelID.StartsWith(y.Hash)); return(index == -1 ? (x.levelID.Length < 32 ? int.MaxValue : int.MaxValue - 1) : index); }).ToList();
                    }; break;
                    }
                }
                else
                {
                    levels = levels.Where(x => ($"{x.songName} {x.songSubName} {x.levelAuthorName} {x.songAuthorName}".ToLower().Contains(searchRequest))).ToList();
                }
            }

            _songSelectionViewController.SetSongs(levels);
        }
        private void LevelPackSelected(LevelPacksViewController viewController, IBeatmapLevelPack levelPack)
        {
            var previousPack = _lastPack;

            if (levelPack.packName != FilteredSongsPackName)
            {
                _lastPack = levelPack;
            }

            if (SongBrowserTweaks.ModLoaded && SongBrowserTweaks.Initialized)
            {
                // on the new version of SongBrowser, selecting the same level pack should have no changes to what is shown
                // unless it is an OST song pack (which we then clear the filter)
                IPreviewBeatmapLevel[] levels = levelPack.beatmapLevelCollection.beatmapLevels;
                if (previousPack != levelPack || (levels.Length > 0 && !(levels[0] is CustomPreviewBeatmapLevel)))
                {
                    if (_filterViewController != null)
                    {
                        _filterViewController.UnapplyFilters(false);
                    }
                    SongBrowserTweaks.FiltersUnapplied();
                }
            }
            else
            {
                UnapplyFilters();
            }
        }
        /// <summary>
        /// Populate word storage with the words in the song name, sub-name, author, and map creator of a level pack.
        /// </summary>
        /// <param name="levelPack">The level pack whose words you want to store.</param>
        public void SetupStorage(IBeatmapLevelPack levelPack)
        {
            IsLoading         = true;
            _manualResetEvent = new ManualResetEvent(true);
            _taskCancelled    = false;

            _task = new HMTask(
                delegate()
            {
                var sw = System.Diagnostics.Stopwatch.StartNew();
                Logger.log.Info($"Creating word count storage object for the \"{levelPack.packName}\" level pack (contains {levelPack.beatmapLevelCollection.beatmapLevels.Length} songs)");

                if (!SetWordsFromLevelPack(levelPack))
                {
                    return;
                }

                sw.Stop();
                Logger.log.Info($"Finished creating word count storage object for the \"{levelPack.packName}\" level pack (took {sw.ElapsedMilliseconds/1000f} seconds, {_words.Count} unique words processed)");
            },
                delegate()
            {
                _manualResetEvent = null;
                _task             = null;
                IsLoading         = false;
            });

            _task.Run();
        }
        /// <summary>
        /// Overwrite the current level pack.
        /// </summary>
        private void OverwriteCurrentLevelPack()
        {
            Logger.Debug("Overwriting levelPack [{0}] beatmapLevelCollection", this._currentLevelPack);
            IBeatmapLevelPack levelPack = this._currentLevelPack;
            var levels = _sortedSongs.ToArray();

            ReflectionUtil.SetPrivateField(levelPack.beatmapLevelCollection, "_beatmapLevels", levels);
        }
Пример #6
0
        /// <summary>
        /// Presents this flow coordinator and sets search space.
        /// This must be used instead of invoking the private PresentFlowCoordinator to ensure the list of levels is provided.
        /// </summary>
        /// <param name="parentFlowCoordinator">The flow coordinator that will be immediately higher in the hierarchy that will present this flow coordinator.</param>
        /// <param name="levels">The list of levels that will be used as the search space.</param>
        public void Activate(FlowCoordinator parentFlowCoordinator, IBeatmapLevelPack levelPack)
        {
            _levelsSearchSpace = levelPack.beatmapLevelCollection.beatmapLevels;
            Action onFinish = PushInitialViewControllersToNavigationController;

            parentFlowCoordinator.PresentFlowCoordinator(this, onFinish);

            WordPredictionEngine.instance.SetActiveWordStorageFromLevelPack(levelPack);
        }
        /// <summary>
        /// Presents this flow coordinator and sets search space.
        /// This must be used instead of invoking the private PresentFlowCoordinator to ensure the list of levels is provided.
        /// </summary>
        /// <param name="parentFlowCoordinator">The flow coordinator that will be immediately higher in the hierarchy that will present this flow coordinator.</param>
        /// <param name="levels">The list of levels that will be used as the search space.</param>
        public void Activate(FlowCoordinator parentFlowCoordinator, IBeatmapLevelPack levelPack)
        {
            _levelsSearchSpace = levelPack.beatmapLevelCollection.beatmapLevels;
            Action onFinish = PushInitialViewControllersToNavigationController;

            parentFlowCoordinator.InvokePrivateMethod("PresentFlowCoordinator", new object[] { this, onFinish, false, false });

            WordPredictionEngine.Instance.SetActiveWordStorageFromLevelPack(levelPack);
        }
        /// <summary>
        /// SongLoader doesn't fire event when we delete a song.
        /// </summary>
        /// <param name="levelPack"></param>
        /// <param name="levelId"></param>
        public void RemoveSongFromLevelPack(IBeatmapLevelPack levelPack, String levelId)
        {
            if (!_levelPackToSongs.ContainsKey(levelPack.packName))
            {
                Logger.Debug("Trying to remove song from level pack [{0}] but we do not have any information on it...", levelPack.packName);
                return;
            }

            _levelPackToSongs[levelPack.packName].RemoveAll(x => x.levelID == levelId);
        }
Пример #9
0
        public void ShowSongsList(string lastLevelId = "")
        {
            if (_songSelectionViewController == null)
            {
                _songSelectionViewController = BeatSaberUI.CreateViewController <SongSelectionViewController>();
                _songSelectionViewController.SongSelected  += SongSelected;
                _songSelectionViewController.SortPressed   += (sortMode) => { SetSongs(_lastSelectedPack, sortMode, _lastSearchRequest); };
                _songSelectionViewController.SearchPressed += () => { _searchKeyboard.inputString = ""; PresentViewController(_searchKeyboard, null); };
            }

            if (_packsViewController == null)
            {
                _packsViewController      = Instantiate(Resources.FindObjectsOfTypeAll <LevelPacksViewController>().First(x => x.name != "CustomLevelPacksViewController"));
                _packsViewController.name = "CustomLevelPacksViewController";

                TableView table = _packsViewController.GetComponentInChildren <TableView>();
                table.Init();
                _packsViewController.GetComponentInChildren <TableViewScroller>().Init(table);


                if (_lastSelectedPack == null)
                {
                    _lastSelectedPack = SongCore.Loader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks[0];
                }

                _packsViewController.didSelectPackEvent += (sender, selectedPack) => { SetSongs(selectedPack, _lastSortMode, _lastSearchRequest); };
            }

            _packsViewController.SetData(SongCore.Loader.CustomBeatmapLevelPackCollectionSO, SongCore.Loader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.FindIndexInArray(_lastSelectedPack));

            if (_roomNavigationController.viewControllers.IndexOf(_songSelectionViewController) < 0)
            {
                PushViewControllerToNavigationController(_roomNavigationController, _songSelectionViewController, null, true);
                SetSongs(_lastSelectedPack, _lastSortMode, _lastSearchRequest);

                if (!string.IsNullOrEmpty(lastLevelId))
                {
                    _songSelectionViewController.ScrollToLevel(lastLevelId);
                }
            }

            if (Client.Instance.isHost)
            {
                _packsViewController.gameObject.SetActive(true);
                SetBottomScreenViewController(_packsViewController);
            }
            else
            {
                _packsViewController.gameObject.SetActive(false);
                SetBottomScreenViewController(null);
            }

            _songSelectionViewController.UpdateViewController(Client.Instance.isHost);
        }
Пример #10
0
 static bool Prefix(IBeatmapLevelPack pack, IPreviewBeatmapLevel previewBeatmapLevel, bool showPlayerStats, bool hidePracticeButton, bool hide360DegreeBeatmapCharacteristic, bool canBuyPack, ref string playButtonText, BeatmapDifficultyMask allowedBeatmapDifficultyMask, BeatmapCharacteristicSO[] notAllowedCharacteristics)
 {
     if (Plugin.cfg.Enabled && NoFailCheck.IsInSoloFreeplay)
     {
         if (NoFailCheck.NoFailEnabled && Plugin.cfg.ChangeText)
         {
             playButtonText = "No Fail!";
         }
     }
     return(true);
 }
        /// <summary>
        /// Get level pack by level pack id.
        /// </summary>
        /// <param name="levelPackId"></param>
        /// <returns></returns>
        public IBeatmapLevelPack GetLevelPackByPackId(String levelPackId)
        {
            IBeatmapLevelPackCollection levelPackCollection = GetLevelPackCollection();

            if (levelPackCollection == null)
            {
                return(null);
            }

            IBeatmapLevelPack levelPack = levelPackCollection.beatmapLevelPacks.ToList().FirstOrDefault(x => x.packID == levelPackId);

            return(levelPack);
        }
Пример #12
0
        /// <summary>
        /// Get level pack by level pack id.
        /// </summary>
        /// <param name="levelPackId"></param>
        /// <returns></returns>
        public IBeatmapLevelPack GetLevelPackByPackId(String levelPackId)
        {
            IBeatmapLevelPack pack = null;

            foreach (IBeatmapLevelPack o in BeatmapLevelsModel.allLoadedBeatmapLevelPackCollection.beatmapLevelPacks)
            {
                if (String.Equals(o.packID, levelPackId))
                {
                    pack = o;
                }
            }

            return(pack);
        }
Пример #13
0
 private void LevelCollectionsTableUpdater_LevelCollectionTableViewUpdated(IAnnotatedBeatmapLevelCollection[] annotatedBeatmapLevelCollections, int indexToSelect)
 {
     if (annotatedBeatmapLevelCollections.Length != 0)
     {
         annotatedBeatmapLevelCollectionsViewController.SetData(annotatedBeatmapLevelCollections, indexToSelect, false);
         levelFilteringNavigationController.HandleAnnotatedBeatmapLevelCollectionsViewControllerDidSelectAnnotatedBeatmapLevelCollection(annotatedBeatmapLevelCollections[indexToSelect]);
     }
     else
     {
         annotatedBeatmapLevelCollections    = new IBeatmapLevelPack[1];
         annotatedBeatmapLevelCollections[0] = emptyBeatmapLevelPack;
         annotatedBeatmapLevelCollectionsViewController.SetData(annotatedBeatmapLevelCollections, 0, true);
         levelFilteringNavigationController.HandleAnnotatedBeatmapLevelCollectionsViewControllerDidSelectAnnotatedBeatmapLevelCollection(annotatedBeatmapLevelCollections[0]);
     }
 }
        /// <summary>
        /// Applies and stores sorting of a provided IBeatmapLevelPack.
        /// </summary>
        /// <param name="levelPack">A level pack to sort.</param>
        /// <returns>Returns itself if not using the non-default sort mode, otherwise returns the provided level pack.</returns>
        public IBeatmapLevelPack SetupFromLevelPack(IBeatmapLevelPack levelPack)
        {
            if (SongSortModule.IsDefaultSort)
            {
                return(levelPack);
            }

            packID        = levelPack.packID + PackIDSuffix;
            packName      = levelPack.packName;
            shortPackName = levelPack.shortPackName;
            coverImage    = levelPack.coverImage;

            _beatmapLevelCollection.SetPrivateField("_levels", SongSortModule.SortSongs(levelPack.beatmapLevelCollection.beatmapLevels), typeof(BeatmapLevelCollection));

            return(this);
        }
Пример #15
0
        private void _levelFilteringNavController_didSelectPackEvent(LevelFilteringNavigationController levelFilteringNavigationController, IAnnotatedBeatmapLevelCollection iAnnotatedBeatmapLevelCollection, GameObject gameObject, BeatmapCharacteristicSO beatmapCharacteristicSO)
        {
            IBeatmapLevelPack levelPack = iAnnotatedBeatmapLevelCollection as IBeatmapLevelPack;

            if (levelPack == null || levelPack.packName != "Random Songs")
            {
                Logger.log.Info("Hiding RandomSongButton");
                RandomButtonUI.instance.Hide();
                return;
            }
            else
            {
                Logger.log.Info("Showing RandomSongButton");
                RandomButtonUI.instance.Show();
            }
        }
Пример #16
0
        public void SetActiveWordStorageFromLevelPack(IBeatmapLevelPack levelPack)
        {
            if (!_cache.TryGetValue(levelPack.packName, out var storage))
            {
                storage = new WordCountStorage(levelPack);

                // never cache filtered level packs
                if (!(levelPack.packName == UI.SongListUI.FilteredSongsPackName) &&
                    !Tweaks.SongBrowserTweaks.IsFilterApplied())
                {
                    _cache[levelPack.packName] = storage;
                }
            }

            _activeWordStorage = storage;
        }
        public void SearchButtonPressed()
        {
            if (_searchFlowCoordinator == null)
            {
                _searchFlowCoordinator = new GameObject("EnhancedSearchFlowCoordinator").AddComponent <SearchFlowCoordinator>();
                _searchFlowCoordinator.BackButtonPressed += DismissSearchFlowCoordinator;
                _searchFlowCoordinator.SongSelected      += SelectSongFromSearchResult;
            }

            // TODO?: toggle to search every level pack instead of just the current?
            IBeatmapLevelPack levelPack = LevelsViewController.GetPrivateField <IBeatmapLevelPack>("_levelPack");

            _searchFlowCoordinator.Activate(_freePlayFlowCoordinator, levelPack);

            Logger.log.Debug("'Search' button pressed.");
        }
Пример #18
0
        public void Construct(PluginConfig config,
                              Submission submission,
                              AudioTimeSyncController audioTimeSyncController,
                              BeatmapLevelsModel beatmapLevelsModel,
                              GameplayCoreSceneSetupData gameplayCoreSceneSetupData,
                              GameSongController gameSongController)
        {
            _config     = config;
            _submission = submission;
            _audioTimeSyncController    = audioTimeSyncController;
            _beatmapLevelsModel         = beatmapLevelsModel;
            _gameplayCoreSceneSetupData = gameplayCoreSceneSetupData;
            _gameSongController         = gameSongController;
            _random = new System.Random();
            IBeatmapLevelPack beatmapLevelPack = _beatmapLevelsModel.GetLevelPackForLevelId(_gameplayCoreSceneSetupData.difficultyBeatmap.level.levelID);

            _previewBeatmapLevels = beatmapLevelPack.beatmapLevelCollection.beatmapLevels;
        }
Пример #19
0
        public void SetSongs(IBeatmapLevelPack selectedPack, SortMode sortMode, string searchRequest)
        {
            _lastSortMode      = sortMode;
            _lastSearchRequest = searchRequest;
            _lastSelectedPack  = selectedPack;

            List <IPreviewBeatmapLevel> levels = new List <IPreviewBeatmapLevel>();

            if (_lastSelectedPack != null)
            {
                levels = _lastSelectedPack.beatmapLevelCollection.beatmapLevels.ToList();

                if (string.IsNullOrEmpty(searchRequest))
                {
                    switch (sortMode)
                    {
                    case SortMode.Newest: { levels = SortLevelsByCreationTime(levels); }; break;

                    case SortMode.Difficulty:
                    {
                        levels = levels.AsParallel().OrderByDescending(x =>
                            {
                                var diffs = ScrappedData.Songs.FirstOrDefault(y => x.levelID.Contains(y.Hash)).Diffs;
                                if (diffs != null && diffs.Count > 0)
                                {
                                    return(diffs.Max(y => y.Stars));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }).ToList();
                    }; break;
                    }
                }
                else
                {
                    levels = levels.Where(x => ($"{x.songName} {x.songSubName} {x.levelAuthorName} {x.songAuthorName}".ToLower().Contains(searchRequest))).ToList();
                }
            }

            _songSelectionViewController.SetSongs(levels);
        }
Пример #20
0
        public void SearchButtonPressed()
        {
            if (_searchFlowCoordinator == null)
            {
                _searchFlowCoordinator      = BeatSaberUI.CreateFlowCoordinator <SearchFlowCoordinator>();
                _searchFlowCoordinator.name = "EnhancedSearchFlowCoordinator";

                _searchFlowCoordinator.BackButtonPressed += DismissSearchFlowCoordinator;
                _searchFlowCoordinator.SongSelected      += SelectSongFromSearchResult;
            }

            IBeatmapLevelPack levelPack = LevelSelectionNavigationController.GetPrivateField <IBeatmapLevelPack>("_levelPack");

            _searchFlowCoordinator.Activate(_freePlayFlowCoordinator, levelPack);

            if (!ButtonPanel.IsSingletonAvailable || !ButtonPanel.instance.Initialized)
            {
                Logger.log.Debug("'Search' button pressed.");
            }
        }
Пример #21
0
        /// <summary>
        /// Applies and stores sorting of a provided <see cref="IBeatmapLevelPack"/>.
        /// </summary>
        /// <param name="levelPack">A level pack to sort.</param>
        /// <returns>Returns itself if not using the non-default sort mode, otherwise returns the provided level pack.</returns>
        private IBeatmapLevelPack SetupFromLevelPack(IBeatmapLevelPack levelPack)
        {
            if (SongSortModule.IsDefaultSort)
            {
                return(levelPack);
            }

            packID = levelPack.packID + PackIDSuffix;
            if (!packID.StartsWith(CustomLevelLoader.kCustomLevelPackPrefixId))
            {
                packID = CustomLevelLoader.kCustomLevelPackPrefixId + packID;
            }

            packName      = levelPack.packName;
            shortPackName = levelPack.shortPackName + PackIDSuffix;
            coverImage    = levelPack.coverImage;

            _beatmapLevelCollection.SetPrivateField("_levels", SongSortModule.SortSongs(levelPack.beatmapLevelCollection.beatmapLevels), typeof(BeatmapLevelCollection));

            return(this);
        }
        public void FilterButtonPressed()
        {
            if (_filterViewController == null)
            {
                _filterViewController = new GameObject("FilterViewController").AddComponent <FilterViewController>();
                _filterViewController.BackButtonPressed += DismissFilterViewController;
                _filterViewController.LevelsModified    += FilterViewControllerSetFilteredSongs;
                _filterViewController.FiltersUnapplied  += FilterViewControllerFiltersUnapplied;
            }

            if (_lastPack == null || LevelsViewController.levelPack.packName != FilteredSongsPackName)
            {
                _lastPack = LevelsViewController.levelPack;
            }

            IPreviewBeatmapLevel[] levels = _lastPack.beatmapLevelCollection.beatmapLevels;

            _filterViewController.Activate(_freePlayFlowCoordinator, levels);

            Logger.log.Debug("'Filter' button pressed.");
        }
Пример #23
0
        public void SetActiveWordStorageFromLevelPack(IAnnotatedBeatmapLevelCollection levelCollection)
        {
            WordCountStorage  storage;
            IBeatmapLevelPack levelPack      = levelCollection as IBeatmapLevelPack;
            string            collectionName = levelCollection.collectionName;
            bool storageWasCached;

            if (levelPack != null)
            {
                storageWasCached = _cache.TryGetValue(levelPack.packID, out storage);
            }
            else
            {
                storageWasCached = _cache.TryGetValue(collectionName.Replace(SortedLevelsLevelPack.PackIDSuffix, ""), out storage);
            }

            if (!storageWasCached)
            {
                storage = new WordCountStorage(levelCollection);

                // never cache filtered/built-in favorites level packs
                // NOTE: ESAF filtered level pack should already be sorted (will never have sorted level pack suffix)
                if (levelPack != null &&
                    levelPack.packID != FilteredLevelsLevelPack.PackID &&
                    !SongBrowserTweaks.IsFilterApplied())
                {
                    _cache[levelPack.packID] = storage;
                }
                else if (collectionName != FilteredLevelsLevelPack.CollectionName &&
                         collectionName != BuiltInFavouritesPackCollectionName &&
                         collectionName != BuiltInFavouritesPackCollectionName + SortedLevelsLevelPack.PackIDSuffix &&
                         collectionName != SortedLevelsLevelPack.PackIDSuffix)
                {
                    _cache[collectionName.Replace(SortedLevelsLevelPack.PackIDSuffix, "")] = storage;
                }
            }

            _activeWordStorage = storage;
        }
Пример #24
0
        /// <summary>
        /// Set current level pack, reset all packs just in case.
        /// </summary>
        /// <param name="pack"></param>
        public void SetCurrentLevelPack(IBeatmapLevelPack pack)
        {
            Logger.Debug("Setting current level pack [{0}]: {1}", pack.packID, pack.packName);

            this.ResetLevelPacks();

            this._currentLevelPack = pack;

            var beatmapLevelPack = pack as BeatmapLevelPackSO;

            if (beatmapLevelPack == null)
            {
                Logger.Debug("DLC Detected...  Disabling SongBrowser...");
                _isPreviewLevelPack = true;
            }
            else
            {
                Logger.Debug("Owned level pack...  Enabling SongBrowser...");
                _isPreviewLevelPack = false;
            }

            this.Settings.currentLevelPackId = pack.packID;
            this.Settings.Save();
        }
Пример #25
0
 private void DidSelectLevelPack(LevelSelectionNavigationController controller, IBeatmapLevelPack beatmap)
 {
     Logger.Debug($"Pack name : {beatmap.packName}, Pack ID : {beatmap.packID}, Pack short name : {beatmap.shortPackName}");
     this.CurrentPack = beatmap;
 }
 public WordCountStorage(IBeatmapLevelPack levelPack)
 {
     SetupStorage(levelPack);
 }
        private bool SetWordsFromLevelPack(IBeatmapLevelPack levelPack)
        {
            // we don't build the _words object immediately only because we want to also add the
            // counts of other words that are prefixed by a word to the count
            List <string> allWords = new List <string>();
            Dictionary <string, Dictionary <string, int> > allWordConnections = new Dictionary <string, Dictionary <string, int> >();

            foreach (var level in levelPack.beatmapLevelCollection.beatmapLevels)
            {
                _manualResetEvent.WaitOne();
                if (_taskCancelled)
                {
                    return(false);
                }

                var songNameWords    = GetWordsFromString(level.songName);
                var songSubNameWords = GetWordsFromString(level.songSubName);
                var authorNameWords  = GetWordsFromString(level.songAuthorName);
                var levelAuthors     = GetWordsFromString(level.levelAuthorName);

                string[][] wordsFromSong = new string[][]
                {
                    songNameWords,
                    songSubNameWords,
                    authorNameWords
                };

                foreach (var wordsFromField in wordsFromSong)
                {
                    for (int i = 0; i < wordsFromField.Length; ++i)
                    {
                        var currentWord = wordsFromField[i];
                        allWords.Add(currentWord);

                        if (!allWordConnections.ContainsKey(currentWord))
                        {
                            allWordConnections[currentWord] = new Dictionary <string, int>();
                        }

                        if (i + 1 < wordsFromField.Length)
                        {
                            var nextWord    = wordsFromField[i + 1];
                            var connections = allWordConnections[currentWord];

                            if (connections.ContainsKey(nextWord))
                            {
                                connections[nextWord] += 1;
                            }
                            else
                            {
                                connections.Add(nextWord, 1);
                            }
                        }
                    }
                }

                // last word of song name connects to the first word of subname and all mappers
                var lastWord = songNameWords.LastOrDefault();
                if (!string.IsNullOrEmpty(lastWord))
                {
                    var      connections = allWordConnections[lastWord];
                    string[] firstWords  = levelAuthors.Append(songSubNameWords.FirstOrDefault()).ToArray();

                    foreach (var firstWord in firstWords)
                    {
                        // only make a connection once (same thing for the below connections)
                        if (!string.IsNullOrEmpty(firstWord) && !connections.ContainsKey(firstWord))
                        {
                            connections.Add(firstWord, 1);
                        }
                    }
                }

                // last word of song subname connects to first word of author
                lastWord = songSubNameWords.LastOrDefault();
                if (!string.IsNullOrEmpty(lastWord))
                {
                    var connections = allWordConnections[lastWord];
                    var firstWord   = authorNameWords.FirstOrDefault();

                    if (!string.IsNullOrEmpty(firstWord) && !connections.ContainsKey(firstWord))
                    {
                        connections.Add(firstWord, 1);
                    }
                }

                // last word of author name connects to first word of song name
                lastWord = authorNameWords.LastOrDefault();
                if (!string.IsNullOrEmpty(lastWord))
                {
                    var connections = allWordConnections[lastWord];
                    var firstWord   = songNameWords.FirstOrDefault();

                    if (!string.IsNullOrEmpty(firstWord) && !connections.ContainsKey(firstWord))
                    {
                        connections.Add(firstWord, 1);
                    }
                }

                // level authors are added to the word storage differently from the other fields
                var firstSongNameWord = songNameWords.FirstOrDefault();
                for (int i = 0; i < levelAuthors.Length; ++i)
                {
                    var author = levelAuthors[i];

                    // since the names of map makers occur very frequently, we limit them to only one entry
                    // otherwise, they always show up as the first couple of predictions
                    if (!allWords.Contains(author))
                    {
                        allWords.Add(author);
                    }

                    Dictionary <string, int> levelAuthorConnections;
                    if (!allWordConnections.ContainsKey(author))
                    {
                        levelAuthorConnections     = new Dictionary <string, int>();
                        allWordConnections[author] = levelAuthorConnections;
                    }
                    else
                    {
                        levelAuthorConnections = allWordConnections[author];
                    }

                    // make connection between this mapper and the first word of the song name
                    if (!string.IsNullOrEmpty(firstSongNameWord) && !levelAuthorConnections.ContainsKey(firstSongNameWord))
                    {
                        levelAuthorConnections.Add(firstSongNameWord, 1);
                    }
                }
            }

            // sort by word length in descending order
            allWords.Sort((x, y) => y.Length - x.Length);

            // add words to the storage
            foreach (var word in allWords)
            {
                _manualResetEvent.WaitOne();
                if (_taskCancelled)
                {
                    return(false);
                }

                if (_words.ContainsKey(word))
                {
                    _words[word].Count += 1;
                    continue;
                }

                // get count of words that have this word as a prefix
                int count = 1;
                foreach (var prefixedWord in _trie.StartsWith(word))
                {
                    count += _words[prefixedWord].Count;
                }

                _trie.AddWord(word);
                _words.Add(
                    word,
                    new WordInformation(count,
                                        allWordConnections[word].ToList()
                                        .OrderByDescending(x => x.Value)
                                        .Select(p => p.Key)
                                        .ToList())
                    );
                _bkTree.AddWord(word);
            }

            IsReady = true;
            return(true);
        }
        /// <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>
 /// SongLoader doesn't fire event when we delete a song.
 /// </summary>
 /// <param name="levelPack"></param>
 /// <param name="levelId"></param>
 public void RemoveSongFromLevelPack(IBeatmapLevelPack levelPack, String levelId)
 {
     levelPack.beatmapLevelCollection.beatmapLevels.ToList().RemoveAll(x => x.levelID == levelId);
 }
Пример #30
0
 private void _levelPacksViewController_didSelectPackEvent(LevelPacksViewController arg1, IBeatmapLevelPack arg2)
 {
     lastPlaylist = null;
 }