protected override void DidActivate(bool firstActivation, ActivationType activationType) { try { if (firstActivation && activationType == ActivationType.AddedToHierarchy) { title = "Playlists"; if (_playlistsReader == null) { _playlistsReader = new PlaylistsReader(); _playlistsReader.UpdatePlaylists(); Logger.Debug("Reader found {0} playlists!", _playlistsReader.Playlists.Count); this.MatchSongsForAllPlaylists(true); } _playlistsNavigationController.didFinishEvent += _playlistsNavigationController_didFinishEvent; _playlistListViewController = BeatSaberUI.CreateViewController <PlaylistListViewController>(); _playlistListViewController.didSelectRow += _playlistListViewController_didSelectRow; _playlistDetailViewController.downloadButtonPressed += _playlistDetailViewController_downloadButtonPressed; _playlistDetailViewController.selectButtonPressed += _playlistDetailViewController_selectButtonPressed; _downloadQueueViewController = BeatSaberUI.CreateViewController <DownloadQueueViewController>(); SetViewControllersToNavigationConctroller(_playlistsNavigationController, new VRUIViewController[] { _playlistListViewController }); ProvideInitialViewControllers(_playlistsNavigationController, _downloadQueueViewController, null); } _downloadingPlaylist = false; _playlistListViewController.SetContent(_playlistsReader.Playlists); _downloadQueueViewController.allSongsDownloaded += _downloadQueueViewController_allSongsDownloaded; } catch (Exception e) { Logger.Exception("Error activating playlist flow coordinator: ", e); } }
/// <summary> /// Get the song cache from the game. /// </summary> public void UpdateSongLists(BeatmapCharacteristicSO gameplayMode) { // give up if (gameplayMode == null) { Logger.Debug("Always null first time if user waits for SongLoader event, which they should..."); return; } Stopwatch timer = new Stopwatch(); timer.Start(); // Get the level collection from song loader LevelCollectionSO levelCollections = Resources.FindObjectsOfTypeAll <LevelCollectionSO>().FirstOrDefault(); // Stash everything we need _originalSongs = levelCollections.GetLevelsWithBeatmapCharacteristic(gameplayMode).ToList(); Logger.Debug("Got {0} songs from level collections...", _originalSongs.Count); //_originalSongs.ForEach(x => Logger.Debug("{0} by {1} = {2}", x.name, x.levelAuthorName, x.levelID)); _sortedSongs = _originalSongs; CurrentBeatmapCharacteristicSO = gameplayMode; // Calculate some information about the custom song dir String customSongsPath = Path.Combine(Environment.CurrentDirectory, CUSTOM_SONGS_DIR); String revSlashCustomSongPath = customSongsPath.Replace('\\', '/'); double currentCustomSongDirLastWriteTIme = (File.GetLastWriteTimeUtc(customSongsPath) - EPOCH).TotalMilliseconds; bool customSongDirChanged = false; if (_customSongDirLastWriteTime != currentCustomSongDirLastWriteTIme) { customSongDirChanged = true; _customSongDirLastWriteTime = currentCustomSongDirLastWriteTIme; } // This operation scales well if (!Directory.Exists(customSongsPath)) { Logger.Error("CustomSong directory is missing..."); return; } IEnumerable <string> directories = Directory.EnumerateDirectories(customSongsPath, "*.*", SearchOption.AllDirectories); // Get LastWriteTimes Stopwatch lastWriteTimer = new Stopwatch(); lastWriteTimer.Start(); foreach (var level in SongLoader.CustomLevels) { // If we already know this levelID, don't both updating it. // SongLoader should filter duplicates but in case of failure we don't want to crash if (!_cachedLastWriteTimes.ContainsKey(level.levelID) || customSongDirChanged) { _cachedLastWriteTimes[level.levelID] = (File.GetLastWriteTimeUtc(level.customSongInfo.path) - EPOCH).TotalMilliseconds; } if (!_levelIdToCustomLevel.ContainsKey(level.levelID)) { _levelIdToCustomLevel.Add(level.levelID, level); } if (!_levelIdToSongVersion.ContainsKey(level.levelID)) { DirectoryInfo info = new DirectoryInfo(level.customSongInfo.path); string currentDirectoryName = info.Name; String version = level.customSongInfo.path.Replace(revSlashCustomSongPath, "").Replace(currentDirectoryName, "").Replace("/", ""); if (!String.IsNullOrEmpty(version)) { //Logger.Debug("MATCH"); _levelIdToSongVersion.Add(level.levelID, version); _keyToSong.Add(version, level); } } } lastWriteTimer.Stop(); Logger.Info("Determining song download time and determining mappings took {0}ms", lastWriteTimer.ElapsedMilliseconds); // Update song Infos, directory tree, and sort this.UpdateScoreSaberDataMapping(); this.UpdatePlayCounts(); this.UpdateDirectoryTree(customSongsPath); // Check if we need to upgrade settings file favorites try { this.Settings.ConvertFavoritesToPlaylist(_levelIdToCustomLevel, _levelIdToSongVersion); } catch (Exception e) { Logger.Exception("FAILED TO CONVERT FAVORITES TO PLAYLIST!", e); } // load the current editing playlist or make one if (!String.IsNullOrEmpty(this.Settings.currentEditingPlaylistFile)) { CurrentEditingPlaylist = PlaylistsReader.ParsePlaylist(this.Settings.currentEditingPlaylistFile); } if (CurrentEditingPlaylist == null) { CurrentEditingPlaylist = new Playlist { Title = "Song Browser Favorites", Author = "SongBrowserPlugin", Path = this.Settings.currentEditingPlaylistFile, Image = Base64Sprites.PlaylistIconB64, Songs = new List <PlaylistSong>(), }; } CurrentEditingPlaylistLevelIds = new HashSet <string>(); foreach (PlaylistSong ps in CurrentEditingPlaylist.Songs) { CurrentEditingPlaylistLevelIds.Add(ps.LevelId); } // Actually sort and filter this.ProcessSongList(); // Signal complete if (SongLoader.CustomLevels.Count > 0) { didFinishProcessingSongs?.Invoke(SongLoader.CustomLevels); } timer.Stop(); Logger.Info("Updating songs infos took {0}ms", timer.ElapsedMilliseconds); Logger.Debug("Song Browser knows about {0} songs from SongLoader...", _originalSongs.Count); }