Пример #1
0
        private async Task ExtractZipAsync(Song songInfo, Stream zipStream, string customSongsPath)
        {
            try
            {
                Logger.Log("Extracting...");
                _extractingZip = true;
                ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read);
                await Task.Run(() => archive.ExtractToDirectory(customSongsPath)).ConfigureAwait(false);

                archive.Dispose();
            }
            catch (Exception e)
            {
                Logger.Exception($"Unable to extract ZIP! Exception: {e}");
                songInfo.songQueueState = SongQueueState.Error;
                _extractingZip          = false;
                return;
            }
            zipStream.Close();

            songInfo.path = Directory.GetDirectories(customSongsPath).FirstOrDefault();

            if (string.IsNullOrEmpty(songInfo.path))
            {
                songInfo.path = customSongsPath;
            }

            _extractingZip          = false;
            songInfo.songQueueState = SongQueueState.Downloaded;
            _alreadyDownloadedSongs.Add(songInfo);
            Logger.Log($"Extracted {songInfo.songName} {songInfo.songSubName}!");

            HMMainThreadDispatcher.instance.Enqueue(() => {
                try
                {
                    string dirName = new DirectoryInfo(customSongsPath).Name;
#if DEBUG
                    Logger.Log("Original path: " + customSongsPath);
                    Logger.Log("Folder name: " + dirName);
#endif
                    SongLoader.Instance.RetrieveNewSong(dirName);
                }
                catch (Exception e)
                {
                    Logger.Exception("Unable to load song! Exception: " + e);
                }
            });
        }
 /// <summary>
 /// Inform browser score saber data is available.
 /// </summary>
 /// <param name="loader"></param>
 /// <param name="levels"></param>
 private void OnScoreSaberDataDownloaded()
 {
     Logger.Trace("OnScoreSaberDataDownloaded");
     try
     {
         _songBrowserUI.Model.UpdateScoreSaberDataMapping();
         if (_songBrowserUI.Model.Settings.sortMode == SongSortMode.PP)
         {
             _songBrowserUI.Model.ProcessSongList();
             _songBrowserUI.RefreshSongList();
         }
     }
     catch (Exception e)
     {
         Logger.Exception("Exception during OnScoreSaberDataDownloaded: ", e);
     }
 }
        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);
            }
        }
Пример #4
0
 /// <summary>
 /// Inform browser score saber data is available.
 /// </summary>
 /// <param name="loader"></param>
 /// <param name="levels"></param>
 private void OnScoreSaberDataDownloaded()
 {
     Logger.Trace("OnScoreSaberDataDownloaded");
     try
     {
         // TODO - this should be in the SongBrowserUI which is acting like the view controller for the SongBrowser
         _songBrowserUI.Model.UpdateScoreSaberDataMapping();
         //_songBrowserUI.RefreshScoreSaberData(null);
         if (_songBrowserUI.Model.Settings.sortMode == SongSortMode.PP)
         {
             _songBrowserUI.Model.ProcessSongList();
             _songBrowserUI.RefreshSongList();
         }
     }
     catch (Exception e)
     {
         Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", 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...");

                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...", 10.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);
                    }
                }
            }
        }
        public IEnumerator GetInfoForSong(Playlist playlist, PlaylistSong song, Action <Song> songCallback)
        {
            string url        = "";
            bool   _usingHash = false;

            if (!string.IsNullOrEmpty(song.key))
            {
                url = $"{PluginConfig.beatsaverURL}/api/songs/detail/{song.key}";
                if (!string.IsNullOrEmpty(playlist.customDetailUrl))
                {
                    url = playlist.customDetailUrl + song.key;
                }
            }
            else if (!string.IsNullOrEmpty(song.hash))
            {
                url        = $"{PluginConfig.beatsaverURL}/api/songs/search/hash/{song.hash}";
                _usingHash = true;
            }
            else if (!string.IsNullOrEmpty(song.levelId))
            {
                string hash = CustomHelpers.CheckHex(song.levelId.Substring(0, Math.Min(32, song.levelId.Length)));
                url        = $"{PluginConfig.beatsaverURL}/api/songs/search/hash/{hash}";
                _usingHash = true;
            }
            else
            {
                yield break;
            }

            UnityWebRequest www = UnityWebRequest.Get(url);

            www.timeout = 15;
            yield return(www.SendWebRequest());

            if (www.isNetworkError || www.isHttpError)
            {
                Logger.Error($"Unable to connect to {PluginConfig.beatsaverURL}! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error")));
            }
            else
            {
                try
                {
                    JSONNode node = JSON.Parse(www.downloadHandler.text);

                    if (_usingHash)
                    {
                        if (node["songs"].Count == 0)
                        {
                            Logger.Error($"Song {song.songName} doesn't exist on BeatSaver!");
                            songCallback?.Invoke(null);
                            yield break;
                        }
                        songCallback?.Invoke(Song.FromSearchNode(node["songs"][0]));
                    }
                    else
                    {
                        songCallback?.Invoke(new Song(node["song"]));
                    }
                }
                catch (Exception e)
                {
                    Logger.Exception("Unable to parse response! Exception: " + 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);
        }
Пример #8
0
        public IEnumerator DownloadSongCoroutine(Song songInfo)
        {
            songInfo.songQueueState = SongQueueState.Downloading;

            UnityWebRequest www;
            bool            timeout = false;
            float           time    = 0f;
            UnityWebRequestAsyncOperation asyncRequest;

            try
            {
                www = UnityWebRequest.Get(songInfo.downloadUrl);

                asyncRequest = www.SendWebRequest();
            }
            catch (Exception e)
            {
                Logger.Exception("DownloadSongCoroutine Exception", e);
                songInfo.songQueueState      = SongQueueState.Error;
                songInfo.downloadingProgress = 1f;

                yield break;
            }

            while ((!asyncRequest.isDone || songInfo.downloadingProgress != 1f) && songInfo.songQueueState != SongQueueState.Error)
            {
                yield return(null);

                time += Time.deltaTime;

                if ((time >= 5f && asyncRequest.progress == 0f) || songInfo.songQueueState == SongQueueState.Error)
                {
                    www.Abort();
                    timeout = true;
                    Logger.Error("Connection timed out!");
                }

                songInfo.downloadingProgress = asyncRequest.progress;
            }


            if (www.isNetworkError || www.isHttpError || timeout || songInfo.songQueueState == SongQueueState.Error)
            {
                songInfo.songQueueState = SongQueueState.Error;
                Logger.Error("Unable to download song! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error")));
            }
            else
            {
                Logger.Info("Received response from BeatSaver.com...");

                //string zipPath = "";
                string docPath         = "";
                string customSongsPath = "";

                byte[] data = www.downloadHandler.data;

                Stream zipStream = null;

                try
                {
                    docPath         = Application.dataPath;
                    docPath         = docPath.Substring(0, docPath.Length - 5);
                    docPath         = docPath.Substring(0, docPath.LastIndexOf("/"));
                    customSongsPath = docPath + "/CustomSongs/" + songInfo.id + "/";
                    if (!Directory.Exists(customSongsPath))
                    {
                        Directory.CreateDirectory(customSongsPath);
                    }
                    zipStream = new MemoryStream(data);
                    Logger.Info("Downloaded zip!");
                }
                catch (Exception e)
                {
                    Logger.Exception("DownloadSongCoroutine exception:", e);
                    songInfo.songQueueState = SongQueueState.Error;
                    yield break;
                }

                while (_extractingZip)
                {
                    yield return(new WaitForSecondsRealtime(0.25f));
                }

                yield return(new WaitWhile(() => _extractingZip)); //because extracting several songs at once sometimes hangs the game

                Task extract = ExtractZipAsync(songInfo, zipStream, customSongsPath);
                yield return(new WaitWhile(() => !extract.IsCompleted));

                songDownloaded?.Invoke(songInfo);
            }
        }
Пример #9
0
        protected override void DidActivate(bool firstActivation, ActivationType type)
        {
            if (firstActivation && type == ActivationType.AddedToHierarchy)
            {
                gameObject.SetActive(true);
                rectTransform.sizeDelta = new Vector2(60f, 0f);

                _levelDetails = GetComponentsInChildren <StandardLevelDetailView>(true).First(x => x.name == "LevelDetail");
                _levelDetails.gameObject.SetActive(true);

                RemoveCustomUIElements(rectTransform);

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

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

                //RectTransform buttonsRect = GetComponentsInChildren<RectTransform>().First(x => x.name == "PlayButtons");
                //buttonsRect.anchoredPosition = new Vector2(0f, 6f);

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

                try
                {
                    songNameText = _textComponents.First(x => x.name == "SongNameText");
                    _textComponents.First(x => x.name == "Title").text = "Playlist";
                    songNameText.enableWordWrapping = true;

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

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

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

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

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

                coverImage = _levelDetails.GetPrivateField <Image>("_coverImage");
            }
        }
Пример #10
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 = "SongBrowserPlugin",
                    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);
        }
Пример #11
0
        public Playlist(JSONNode playlistNode)
        {
            string image = playlistNode["image"].Value;

            if (!string.IsNullOrEmpty(image))
            {
                try
                {
                    icon = Sprites.Base64ToSprite(image.Substring(image.IndexOf(",") + 1));
                }
                catch
                {
                    Logger.Exception("Unable to convert playlist image to sprite!");
                    icon = Sprites.BeastSaberLogo;
                }
            }
            else
            {
                icon = Sprites.BeastSaberLogo;
            }
            playlistTitle    = playlistNode["playlistTitle"];
            playlistAuthor   = playlistNode["playlistAuthor"];
            customDetailUrl  = playlistNode["customDetailUrl"];
            customArchiveUrl = playlistNode["customArchiveUrl"];
            if (!string.IsNullOrEmpty(customDetailUrl))
            {
                if (!customDetailUrl.EndsWith("/"))
                {
                    customDetailUrl += "/";
                }
                Logger.Log("Found playlist with customDetailUrl! Name: " + playlistTitle + ", CustomDetailUrl: " + customDetailUrl);
            }
            if (!string.IsNullOrEmpty(customArchiveUrl) && customArchiveUrl.Contains("[KEY]"))
            {
                Logger.Log("Found playlist with customArchiveUrl! Name: " + playlistTitle + ", CustomArchiveUrl: " + customArchiveUrl);
            }

            songs = new List <PlaylistSong>();

            foreach (JSONNode node in playlistNode["songs"].AsArray)
            {
                PlaylistSong song = new PlaylistSong();
                song.key      = node["key"];
                song.songName = node["songName"];
                song.hash     = node["hash"];
                song.levelId  = node["levelId"];

                songs.Add(song);
            }

            if (playlistNode["playlistSongCount"] != null)
            {
                playlistSongCount = playlistNode["playlistSongCount"].AsInt;
            }
            if (playlistNode["fileLoc"] != null)
            {
                fileLoc = playlistNode["fileLoc"];
            }

            if (playlistNode["playlistURL"] != null)
            {
                fileLoc = playlistNode["playlistURL"];
            }
        }
Пример #12
0
        public static void ReloadPlaylists(bool fullRefresh = true)
        {
            try
            {
                List <string> playlistFiles = new List <string>();

                if (PluginConfig.beatDropInstalled)
                {
                    string[] beatDropJSONPlaylists   = Directory.GetFiles(Path.Combine(PluginConfig.beatDropPlaylistsLocation, "playlists"), "*.json");
                    string[] beatDropBPLISTPlaylists = Directory.GetFiles(Path.Combine(PluginConfig.beatDropPlaylistsLocation, "playlists"), "*.bplist");
                    playlistFiles.AddRange(beatDropJSONPlaylists);
                    playlistFiles.AddRange(beatDropBPLISTPlaylists);
                    Logger.Log($"Found {beatDropJSONPlaylists.Length + beatDropBPLISTPlaylists.Length} playlists in BeatDrop folder");
                }

                string[] localJSONPlaylists   = Directory.GetFiles(Path.Combine(Environment.CurrentDirectory, "Playlists"), "*.json");
                string[] localBPLISTPlaylists = Directory.GetFiles(Path.Combine(Environment.CurrentDirectory, "Playlists"), "*.bplist");
                playlistFiles.AddRange(localJSONPlaylists);
                playlistFiles.AddRange(localBPLISTPlaylists);

                Logger.Log($"Found {localJSONPlaylists.Length + localBPLISTPlaylists.Length} playlists in Playlists folder");

                if (fullRefresh)
                {
                    loadedPlaylists.Clear();

                    foreach (string path in playlistFiles)
                    {
                        try
                        {
                            Playlist playlist = Playlist.LoadPlaylist(path);
                            if (Path.GetFileName(path) == "favorites.json" && playlist.playlistTitle == "Your favorite songs")
                            {
                                continue;
                            }
                            loadedPlaylists.Add(playlist);
                            Logger.Log($"Found \"{playlist.playlistTitle}\" by {playlist.playlistAuthor}");
                        }
                        catch (Exception e)
                        {
                            Logger.Log($"Unable to parse playlist @ {path}! Exception: {e}");
                        }
                    }
                }
                else
                {
                    foreach (string path in playlistFiles)
                    {
                        if (!loadedPlaylists.Any(x => x.fileLoc == path))
                        {
                            Logger.Log("Found new playlist! Path: " + path);
                            try
                            {
                                Playlist playlist = Playlist.LoadPlaylist(path);
                                if (Path.GetFileName(path) == "favorites.json" && playlist.playlistTitle == "Your favorite songs")
                                {
                                    continue;
                                }
                                loadedPlaylists.Add(playlist);
                                Logger.Log($"Found \"{playlist.playlistTitle}\" by {playlist.playlistAuthor}");

                                if (SongLoader.AreSongsLoaded)
                                {
                                    MatchSongsForPlaylist(playlist);
                                }
                            }
                            catch (Exception e)
                            {
                                Logger.Log($"Unable to parse playlist @ {path}! Exception: {e}");
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Exception("Unable to load playlists! Exception: " + e);
            }
        }