Example #1
0
        internal void Setup()
        {
            Logger.log.Debug("Setup for UI");
            var soloFreePlayFlowCoordinator = Resources.FindObjectsOfTypeAll <SoloFreePlayFlowCoordinator>().FirstOrDefault();
            var levelSelectionNavController = soloFreePlayFlowCoordinator.GetPrivateField <LevelSelectionNavigationController>("_levelSelectionNavigationController");
            var levelDetailViewController   = levelSelectionNavController.GetPrivateField <StandardLevelDetailViewController>("_levelDetailViewController");

            _standardLevelDetailView = levelDetailViewController.GetPrivateField <StandardLevelDetailView>("_standardLevelDetailView");
            var playerStatsContainer = _standardLevelDetailView.GetPrivateField <GameObject>("_playerStatsContainer");

            // Add PP Helper UI
            BSMLParser.instance.Parse(BeatSaberMarkupLanguage.Utilities.GetResourceContent(Assembly.GetExecutingAssembly(), "PP_Helper.UI.ppDisplay.bsml"), playerStatsContainer.transform.parent.gameObject, this);
            _parentObject = _ppText.transform.parent.gameObject;

            // Resize accuracy font size
            var _accText = _accuracyObject.GetComponentsInChildren <TextMeshProUGUI>().Last();

            _accText.fontSize = 3.5f;

            // Resize accuracy adjuster
            var accTransform = (RectTransform)_accText.transform.parent.transform.parent.transform;

            accTransform.sizeDelta = new Vector2(30f, 1f);

            // We want pp stuff above play button
            if (Config.ppTop)
            {
                var playButton    = _standardLevelDetailView.GetPrivateField <Button>("_playButton");
                var playContainer = playButton.transform.parent.transform.parent;
                playContainer.transform.SetAsLastSibling();
            }

            Logger.log.Debug("Done setup");
        }
        internal void OnLoad()
        {
            initialized = false;

            // remove potential for duplicate event calls
            BSEvents.levelSelected -= BSEvents_levelSelected;

            // attach to level selected event if we are enabled, and double presses are required
            if (Plugin.cfg.Enabled && Plugin.cfg.DoublePress)
            {
                BSEvents.levelSelected += BSEvents_levelSelected;
            }

            MainMenuViewController = Resources.FindObjectsOfTypeAll <MainMenuViewController>().FirstOrDefault();
            MainMenuViewController.didFinishEvent += MainMenuViewController_didFinishEvent;

            // get PromoViewController
            PromoViewController = Resources.FindObjectsOfTypeAll <PromoViewController>().FirstOrDefault();
            PromoViewController.promoButtonWasPressedEvent += PromoViewController_promoButtonWasPressedEvent;

            SoloFreePlayFlowCoordinator = Resources.FindObjectsOfTypeAll <SoloFreePlayFlowCoordinator>().FirstOrDefault();
            SoloFreePlayFlowCoordinator.didFinishEvent += SoloFreePlayFlowCoordinator_didFinishEvent;

            StandardLevelDetailView = Resources.FindObjectsOfTypeAll <StandardLevelDetailView>().LastOrDefault(v => v.name.IndexOf("Clone", StringComparison.OrdinalIgnoreCase) == -1);

            // setup settings
            SetupUI();
        }
Example #3
0
 public LTUI(Config config, StandardLevelDetailViewController standardLevelDetailViewController)
 {
     Y2Pos   = -100f;
     _config = config;
     _standardLevelDetailViewController = standardLevelDetailViewController;
     _detailView = standardLevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView");
 }
Example #4
0
        /// <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);
        }
Example #5
0
 public LTUI(Config config, StandardLevelDetailViewController standardLevelDetailViewController)
 {
     Y2Pos   = -100f;
     _config = config;
     _standardLevelDetailViewController = standardLevelDetailViewController;
     _detailView = standardLevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView");
     _beatmapCharacteristicSegmentedControlController = _detailView.GetField <BeatmapCharacteristicSegmentedControlController, StandardLevelDetailView>("_beatmapCharacteristicSegmentedControlController");
 }
Example #6
0
 public DiffdelController(Config config, PlatformLeaderboardViewController platformLeaderboardViewController, StandardLevelDetailViewController standardLevelDetailViewController)
 {
     _config = config;
     _platformLeaderboardViewController = platformLeaderboardViewController;
     _standardLevelDetailView           = Accessors.LevelDetailView(ref standardLevelDetailViewController) !;
     _buttonText = (Accessors.NPSText(ref Accessors.ParamsPanel(ref _standardLevelDetailView)) as ButtonText) !;
     _beatmapCharacteristicSegmentedControlController = (Accessors.CharacteristicSegment(ref _standardLevelDetailView)) !;
     _diffdelDifficultyControlController = (Accessors.DifficultySegment(ref _standardLevelDetailView) as DiffdelDifficultyControlController) !;
 }
Example #7
0
        public DifficultyHighlighter(StandardLevelDetailViewController standardLevelDetailViewController)
        {
            StandardLevelDetailView standardLevelDetailView = Accessors.StandardLevelDetailViewAccessor(ref standardLevelDetailViewController);

            beatmapCharacteristicSegmentedControlController = Accessors.BeatmapCharacteristicSegmentedControlController(ref standardLevelDetailView);
            beatmapCharacteristicSegmentedControl           = Accessors.BeatmapCharacteristicsSegmentedControlAccessor(ref beatmapCharacteristicSegmentedControlController);
            beatmapDifficultySegmentedControlController     = Accessors.BeatmapDifficultySegmentedControlControllerAccessor(ref standardLevelDetailView);
            beatmapDifficultySegmentedControl = Accessors.BeatmapDifficultySegmentedControlAccessor(ref beatmapDifficultySegmentedControlController);
        }
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Prefix
        /// </summary>
        /// <param name="__instance">LevelCollectionViewController instance</param>
        internal static void Postfix(ref StandardLevelDetailView __instance)
        {
            m_StandardLevelDetailView = __instance;

            /// Apply
            if (Config.GameTweaker.Enabled && Config.GameTweaker.DeleteSongButton)
            {
                SetDeleteSongButtonEnabled(Config.GameTweaker.DeleteSongButton);
            }
        }
Example #9
0
        /// <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();
        }
Example #10
0
        protected override void DidActivate(bool firstActivation, ActivationType activationType)
        {
            if (firstActivation)
            {
                this.name = "SongDetailsViewController";

                var referenceViewController             = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First();
                StandardLevelDetailView reference       = referenceViewController.GetPrivateField <StandardLevelDetailView>("_standardLevelDetailView");
                RectTransform           referenceParent = reference.transform.parent as RectTransform;

                this.rectTransform.anchorMin        = referenceParent.anchorMin;
                this.rectTransform.anchorMax        = referenceParent.anchorMax;
                this.rectTransform.anchoredPosition = Vector2.zero;
                this.rectTransform.sizeDelta        = new Vector2(80f, 0f);

                if (Tweaks.SongBrowserTweaks.ModLoaded)
                {
                    Logger.log.Notice("SongBrowser detected. Instantiating StandardLevelDetailView with SongBrowser's modifications. This may result in various NullReferenceExceptions being thrown (and caught) by UnityEngine. These exceptions appear to have no effect on regular operation and can be ignored.");
                }
                _standardLevelDetailView = Instantiate(reference, this.transform, false);
                _standardLevelDetailView.gameObject.SetActive(true);
                _standardLevelDetailView.name = "SearchResultLevelDetail";
                if (Tweaks.SongBrowserTweaks.ModLoaded)
                {
                    Logger.log.Notice("Finished instantiating StandardLevelDetailView");
                }

                _levelParamsPanel = _standardLevelDetailView.GetPrivateField <LevelParamsPanel>("_levelParamsPanel");
                _songNameText     = _standardLevelDetailView.GetPrivateField <TextMeshProUGUI>("_songNameText");

                _checkmarkSprite = BSUtilsUtilities.LoadSpriteFromResources("EnhancedSearchAndFilters.Assets.checkmark.png");
                _crossSprite     = BSUtilsUtilities.LoadSpriteFromResources("EnhancedSearchAndFilters.Assets.cross.png");
                _blankSprite     = Sprite.Create(Texture2D.blackTexture, new Rect(0f, 0f, 1f, 1f), Vector2.zero);

                RemoveCustomUIElements(this.rectTransform);
                ModifyPanelElements();
                ModifyTextElements();
                ModifySelectionElements();
            }
            else
            {
                // stats panel gets disabled when in party mode, so re-enable it here just in case
                RectTransform statsPanel = _standardLevelDetailView.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "Stats");
                statsPanel.gameObject.SetActive(true);
                _compactKeyboardButton.gameObject.SetActive(PluginConfig.CompactSearchMode);

                // strings get reset, so they have to be reapplied
                foreach (var str in _difficultyStrings)
                {
                    _difficultyElements[str].Item1.text = str;
                }
            }
        }
        /// <summary>
        /// Constructor.  Acquire all necessary BeatSaberUi elements.
        /// </summary>
        /// <param name="flowCoordinator"></param>
        public BeatSaberUIController(FlowCoordinator flowCoordinator)
        {
            LevelSelectionFlowCoordinator = flowCoordinator;

            // gather controllers and ui elements.
            LevelPackViewController = LevelSelectionFlowCoordinator.GetPrivateField <LevelPacksViewController>("_levelPacksViewController");
            Logger.Debug("Acquired LevelPacksViewController [{0}]", LevelPackViewController.GetInstanceID());

            LevelPackDetailViewController = LevelSelectionFlowCoordinator.GetPrivateField <LevelPackDetailViewController>("_levelPackDetailViewController");
            Logger.Debug("Acquired LevelPackDetailViewController [{0}]", LevelPackDetailViewController.GetInstanceID());

            LevelPacksTableView = LevelPackViewController.GetPrivateField <LevelPacksTableView>("_levelPacksTableView");
            Logger.Debug("Acquired LevelPacksTableView [{0}]", LevelPacksTableView.GetInstanceID());

            LevelPackLevelsViewController = LevelSelectionFlowCoordinator.GetPrivateField <LevelPackLevelsViewController>("_levelPackLevelsViewController");
            Logger.Debug("Acquired LevelPackLevelsViewController [{0}]", LevelPackLevelsViewController.GetInstanceID());

            LevelPackLevelsTableView = this.LevelPackLevelsViewController.GetPrivateField <LevelPackLevelsTableView>("_levelPackLevelsTableView");
            Logger.Debug("Acquired LevelPackLevelsTableView [{0}]", LevelPackLevelsTableView.GetInstanceID());

            LevelDetailViewController = LevelSelectionFlowCoordinator.GetPrivateField <StandardLevelDetailViewController>("_levelDetailViewController");
            Logger.Debug("Acquired StandardLevelDetailViewController [{0}]", LevelDetailViewController.GetInstanceID());

            StandardLevelDetailView = LevelDetailViewController.GetPrivateField <StandardLevelDetailView>("_standardLevelDetailView");
            Logger.Debug("Acquired StandardLevelDetailView [{0}]", StandardLevelDetailView.GetInstanceID());

            BeatmapCharacteristicSelectionViewController = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSegmentedControlController>().First();
            Logger.Debug("Acquired BeatmapCharacteristicSegmentedControlController [{0}]", BeatmapCharacteristicSelectionViewController.GetInstanceID());

            LevelSelectionNavigationController = LevelSelectionFlowCoordinator.GetPrivateField <DismissableNavigationController>("_navigationController");
            Logger.Debug("Acquired DismissableNavigationController [{0}]", LevelSelectionNavigationController.GetInstanceID());

            LevelDifficultyViewController = StandardLevelDetailView.GetPrivateField <BeatmapDifficultySegmentedControlController>("_beatmapDifficultySegmentedControlController");
            Logger.Debug("Acquired BeatmapDifficultySegmentedControlController [{0}]", LevelDifficultyViewController.GetInstanceID());

            LevelPackLevelsTableViewRectTransform = LevelPackLevelsTableView.transform as RectTransform;
            Logger.Debug("Acquired TableViewRectTransform from LevelPackLevelsTableView [{0}]", LevelPackLevelsTableViewRectTransform.GetInstanceID());

            TableView tableView = ReflectionUtil.GetPrivateField <TableView>(LevelPackLevelsTableView, "_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();
        }
        static void Prefix(StandardLevelDetailView __instance, IBeatmapLevel level, BeatmapDifficulty defaultDifficulty, BeatmapCharacteristicSO defaultBeatmapCharacteristic, PlayerData playerData)
        {
            List <BeatmapCharacteristicSO> toGenerate = new List <BeatmapCharacteristicSO>();

            if (Config.Instance.ShowGenerated360)
            {
                toGenerate.Add(GameModeHelper.GetGenerated360GameMode());
            }
            if (Config.Instance.ShowGenerated90)
            {
                toGenerate.Add(GameModeHelper.GetGenerated90GameMode());
            }

            List <IDifficultyBeatmapSet> sets = new List <IDifficultyBeatmapSet>(level.beatmapLevelData.difficultyBeatmapSets);

            // Generate each custom gamemode
            foreach (BeatmapCharacteristicSO customGameMode in toGenerate)
            {
                if (level.beatmapLevelData.difficultyBeatmapSets.Any((e) => e.beatmapCharacteristic.serializedName == GameModeHelper.GENERATED_360DEGREE_MODE))
                {
                    // Already added the generated gamemode
                    continue;
                }

                IDifficultyBeatmapSet basedOnGameMode = level.beatmapLevelData.difficultyBeatmapSets.FirstOrDefault((e) => e.beatmapCharacteristic.serializedName == Config.Instance.BasedOn);
                if (basedOnGameMode == null)
                {
                    // Level does not have a standard mode to base its 360 mode on
                    continue;
                }

                CustomDifficultyBeatmapSet customSet    = new CustomDifficultyBeatmapSet(customGameMode);
                CustomDifficultyBeatmap[]  difficulties = basedOnGameMode.difficultyBeatmaps.Select((e) => new CustomDifficultyBeatmap(e.level, customSet, e.difficulty, e.difficultyRank, e.noteJumpMovementSpeed, e.noteJumpStartBeatOffset, e.beatmapData.GetCopy())).ToArray();
                customSet.SetCustomDifficultyBeatmaps(difficulties);
                sets.Add(customSet);
            }

            // Update difficultyBeatmapSets
            if (level.beatmapLevelData is BeatmapLevelData data)
            {
                if (!FieldHelper.Set(data, "_difficultyBeatmapSets", sets.ToArray()))
                {
                    Plugin.Log.Warn("Could not set new difficulty sets");
                    return;
                }
            }
            else
            {
                Plugin.Log.Info("Unsupported beatmapLevelData: " + (level.beatmapLevelData?.GetType().FullName ?? "null"));
            }
        }
        public MockPartyViewController()
        {
            Instance = this;
            _partyFlowCoordinator = Resources.FindObjectsOfTypeAll <PartyFreePlayFlowCoordinator>().FirstOrDefault();
            LevelPackLevelsViewController     levels          = ReflectionUtil.GetPrivateField <LevelPackLevelsViewController>(_partyFlowCoordinator, "_levelPackLevelsViewController");
            LevelPacksViewController          levelPacks      = ReflectionUtil.GetPrivateField <LevelPacksViewController>(_partyFlowCoordinator, "_levelPacksViewController");
            LevelPackDetailViewController     levelPackDetail = ReflectionUtil.GetPrivateField <LevelPackDetailViewController>(_partyFlowCoordinator, "_levelPackDetailViewController");
            StandardLevelDetailViewController detail          = ReflectionUtil.GetPrivateField <StandardLevelDetailViewController>(_partyFlowCoordinator, "_levelDetailViewController");

            detailView = ReflectionUtil.GetPrivateField <StandardLevelDetailView>(detail, "_standardLevelDetailView");
            _gameplaySetupViewController = ReflectionUtil.GetPrivateField <GameplaySetupViewController>(_partyFlowCoordinator, "_gameplaySetupViewController");
            LocalLeaderboardViewController leaderboard = ReflectionUtil.GetPrivateField <LocalLeaderboardViewController>(_partyFlowCoordinator, "_localLeaderboardViewController");

            detail.didPresentContentEvent += (controller, type) =>
            {
                if (type == StandardLevelDetailViewController.ContentType.OwnedAndReady)
                {
                    didSelectLevel(detail.selectedDifficultyBeatmap);
                }
            };
            detail.didChangeDifficultyBeatmapEvent += didSelectDifficultyBeatmap;
            detail.didPressPlayButtonEvent         += didPressPlay;

            levelPackDetail.didActivateEvent += (firstActivation, type) => showLeaderboard();
            leaderboard.didActivateEvent     += (firstActivation, type) => showLeaderboard();

            _mainMenuController = Resources.FindObjectsOfTypeAll <MainMenuViewController>().FirstOrDefault();
            Button    partyButton = ReflectionUtil.GetPrivateField <Button>(_mainMenuController, "_partyButton");
            HoverHint hint        = Resources.FindObjectsOfTypeAll <HoverHint>().Where(x => x.text == "Play with your friends locally!").First();

            _mainMenuController.didActivateEvent += (first, type) =>
            {
                if (Data.Steam.SteamAPI.GetConnectionState() != SteamAPI.ConnectionState.CONNECTED)
                {
                    partyButton.SetButtonText("Party");
                    if (hint)
                    {
                        hint.text = "Play with your friends locally!";
                    }
                }
                else
                {
                    partyButton.SetButtonText("Online Lobby");
                    if (hint)
                    {
                        hint.text = "Play with your friends in your steam lobby!";
                    }
                }
            };
        }
        protected override void DidActivate(bool firstActivation, ActivationType activationType)
        {
            if (firstActivation)
            {
                var referenceViewController             = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First();
                StandardLevelDetailView reference       = referenceViewController.GetPrivateField <StandardLevelDetailView>("_standardLevelDetailView");
                RectTransform           referenceParent = reference.transform.parent as RectTransform;

                this.rectTransform.anchorMin        = referenceParent.anchorMin;
                this.rectTransform.anchorMax        = referenceParent.anchorMax;
                this.rectTransform.anchoredPosition = Vector2.zero;
                this.rectTransform.sizeDelta        = new Vector2(80f, 0f);

                _standardLevelDetailView = Instantiate(reference, this.transform, false);
                _standardLevelDetailView.gameObject.SetActive(true);
                _standardLevelDetailView.name = "SearchResultLevelDetail";

                _levelParamsPanel = _standardLevelDetailView.GetPrivateField <LevelParamsPanel>("_levelParamsPanel");
                _songNameText     = _standardLevelDetailView.GetPrivateField <TextMeshProUGUI>("_songNameText");

                _checkmarkSprite = UIUtilities.LoadSpriteFromResources("EnhancedSearchAndFilters.Assets.checkmark.png");
                _crossSprite     = UIUtilities.LoadSpriteFromResources("EnhancedSearchAndFilters.Assets.cross.png");
                _blankSprite     = Sprite.Create(Texture2D.blackTexture, new Rect(0f, 0f, 1f, 1f), Vector2.zero);

                RemoveCustomUIElements(this.rectTransform);
                RemoveSongRequirementsButton();
                ModifyPanelElements();
                ModifyTextElements();
                ModifySelectionElements();
            }
            else
            {
                // stats panel gets disabled when in party mode, so re-enable it here just in case
                RectTransform statsPanel = _standardLevelDetailView.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "Stats");
                statsPanel.gameObject.SetActive(true);
                _compactKeyboardButton.gameObject.SetActive(PluginConfig.CompactSearchMode);

                // strings get reset, so they have to be reapplied
                foreach (var str in _difficultyStrings)
                {
                    _difficultyElements[str].Item1.text = str;
                }
            }
        }
        static bool Prefix(SinglePlayerLevelSelectionFlowCoordinator __instance,
                           ref Action beforeSceneSwitchCallback, ref bool practice,
                           LevelSelectionNavigationController ___levelSelectionNavigationController)
        {
            if (RecordingController.instance == null)
            {
                Logger.log?.Warn($"RecordingController is null, unable to start recording.");
                return(true);
            }
            if (!(OBSController.instance?.IsConnected ?? false))
            {
                Logger.log?.Warn($"Not connected to OBS, skipping StartLevel override.");
                return(true);
            }
            if (Plugin.config.LevelStartDelay == 0)
            {
                RecordingController.instance.StartRecordingLevel();
                SharedCoroutineStarter.instance.StartCoroutine(RecordingController.instance.GameStatusSetup());
                return(true);
            }
            if (DelayedStartActive && WaitingToStart)
            {
                return(false);                         // Ignore this call to StartLevel
            }
            if (!WaitingToStart && DelayedStartActive) // Done waiting, start the level
            {
                DelayedStartActive = false;
                return(true);
            }
            DelayedStartActive = true;
            WaitingToStart     = true;
            Logger.log?.Debug("LevelSelectionNavigationController_StartLevel");
            LevelCollectionNavigationController navigationController = AccessNavigationController(ref ___levelSelectionNavigationController);
            StandardLevelDetailViewController   detailViewController = AccessDetailViewController(ref navigationController);
            StandardLevelDetailView             levelView            = AccessDetailView(ref detailViewController);

            if (levelView != null)
            {
                levelView.actionButton.interactable = false;
            }
            SharedCoroutineStarter.instance.StartCoroutine(DelayedLevelStart(__instance, beforeSceneSwitchCallback, practice, levelView?.actionButton));
            return(false);
        }
Example #16
0
        //Time      - Downloads
        //BPM       - Plays
        //Notes     - BPM
        //Obstacles - Upvotes
        //Bombs     - Downvotes

        protected override void DidActivate(bool firstActivation, ActivationType type)
        {
            if (firstActivation)
            {
                gameObject.SetActive(true);
                _levelDetails = GetComponentsInChildren <StandardLevelDetailView>(true).First(x => x.name == "LevelDetail");
                _levelDetails.gameObject.SetActive(true);
                (_levelDetails.transform as RectTransform).anchoredPosition = new Vector2(-40, 0);
                BeatmapDifficultySegmentedControlController beatmapDifficultySegmentedControl = GetComponentsInChildren <BeatmapDifficultySegmentedControlController>(true).First(x => x.name == "BeatmapDifficultySegmentedControl");
                beatmapDifficultySegmentedControl.gameObject.SetActive(false);
                BeatmapCharacteristicSegmentedControlController beatmapCharacteristicSegmentedControl = GetComponentsInChildren <BeatmapCharacteristicSegmentedControlController>(true).First(x => x.name == "BeatmapCharacteristicSegmentedControl");
                beatmapCharacteristicSegmentedControl.gameObject.SetActive(false);

                RemoveCustomUIElements(rectTransform);

                _levelParams = GetComponentsInChildren <LevelParamsPanel>().First(x => x.name == "LevelParamsPanel");

                foreach (HoverHint hint in _levelParams.transform.GetComponentsInChildren <HoverHint>())
                {
                    switch (hint.name)
                    {
                    case "Time":
                    {
                        hint.GetComponentInChildren <UnityEngine.UI.Image>().sprite = Sprites.DownloadIcon;
                    }; break;

                    case "BPM":
                    {
                        hint.GetComponentInChildren <UnityEngine.UI.Image>().sprite = Sprites.PlayIcon;
                    }; break;

                    case "NotesCount":
                    {
                        hint.GetComponentInChildren <UnityEngine.UI.Image>().sprite = Resources.FindObjectsOfTypeAll <Sprite>().First(x => x.name == "MetronomeIcon");
                    }; break;

                    case "ObstaclesCount":
                    {
                        hint.GetComponentInChildren <UnityEngine.UI.Image>().sprite = Sprites.ThumbUp;
                    }; break;

                    case "BombsCount":
                    {
                        hint.GetComponentInChildren <UnityEngine.UI.Image>().sprite = Sprites.ThumbDown;
                    }; break;
                    }

                    Destroy(hint);
                }

                RectTransform yourStats = GetComponentsInChildren <RectTransform>().First(x => x.name == "Stats");
                yourStats.gameObject.SetActive(true);

                TextMeshProUGUI[] _textComponents = GetComponentsInChildren <TextMeshProUGUI>();

                try
                {
                    songNameText = _textComponents.First(x => x.name == "SongNameText");

                    downloadsText          = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "Time");
                    downloadsText.fontSize = 3f;

                    playsText          = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "BPM");
                    playsText.fontSize = 3f;
                    //        foreach (var x in _textComponents)
                    //        {
                    //            Console.WriteLine(x.name);
                    //            Console.WriteLine(x.transform.parent.name);
                    //        }
                    difficulty1Title = _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxRank"); //.text = "Expert/+";
                    difficulty1Text  = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxRank");

                    difficulty2Title = _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "Highscore");//.text = "Hard";
                    difficulty2Text  = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "Highscore");

                    difficulty3Title = _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxCombo");//.text = "Easy/Normal";
                    difficulty3Text  = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxCombo");
                }
                catch (Exception e)
                {
                    Plugin.log.Critical("Unable to convert detail view controller! Exception:  " + e);
                }

                _downloadButton = _levelDetails.playButton;
                _downloadButton.SetButtonText("DOWNLOAD");
                _downloadButton.ToggleWordWrapping(false);
                _downloadButton.onClick.RemoveAllListeners();
                _downloadButton.onClick.AddListener(() => { downloadButtonPressed?.Invoke(_currentSong); });
                (_downloadButton.transform as RectTransform).sizeDelta = new Vector2(26f, 8.8f);

                _favoriteButton = _levelDetails.practiceButton;
                _favoriteButton.SetButtonIcon(Sprites.AddToFavorites);
                _favoriteButton.onClick.RemoveAllListeners();
                _favoriteButton.onClick.AddListener(() => { favoriteButtonPressed?.Invoke(_currentSong); });

                coverImage = _levelDetails.GetPrivateField <RawImage>("_coverImage");

                _loadingIndicator = BeatSaberUI.CreateLoadingSpinner(rectTransform);
                (_loadingIndicator.transform as RectTransform).anchorMin        = new Vector2(0.5f, 0.5f);
                (_loadingIndicator.transform as RectTransform).anchorMax        = new Vector2(0.5f, 0.5f);
                (_loadingIndicator.transform as RectTransform).anchoredPosition = new Vector2(0f, 0f);
                (_loadingIndicator.transform as RectTransform).anchoredPosition = new Vector2(-40f, 0f);
            }
        }
 internal static void Postfix(ref StandardLevelDetailView __instance, ref BeatmapCharacteristicSegmentedControlController ____beatmapDifficultySegmentedControlController)
 {
     SiraEvents.InvokeLevelSelectionChange(__instance.selectedDifficultyBeatmap, ____beatmapDifficultySegmentedControlController.selectedBeatmapCharacteristic);
 }
Example #18
0
        //Time      - Downloads
        //BPM       - Plays
        //Notes     - BPM
        //Obstacles - Upvotes
        //Bombs     - Downvotes

        protected override void DidActivate(bool firstActivation, ActivationType type)
        {
            if (firstActivation)
            {
                gameObject.SetActive(true);
                _levelDetails = GetComponentsInChildren <StandardLevelDetailView>(true).First(x => x.name == "LevelDetail");
                _levelDetails.gameObject.SetActive(true);

                RemoveCustomUIElements(rectTransform);

                _levelParams = GetComponentsInChildren <LevelParamsPanel>().First(x => x.name == "LevelParamsPanel");

                foreach (HoverHint hint in _levelParams.transform.GetComponentsInChildren <HoverHint>())
                {
                    switch (hint.name)
                    {
                    case "Time":
                    {
                        hint.GetComponentInChildren <Image>().sprite = Sprites.DownloadIcon;
                    }; break;

                    case "BPM":
                    {
                        hint.GetComponentInChildren <Image>().sprite = Sprites.PlayIcon;
                    }; break;

                    case "NotesCount":
                    {
                        hint.GetComponentInChildren <Image>().sprite = Resources.FindObjectsOfTypeAll <Sprite>().First(x => x.name == "MetronomeIcon");
                    }; break;

                    case "ObstaclesCount":
                    {
                        hint.GetComponentInChildren <Image>().sprite = Sprites.ThumbUp;
                    }; break;

                    case "BombsCount":
                    {
                        hint.GetComponentInChildren <Image>().sprite = Sprites.ThumbDown;
                    }; break;
                    }

                    Destroy(hint);
                }

                RectTransform yourStats = GetComponentsInChildren <RectTransform>().First(x => x.name == "Stats");
                yourStats.gameObject.SetActive(true);

                TextMeshProUGUI[] _textComponents = GetComponentsInChildren <TextMeshProUGUI>();

                try
                {
                    songNameText = _textComponents.First(x => x.name == "SongNameText");

                    downloadsText          = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "Time");
                    downloadsText.fontSize = 3f;

                    playsText          = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "BPM");
                    playsText.fontSize = 3f;

                    _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxRank").text = "Expert/+";
                    difficulty1Text = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxRank");

                    _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "Highscore").text = "Hard";
                    difficulty2Text = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "Highscore");

                    _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxCombo").text = "Easy/Normal";
                    difficulty3Text = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxCombo");
                }
                catch (Exception e)
                {
                    Logger.Exception("Unable to convert detail view controller! Exception:  " + e);
                }

                _downloadButton = _levelDetails.playButton;
                _downloadButton.SetButtonText("DOWNLOAD");
                _downloadButton.ToggleWordWrapping(false);
                _downloadButton.onClick.RemoveAllListeners();
                _downloadButton.onClick.AddListener(() => { downloadButtonPressed?.Invoke(_currentSong); });
                (_downloadButton.transform as RectTransform).sizeDelta = new Vector2(26f, 8.8f);

                _favoriteButton = _levelDetails.practiceButton;
                _favoriteButton.SetButtonIcon(Sprites.AddToFavorites);
                _favoriteButton.onClick.RemoveAllListeners();
                _favoriteButton.onClick.AddListener(() => { favoriteButtonPressed?.Invoke(_currentSong); });

                coverImage = _levelDetails.GetPrivateField <Image>("_coverImage");
            }
        }
        protected override void DidActivate(bool firstActivation, ActivationType type)
        {
            if (firstActivation && type == ActivationType.AddedToHierarchy)
            {
                gameObject.SetActive(true);
                rectTransform.sizeDelta = new Vector2(60f, 0f);

                _levelDetails = GetComponentsInChildren <StandardLevelDetailView>(true).First(x => x.name == "LevelDetail");
                _levelDetails.gameObject.SetActive(true);
                (_levelDetails.transform as RectTransform).anchoredPosition = new Vector2(-40f, 0f);
                RemoveCustomUIElements(rectTransform);

                Destroy(GetComponentsInChildren <LevelParamsPanel>().First(x => x.name == "LevelParamsPanel").gameObject);

                RectTransform yourStats = GetComponentsInChildren <RectTransform>(true).First(x => x.name == "Stats");
                yourStats.gameObject.SetActive(true);

                RectTransform characteristicsRect = GetComponentsInChildren <RectTransform>(true).First(x => x.name == "BeatmapCharacteristicSegmentedControl");
                RectTransform difficultyRect      = GetComponentsInChildren <RectTransform>(true).First(x => x.name == "BeatmapDifficultySegmentedControl");

                Destroy(characteristicsRect.gameObject);
                Destroy(difficultyRect.gameObject);

                TextMeshProUGUI[] _textComponents = GetComponentsInChildren <TextMeshProUGUI>();

                try
                {
                    songNameText = _textComponents.First(x => x.name == "SongNameText");
                    _textComponents.First(x => x.name == "Title").text = "Playlist";
                    songNameText.enableWordWrapping      = true;
                    songNameText.rectTransform.sizeDelta = new Vector2(-22f, 20f);

                    _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxCombo").text = "Author";
                    authorText = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxCombo");
                    authorText.rectTransform.sizeDelta = new Vector2(24f, 0f);

                    _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "Highscore").text = "Total songs";
                    totalSongsText = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "Highscore");

                    Destroy(_textComponents.First(x => x.transform.parent.name == "MaxRank").transform.parent.gameObject);
                }
                catch (Exception e)
                {
                    Plugin.log.Critical("Unable to convert detail view controller! Exception:  " + e);
                }

                _selectButton = _levelDetails.playButton;
                _selectButton.SetButtonText(_selectButtonText);
                _selectButton.ToggleWordWrapping(false);
                _selectButton.onClick.RemoveAllListeners();
                _selectButton.onClick.AddListener(() => { selectButtonPressed?.Invoke(_currentPlaylist); });

                if (addDownloadButton)
                {
                    _downloadButton = _levelDetails.practiceButton;
                    _downloadButton.SetButtonIcon(Sprites.DownloadIcon);
                    _downloadButton.onClick.RemoveAllListeners();
                    _downloadButton.onClick.AddListener(() => { downloadButtonPressed?.Invoke(_currentPlaylist); });
                }
                else
                {
                    Destroy(_levelDetails.practiceButton.gameObject);
                }

                coverImage = _levelDetails.GetPrivateField <RawImage>("_coverImage");
            }
        }
        protected override void DidActivate(bool firstActivation, bool addedToHierarchy, bool screenSystemEnabling)
        {
            if (firstActivation)
            {
                //Set up UI
                SetTitle("Game Room", ViewController.AnimationType.None);

                showBackButton = true;

                _playerDataModel                   = Resources.FindObjectsOfTypeAll <PlayerDataModel>().First();
                _menuLightsManager                 = Resources.FindObjectsOfTypeAll <MenuLightsManager>().First();
                _soloFreePlayFlowCoordinator       = Resources.FindObjectsOfTypeAll <SoloFreePlayFlowCoordinator>().First();
                _standardLevelDetailViewController = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First();
                _standardLevelDetailView           = _standardLevelDetailViewController.GetField <StandardLevelDetailView, StandardLevelDetailViewController>("_standardLevelDetailView");
                _resultsViewController             = Resources.FindObjectsOfTypeAll <ResultsViewController>().First();
                _scoreLights   = _soloFreePlayFlowCoordinator.GetField <MenuLightsPresetSO>("_resultsClearedLightsPreset");
                _defaultLights = _soloFreePlayFlowCoordinator.GetField <MenuLightsPresetSO>("_defaultLightsPreset");

                _songSelection = BeatSaberUI.CreateViewController <SongSelection>();
                _songSelection.SongSelected += SongSelection_SongSelected;

                _splashScreen = BeatSaberUI.CreateViewController <SplashScreen>();

                _songDetail              = BeatSaberUI.CreateViewController <SongDetail>();
                _songDetail.PlayPressed += SongDetail_didPressPlayButtonEvent;
                _songDetail.DifficultyBeatmapChanged += SongDetail_didChangeDifficultyBeatmapEvent;

                _playerList = BeatSaberUI.CreateViewController <PlayerList>();
            }
            if (addedToHierarchy)
            {
                TournamentMode = Match == null;
                if (TournamentMode)
                {
                    _splashScreen.StatusText = $"Connecting to \"{Host.Name}\"...";
                    ProvideInitialViewControllers(_splashScreen);
                }
                else
                {
                    //If we're not in tournament mode, then a client connection has already been made
                    //by the room selection screen, so we can just assume Plugin.client isn't null
                    //NOTE: This is *such* a hack. Oh my god.
                    isHost = Match.Leader == Plugin.client.Self;
                    _songSelection.SetSongs(SongUtils.masterLevelList);
                    _playerList.Players      = Match.Players;
                    _splashScreen.StatusText = "Waiting for the host to select a song...";

                    if (isHost)
                    {
                        ProvideInitialViewControllers(_songSelection, _playerList);
                    }
                    else
                    {
                        ProvideInitialViewControllers(_splashScreen, _playerList);
                    }
                }
            }

            //The ancestor sets up the server event listeners
            //It would be possible to recieve an event that does a ui update after this call
            //and before the rest of the ui is set up, if we did this at the top.
            //So, we do it last
            base.DidActivate(firstActivation, addedToHierarchy, screenSystemEnabling);
        }
        static void Postfix(StandardLevelDetailView __instance, ref LevelParamsPanel ____levelParamsPanel, ref IDifficultyBeatmap ____selectedDifficultyBeatmap,
                            ref PlayerData ____playerData, ref LevelBar ____levelBar, ref UnityEngine.UI.Button ____actionButton,
                            ref UnityEngine.UI.Button ____practiceButton, ref BeatmapDifficultySegmentedControlController ____beatmapDifficultySegmentedControlController,
                            ref BeatmapCharacteristicSegmentedControlController ____beatmapCharacteristicSegmentedControlController)
        {
            bool firstSelection = false;
            var  level          = ____selectedDifficultyBeatmap.level is CustomBeatmapLevel ? ____selectedDifficultyBeatmap.level as CustomPreviewBeatmapLevel : null;

            if (level != lastLevel)
            {
                firstSelection = true;
                lastLevel      = level;
            }
            ____actionButton.interactable   = true;
            ____practiceButton.interactable = true;

            // ____levelBar.GetField<TextMeshProUGUI>("_songNameText").overflowMode = TextOverflowModes;
            //____songNameText.text = "<size=78%>" + ____songNameText.text.Replace(@"<", "<\u200B").Replace(@">", ">\u200B");
            //    ____songNameText.overflowMode = TextOverflowModes.Overflow;
            //     ____songNameText.enableWordWrapping = false;

            //____songNameText.richText = true;
            RequirementsUI.instance.ButtonGlowColor    = false;
            RequirementsUI.instance.ButtonInteractable = false;
            if (level != null)
            {
                Data.ExtraSongData songData = Collections.RetrieveExtraSongData(Utilities.Hashing.GetCustomLevelHash(level), level.customLevelPath);

                if (songData == null)
                {
                    RequirementsUI.instance.ButtonGlowColor    = false;
                    RequirementsUI.instance.ButtonInteractable = false;
                    return;
                }
                bool wipFolderSong = false;
                IDifficultyBeatmap selectedDiff            = ____selectedDifficultyBeatmap;
                Data.ExtraSongData.DifficultyData diffData = Collections.RetrieveDifficultyData(selectedDiff);
                //songData._difficulties?.FirstOrDefault(x => x._difficulty == selectedDiff.difficulty
                //&& (x._beatmapCharacteristicName == selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.characteristicName || x._beatmapCharacteristicName == selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName));
                if (diffData != null)
                {
                    //If no additional information is present
                    if (diffData.additionalDifficultyData._requirements.Count() == 0 && diffData.additionalDifficultyData._suggestions.Count() == 0 &&
                        diffData.additionalDifficultyData._warnings.Count() == 0 && diffData.additionalDifficultyData._information.Count() == 0 &&
                        songData.contributors.Count() == 0)
                    {
                        RequirementsUI.instance.ButtonGlowColor    = false;
                        RequirementsUI.instance.ButtonInteractable = false;
                    }
                    else if (diffData.additionalDifficultyData._warnings.Count() == 0)
                    {
                        RequirementsUI.instance.ButtonGlowColor    = true;
                        RequirementsUI.instance.ButtonInteractable = true;
                    }
                    else if (diffData.additionalDifficultyData._warnings.Count() > 0)
                    {
                        RequirementsUI.instance.ButtonGlowColor    = true;
                        RequirementsUI.instance.ButtonInteractable = true;
                        if (diffData.additionalDifficultyData._warnings.Contains("WIP"))
                        {
                            ____actionButton.interactable = false;
                        }
                    }
                }
                if (level.levelID.EndsWith(" WIP"))
                {
                    RequirementsUI.instance.ButtonGlowColor    = true;
                    RequirementsUI.instance.ButtonInteractable = true;
                    ____actionButton.interactable = false;
                    wipFolderSong = true;
                }
                if (diffData != null)
                {
                    for (int i = 0; i < diffData.additionalDifficultyData._requirements.Count(); i++)
                    {
                        if (!Collections.capabilities.Contains(diffData.additionalDifficultyData._requirements[i]))
                        {
                            ____actionButton.interactable              = false;
                            ____practiceButton.interactable            = false;
                            RequirementsUI.instance.ButtonGlowColor    = true;
                            RequirementsUI.instance.ButtonInteractable = true;
                        }
                    }
                }


                if (selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName == "MissingCharacteristic")
                {
                    ____actionButton.interactable              = false;
                    ____practiceButton.interactable            = false;
                    RequirementsUI.instance.ButtonGlowColor    = true;
                    RequirementsUI.instance.ButtonInteractable = true;
                }

                RequirementsUI.instance.level     = level;
                RequirementsUI.instance.songData  = songData;
                RequirementsUI.instance.diffData  = diffData;
                RequirementsUI.instance.wipFolder = wipFolderSong;


                //Difficulty Label Handling
                levelLabels.Clear();
                string currentCharacteristic = "";
                foreach (Data.ExtraSongData.DifficultyData diffLevel in songData._difficulties)
                {
                    var    difficulty     = diffLevel._difficulty;
                    string characteristic = diffLevel._beatmapCharacteristicName;
                    if (characteristic == selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName)
                    {
                        currentCharacteristic = characteristic;
                    }
                    if (!levelLabels.ContainsKey(characteristic))
                    {
                        levelLabels.Add(characteristic, new OverrideLabels());
                    }
                    OverrideLabels charLabels = levelLabels[characteristic];
                    if (!string.IsNullOrWhiteSpace(diffLevel._difficultyLabel))
                    {
                        switch (difficulty)
                        {
                        case BeatmapDifficulty.Easy:
                            charLabels.EasyOverride = diffLevel._difficultyLabel;
                            break;

                        case BeatmapDifficulty.Normal:
                            charLabels.NormalOverride = diffLevel._difficultyLabel;
                            break;

                        case BeatmapDifficulty.Hard:
                            charLabels.HardOverride = diffLevel._difficultyLabel;
                            break;

                        case BeatmapDifficulty.Expert:
                            charLabels.ExpertOverride = diffLevel._difficultyLabel;
                            break;

                        case BeatmapDifficulty.ExpertPlus:
                            charLabels.ExpertPlusOverride = diffLevel._difficultyLabel;
                            break;
                        }
                    }
                }
                if (!string.IsNullOrWhiteSpace(currentCharacteristic))
                {
                    SetCurrentLabels(levelLabels[currentCharacteristic]);
                }
                else
                {
                    clearOverrideLabels();
                }

                ____beatmapDifficultySegmentedControlController.SetData(____selectedDifficultyBeatmap.parentDifficultyBeatmapSet.difficultyBeatmaps, ____beatmapDifficultySegmentedControlController.selectedDifficulty);
                clearOverrideLabels();
                if (songData._defaultCharacteristic != null && firstSelection)
                {
                    if (____beatmapCharacteristicSegmentedControlController.selectedBeatmapCharacteristic.serializedName != songData._defaultCharacteristic)
                    {
                        var chars = ____beatmapCharacteristicSegmentedControlController.GetField <List <BeatmapCharacteristicSO>, BeatmapCharacteristicSegmentedControlController>("_beatmapCharacteristics");
                        int index = 0;
                        foreach (var characteristic in chars)
                        {
                            if (songData._defaultCharacteristic == characteristic.serializedName)
                            {
                                break;
                            }
                            index++;
                        }
                        if (index != chars.Count)
                        {
                            ____beatmapCharacteristicSegmentedControlController.GetField <HMUI.IconSegmentedControl, BeatmapCharacteristicSegmentedControlController>("_segmentedControl").SelectCellWithNumber(index);
                        }
                        ____beatmapCharacteristicSegmentedControlController.HandleDifficultySegmentedControlDidSelectCell(
                            ____beatmapCharacteristicSegmentedControlController.GetField <HMUI.IconSegmentedControl, BeatmapCharacteristicSegmentedControlController>("_segmentedControl"), index);
                    }
                }
            }
        }
        private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyBeatmap ____selectedDifficultyBeatmap, ref Button ____actionButton, ref Button ____practiceButton,
                                    ref BeatmapDifficultySegmentedControlController ____beatmapDifficultySegmentedControlController,
                                    ref BeatmapCharacteristicSegmentedControlController ____beatmapCharacteristicSegmentedControlController)
        {
            var firstSelection = false;
            var level          = ____selectedDifficultyBeatmap.level is CustomBeatmapLevel ? ____selectedDifficultyBeatmap.level as CustomPreviewBeatmapLevel : null;

            if (level != lastLevel)
            {
                firstSelection = true;
                lastLevel      = level;
            }

            ____actionButton.interactable   = true;
            ____practiceButton.interactable = true;

            RequirementsUI.instance.ButtonGlowColor    = false;
            RequirementsUI.instance.ButtonInteractable = false;
            if (level == null)
            {
                return;
            }

            var songData = Collections.RetrieveExtraSongData(Hashing.GetCustomLevelHash(level));

            if (songData == null)
            {
                RequirementsUI.instance.ButtonGlowColor    = false;
                RequirementsUI.instance.ButtonInteractable = false;
                return;
            }

            var wipFolderSong = false;
            var selectedDiff  = ____selectedDifficultyBeatmap;
            var diffData      = Collections.RetrieveDifficultyData(selectedDiff);

            if (diffData != null)
            {
                //If no additional information is present
                if (!diffData.additionalDifficultyData._requirements.Any() &&
                    !diffData.additionalDifficultyData._suggestions.Any() &&
                    !diffData.additionalDifficultyData._warnings.Any() &&
                    !diffData.additionalDifficultyData._information.Any() &&
                    !songData.contributors.Any() && !Utilities.Utils.DiffHasColors(diffData))
                {
                    RequirementsUI.instance.ButtonGlowColor    = false;
                    RequirementsUI.instance.ButtonInteractable = false;
                }
                else if (!diffData.additionalDifficultyData._warnings.Any())
                {
                    RequirementsUI.instance.ButtonGlowColor    = true;
                    RequirementsUI.instance.ButtonInteractable = true;
                    RequirementsUI.instance.SetRainbowColors(Utilities.Utils.DiffHasColors(diffData));
                }
                else if (diffData.additionalDifficultyData._warnings.Any())
                {
                    RequirementsUI.instance.ButtonGlowColor    = true;
                    RequirementsUI.instance.ButtonInteractable = true;
                    if (diffData.additionalDifficultyData._warnings.Contains("WIP"))
                    {
                        ____actionButton.interactable = false;
                    }
                    RequirementsUI.instance.SetRainbowColors(Utilities.Utils.DiffHasColors(diffData));
                }
            }

            if (level.levelID.EndsWith(" WIP"))
            {
                RequirementsUI.instance.ButtonGlowColor    = true;
                RequirementsUI.instance.ButtonInteractable = true;
                ____actionButton.interactable = false;
                wipFolderSong = true;
            }

            if (diffData != null)
            {
                foreach (var requirement in diffData.additionalDifficultyData._requirements)
                {
                    if (!Collections.capabilities.Contains(requirement))
                    {
                        ____actionButton.interactable              = false;
                        ____practiceButton.interactable            = false;
                        RequirementsUI.instance.ButtonGlowColor    = true;
                        RequirementsUI.instance.ButtonInteractable = true;
                    }
                }
            }

            if (selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName == "MissingCharacteristic")
            {
                ____actionButton.interactable              = false;
                ____practiceButton.interactable            = false;
                RequirementsUI.instance.ButtonGlowColor    = true;
                RequirementsUI.instance.ButtonInteractable = true;
            }

            RequirementsUI.instance.level     = level;
            RequirementsUI.instance.songData  = songData;
            RequirementsUI.instance.diffData  = diffData;
            RequirementsUI.instance.wipFolder = wipFolderSong;


            //Difficulty Label Handling
            LevelLabels.Clear();
            string currentCharacteristic = string.Empty;

            foreach (Data.ExtraSongData.DifficultyData diffLevel in songData._difficulties)
            {
                var    difficulty     = diffLevel._difficulty;
                string characteristic = diffLevel._beatmapCharacteristicName;
                if (characteristic == selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName)
                {
                    currentCharacteristic = characteristic;
                }

                if (!LevelLabels.ContainsKey(characteristic))
                {
                    LevelLabels.Add(characteristic, new OverrideLabels());
                }

                var charLabels = LevelLabels[characteristic];
                if (!string.IsNullOrWhiteSpace(diffLevel._difficultyLabel))
                {
                    switch (difficulty)
                    {
                    case BeatmapDifficulty.Easy:
                        charLabels.EasyOverride = diffLevel._difficultyLabel;
                        break;

                    case BeatmapDifficulty.Normal:
                        charLabels.NormalOverride = diffLevel._difficultyLabel;
                        break;

                    case BeatmapDifficulty.Hard:
                        charLabels.HardOverride = diffLevel._difficultyLabel;
                        break;

                    case BeatmapDifficulty.Expert:
                        charLabels.ExpertOverride = diffLevel._difficultyLabel;
                        break;

                    case BeatmapDifficulty.ExpertPlus:
                        charLabels.ExpertPlusOverride = diffLevel._difficultyLabel;
                        break;
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(currentCharacteristic))
            {
                SetCurrentLabels(LevelLabels[currentCharacteristic]);
            }
            else
            {
                ClearOverrideLabels();
            }

            ____beatmapDifficultySegmentedControlController.SetData(____selectedDifficultyBeatmap.parentDifficultyBeatmapSet.difficultyBeatmaps,
                                                                    ____beatmapDifficultySegmentedControlController.selectedDifficulty);
            ClearOverrideLabels();

            // TODO: Check if this whole if block is still needed
            if (songData._defaultCharacteristic != null && firstSelection)
            {
                if (____beatmapCharacteristicSegmentedControlController.selectedBeatmapCharacteristic.serializedName != songData._defaultCharacteristic)
                {
                    var chars =
                        ____beatmapCharacteristicSegmentedControlController.GetField <List <BeatmapCharacteristicSO>, BeatmapCharacteristicSegmentedControlController>("_beatmapCharacteristics");
                    var index = 0;
                    foreach (var characteristic in chars)
                    {
                        if (songData._defaultCharacteristic == characteristic.serializedName)
                        {
                            break;
                        }

                        index++;
                    }

                    if (index != chars.Count)
                    {
                        ____beatmapCharacteristicSegmentedControlController.GetField <HMUI.IconSegmentedControl, BeatmapCharacteristicSegmentedControlController>("_segmentedControl")
                        .SelectCellWithNumber(index);
                        ____beatmapCharacteristicSegmentedControlController.HandleDifficultySegmentedControlDidSelectCell(
                            ____beatmapCharacteristicSegmentedControlController.GetField <HMUI.IconSegmentedControl, BeatmapCharacteristicSegmentedControlController>("_segmentedControl"), index);
                    }
                }
            }
        }