/// <summary>
        /// Select a level collection.
        /// </summary>
        /// <param name="levelCollectionName"></param>
        public void SelectLevelCollection(String levelCollectionName)
        {
            Logger.Trace("SelectLevelCollection({0})", levelCollectionName);

            try
            {
                IAnnotatedBeatmapLevelCollection collection = GetLevelCollectionByName(levelCollectionName);

                if (collection == null)
                {
                    Logger.Debug("Could not locate requested level collection...");
                    return;
                }

                Logger.Info("Selecting level collection: {0}", collection.collectionName);

                LevelFilteringNavigationController.SelectBeatmapLevelPackOrPlayList(collection as IBeatmapLevelPack, collection as IPlaylist);
                LevelFilteringNavigationController.TabBarDidSwitch();

                Logger.Debug("Done selecting level collection!");
            }
            catch (Exception e)
            {
                Logger.Exception(e);
            }
        }
        /// <summary>
        /// Select a level pack.
        /// </summary>
        /// <param name="levelPackId"></param>
        public void SelectLevelPack(String levelPackId)
        {
            Logger.Trace("SelectLevelPack({0})", levelPackId);

            try
            {
                var levelPacks = GetLevelPackCollection();
                var index      = GetLevelPackIndexByPackId(levelPackId);
                var pack       = GetLevelPackByPackId(levelPackId);

                if (index < 0)
                {
                    Logger.Debug("Cannot select level packs yet...");
                    return;
                }

                Logger.Info("Selecting level pack index: {0}", pack.packName);
                var tableView = LevelPacksTableView.GetPrivateField <TableView>("_tableView");

                LevelPacksTableView.SelectCellWithIdx(index);
                tableView.SelectCellWithIdx(index, true);
                tableView.ScrollToCellWithIdx(0, TableViewScroller.ScrollPositionType.Beginning, false);
                for (int i = 0; i < index; i++)
                {
                    tableView.GetPrivateField <TableViewScroller>("_scroller").PageScrollDown();
                }

                Logger.Debug("Done selecting level pack!");
            }
            catch (Exception e)
            {
                Logger.Exception(e);
            }
        }
        /// <summary>
        /// Get a copy of the unfiltered, unsorted list of songs from level packs.
        /// </summary>
        public void UpdateLevelPackOriginalLists(bool refreshOnlyUnknown)
        {
            BeatmapLevelPackSO[] levelPacks = Resources.FindObjectsOfTypeAll <BeatmapLevelPackSO>();
            foreach (BeatmapLevelPackSO levelPack in levelPacks)
            {
                Logger.Debug("Attempting to get song list from levelPack: {0}...", levelPack);
                var beatmapLevelPack = levelPack as BeatmapLevelPackSO;

                // TODO - need to rethink interface here, not all level packs can be cast this high, some sort functions need it.
                //      - this helps prevent DLC from breaking everything
                if (beatmapLevelPack == null)
                {
                    continue;
                }

                if (refreshOnlyUnknown && _levelPackToSongs.ContainsKey(levelPack.packName))
                {
                    Logger.Debug("Already know about {0}, not refreshing...", levelPack.packName);
                    continue;
                }

                _levelPackToSongs[levelPack.packName] = (beatmapLevelPack.beatmapLevelCollection as BeatmapLevelCollectionSO).GetPrivateField <BeatmapLevelSO[]>("_beatmapLevels").ToList();
                Logger.Debug("Got {0} songs from level collections...", _levelPackToSongs[levelPack.packName].Count);
                //_levelPackToSongs[levelPack.packName].ForEach(x => Logger.Debug("{0} by {1} = {2}", x.name, x.levelAuthorName, x.levelID));
            }
        }
        /// <summary>
        /// Callback, invoked when the data property is accessed.
        /// </summary>
        protected override byte[] GetData()
        {
            if (!isDone)
            {
                Logger.Error("{0}Downloading is not completed : {1}", kLog, m_WebRequest.url);
                throw new InvalidOperationException("Downloading is not completed. " + m_WebRequest.url);
            }
            else if (m_Buffer == null)
            {
                // Etag cache hit!
                if (m_WebRequest.responseCode == 304)
                {
                    Logger.Debug("<color=green>{0}Etag cache hit : {1}</color>", kLog, m_WebRequest.url);
                    m_Buffer = LoadCache(m_WebRequest.url);
                }
                // Download is completed successfully.
                else if (m_WebRequest.responseCode == 200)
                {
                    Logger.Debug("<color=green>{0}Download is completed successfully : {1}</color>", kLog, m_WebRequest.url);
                    m_Buffer = m_Stream.GetBuffer();
                    SaveCache(m_WebRequest.url, m_WebRequest.GetResponseHeader("Etag"), m_Buffer);
                }
            }

            if (m_Stream != null)
            {
                m_Stream.Dispose();
                m_Stream = null;
            }
            return(m_Buffer);
        }
Пример #5
0
        /// <summary>
        /// Select a level pack.
        /// </summary>
        /// <param name="levelPackId"></param>
        public void SelectLevelPack(String levelPackId)
        {
            Logger.Trace("SelectLevelPack({0})", levelPackId);

            try
            {
                //var levelPacks = GetLevelPackCollection();
                IBeatmapLevelPack pack = GetLevelPackByPackId(levelPackId);

                if (pack == null)
                {
                    Logger.Debug("Could not locate requested level pack...");
                    return;
                }

                Logger.Info("Selecting level pack: {0}", pack.packID);

                LevelFilteringNavigationController.SelectBeatmapLevelPackOrPlayList(pack, null);
                LevelFilteringNavigationController.TabBarDidSwitch();

                Logger.Debug("Done selecting level pack!");
            }
            catch (Exception e)
            {
                Logger.Exception(e);
            }
        }
Пример #6
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);
        }
        /// <summary>
        /// Overwrite the current level pack.
        /// </summary>
        private void OverwriteCurrentLevelPack()
        {
            Logger.Debug("Overwriting levelPack [{0}] beatmapLevelCollection", this._currentLevelPack);
            IBeatmapLevelPack levelPack = this._currentLevelPack;
            var levels = _sortedSongs.ToArray();

            ReflectionUtil.SetPrivateField(levelPack.beatmapLevelCollection, "_beatmapLevels", levels);
        }
        /// <summary>
        /// Load the settings file for this plugin.
        /// If we fail to load return Default settings.
        /// </summary>
        /// <returns>SongBrowserSettings</returns>
        public static SongBrowserSettings Load()
        {
            Logger.Trace("Load()");
            SongBrowserSettings retVal = null;

            // No Settings file.
            String settingsFilePath = SongBrowserSettings.SettingsPath();

            if (File.Exists(settingsFilePath))
            {
                // Deserialization from JSON
                FileStream fs = null;
                try
                {
                    fs = File.OpenRead(settingsFilePath);
                    XmlSerializer serializer = new XmlSerializer(typeof(SongBrowserSettings));
                    retVal = (SongBrowserSettings)serializer.Deserialize(fs);

                    // Success loading, sane time to make a backup
                    retVal.SaveBackup();
                }
                catch (Exception e)
                {
                    Logger.Exception("Unable to deserialize song browser settings file, using default settings: ", e);
                    retVal = new SongBrowserSettings
                    {
                        DisableSavingSettings = true
                    };
                }
                finally
                {
                    if (fs != null)
                    {
                        fs.Close();
                    }
                }
            }
            else
            {
                Logger.Debug("Settings file does not exist, returning defaults: " + settingsFilePath);
                retVal = new SongBrowserSettings();
            }

            // check if the playlist directory exists, make it otherwise.
            String playlistDirPath = Path.Combine(Environment.CurrentDirectory, "Playlists");

            if (!Directory.Exists(playlistDirPath))
            {
                Directory.CreateDirectory(playlistDirPath);
            }

            MigrateFavorites();
            ApplyFixes(retVal);

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

            _levelPackToSongs[levelPack.packName].RemoveAll(x => x.levelID == levelId);
        }
        /// <summary>
        /// Scroll to a level by Row
        /// </summary>
        /// <param name="selectedIndex"></param>
        public void ScrollToLevelByRow(int selectedIndex)
        {
            Logger.Debug("Scrolling level list to idx: {0}", selectedIndex);

            TableView tableView = LevelPackLevelsTableView.GetPrivateField <TableView>("_tableView");

            LevelPackLevelsTableView.HandleDidSelectRowEvent(tableView, selectedIndex);
            tableView.ScrollToCellWithIdx(selectedIndex, TableViewScroller.ScrollPositionType.Beginning, true);
            tableView.SelectCellWithIdx(selectedIndex);
        }
Пример #11
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();
        }
        /// <summary>
        /// Get Current levels from current level collection.
        /// </summary>
        /// <returns></returns>
        public IPreviewBeatmapLevel[] GetCurrentLevelCollectionLevels()
        {
            var levelCollection = GetCurrentSelectedAnnotatedBeatmapLevelCollection();

            if (levelCollection == null)
            {
                Logger.Debug("Current selected level collection is null for some reason...");
                return(null);
            }
            return(SongBrowserModel.GetLevelsForLevelCollection(levelCollection));
        }
Пример #13
0
        /// <summary>
        /// Get Current levels from current level pack.
        /// </summary>
        /// <returns></returns>
        public IPreviewBeatmapLevel[] GetCurrentLevelPackLevels()
        {
            var levelPack = GetCurrentSelectedLevelPack();

            if (levelPack == null)
            {
                Logger.Debug("Current selected level pack is null for some reason...");
                return(null);
            }

            return(levelPack.beatmapLevelCollection.beatmapLevels);
        }
        /// <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();
        }
Пример #15
0
        /// <summary>
        /// Creates a copy of a template button and returns it.
        /// </summary>
        /// <param name="parent">The transform to parent the button to.</param>
        /// <param name="buttonTemplate">The name of the button to make a copy of. Example: "QuitButton", "PlayButton", etc.</param>
        /// <param name="anchoredPosition">The position the button should be anchored to.</param>
        /// <param name="sizeDelta">The size of the buttons RectTransform.</param>
        /// <param name="onClick">Callback for when the button is pressed.</param>
        /// <param name="buttonText">The text that should be shown on the button.</param>
        /// <param name="icon">The icon that should be shown on the button.</param>
        /// <returns>The newly created button.</returns>
        public static Button CreateUIButton(String name, RectTransform parent, string buttonTemplate, Vector2 anchoredPosition, Vector2 sizeDelta, UnityAction onClick = null, string buttonText = "BUTTON")
        {
            Logger.Debug("CreateUIButton({0}, {1}, {2}, {3}, {4}", name, parent, buttonTemplate, anchoredPosition, sizeDelta);
            Button btn = CreateBaseButton(name, parent, buttonTemplate);

            btn.gameObject.SetActive(true);

            Polyglot.LocalizedTextMeshProUGUI localizer = btn.GetComponentInChildren <Polyglot.LocalizedTextMeshProUGUI>();
            if (localizer != null)
            {
                GameObject.Destroy(localizer);
            }
            BeatSaberMarkupLanguage.Components.ExternalComponents externalComponents = btn.gameObject.AddComponent <BeatSaberMarkupLanguage.Components.ExternalComponents>();
            TextMeshProUGUI textMesh = btn.GetComponentInChildren <TextMeshProUGUI>();

            textMesh.richText = true;
            externalComponents.components.Add(textMesh);

            var contentTransform = btn.transform.Find("Content").GetComponent <LayoutElement>();

            if (contentTransform != null)
            {
                GameObject.Destroy(contentTransform);
            }

            ContentSizeFitter buttonSizeFitter = btn.gameObject.AddComponent <ContentSizeFitter>();

            buttonSizeFitter.verticalFit   = ContentSizeFitter.FitMode.PreferredSize;
            buttonSizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;

            LayoutGroup stackLayoutGroup = btn.GetComponentInChildren <LayoutGroup>();

            if (stackLayoutGroup != null)
            {
                externalComponents.components.Add(stackLayoutGroup);
            }

            btn.onClick.RemoveAllListeners();
            if (onClick != null)
            {
                btn.onClick.AddListener(onClick);
            }

            (btn.transform as RectTransform).anchorMin        = new Vector2(0.5f, 0.5f);
            (btn.transform as RectTransform).anchorMax        = new Vector2(0.5f, 0.5f);
            (btn.transform as RectTransform).anchoredPosition = anchoredPosition;
            (btn.transform as RectTransform).sizeDelta        = sizeDelta;

            btn.SetButtonText(buttonText);

            return(btn);
        }
Пример #16
0
        public bool SelectLevelCategory(String levelCategoryName)
        {
            Logger.Trace("SelectLevelCategory({0})", levelCategoryName);

            try
            {
                if (String.IsNullOrEmpty(levelCategoryName))
                {
                    // hack for now, just assume custom levels if a user has an old settings file, corrects itself first time they change level packs.
                    levelCategoryName = SelectLevelCategoryViewController.LevelCategory.CustomSongs.ToString();
                }

                SelectLevelCategoryViewController.LevelCategory category;
                try
                {
                    category = (SelectLevelCategoryViewController.LevelCategory)Enum.Parse(typeof(SelectLevelCategoryViewController.LevelCategory), levelCategoryName, true);
                }
                catch (Exception)
                {
                    // invalid input
                    return(false);
                }

                if (category == LevelFilteringNavigationController.selectedLevelCategory)
                {
                    Logger.Debug($"Level category [{category}] is already selected");
                    return(false);
                }

                Logger.Info("Selecting level category: {0}", levelCategoryName);

                var selectLeveCategoryViewController = LevelFilteringNavigationController.GetComponentInChildren <SelectLevelCategoryViewController>();
                var iconSegementController           = selectLeveCategoryViewController.GetComponentInChildren <IconSegmentedControl>();

                int selectCellNumber = (from x in selectLeveCategoryViewController.GetField <SelectLevelCategoryViewController.LevelCategoryInfo[], SelectLevelCategoryViewController>("_levelCategoryInfos")
                                        select x.levelCategory).ToList().IndexOf(category);

                iconSegementController.SelectCellWithNumber(selectCellNumber);
                selectLeveCategoryViewController.LevelFilterCategoryIconSegmentedControlDidSelectCell(iconSegementController, selectCellNumber);
                LevelFilteringNavigationController.UpdateSecondChildControllerContent(category);
                //AnnotatedBeatmapLevelCollectionsViewController.RefreshAvailability();

                Logger.Debug("Done selecting level category.");

                return(true);
            } catch (Exception e)
            {
                Logger.Exception(e);
            }

            return(false);
        }
Пример #17
0
        /// <summary>
        /// Adjust button background color.
        /// </summary>
        /// <param name="button"></param>
        /// <param name="background"></param>
        static public void SetButtonBackground(Button button, Sprite background)
        {
            Image img = button.GetComponentsInChildren <Image>().FirstOrDefault(x => x.name == "BG");

            if (img != null)
            {
                img.sprite = background;
            }
            else
            {
                Logger.Debug("NULL BG");
            }
        }
Пример #18
0
        /// <summary>
        /// Scroll to a level by Row
        /// </summary>
        /// <param name="selectedIndex"></param>
        public void ScrollToLevelByRow(int selectedIndex)
        {
            Logger.Debug("Scrolling level list to idx: {0}", selectedIndex);

            TableView tableView = LevelCollectionTableView.GetPrivateField <TableView>("_tableView");

            if (LevelCollectionTableView.selectedRow != selectedIndex && LevelCollectionTableView.isActiveAndEnabled)
            {
                LevelCollectionTableView.HandleDidSelectRowEvent(tableView, selectedIndex);
            }
            tableView.ScrollToCellWithIdx(selectedIndex, TableViewScroller.ScrollPositionType.Beginning, true);
            tableView.SelectCellWithIdx(selectedIndex);
        }
        /// <summary>
        /// Scroll TableView to proper row, fire events.
        /// </summary>
        /// <param name="table"></param>
        /// <param name="levelID"></param>
        public void SelectAndScrollToLevel(string levelID)
        {
            Logger.Debug("Scrolling to LevelID: {0}", levelID);

            // Check once per load
            if (!_checkedForTwitchPlugin)
            {
                Logger.Info("Checking for BeatSaber Twitch Integration Plugin...");
                _detectedTwitchPluginQueue = Resources.FindObjectsOfTypeAll <HMUI.ViewController>().Any(x => x.name == "RequestInfo");
                Logger.Info("BeatSaber Twitch Integration plugin detected: " + _detectedTwitchPluginQueue);

                _checkedForTwitchPlugin = true;
            }

            // Skip scrolling to level if twitch plugin has queue active.
            if (_detectedTwitchPluginQueue)
            {
                Logger.Debug("Skipping SelectAndScrollToLevel() because we detected Twitch Integration Plugin has a Queue active...");
                return;
            }

            // try to find the index and scroll to it
            int selectedIndex = 0;
            List <IPreviewBeatmapLevel> levels = GetCurrentLevelCollectionLevels().ToList();

            if (levels.Count <= 0)
            {
                return;
            }

            // acquire the index or try the last row
            selectedIndex = levels.FindIndex(x => x.levelID == levelID);
            if (selectedIndex < 0)
            {
                // this might look like an off by one error but the _level list we keep is missing the header entry BeatSaber.
                // so the last row is +1 the max index, the count.
                int maxCount = levels.Count;

                int selectedRow = LevelCollectionTableView.GetPrivateField <int>("_selectedRow");

                Logger.Debug("Song is not in the level pack, cannot scroll to it...  Using last known row {0}/{1}", selectedRow, maxCount);
                selectedIndex = Math.Min(maxCount, selectedRow);
            }
            else
            {
                // the header counts as an index, so if the index came from the level array we have to add 1.
                selectedIndex += 1;
            }

            ScrollToLevelByRow(selectedIndex);
        }
        /// <summary>
        /// Get path for web-caching.
        /// </summary>
        public static string GetCachePath(string url)
        {
            if (s_WebCachePath == null)
            {
                s_WebCachePath = Application.temporaryCachePath + "/WebCache/";
                Logger.Debug("{0}WebCachePath : {1}", kLog, s_WebCachePath);
            }

            if (!Directory.Exists(s_WebCachePath))
            {
                Directory.CreateDirectory(s_WebCachePath);
            }

            return(s_WebCachePath + Convert.ToBase64String(s_SHA1.ComputeHash(UTF8Encoding.Default.GetBytes(url))).Replace('/', '_'));
        }
Пример #21
0
        /// <summary>
        /// Resets all the level packs back to their original values.
        /// </summary>
        /// <param name="pack"></param>
        private void ResetLevelPacks()
        {
            Logger.Debug("Setting level packs back to their original values!");

            BeatmapLevelPackSO[] levelPacks = Resources.FindObjectsOfTypeAll <BeatmapLevelPackSO>();
            foreach (BeatmapLevelPackSO levelPack in levelPacks)
            {
                if (levelPack.packName == null || !_levelPackToSongs.ContainsKey(levelPack.packName))
                {
                    Logger.Debug("We know nothing about pack: {0}", levelPack.packName);
                    continue;
                }

                var levels = _levelPackToSongs[levelPack.packName].ToArray();
                ReflectionUtil.SetPrivateField(levelPack.beatmapLevelCollection, "_beatmapLevels", levels);
            }
        }
Пример #22
0
        private List <BeatmapLevelSO> 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...");
                this.Settings.filterMode = SongFilterMode.None;
                return(null);
            }

            // Get song keys
            PlaylistsCollection.MatchSongsForPlaylist(this.CurrentPlaylist, true);

            Logger.Debug("Filtering songs for playlist: {0}", this.CurrentPlaylist.playlistTitle);

            Dictionary <String, BeatmapLevelSO> levelDict = new Dictionary <string, BeatmapLevelSO>();

            foreach (KeyValuePair <string, List <BeatmapLevelSO> > entry in _levelPackToSongs)
            {
                foreach (BeatmapLevelSO level in entry.Value)
                {
                    if (!levelDict.ContainsKey(level.levelID))
                    {
                        levelDict.Add(level.levelID, level);
                    }
                }
            }

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

            foreach (PlaylistSong ps in this.CurrentPlaylist.songs)
            {
                if (ps.level != null)
                {
                    songList.Add(levelDict[ps.level.levelID]);
                }
                else
                {
                    Logger.Debug("Could not find song in playlist: {0}", ps.songName);
                }
            }

            Logger.Debug("Playlist filtered song count: {0}", songList.Count);
            return(songList);
        }
Пример #23
0
        /// <summary>
        /// Create an icon button, simple.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="buttonTemplate"></param>
        /// <param name="iconSprite"></param>
        /// <returns></returns>
        public static Button CreateIconButton(String name, RectTransform parent, String buttonTemplate, Vector2 anchoredPosition, Vector2 sizeDelta, UnityAction onClick, Sprite icon)
        {
            Logger.Debug("CreateIconButton({0}, {1}, {2}, {3}, {4}", name, parent, buttonTemplate, anchoredPosition, sizeDelta);
            Button btn = CreateIconButton(name, parent, buttonTemplate, icon);

            (btn.transform as RectTransform).anchorMin        = new Vector2(0.5f, 0.5f);
            (btn.transform as RectTransform).anchorMax        = new Vector2(0.5f, 0.5f);
            (btn.transform as RectTransform).anchoredPosition = anchoredPosition;
            (btn.transform as RectTransform).sizeDelta        = sizeDelta;

            btn.onClick.RemoveAllListeners();
            if (onClick != null)
            {
                btn.onClick.AddListener(onClick);
            }

            return(btn);
        }
        /// <summary>
        /// Try to refresh the song list.  Broken for now.
        /// </summary>
        public void RefreshSongList(string currentSelectedLevelId, bool scrollToLevel = true)
        {
            Logger.Info("Refreshing the song list view.");
            try
            {
                var levels = GetCurrentLevelCollectionLevels();
                if (levels == null)
                {
                    Logger.Info("Nothing to refresh yet.");
                    return;
                }

                Logger.Debug("Checking if TableView is initialized...");
                TableView tableView     = LevelCollectionTableView.GetPrivateField <TableView>("_tableView");
                bool      tableViewInit = tableView.GetPrivateField <bool>("_isInitialized");

                Logger.Debug("Reloading SongList TableView");
                tableView.ReloadData();

                Logger.Debug("Attempting to scroll to level [{0}]", currentSelectedLevelId);
                String selectedLevelID = currentSelectedLevelId;
                if (!String.IsNullOrEmpty(currentSelectedLevelId))
                {
                    selectedLevelID = currentSelectedLevelId;
                }
                else
                {
                    if (levels.Length > 0)
                    {
                        Logger.Debug("Currently selected level ID does not exist, picking the first...");
                        selectedLevelID = levels.FirstOrDefault().levelID;
                    }
                }

                if (scrollToLevel)
                {
                    SelectAndScrollToLevel(selectedLevelID);
                }
            }
            catch (Exception e)
            {
                Logger.Exception("Exception refreshing song list:", e);
            }
        }
Пример #25
0
        /// <summary>
        /// Wait for score saber related files to download.
        /// </summary>
        /// <returns></returns>
        private IEnumerator WaitForDownload()
        {
            if (ScoreSaberDatabaseDownloader.ScoreSaberDataFile != null)
            {
                Logger.Info("Using cached copy of ScoreSaberData...");
            }
            else
            {
                SongBrowserApplication.MainProgressBar.ShowMessage("Downloading BeatStar data...", 5.0f);

                Logger.Info("Attempting to download: {0}", ScoreSaberDatabaseDownloader.SCRAPED_SCORE_SABER_JSON_URL);
                using (UnityWebRequest www = UnityWebRequest.Get(ScoreSaberDatabaseDownloader.SCRAPED_SCORE_SABER_JSON_URL))
                {
                    // Use 4MB cache, large enough for this file to grow for awhile.
                    www.SetCacheable(new CacheableDownloadHandlerScoreSaberData(www, _buffer));
                    yield return(www.SendWebRequest());

                    Logger.Debug("Returned from web request!...");

                    try
                    {
                        ScoreSaberDatabaseDownloader.ScoreSaberDataFile = (www.downloadHandler as CacheableDownloadHandlerScoreSaberData).ScoreSaberDataFile;
                        Logger.Info("Success downloading ScoreSaber data!");

                        SongBrowserApplication.MainProgressBar.ShowMessage("Success downloading BeatStar data...", 5.0f);
                        onScoreSaberDataDownloaded?.Invoke();
                    }
                    catch (System.InvalidOperationException)
                    {
                        Logger.Error("Failed to download ScoreSaber data file...");
                    }
                    catch (Exception e)
                    {
                        Logger.Exception("Exception trying to download ScoreSaber data file...", e);
                    }
                }
            }
        }
        /// <summary>
        /// Try to refresh the song list.  Broken for now.
        /// </summary>
        public void RefreshSongList(string currentSelectedLevelId, bool scrollToLevel = true)
        {
            Logger.Info("Refreshing the song list view.");
            try
            {
                var levels = GetCurrentLevelPackLevels();

                Logger.Debug("Checking if TableView is initialized...");
                TableView tableView     = ReflectionUtil.GetPrivateField <TableView>(LevelPackLevelsTableView, "_tableView");
                bool      tableViewInit = ReflectionUtil.GetPrivateField <bool>(tableView, "_isInitialized");

                Logger.Debug("Reloading SongList TableView");
                tableView.ReloadData();

                Logger.Debug("Attempting to scroll to level...");
                String selectedLevelID = currentSelectedLevelId;
                if (!String.IsNullOrEmpty(currentSelectedLevelId))
                {
                    selectedLevelID = currentSelectedLevelId;
                }
                else
                {
                    if (levels.Length > 0)
                    {
                        selectedLevelID = levels.FirstOrDefault().levelID;
                    }
                }

                if (scrollToLevel)
                {
                    SelectAndScrollToLevel(LevelPackLevelsTableView, selectedLevelID);
                }
            }
            catch (Exception e)
            {
                Logger.Exception("Exception refreshing song list:", e);
            }
        }
Пример #27
0
        public static Button CreatePageButton(String name, RectTransform parent, String buttonTemplate, Vector2 anchoredPosition, Vector2 sizeDelta, UnityAction onClick, Sprite icon)
        {
            Logger.Debug("CreatePageButton({0}, {1}, {2}, {3}, {4}", name, parent, buttonTemplate, anchoredPosition, sizeDelta);
            Button btn = CreateBaseButton(name, parent, buttonTemplate);

            (btn.transform as RectTransform).anchorMin        = new Vector2(0.5f, 0.5f);
            (btn.transform as RectTransform).anchorMax        = new Vector2(0.5f, 0.5f);
            (btn.transform as RectTransform).anchoredPosition = anchoredPosition;
            (btn.transform as RectTransform).sizeDelta        = sizeDelta;
            (btn.transform as RectTransform).pivot            = new Vector2(0.5f, 0.5f);

            ButtonIconImage btnIcon = btn.gameObject.AddComponent <ButtonIconImage>();

            btnIcon.image        = btn.gameObject.GetComponentsInChildren <Image>(true).Where(x => x.gameObject.name == "Icon").FirstOrDefault();
            btnIcon.image.sprite = icon;

            btn.onClick.RemoveAllListeners();
            if (onClick != null)
            {
                btn.onClick.AddListener(onClick);
            }

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

            this.ResetLevelPacks();

            this._currentLevelPack = pack;

            var beatmapLevelPack = pack as BeatmapLevelPackSO;

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

            this.Settings.currentLevelPackId = pack.packID;
            this.Settings.Save();
        }
Пример #29
0
        /// <summary>
        /// Get the song cache from the game.
        /// </summary>
        public void UpdateLevelRecords()
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();

            // 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;
            }

            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)
                {
                    // Always use the newest date.
                    var lastWriteTime  = File.GetLastWriteTimeUtc(level.customSongInfo.path);
                    var lastCreateTime = File.GetCreationTimeUtc(level.customSongInfo.path);
                    var lastTime       = lastWriteTime > lastCreateTime ? lastWriteTime : lastCreateTime;
                    _cachedLastWriteTimes[level.levelID] = (lastTime - 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))
                    {
                        _levelIdToSongVersion.Add(level.levelID, version);

                        if (!_keyToSong.ContainsKey(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();

            // 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 (CurrentEditingPlaylist == null && !String.IsNullOrEmpty(this.Settings.currentEditingPlaylistFile))
            {
                Logger.Debug("Loading playlist for editing: {0}", this.Settings.currentEditingPlaylistFile);
                CurrentEditingPlaylist = Playlist.LoadPlaylist(this.Settings.currentEditingPlaylistFile);
                PlaylistsCollection.MatchSongsForPlaylist(CurrentEditingPlaylist);
            }

            if (CurrentEditingPlaylist == null)
            {
                Logger.Debug("Current editing playlist does not exit, create...");
                CurrentEditingPlaylist = new Playlist
                {
                    playlistTitle  = "Song Browser Favorites",
                    playlistAuthor = "SongBrowser",
                    fileLoc        = this.Settings.currentEditingPlaylistFile,
                    image          = Base64Sprites.PlaylistIconB64,
                    songs          = new List <PlaylistSong>(),
                };
            }

            CurrentEditingPlaylistLevelIds = new HashSet <string>();
            foreach (PlaylistSong ps in CurrentEditingPlaylist.songs)
            {
                // Sometimes we cannot match a song
                if (ps.level == null)
                {
                    continue;
                }

                CurrentEditingPlaylistLevelIds.Add(ps.level.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);
        }
Пример #30
0
        /// <summary>
        /// Sort the song list based on the settings.
        /// </summary>
        public void ProcessSongList()
        {
            Logger.Trace("ProcessSongList()");

            // This has come in handy many times for debugging issues with Newest.

            /*foreach (BeatmapLevelSO level in _originalSongs)
             * {
             *  if (_levelIdToCustomLevel.ContainsKey(level.levelID))
             *  {
             *      Logger.Debug("HAS KEY {0}: {1}", _levelIdToCustomLevel[level.levelID].customSongInfo.path, level.levelID);
             *  }
             *  else
             *  {
             *      Logger.Debug("Missing KEY: {0}", level.levelID);
             *  }
             * }*/

            // TODO - remove as part of unifying song list interface
            if (_isPreviewLevelPack)
            {
                return;
            }

            if (_levelPackToSongs.Count == 0)
            {
                Logger.Debug("Cannot process songs yet, level packs have not been processed...");
                return;
            }

            if (this._currentLevelPack == null || !this._levelPackToSongs.ContainsKey(this._currentLevelPack.packName))
            {
                Logger.Debug("Cannot process songs yet, no level pack selected...");
                return;
            }

            // Playlist filter will load the original songs.
            List <BeatmapLevelSO> unsortedSongs = null;
            List <BeatmapLevelSO> filteredSongs = null;

            if (this._settings.filterMode == SongFilterMode.Playlist && this.CurrentPlaylist != null)
            {
                unsortedSongs = null;
            }
            else
            {
                Logger.Debug("Using songs from level pack: {0}", this._currentLevelPack.packName);
                unsortedSongs = new List <BeatmapLevelSO>(_levelPackToSongs[this._currentLevelPack.packName]);
            }

            // filter
            Logger.Debug("Starting filtering songs...");
            Stopwatch stopwatch = Stopwatch.StartNew();

            switch (_settings.filterMode)
            {
            case SongFilterMode.Favorites:
                filteredSongs = FilterFavorites();
                break;

            case SongFilterMode.Search:
                filteredSongs = FilterSearch(unsortedSongs);
                break;

            case SongFilterMode.Playlist:
                filteredSongs = FilterPlaylist();
                break;

            case SongFilterMode.None:
            default:
                Logger.Info("No song filter selected...");
                filteredSongs = unsortedSongs;
                break;
            }

            stopwatch.Stop();
            Logger.Info("Filtering songs took {0}ms", stopwatch.ElapsedMilliseconds);

            // sort
            Logger.Debug("Starting to sort songs...");
            stopwatch = Stopwatch.StartNew();

            switch (_settings.sortMode)
            {
            case SongSortMode.Original:
                SortOriginal(filteredSongs);
                break;

            case SongSortMode.Newest:
                SortNewest(filteredSongs);
                break;

            case SongSortMode.Author:
                SortAuthor(filteredSongs);
                break;

            case SongSortMode.PlayCount:
                SortPlayCount(filteredSongs);
                break;

            case SongSortMode.PP:
                SortPerformancePoints(filteredSongs);
                break;

            case SongSortMode.Difficulty:
                SortDifficulty(filteredSongs);
                break;

            case SongSortMode.Random:
                SortRandom(filteredSongs);
                break;

            case SongSortMode.Default:
            default:
                SortSongName(filteredSongs);
                break;
            }

            if (this.Settings.invertSortResults && _settings.sortMode != SongSortMode.Random)
            {
                _sortedSongs.Reverse();
            }

            stopwatch.Stop();
            Logger.Info("Sorting songs took {0}ms", stopwatch.ElapsedMilliseconds);

            this.OverwriteCurrentLevelPack();
            //_sortedSongs.ForEach(x => Logger.Debug(x.levelID));
        }