public void Constractor(DiContainer container) { this._levelCollectionViewController = container.Resolve <LevelCollectionViewController>(); this._levelFilteringNavigationController = container.Resolve <LevelFilteringNavigationController>(); this._annotatedBeatmapLevelCollectionsViewController = container.Resolve <AnnotatedBeatmapLevelCollectionsViewController>(); this._selectLevelCategoryViewController = container.Resolve <SelectLevelCategoryViewController>(); }
internal void AttemptReselectCurrentLevelPack(LevelFilteringNavigationController controller) { var tabBarView = controller.GetField <TabBarViewController>("_tabBarViewController"); if (tabBarView?.selectedCellNumber != 3) { return; } var tabBarDatas = controller.GetField <object[]>("_tabBarDatas"); if (tabBarDatas == null) { return; } int selectedPackNum = tabBarDatas[tabBarView.selectedCellNumber].GetField <int>("selectedItem"); var currentLevelPacksCollection = tabBarDatas[tabBarView.selectedCellNumber].GetField <IAnnotatedBeatmapLevelCollection[]>("annotatedBeatmapLevelCollections"); if (currentLevelPacksCollection == null) { return; } int packCount = currentLevelPacksCollection.Length; if (!(selectedPackNum < packCount)) { return; } controller.SelectBeatmapLevelPackOrPlayList(currentLevelPacksCollection[selectedPackNum] as IBeatmapLevelPack, null); }
private static void Postfix(ref LevelFilteringNavigationController __instance, LevelSearchViewController ____levelSearchViewController, SelectLevelCategoryViewController ____selectLevelCategoryViewController, ref IBeatmapLevelPack[] ____ostBeatmapLevelPacks, ref IBeatmapLevelPack[] ____musicPacksBeatmapLevelPacks, ref IBeatmapLevelPack[] ____customLevelPacks, ref IBeatmapLevelPack[] ____allBeatmapLevelPacks) { if (Loader.CustomBeatmapLevelPackCollectionSO == null) { return; } ____customLevelPacks = Loader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks; List <IBeatmapLevelPack> packs = new List <IBeatmapLevelPack>(); if (____ostBeatmapLevelPacks != null) { packs = packs.Concat(____ostBeatmapLevelPacks).ToList(); } if (____musicPacksBeatmapLevelPacks != null) { packs = packs.Concat(____musicPacksBeatmapLevelPacks).ToList(); } if (____customLevelPacks != null) { packs = packs.Concat(____customLevelPacks).ToList(); } ____allBeatmapLevelPacks = packs.ToArray(); ____levelSearchViewController.Setup(____allBeatmapLevelPacks); __instance.UpdateSecondChildControllerContent(____selectLevelCategoryViewController.selectedLevelCategory); }
private void Awake() { BSEvents.levelSelected += LevelSelectionChanged; _levelFilteringNav = Resources.FindObjectsOfTypeAll <LevelFilteringNavigationController>().FirstOrDefault(); _levelFilteringNav.didSelectAnnotatedBeatmapLevelCollectionEvent += LevelFilteringNav_didSelectAnnotatedBeatmapLevelCollectionEvent; }
/// <summary> /// Constructor. Acquire all necessary BeatSaberUi elements. /// </summary> /// <param name="flowCoordinator"></param> public BeatSaberUIController(LevelSelectionFlowCoordinator flowCoordinator) { Logger.Debug("Collecting all BeatSaberUI Elements..."); LevelSelectionFlowCoordinator = flowCoordinator; // gather flow coordinator elements LevelSelectionNavigationController = LevelSelectionFlowCoordinator.GetField <LevelSelectionNavigationController, LevelSelectionFlowCoordinator>("levelSelectionNavigationController"); Logger.Debug("Acquired LevelSelectionNavigationController [{0}]", LevelSelectionNavigationController.GetInstanceID()); LevelFilteringNavigationController = LevelSelectionNavigationController.GetField <LevelFilteringNavigationController, LevelSelectionNavigationController>("_levelFilteringNavigationController"); Logger.Debug("Acquired LevelFilteringNavigationController [{0}]", LevelFilteringNavigationController.GetInstanceID()); LevelCollectionNavigationController = LevelSelectionNavigationController.GetField <LevelCollectionNavigationController, LevelSelectionNavigationController>("_levelCollectionNavigationController"); Logger.Debug("Acquired LevelCollectionNavigationController [{0}]", LevelCollectionNavigationController.GetInstanceID()); LevelCollectionViewController = LevelCollectionNavigationController.GetField <LevelCollectionViewController, LevelCollectionNavigationController>("_levelCollectionViewController"); Logger.Debug("Acquired LevelPackLevelsViewController [{0}]", LevelCollectionViewController.GetInstanceID()); LevelDetailViewController = LevelCollectionNavigationController.GetField <StandardLevelDetailViewController, LevelCollectionNavigationController>("_levelDetailViewController"); Logger.Debug("Acquired StandardLevelDetailViewController [{0}]", LevelDetailViewController.GetInstanceID()); LevelCollectionTableView = this.LevelCollectionViewController.GetField <LevelCollectionTableView, LevelCollectionViewController>("_levelCollectionTableView"); Logger.Debug("Acquired LevelPackLevelsTableView [{0}]", LevelCollectionTableView.GetInstanceID()); StandardLevelDetailView = LevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView"); Logger.Debug("Acquired StandardLevelDetailView [{0}]", StandardLevelDetailView.GetInstanceID()); BeatmapCharacteristicSelectionViewController = StandardLevelDetailView.GetField <BeatmapCharacteristicSegmentedControlController, StandardLevelDetailView>("_beatmapCharacteristicSegmentedControlController"); Logger.Debug("Acquired BeatmapCharacteristicSegmentedControlController [{0}]", BeatmapCharacteristicSelectionViewController.GetInstanceID()); LevelDifficultyViewController = StandardLevelDetailView.GetField <BeatmapDifficultySegmentedControlController, StandardLevelDetailView>("_beatmapDifficultySegmentedControlController"); Logger.Debug("Acquired BeatmapDifficultySegmentedControlController [{0}]", LevelDifficultyViewController.GetInstanceID()); LevelCollectionTableViewTransform = LevelCollectionTableView.transform as RectTransform; Logger.Debug("Acquired TableViewRectTransform from LevelPackLevelsTableView [{0}]", LevelCollectionTableViewTransform.GetInstanceID()); AnnotatedBeatmapLevelCollectionsViewController = LevelFilteringNavigationController.GetField <AnnotatedBeatmapLevelCollectionsViewController, LevelFilteringNavigationController>("_annotatedBeatmapLevelCollectionsViewController"); Logger.Debug("Acquired AnnotatedBeatmapLevelCollectionsViewController from LevelFilteringNavigationController [{0}]", AnnotatedBeatmapLevelCollectionsViewController.GetInstanceID()); TableView tableView = LevelCollectionTableView.GetField <TableView, LevelCollectionTableView>("_tableView"); ScrollView scrollView = tableView.GetField <ScrollView, TableView>("_scrollView"); TableViewPageUpButton = scrollView.GetField <Button, ScrollView>("_pageUpButton"); TableViewPageDownButton = scrollView.GetField <Button, ScrollView>("_pageDownButton"); Logger.Debug("Acquired Page Up and Down buttons..."); ActionButtons = StandardLevelDetailView.GetComponentsInChildren <RectTransform>().First(x => x.name == "ActionButtons"); Logger.Debug("Acquired ActionButtons [{0}]", ActionButtons.GetInstanceID()); ScreenSystem = Resources.FindObjectsOfTypeAll <ScreenSystem>().Last(); Logger.Debug("Acquired ScreenSystem [{0}]", ScreenSystem.GetInstanceID()); SimpleDialogPromptViewControllerPrefab = Resources.FindObjectsOfTypeAll <SimpleDialogPromptViewController>().Last(); Logger.Debug("Acquired SimpleDialogPromptViewControllerPrefab [{0}]", SimpleDialogPromptViewControllerPrefab.GetInstanceID()); BeatmapLevelsModel = Resources.FindObjectsOfTypeAll <BeatmapLevelsModel>().Last(); Logger.Debug("Acquired BeatmapLevelsModel [{0}]", BeatmapLevelsModel); }
private void PrepareLevelPackSelectedEvent() { // we still need this delegate when using SongBrowser, since the WordPredictionEngine now uses IAnnotatedBeatmapLevelCollections, // which aren't stored by the LevelFilteringNavigationController _isSelectingInitialLevelPack = true; LevelFilteringNavigationController = _freePlayFlowCoordinator.GetPrivateField <LevelFilteringNavigationController>("_levelFilteringNavigationController", typeof(LevelSelectionFlowCoordinator)); LevelFilteringNavigationController.didSelectAnnotatedBeatmapLevelCollectionEvent -= LevelPackSelected; LevelFilteringNavigationController.didSelectAnnotatedBeatmapLevelCollectionEvent += LevelPackSelected; }
private void PrepareLevelPackSelectedEvent() { // we don't need the LevelPackSelected event if using SongBrowser, since it passes the songs it needs filtered // directly to us (so we don't need to store last pack at all) _isSelectingInitialLevelPack = true; LevelFilteringNavigationController = _freePlayFlowCoordinator.GetPrivateField <LevelFilteringNavigationController>("_levelFilteringNavigationController", typeof(LevelSelectionFlowCoordinator)); LevelFilteringNavigationController.didSelectAnnotatedBeatmapLevelCollectionEvent -= LevelPackSelected; LevelFilteringNavigationController.didSelectAnnotatedBeatmapLevelCollectionEvent += LevelPackSelected; }
/// <summary> /// Constructor. Acquire all necessary BeatSaberUi elements. /// </summary> /// <param name="flowCoordinator"></param> public BeatSaberUIController(FlowCoordinator flowCoordinator) { Logger.Debug("Collecting all BeatSaberUI Elements..."); LevelSelectionFlowCoordinator = flowCoordinator; // gather flow coordinator elements LevelSelectionNavigationController = LevelSelectionFlowCoordinator.GetPrivateField <LevelSelectionNavigationController>("_levelSelectionNavigationController"); Logger.Debug("Acquired LevelSelectionNavigationController [{0}]", LevelSelectionNavigationController.GetInstanceID()); // this is loaded late but available early, grab globally. LevelFilteringNavigationController = Resources.FindObjectsOfTypeAll <LevelFilteringNavigationController>().First(); //LevelSelectionFlowCoordinator.GetPrivateField<LevelFilteringNavigationController>("_levelFilteringNavigationController"); Logger.Debug("Acquired LevelFilteringNavigationController [{0}]", LevelFilteringNavigationController.GetInstanceID()); // grab nav controller elements LevelCollectionViewController = LevelSelectionNavigationController.GetPrivateField <LevelCollectionViewController>("_levelCollectionViewController"); Logger.Debug("Acquired LevelPackLevelsViewController [{0}]", LevelCollectionViewController.GetInstanceID()); LevelDetailViewController = LevelSelectionNavigationController.GetPrivateField <StandardLevelDetailViewController>("_levelDetailViewController"); Logger.Debug("Acquired StandardLevelDetailViewController [{0}]", LevelDetailViewController.GetInstanceID()); // grab level collection view controller elements LevelCollectionTableView = this.LevelCollectionViewController.GetPrivateField <LevelCollectionTableView>("_levelCollectionTableView"); Logger.Debug("Acquired LevelPackLevelsTableView [{0}]", LevelCollectionTableView.GetInstanceID()); // grab letel detail view StandardLevelDetailView = LevelDetailViewController.GetPrivateField <StandardLevelDetailView>("_standardLevelDetailView"); Logger.Debug("Acquired StandardLevelDetailView [{0}]", StandardLevelDetailView.GetInstanceID()); BeatmapCharacteristicSelectionViewController = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSegmentedControlController>().First(); Logger.Debug("Acquired BeatmapCharacteristicSegmentedControlController [{0}]", BeatmapCharacteristicSelectionViewController.GetInstanceID()); LevelDifficultyViewController = StandardLevelDetailView.GetPrivateField <BeatmapDifficultySegmentedControlController>("_beatmapDifficultySegmentedControlController"); Logger.Debug("Acquired BeatmapDifficultySegmentedControlController [{0}]", LevelDifficultyViewController.GetInstanceID()); LevelCollectionTableViewTransform = LevelCollectionTableView.transform as RectTransform; Logger.Debug("Acquired TableViewRectTransform from LevelPackLevelsTableView [{0}]", LevelCollectionTableViewTransform.GetInstanceID()); TableView tableView = LevelCollectionTableView.GetPrivateField <TableView>("_tableView"); TableViewPageUpButton = tableView.GetPrivateField <Button>("_pageUpButton"); TableViewPageDownButton = tableView.GetPrivateField <Button>("_pageDownButton"); Logger.Debug("Acquired Page Up and Down buttons..."); PlayContainer = StandardLevelDetailView.GetComponentsInChildren <RectTransform>().First(x => x.name == "PlayContainer"); PlayButtons = PlayContainer.GetComponentsInChildren <RectTransform>().First(x => x.name == "PlayButtons"); PlayButton = Resources.FindObjectsOfTypeAll <Button>().First(x => x.name == "PlayButton"); PracticeButton = PlayButtons.GetComponentsInChildren <Button>().First(x => x.name == "PracticeButton"); SimpleDialogPromptViewControllerPrefab = Resources.FindObjectsOfTypeAll <SimpleDialogPromptViewController>().First(); BeatmapLevelsModel = Resources.FindObjectsOfTypeAll <BeatmapLevelsModel>().First(); }
internal PlaylistDataManager(AnnotatedBeatmapLevelCollectionsViewController annotatedBeatmapLevelCollectionsViewController, LevelPackDetailViewController levelPackDetailViewController, LevelFilteringNavigationController levelFilteringNavigationController, List <ILevelCollectionUpdater> levelCollectionUpdaters, List <ILevelCollectionsTableUpdater> levelCollectionsTableUpdaters, List <IPreviewBeatmapLevelUpdater> previewBeatmapLevelUpdaters) { this.annotatedBeatmapLevelCollectionsViewController = annotatedBeatmapLevelCollectionsViewController; this.levelPackDetailViewController = levelPackDetailViewController; this.levelFilteringNavigationController = levelFilteringNavigationController; this.levelCollectionUpdaters = levelCollectionUpdaters; this.levelCollectionsTableUpdaters = levelCollectionsTableUpdaters; this.previewBeatmapLevelUpdaters = previewBeatmapLevelUpdaters; emptyBeatmapLevelPack = new BeatmapLevelPack(CustomLevelLoader.kCustomLevelPackPrefixId + "CustomLevels", "Custom Levels", "Custom Levels", BeatSaberMarkupLanguage.Utilities.ImageResources.BlankSprite, new BeatmapLevelCollection(new IPreviewBeatmapLevel[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(); } }
private void BSEvents_menuSceneLoadedFresh() { LevelFilteringNavigationController levelFiltering = Resources.FindObjectsOfTypeAll <LevelFilteringNavigationController>().First(); levelFiltering.didSelectAnnotatedBeatmapLevelCollectionEvent -= _levelFilteringNavController_didSelectPackEvent; levelFiltering.didSelectAnnotatedBeatmapLevelCollectionEvent += _levelFilteringNavController_didSelectPackEvent; RandomButtonUI.instance.Setup(this); try { MenuButton menuButton = new MenuButton("Random Song Player", "Download a random song from Beat Saver and play it", async() => { await PlayRandomSongAsync(); }); MenuButtons.instance.RegisterButton(menuButton); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } }
private void BSEvents_lateMenuSceneLoadedFresh(ScenesTransitionSetupDataSO scenesTransitionSetupData) { LevelFilteringNavigationController levelFiltering = Resources.FindObjectsOfTypeAll <LevelFilteringNavigationController>().First(); levelFiltering.didSelectAnnotatedBeatmapLevelCollectionEvent -= _levelFilteringNavController_didSelectPackEvent; levelFiltering.didSelectAnnotatedBeatmapLevelCollectionEvent += _levelFilteringNavController_didSelectPackEvent; RandomButtonUI.instance.Setup(this); BeatSaberMarkupLanguage.GameplaySetup.GameplaySetup.instance.AddTab("Random Song Player", "RandomSongPlayer.UI.FilterSettings.bsml", FilterSettingsUI.instance); /*try * { * MenuButton menuButton = new MenuButton("Random Song Player", "Download a random song from Beat Saver and play it", async () => { await PlayRandomSongAsync(); }); * MenuButtons.instance.RegisterButton(menuButton); * } * catch (Exception e) * { * Console.WriteLine("Error: " + e.Message); * }*/ }
private IEnumerator buttonClickCoroutine(string buttonName) { /* * foreach (Button b in Resources.FindObjectsOfTypeAll<Button>()) * { * Logger.log?.Debug($"Button.name={b.name}"); * } */ Logger.log?.Debug($"Time.time={Time.time}, WaitUntil={buttonName}"); yield return(new WaitUntil(() => Resources.FindObjectsOfTypeAll <Button>().Any(x => x != null && x.name == buttonName))); Logger.log?.Debug($"Time.time={Time.time}, Found"); Button button = Resources.FindObjectsOfTypeAll <Button>().Where(x => x != null && x.name == buttonName).First(); // need some wait yield return(new WaitForSecondsRealtime(Configuration.PluginConfig.Instance.wait)); // wait for SongCore GameObject songCoreLoader = GameObject.Find("SongCore Loader"); if (songCoreLoader != null) { Logger.log?.Debug($"Time.time={Time.time}, SongCore Found"); foreach (var monoBehaviour in songCoreLoader.GetComponents <MonoBehaviour>()) { if (monoBehaviour.GetType().Name == "Loader") { Logger.log?.Debug($"Time.time={Time.time}, SongCore Loader Found"); Logger.log?.Debug($"Time.time={Time.time}, WaitUntil AreSongsLoading"); yield return(new WaitUntil(() => AreSongsLoading(monoBehaviour) == false)); Logger.log?.Debug($"Time.time={Time.time}, SongsLoaded"); // need some wait for update screen yield return(new WaitForSecondsRealtime(1f)); break; } } } button.onClick.Invoke(); if ((Configuration.PluginConfig.Instance.selectTab >= 0) && (Configuration.PluginConfig.Instance.selectTab <= 3)) { // need some wait yield return(new WaitForSecondsRealtime(Configuration.PluginConfig.Instance.wait)); LevelFilteringNavigationController levelFilteringNavigationController = Resources.FindObjectsOfTypeAll <LevelFilteringNavigationController>().First(); TabBarViewController tabBarViewController = levelFilteringNavigationController?.GetField <TabBarViewController, LevelFilteringNavigationController>("_tabBarViewController"); if (levelFilteringNavigationController != null && tabBarViewController != null) { tabBarViewController.SelectItem(Configuration.PluginConfig.Instance.selectTab); levelFilteringNavigationController.SwitchToPlaylists(); } } Logger.log?.Debug($"Time.time={Time.time}, Done"); }
static void Postfix(ref LevelFilteringNavigationController __instance, ref TabBarViewController ____tabBarViewController) { // Logging.logger.Info("Set CustomLevelCollection"); __instance.GetField("_customLevelsTabBarData")?.SetField("annotatedBeatmapLevelCollections", Loader.CustomBeatmapLevelPackCollectionSO?.beatmapLevelPacks); }
//////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /// <summary> /// Change current song view to all songs view /// </summary> /// <param name="p_FirstActivation"></param> /// <param name="p_AddedToHierarchy"></param> /// <param name="p_ScreenSystemEnabling"></param> private static void LevelSelectionNavigationController_didActivateEvent(bool p_FirstActivation, bool p_AddedToHierarchy, bool p_ScreenSystemEnabling) { var l_LevelSelectionNavigationController = Resources.FindObjectsOfTypeAll <LevelSelectionNavigationController>().FirstOrDefault(); if (l_LevelSelectionNavigationController == null) { return; } l_LevelSelectionNavigationController.didActivateEvent -= LevelSelectionNavigationController_didActivateEvent; LevelFilteringNavigationController l_LevelFilteringNavigationController = l_LevelSelectionNavigationController.GetField <LevelFilteringNavigationController>("_levelFilteringNavigationController"); try { if (l_LevelFilteringNavigationController != null) { var l_Selector = l_LevelFilteringNavigationController.GetField <SelectLevelCategoryViewController>("_selectLevelCategoryViewController"); if (l_Selector != null && l_Selector) { var l_Tags = l_Selector.GetField <SelectLevelCategoryViewController.LevelCategoryInfo[]>("_allLevelCategoryInfos"); for (int l_I = 0; l_I < l_Tags.Length; ++l_I) { if (l_Tags[l_I].levelCategory != SelectLevelCategoryViewController.LevelCategory.All) { continue; } var l_SegmentControl = l_Selector.GetField <IconSegmentedControl>("_levelFilterCategoryIconSegmentedControl"); var l_Cells = l_Selector != null?l_SegmentControl.GetField <List <SegmentedControlCell> >("_cells") : null as List <SegmentedControlCell>; if (l_Cells != null) { /// Multiplayer fix if (l_Cells.Count == 4) { l_I = l_I - 1; } l_SegmentControl.SelectCellWithNumber(l_I); l_Selector.LevelFilterCategoryIconSegmentedControlDidSelectCell(l_SegmentControl, l_I); //l_SegmentControl.HandleCellSelectionDidChange(l_Cells.ElementAt(l_I), SelectableCell.TransitionType.Instant, null); //l_SegmentControl.SelectCellWithNumber(l_I); } break; } } /// Wait next frame HMMainThreadDispatcher.instance.Enqueue(() => { try { var l_LevelSearchViewController = l_LevelFilteringNavigationController.GetField <LevelSearchViewController>("_levelSearchViewController"); if (l_LevelSearchViewController != null && l_LevelSearchViewController && l_LevelSearchViewController.isInViewControllerHierarchy && !l_LevelSearchViewController.isInTransition && l_LevelSearchViewController.gameObject.activeInHierarchy) { l_LevelSearchViewController.didStartLoadingEvent -= LevelSearchViewController_didStartLoadingEvent; l_LevelSearchViewController.ResetCurrentFilterParams(); var l_InputFieldView = l_LevelSearchViewController.GetField <InputFieldView>("_searchTextInputFieldView"); if (l_InputFieldView != null && l_InputFieldView) { l_InputFieldView.SetText(m_PendingFilterSong.songName); l_InputFieldView.UpdateClearButton(); l_InputFieldView.UpdatePlaceholder(); } l_LevelSearchViewController.UpdateSearchLevelFilterParams(LevelFilterParams.ByBeatmapLevelIds(new HashSet <string>() { m_PendingFilterSong.levelID })); l_LevelSearchViewController.didStartLoadingEvent += LevelSearchViewController_didStartLoadingEvent; } } catch (System.Exception p_Exception) { Logger.Instance.Error("[ChatRequest] LevelSelectionNavigationController_didActivateEvent coroutine failed : "); Logger.Instance.Error(p_Exception); LevelSearchViewController_didStartLoadingEvent(l_LevelFilteringNavigationController.GetField <LevelSearchViewController>("_levelSearchViewController")); } }); } } catch (System.Exception p_Exception) { Logger.Instance.Error("[ChatRequest] LevelSelectionNavigationController_didActivateEvent failed : "); Logger.Instance.Error(p_Exception); LevelSearchViewController_didStartLoadingEvent(l_LevelFilteringNavigationController.GetField <LevelSearchViewController>("_levelSearchViewController")); } }
static bool Prefix(ref LevelFilteringNavigationController __instance, ref TabBarViewController ____tabBarViewController) { __instance.GetField("_customLevelsTabBarData")?.SetField("annotatedBeatmapLevelCollections", Loader.CustomBeatmapLevelPackCollectionSO?.beatmapLevelPacks); return(false); }
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)); } }
/// <summary> /// Sort the song list based on the settings. /// </summary> public void ProcessSongList(IAnnotatedBeatmapLevelCollection selectedBeatmapCollection, LevelSelectionNavigationController navController) { Logger.Trace("ProcessSongList()"); List <IPreviewBeatmapLevel> unsortedSongs; List <IPreviewBeatmapLevel> filteredSongs; List <IPreviewBeatmapLevel> sortedSongs; // 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.Count}"); unsortedSongs = GetLevelsForLevelCollection(selectedBeatmapCollection).ToList(); // filter Logger.Debug($"Starting filtering songs by {PluginConfig.Instance.FilterMode}"); Stopwatch stopwatch = Stopwatch.StartNew(); if (PluginConfig.Instance.FilterMode == SongFilterMode.Requirements && !Plugin.IsCustomJsonDataEnabled) { PluginConfig.Instance.FilterMode = SongFilterMode.None; } switch (PluginConfig.Instance.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.Played: filteredSongs = FilterPlayed(unsortedSongs, true, false); break; case SongFilterMode.Unplayed: filteredSongs = FilterPlayed(unsortedSongs, false, true); break; case SongFilterMode.Requirements: filteredSongs = FilterRequirements(unsortedSongs); 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 {PluginConfig.Instance.SortMode}"); stopwatch = Stopwatch.StartNew(); SortWasMissingData = false; switch (PluginConfig.Instance.SortMode) { case SongSortMode.Original: sortedSongs = SortOriginal(filteredSongs); break; case SongSortMode.Newest: sortedSongs = SortNewest(filteredSongs); break; case SongSortMode.Author: sortedSongs = SortAuthor(filteredSongs); break; case SongSortMode.Mapper: sortedSongs = SortMapper(filteredSongs); break; case SongSortMode.Vanilla: sortedSongs = SortVanilla(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.Bpm: sortedSongs = SortSongBpm(filteredSongs); break; case SongSortMode.Length: sortedSongs = SortSongLength(filteredSongs); break; case SongSortMode.Custom: sortedSongs = CustomSortHandler != null?CustomSortHandler.Invoke(filteredSongs) : filteredSongs; break; case SongSortMode.Default: default: sortedSongs = SortSongName(filteredSongs); break; } if (PluginConfig.Instance.InvertSortResults && PluginConfig.Instance.SortMode != SongSortMode.Random && PluginConfig.Instance.SortMode != SongSortMode.Stars) { 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("*") && PluginConfig.Instance.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; } var smallCoverImage = selectedBeatmapCollection.smallCoverImage; if (smallCoverImage == null) { smallCoverImage = BeatSaberMarkupLanguage.Utilities.ImageResources.BlankSprite; } Logger.Debug("Creating filtered level pack..."); BeatmapLevelPack levelPack = new BeatmapLevelPack(SongBrowserModel.FilteredSongsCollectionName, packName, selectedBeatmapCollection.collectionName, coverImage, smallCoverImage, 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"); LevelFilteringNavigationController lfnc = navController.GetField <LevelFilteringNavigationController, LevelSelectionNavigationController>("_levelFilteringNavigationController"); 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"); var noDataPrefab = lfnc.GetField <GameObject, LevelFilteringNavigationController>("_currentNoDataInfoPrefab"); Logger.Debug("Calling lcnvc.SetData..."); lcnvc.SetData(levelPack, true, !_hidePracticeButton, _actionButtonText, noDataPrefab, _allowedBeatmapDifficultyMask, _notAllowedCharacteristics); //_sortedSongs.ForEach(x => Logger.Debug(x.levelID)); }
private void LevelFilteringNavigationController_didSelectAnnotatedBeatmapLevelCollectionEvent(LevelFilteringNavigationController _, IAnnotatedBeatmapLevelCollection annotatedBeatmapLevelCollection, UnityEngine.GameObject __, BeatmapCharacteristicSO ___) { AnnotatedBeatmapLevelCollectionsViewController_didSelectAnnotatedBeatmapLevelCollectionEvent(annotatedBeatmapLevelCollection); }