/// <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); }
/// <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); } }
/// <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); }
/// <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)); }
/// <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(); }
/// <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); }
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); }
/// <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"); } }
/// <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('/', '_')); }
/// <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); } }
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); }
/// <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); } }
/// <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); } }
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); }
/// <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(); }
/// <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); }
/// <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)); }