private void SetupUI()
        {
            if (initialized)
            {
                return;
            }
            _beatmapCharacteristics = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>();
            _lastCharacteristic     = _beatmapCharacteristics.First(x => x.characteristicName == "Standard");

            Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSelectionViewController>().First().didSelectBeatmapCharacteristicEvent += (BeatmapCharacteristicSelectionViewController sender, BeatmapCharacteristicSO selected) => { _lastCharacteristic = selected; };
            if (SongLoader.AreSongsLoaded)
            {
                _levelCollection = SongLoader.CustomLevelCollectionSO;
            }
            else
            {
                SongLoader.SongsLoadedEvent += (SongLoader sender, List <CustomLevel> levels) =>
                {
                    _levelCollection = SongLoader.CustomLevelCollectionSO;
                };
            }

            _levelListViewController = Resources.FindObjectsOfTypeAll <LevelListViewController>().FirstOrDefault();

            RectTransform _tableViewRectTransform = _levelListViewController.GetComponentsInChildren <RectTransform>().First(x => x.name == "TableViewContainer");

            _tableViewRectTransform.sizeDelta = new Vector2(0f, -35f);
            //_tableViewRectTransform.anchoredPosition = new Vector2(0f, -2.5f);

            RectTransform _pageUp = _tableViewRectTransform.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "PageUpButton");

            _pageUp.anchoredPosition = new Vector2(0f, -1f);

            RectTransform _pageDown = _tableViewRectTransform.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "PageDownButton");

            _pageDown.anchoredPosition = new Vector2(0f, 1f);

            _requestButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(0, 30.25f), new Vector2(20f, 6f), RequestsButtonPressed, "Requests");
            _requestButton.SetButtonTextSize(3f);
            _requestButton.ToggleWordWrapping(false);

            _detailViewController = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First(x => x.name == "StandardLevelDetailViewController");

            //based on https://github.com/halsafar/BeatSaberSongBrowser/blob/master/SongBrowserPlugin/UI/Browser/SongBrowserUI.cs#L192
            var statsPanel     = _detailViewController.GetComponentsInChildren <CanvasRenderer>(true).First(x => x.name == "LevelParamsPanel");
            var statTransforms = statsPanel.GetComponentsInChildren <RectTransform>();
            var valueTexts     = statsPanel.GetComponentsInChildren <TextMeshProUGUI>().Where(x => x.name == "ValueText").ToList();

            foreach (RectTransform r in statTransforms)
            {
                if (r.name == "Separator")
                {
                    continue;
                }
                r.sizeDelta = new Vector2(r.sizeDelta.x * 0.85f, r.sizeDelta.y * 0.85f);
            }

            _levelListViewController.didSelectLevelEvent += _levelListViewController_didSelectLevelEvent;
            initialized = true;
        }
        public static CustomLevelCollectionSO ReplaceOriginal(LevelCollectionSO original)
        {
            var newCollection = CreateInstance <CustomLevelCollectionSO>();

            newCollection._levelList.AddRange(original.levels);
            newCollection.UpdateArray();

            newCollection.ReplaceReferences();

            foreach (var originalLevel in original.levels)
            {
                if (_standardCharacteristic == null)
                {
                    _standardCharacteristic = originalLevel.beatmapCharacteristics.FirstOrDefault(x => x.characteristicName == "Standard");
                }

                if (_oneSaberCharacteristic == null)
                {
                    _oneSaberCharacteristic = originalLevel.beatmapCharacteristics.FirstOrDefault(x => x.characteristicName == "One Saber");
                }

                if (_noArrowsCharacteristic == null)
                {
                    _noArrowsCharacteristic = originalLevel.beatmapCharacteristics.FirstOrDefault(x => x.characteristicName == "No Arrows");
                }
            }

            return(newCollection);
        }
        private void FilterPlaylist()
        {
            // bail if no playlist, usually means the settings stored one the user then moved.
            if (this.CurrentPlaylist == null)
            {
                Logger.Error("Trying to load a null playlist...");
                _filteredSongs           = _originalSongs;
                this.Settings.filterMode = SongFilterMode.None;
                return;
            }

            Logger.Debug("Filtering songs for playlist: {0}", this.CurrentPlaylist.Title);
            LevelCollectionSO levelCollections = Resources.FindObjectsOfTypeAll <LevelCollectionSO>().FirstOrDefault();
            var levels = levelCollections.GetLevelsWithBeatmapCharacteristic(CurrentBeatmapCharacteristicSO);

            //Dictionary<String, LevelSO> levelDict = levels.Select((val, index) => new { LevelId = val.levelID, Level = val }).ToDictionary(i => i.LevelId, i => i.Level);
            Dictionary <String, LevelSO> levelDict = new Dictionary <string, LevelSO>();

            foreach (LevelSO level in levels)
            {
                if (!levelDict.ContainsKey(level.levelID))
                {
                    levelDict.Add(level.levelID, level);
                }
            }

            List <LevelSO> songList = new List <LevelSO>();

            foreach (PlaylistSong ps in this.CurrentPlaylist.Songs)
            {
                if (!String.IsNullOrEmpty(ps.LevelId))
                {
                    if (levelDict.ContainsKey(ps.LevelId))
                    {
                        songList.Add(levelDict[ps.LevelId]);
                    }
                }
                else if (!ps.Key.StartsWith("Level_") && _keyToSong.ContainsKey(ps.Key))
                {
                    songList.Add(_keyToSong[ps.Key]);
                }
            }

            _originalSongs = songList;
            _filteredSongs = _originalSongs;

            Logger.Debug("Playlist filtered song count: {0}", _filteredSongs.Count);
        }
예제 #4
0
	public static void Init(LevelCollectionSO collection) {
		if (!Initialized) {
			Debug.Log("Levels local Path  : " + saveFilePath);
			LevelCollection data = LoadLevelData();
			if (data != null && data.localLevelData != null) {
				LEVELS = new List<LocalLevelData>();
				LEVELS = data.localLevelData;
				Debug.Log("Level Data fetched, updating variables..");
				UpdateLevelVariables(collection);

				Initialized = true;
			} else {
				Debug.LogError("Level Collection type is not attached to resource fetched");
			}
		}
	}
        protected override void DidActivate(bool firstActivation, ActivationType activationType)
        {
            _beatmapCharacteristics  = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>();
            _standardCharacteristics = _beatmapCharacteristics.First(x => x.characteristicName == "Standard");
            _levelCollection         = SongLoader.CustomLevelCollectionSO;

            if (firstActivation)
            {
                _radioNavController = BeatSaberUI.CreateViewController <RoomNavigationController>();
                _radioNavController.didFinishEvent += () => { LeaveChannel(); };

                _inGameViewController = BeatSaberUI.CreateViewController <InGameScreenViewController>();
                _inGameViewController.playPressedEvent += PlayNow_Pressed;

                _nextSongScreenViewController = BeatSaberUI.CreateViewController <NextSongScreenViewController>();
                _nextSongScreenViewController.skipPressedEvent += SkipSong_Pressed;

                _resultsScreenViewController = BeatSaberUI.CreateViewController <ResultsScreenViewController>();
            }


            ProvideInitialViewControllers(_radioNavController, null, null);
        }
예제 #6
0
        protected override void DidActivate(bool firstActivation, ActivationType activationType)
        {
            _beatmapCharacteristics = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>();
            _levelCollection        = SongLoader.CustomLevelCollectionSO;

            if (firstActivation && activationType == ActivationType.AddedToHierarchy)
            {
                _serverHubsViewController = BeatSaberUI.CreateViewController <RoomCreationServerHubsListViewController>();
                _serverHubsViewController.selectedServerHub += ServerHubSelected;
                _serverHubsViewController.didFinishEvent    += () => { didFinishEvent?.Invoke(false); };

                _mainRoomCreationViewController                         = BeatSaberUI.CreateViewController <MainRoomCreationViewController>();
                _mainRoomCreationViewController.CreatedRoom            += CreateRoomPressed;
                _mainRoomCreationViewController.SavePresetPressed      += SavePreset;
                _mainRoomCreationViewController.LoadPresetPressed      += LoadPresetPressed;
                _mainRoomCreationViewController.keyboardDidFinishEvent += _mainRoomCreationViewController_keyboardDidFinishEvent;
                _mainRoomCreationViewController.didFinishEvent         += () => { DismissViewController(_mainRoomCreationViewController); SetLeftScreenViewController(null); };

                _presetsListViewController = BeatSaberUI.CreateViewController <PresetsListViewController>();
                _presetsListViewController.didFinishEvent += _presetsListViewController_didFinishEvent;
            }

            ProvideInitialViewControllers(_serverHubsViewController, null, null);
        }
예제 #7
0
	public static void UpdateLevelVariables(LevelCollectionSO collection) {
		if (collection != null && collection.levels != null) {
			int total_levels = collection.levels.Count;
			for (int i = 0; i < total_levels ; i++) {
				LevelData levelData = collection.levels[i].levelData;
				int index = LEVELS.FindIndex(x => x.id == levelData.id);
				LocalLevelData data = null;
				if (index < 0) {
					data = new LocalLevelData();
					LEVELS.Add(data);
				} else {
					data = LEVELS[index];
				}

				data.id = levelData.id;
				data.sceneName = levelData.sceneName;
				data.maxLives = levelData.maxLives;
				data.difficulty = levelData.difficulty;
			}
			Debug.Log("Level Data Variable Updated");
		} else {
			Debug.LogError("Level collection SO is null");
		}
	}
        protected override void DidActivate(bool firstActivation, ActivationType activationType)
        {
            _beatmapCharacteristics = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>();
            _standardCharacteristic = _beatmapCharacteristics.First(x => x.characteristicName == "Standard");
            _levelCollection        = SongLoader.CustomLevelCollectionSO;

            if (firstActivation && activationType == ActivationType.AddedToHierarchy)
            {
                _lastCharacteristic = _standardCharacteristic;

                _roomManagementViewController = BeatSaberUI.CreateViewController <RoomManagementViewController>();
                _roomManagementViewController.DestroyRoomPressed += DestroyRoomPressed;

                _roomNavigationController = BeatSaberUI.CreateViewController <RoomNavigationController>();
                _roomNavigationController.didFinishEvent += () => { LeaveRoom(); };

                _searchKeyboard = BeatSaberUI.CreateViewController <CustomKeyboardViewController>();
                _searchKeyboard.enterButtonPressed += SearchPressed;
                _searchKeyboard.backButtonPressed  += () => { DismissViewController(_searchKeyboard); };
                _searchKeyboard.allowEmptyInput     = true;
            }

            ProvideInitialViewControllers(_roomNavigationController, _roomManagementViewController, null);
        }
예제 #9
0
        private void SetupTweaks()
        {
            if (initialized || PluginConfig.disableSongListTweaks)
            {
                return;
            }

            Logger.Log("Setting up song list tweaks...");

            _playlistsFlowCoordinator = (new GameObject("PlaylistsFlowCoordinator")).AddComponent <PlaylistsFlowCoordinator>();
            _playlistsFlowCoordinator.didFinishEvent += _playlistsFlowCoordinator_didFinishEvent;

            _beatmapCharacteristics = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>();
            _lastCharacteristic     = _beatmapCharacteristics.First(x => x.characteristicName == "Standard");

            Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSelectionViewController>().First().didSelectBeatmapCharacteristicEvent += (BeatmapCharacteristicSelectionViewController sender, BeatmapCharacteristicSO selected) => { _lastCharacteristic = selected; };

            if (SongLoader.AreSongsLoaded)
            {
                _levelCollection = SongLoader.CustomLevelCollectionSO;
            }
            else
            {
                SongLoader.SongsLoadedEvent += (SongLoader sender, List <CustomLevel> levels) => {
                    _levelCollection = SongLoader.CustomLevelCollectionSO;
                };
            }

            _mainFlowCoordinator = Resources.FindObjectsOfTypeAll <MainFlowCoordinator>().FirstOrDefault();
            _mainFlowCoordinator.GetPrivateField <MainMenuViewController>("_mainMenuViewController").didFinishEvent += SongListTweaks_didFinishEvent;

            _simpleDialog = ReflectionUtil.GetPrivateField <SimpleDialogPromptViewController>(_mainFlowCoordinator, "_simpleDialogPromptViewController");
            _simpleDialog = Instantiate(_simpleDialog.gameObject, _simpleDialog.transform.parent).GetComponent <SimpleDialogPromptViewController>();

            _difficultyViewController = Resources.FindObjectsOfTypeAll <BeatmapDifficultyViewController>().FirstOrDefault();
            _difficultyViewController.didSelectDifficultyEvent += _difficultyViewController_didSelectDifficultyEvent;

            _levelListViewController = Resources.FindObjectsOfTypeAll <LevelListViewController>().FirstOrDefault();
            _levelListViewController.didSelectLevelEvent += _levelListViewController_didSelectLevelEvent;;

            RectTransform _tableViewRectTransform = _levelListViewController.GetComponentsInChildren <RectTransform>().First(x => x.name == "TableViewContainer");

            _tableViewRectTransform.sizeDelta        = new Vector2(0f, -20f);
            _tableViewRectTransform.anchoredPosition = new Vector2(0f, -2.5f);

            RectTransform _pageUp = _tableViewRectTransform.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "PageUpButton");

            _pageUp.anchoredPosition = new Vector2(0f, -1f);

            RectTransform _pageDown = _tableViewRectTransform.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "PageDownButton");

            _pageDown.anchoredPosition = new Vector2(0f, 1f);

            _searchButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(-20f, 36.25f), new Vector2(20f, 6f), SearchPressed, "Search");
            _searchButton.SetButtonTextSize(3f);
            _searchButton.ToggleWordWrapping(false);

            _sortByButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(0f, 36.25f), new Vector2(20f, 6f), () =>
            {
                SelectTopButtons(TopButtonsState.SortBy);
            }, "Sort By");
            _sortByButton.SetButtonTextSize(3f);
            _sortByButton.ToggleWordWrapping(false);

            _playlistsButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(20f, 36.25f), new Vector2(20f, 6f), PlaylistsButtonPressed, "Playlists");
            _playlistsButton.SetButtonTextSize(3f);
            _playlistsButton.ToggleWordWrapping(false);

            _defButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(-20f, 36.25f), new Vector2(20f, 6f), () =>
            {
                SelectTopButtons(TopButtonsState.Select);
                SetLevels(_lastCharacteristic, SortMode.Default, "");
            },
                                                                 "Default");

            _defButton.SetButtonTextSize(3f);
            _defButton.ToggleWordWrapping(false);
            _defButton.gameObject.SetActive(false);

            _newButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(0f, 36.25f), new Vector2(20f, 6f), () =>
            {
                SelectTopButtons(TopButtonsState.Select);
                SetLevels(_lastCharacteristic, SortMode.Newest, "");
            }, "Newest");

            _newButton.SetButtonTextSize(3f);
            _newButton.ToggleWordWrapping(false);
            _newButton.gameObject.SetActive(false);


            _authorButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(20f, 36.25f), new Vector2(20f, 6f), () =>
            {
                SelectTopButtons(TopButtonsState.Select);
                SetLevels(_lastCharacteristic, SortMode.Difficulty, "");
            }, "Difficulty");

            _authorButton.SetButtonTextSize(3f);
            _authorButton.ToggleWordWrapping(false);
            _authorButton.gameObject.SetActive(false);

            _detailViewController = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First(x => x.name == "StandardLevelDetailViewController");
            RectTransform buttonsRect = _detailViewController.GetComponentsInChildren <RectTransform>().First(x => x.name == "Buttons");

            buttonsRect.anchoredPosition = new Vector2(0f, 10.75f);

            RectTransform customButtonsRect = Instantiate(buttonsRect, buttonsRect.parent, true);

            Destroy(customButtonsRect.GetComponent <ContentSizeFitter>());
            Destroy(customButtonsRect.GetComponent <HorizontalLayoutGroup>());

            customButtonsRect.name             = "CustomUIButtonsHolder";
            customButtonsRect.anchoredPosition = new Vector2(0f, 1.25f);

            _favoriteButton = customButtonsRect.GetComponentsInChildren <Button>().First(x => x.name == "PracticeButton");
            _favoriteButton.SetButtonIcon(Base64Sprites.AddToFavorites);
            _favoriteButton.onClick.AddListener(() => {
                if (PluginConfig.favoriteSongs.Any(x => x.Contains(_detailViewController.difficultyBeatmap.level.levelID)))
                {
                    PluginConfig.favoriteSongs.Remove(_detailViewController.difficultyBeatmap.level.levelID);
                    PluginConfig.SaveConfig();
                    _favoriteButton.SetButtonIcon(Base64Sprites.AddToFavorites);
                    PlaylistsCollection.RemoveLevelFromPlaylist(PlaylistsCollection.loadedPlaylists.First(x => x.playlistTitle == "Your favorite songs"), _detailViewController.difficultyBeatmap.level.levelID);
                }
                else
                {
                    PluginConfig.favoriteSongs.Add(_detailViewController.difficultyBeatmap.level.levelID);
                    PluginConfig.SaveConfig();
                    _favoriteButton.SetButtonIcon(Base64Sprites.RemoveFromFavorites);
                    PlaylistsCollection.AddSongToPlaylist(PlaylistsCollection.loadedPlaylists.First(x => x.playlistTitle == "Your favorite songs"), new PlaylistSong()
                    {
                        levelId = _detailViewController.difficultyBeatmap.level.levelID, songName = _detailViewController.difficultyBeatmap.level.songName, level = SongDownloader.GetLevel(_detailViewController.difficultyBeatmap.level.levelID)
                    });
                }
            });

            _deleteButton = customButtonsRect.GetComponentsInChildren <Button>().First(x => x.name == "PlayButton");
            _deleteButton.SetButtonText("Delete");
            _deleteButton.ToggleWordWrapping(false);
            _deleteButton.onClick.AddListener(DeletePressed);
            _deleteButton.GetComponentsInChildren <RectTransform>().First(x => x.name == "GlowContainer").gameObject.SetActive(false);
            _deleteButton.interactable = !PluginConfig.disableDeleteButton;

            //based on https://github.com/halsafar/BeatSaberSongBrowser/blob/master/SongBrowserPlugin/UI/Browser/SongBrowserUI.cs#L192
            var statsPanel     = _detailViewController.GetComponentsInChildren <CanvasRenderer>(true).First(x => x.name == "LevelParamsPanel");
            var statTransforms = statsPanel.GetComponentsInChildren <RectTransform>();
            var valueTexts     = statsPanel.GetComponentsInChildren <TextMeshProUGUI>().Where(x => x.name == "ValueText").ToList();

            foreach (RectTransform r in statTransforms)
            {
                if (r.name == "Separator")
                {
                    continue;
                }
                r.sizeDelta = new Vector2(r.sizeDelta.x * 0.85f, r.sizeDelta.y * 0.85f);
            }

            var _starStatTransform = Instantiate(statTransforms[1], statsPanel.transform, false);

            _starStatText = _starStatTransform.GetComponentInChildren <TextMeshProUGUI>();
            _starStatTransform.GetComponentInChildren <UnityEngine.UI.Image>().sprite = Base64Sprites.StarFull;
            _starStatText.text = "--";

            initialized = true;
        }
예제 #10
0
        void SelectAndLoadSong(string name, string difficulty)
        {
            //try
            //{
            //    mainMenuViewController.HandleMenuButton(MainMenuViewController.MenuButton.SoloFreePlay);
            //}
            //catch (Exception e)
            //{

            //}
            //try
            //{
            //    soloModeSelectionViewController.HandleMenuButton(SoloModeSelectionViewController.MenuType.FreePlayMode);
            //}
            //catch (Exception e)
            //{

            //}
            LevelCollectionSO _levelCollection = SongLoader.CustomLevelCollectionSO;
            LevelSO           level            = _levelCollection.GetLevelsWithBeatmapCharacteristic(Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>().First(x => x.characteristicName == "Standard")).First(x => x.songName == name);

            //level = listViewController.GetPrivateField<IBeatmapLevel[]>("_levels").Where(x => x.songName == name)// && x.songAuthorName == author && x.songSubName == subname)
            //    .ToList().ElementAt(0);



            Console.WriteLine("Song found:" + level.songName);

            difficultyLevel = level.GetDifficultyBeatmap(_difficulties[difficulty]);
            //////////////////////////////////////////////////////////////////
            //            THING TO GET SONG BY JUST STARTING IT             //
            //////////////////////////////////////////////////////////////////
            GameplayModifiers gameplayModifiers = new GameplayModifiers();

            gameplayModifiers.ResetToDefault();
            gameplayModifiers.noFail = true;
            PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings;

            var practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings);

            practiceSettings.startSongTime = time;
            practiceSettings.songSpeedMul  = playbackSpeed;

            MenuSceneSetupDataSO menu   = Resources.FindObjectsOfTypeAll <MenuSceneSetupDataSO>().First();
            SongLoader           loader = Resources.FindObjectsOfTypeAll <SongLoader>().First();

            loader.LoadAudioClipForLevel((CustomLevel)level, delegate(CustomLevel customLevel)
            {
                menu.StartStandardLevel(difficultyLevel, gameplayModifiers, playerSettings, practiceSettings, null, null);
            });

            ///////////////////////////////////////////////////////////////////
            //          THING TO GET SONG BY NAVIGATING THROUGH MENUS        //
            ///////////////////////////////////////////////////////////////////
            //MenuSceneSetupDataSO menu = Resources.FindObjectsOfTypeAll<MenuSceneSetupDataSO>().First();

            //soloFreePlayFlowCoordinator.HandleLevelListViewControllerDidSelectLevel(listViewController, level);
            //levelListView.SelectAndScrollToLevel(level.levelID);
            //int row = levelListView.RowNumberForLevelID(level.levelID);
            //levelListView.HandleDidSelectRowEvent(levelListView.GetPrivateField<TableView>("_tableView"), row);
            //try
            //{

            //    DifficultyTableView difficultyTableView = beatmapDifficultyViewController.GetPrivateField<DifficultyTableView>("_difficultyTableView");
            //    TableView tableView = difficultyTableView.GetPrivateField<TableView>("_tableView");
            //    difficultyTableView.HandleDidSelectRowEvent(tableView, 0);
            //    tableView.SelectRow(0);
            //    difficultyTableView.SelectRow(difficultyLevel, false);
            //    soloFreePlayFlowCoordinator.HandleDifficultyViewControllerDidSelectDifficulty(beatmapDifficultyViewController, difficultyLevel);

            //    practiceController.Init(level, new PracticeSettings());

            //    GameplayModifiers gameplayModifiers = new GameplayModifiers();
            //    gameplayModifiers.ResetToDefault();
            //    gameplayModifiers.noFail = true;

            //    gameplaySetupViewController.SetData(gameplaySetupViewController.playerSettings, gameplayModifiers);
            //    soloFreePlayFlowCoordinator.HandleLevelDetailViewControllerDidPressPracticeButton(detailViewController);
            //    Console.WriteLine("loading " + difficultyLevel.level.songName);
            //    detailViewController.PracticeButtonPressed();

            //    if (!autoPlayBuffer && time > 2)
            //    {   // pause on start
            //        practiceController.HandleSongStartScrollbarOnValueChanged(time - 2);
            //    }
            //    else
            //    {   // autoplay or negative time will f**k it up
            //        practiceController.HandleSongStartScrollbarOnValueChanged(time);
            //    }
            //    Console.WriteLine("Starting song at: " + practiceController.GetPrivateField<PracticeSettings>("_practiceSettings").startSongTime);
            //    practiceController.PlayButtonPressed();
            //    soloFreePlayFlowCoordinator.HandlePracticeViewControllerDidPressPlayButton();
            //}
            //catch (Exception e)
            //{
            //    Console.WriteLine(e);
            //    //Console.WriteLine(e.StackTrace);
            //}
            //finally
            //{
            //    Console.WriteLine("[Mediocre Loader] Finally");
            //}

            //mainGameSceneSetupData.TransitionToScene(0.7f);
        }
        /// <summary>
        /// Get the song cache from the game.
        /// </summary>
        public void UpdateSongLists(BeatmapCharacteristicSO gameplayMode)
        {
            // give up
            if (gameplayMode == null)
            {
                Logger.Debug("Always null first time if user waits for SongLoader event, which they should...");
                return;
            }

            Stopwatch timer = new Stopwatch();

            timer.Start();

            // Get the level collection from song loader
            LevelCollectionSO levelCollections = Resources.FindObjectsOfTypeAll <LevelCollectionSO>().FirstOrDefault();

            // Stash everything we need
            _originalSongs = levelCollections.GetLevelsWithBeatmapCharacteristic(gameplayMode).ToList();

            Logger.Debug("Got {0} songs from level collections...", _originalSongs.Count);
            //_originalSongs.ForEach(x => Logger.Debug("{0} by {1} = {2}", x.name, x.levelAuthorName, x.levelID));

            _sortedSongs = _originalSongs;
            CurrentBeatmapCharacteristicSO = gameplayMode;

            // Calculate some information about the custom song dir
            String customSongsPath                   = Path.Combine(Environment.CurrentDirectory, CUSTOM_SONGS_DIR);
            String revSlashCustomSongPath            = customSongsPath.Replace('\\', '/');
            double currentCustomSongDirLastWriteTIme = (File.GetLastWriteTimeUtc(customSongsPath) - EPOCH).TotalMilliseconds;
            bool   customSongDirChanged              = false;

            if (_customSongDirLastWriteTime != currentCustomSongDirLastWriteTIme)
            {
                customSongDirChanged        = true;
                _customSongDirLastWriteTime = currentCustomSongDirLastWriteTIme;
            }

            // This operation scales well
            if (!Directory.Exists(customSongsPath))
            {
                Logger.Error("CustomSong directory is missing...");
                return;
            }
            IEnumerable <string> directories = Directory.EnumerateDirectories(customSongsPath, "*.*", SearchOption.AllDirectories);

            // Get LastWriteTimes
            Stopwatch lastWriteTimer = new Stopwatch();

            lastWriteTimer.Start();
            foreach (var level in SongLoader.CustomLevels)
            {
                // If we already know this levelID, don't both updating it.
                // SongLoader should filter duplicates but in case of failure we don't want to crash

                if (!_cachedLastWriteTimes.ContainsKey(level.levelID) || customSongDirChanged)
                {
                    _cachedLastWriteTimes[level.levelID] = (File.GetLastWriteTimeUtc(level.customSongInfo.path) - EPOCH).TotalMilliseconds;
                }

                if (!_levelIdToCustomLevel.ContainsKey(level.levelID))
                {
                    _levelIdToCustomLevel.Add(level.levelID, level);
                }

                if (!_levelIdToSongVersion.ContainsKey(level.levelID))
                {
                    DirectoryInfo info = new DirectoryInfo(level.customSongInfo.path);
                    string        currentDirectoryName = info.Name;

                    String version = level.customSongInfo.path.Replace(revSlashCustomSongPath, "").Replace(currentDirectoryName, "").Replace("/", "");
                    if (!String.IsNullOrEmpty(version))
                    {
                        //Logger.Debug("MATCH");
                        _levelIdToSongVersion.Add(level.levelID, version);
                        _keyToSong.Add(version, level);
                    }
                }
            }

            lastWriteTimer.Stop();
            Logger.Info("Determining song download time and determining mappings took {0}ms", lastWriteTimer.ElapsedMilliseconds);

            // Update song Infos, directory tree, and sort
            this.UpdateScoreSaberDataMapping();
            this.UpdatePlayCounts();
            this.UpdateDirectoryTree(customSongsPath);

            // Check if we need to upgrade settings file favorites
            try
            {
                this.Settings.ConvertFavoritesToPlaylist(_levelIdToCustomLevel, _levelIdToSongVersion);
            }
            catch (Exception e)
            {
                Logger.Exception("FAILED TO CONVERT FAVORITES TO PLAYLIST!", e);
            }

            // load the current editing playlist or make one
            if (!String.IsNullOrEmpty(this.Settings.currentEditingPlaylistFile))
            {
                CurrentEditingPlaylist = PlaylistsReader.ParsePlaylist(this.Settings.currentEditingPlaylistFile);
            }

            if (CurrentEditingPlaylist == null)
            {
                CurrentEditingPlaylist = new Playlist
                {
                    Title  = "Song Browser Favorites",
                    Author = "SongBrowserPlugin",
                    Path   = this.Settings.currentEditingPlaylistFile,
                    Image  = Base64Sprites.PlaylistIconB64,
                    Songs  = new List <PlaylistSong>(),
                };
            }

            CurrentEditingPlaylistLevelIds = new HashSet <string>();
            foreach (PlaylistSong ps in CurrentEditingPlaylist.Songs)
            {
                CurrentEditingPlaylistLevelIds.Add(ps.LevelId);
            }

            // Actually sort and filter
            this.ProcessSongList();

            // Signal complete
            if (SongLoader.CustomLevels.Count > 0)
            {
                didFinishProcessingSongs?.Invoke(SongLoader.CustomLevels);
            }

            timer.Stop();

            Logger.Info("Updating songs infos took {0}ms", timer.ElapsedMilliseconds);
            Logger.Debug("Song Browser knows about {0} songs from SongLoader...", _originalSongs.Count);
        }