Beispiel #1
0
        private async Task LoadMenu(StandardLevelDetailViewController standardLevelDetailViewController, IDifficultyBeatmap difficultyBeatmap)
        {
            _activeBeatmap = difficultyBeatmap;
            await Parse(standardLevelDetailViewController);

            SetupVotingButtons();

            ShowPanel = false;
            parserParams?.EmitEvent("show-detail");
            var map = await _levelDataService.GetBeatmap(difficultyBeatmap, _cts.Token);

            ShowPanel = true;
            if (map != null)
            {
                Key      = map.ID;
                Mapper   = difficultyBeatmap.level.levelAuthorName ?? map.Uploader.Name ?? "Unknown";
                Uploaded = map.Uploaded.ToString("MMMM dd, yyyy");
                Votes    = (map.Stats.Upvotes + -map.Stats.Downvotes).ToString();
                SetRating(map.Stats.Score);
            }
            Author = difficultyBeatmap.level.songAuthorName;
            _activeBeatSaverMap = map;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsCustomLevel)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsOST)));
        }
Beispiel #2
0
        public async Task <Sprite?> GetCoverImageAsync(CancellationToken cancellationToken)
        {
            Beatmap?bm = await GetBeatmap;

            if (bm != null)
            {
                var img = await bm.FetchCoverImage(cancellationToken);

                return(Utilities.Utils.GetSprite(img));
            }
            else
            {
                return(Sprite.Create(Texture2D.blackTexture, new Rect(0, 0, 2, 2), new Vector2(0, 0), 100.0f));
            }
        }
 public async Task <byte[]?> DownloadZip(CancellationToken cancellationToken, IProgress <double>?progress = null)
 {
     if (beatmap == null)
     {
         try
         {
             beatmap = await Plugin.BeatSaver.Hash(levelHash);
         }
         catch
         {
             Plugin.Log?.Warn($"Song '{levelHash}' cannot be downloaded form Beat Saver.");
             return(null);
         }
     }
     return(await beatmap.ZipBytes(false));
 }
Beispiel #4
0
 private void Populate(Beatmap?beatmap)
 {
     if (beatmap != null)
     {
         songName        = beatmap.Metadata.SongName;
         songSubName     = beatmap.Metadata.SongSubName;
         songAuthorName  = beatmap.Metadata.SongAuthorName;
         levelAuthorName = beatmap.Metadata.LevelAuthorName;
         beatsPerMinute  = beatmap.Metadata.BPM;
         songDuration    = beatmap.Metadata.Duration;
     }
     else
     {
         songName = "Not Found On BeatSaver!";
         levelID  = "";
     }
 }
Beispiel #5
0
        public PreviewBeatmapStub Populate(Beatmap?bm)
        {
            isDownloadable = bm != null;
            if (isDownloadable)
            {
                Plugin.Log?.Debug($"PreviewBeatmap({levelID}): Metadata downloaded.");
                downloadURL = bm.DownloadURL;
                songName ??= bm.Metadata.SongName;
                songSubName ??= bm.Metadata.SongSubName;
                songAuthorName ??= bm.Metadata.SongAuthorName;
                levelAuthorName ??= bm.Metadata.LevelAuthorName;
                beatsPerMinute = bm.Metadata.BPM;
                songDuration   = bm.Metadata.Duration;
            }

            return(this);
        }
Beispiel #6
0
        protected async Task Vote(bool upvote)
        {
            CanVote = false;

            if (_activeBeatSaverMap != null)
            {
                VoteLoading         = true;
                _activeBeatSaverMap = await _levelDataService.Vote(_activeBeatSaverMap, upvote, token : _cts.Token);

                Votes = (_activeBeatSaverMap.Stats.Upvotes + -_activeBeatSaverMap.Stats.Downvotes).ToString();
                SetRating(_activeBeatSaverMap.Stats.Score);

                VoteLoading = false;
            }

            var info = await _platformUserModel.GetUserInfo();

            CanVote = info.platform == UserInfo.Platform.Steam || info.platform == UserInfo.Platform.Test || info.platform == UserInfo.Platform.Oculus;
        }
        public PreviewBeatmapStub(string levelID, Beatmap bm)
        {
            this.levelID   = levelID;
            this.levelHash = bm.Hash;

            this.beatmap      = bm;
            this.isDownloaded = false;

            this.songName        = bm.Metadata.SongName;
            this.songSubName     = bm.Metadata.SongSubName;
            this.songAuthorName  = bm.Metadata.SongAuthorName;
            this.levelAuthorName = bm.Metadata.LevelAuthorName;

            this.beatsPerMinute = bm.Metadata.BPM;
            this.songDuration   = bm.Metadata.Duration;

            this._downloadable = DownloadableState.True;

            _rawCoverTask = bm.CoverImageBytes();
        }
        public PreviewBeatmapStub(Beatmap bm)
        {
            this.levelID   = bm.ID;
            this.levelHash = bm.Hash;

            this.beatmap      = bm;
            this.isDownloaded = false;

            this.songName        = bm.Metadata.SongName;
            this.songSubName     = bm.Metadata.SongSubName;
            this.songAuthorName  = bm.Metadata.SongAuthorName;
            this.levelAuthorName = bm.Metadata.LevelAuthorName;

            this.beatsPerMinute = bm.Metadata.BPM;
            this.songDuration   = bm.Metadata.Duration;

            this._downloadable = DownloadableState.True;

            _rawCoverTask = bm.FetchCoverImage(CancellationToken.None);
        }
        public async Task <Sprite> GetCoverImageAsync(CancellationToken cancellationToken)
        {
            if (_localPreview != null)
            {
                return(await _localPreview.GetCoverImageAsync(cancellationToken));
            }

            Beatmap?bm = await FetchBeatmap();

            Sprite?sprite = null;

            if (bm != null && await bm.FetchCoverImage(cancellationToken) is byte[] img)
            {
                sprite = Utilities.Utils.GetSprite(img);
            }
            if (sprite == null)
            {
                sprite = Sprite.Create(Texture2D.blackTexture, new Rect(0, 0, 2, 2), new Vector2(0, 0), 100.0f);
            }
            return(sprite);
        }
        private static async Task <IPreviewBeatmapLevel?> DownloadSong(string hash, CancellationToken cancellationToken)
        {
            Beatmap?bm = await Plugin.BeatSaver.Hash(hash);

            if (bm == null)
            {
                Plugin.Log?.Warn($"Could not find song '{hash}' on Beat Saver.");
                return(null);
            }
            Plugin.Log.Info($"Attempting to download song '({bm.Key}) {bm.Name ?? hash}'");
#if DEBUG
            if ((Plugin.Config.DebugConfig?.FailDownloads ?? false))
            {
                await Task.Delay(2000);

                Plugin.Log.Info("Simulating a failed download by returning null.");
                return(null);
            }
#endif
            Stopwatch sw = new Stopwatch();
            sw.Start();
            byte[] beatmapBytes = await bm.ZipBytes(false, new StandardRequestOptions()
            {
                Progress = new Progress <double>(d =>
                {
#if DEBUG
                    Plugin.Log.Debug($"Downloading '{hash}': {d}");
#endif
                    DownloadProgressChanged?.Invoke(hash, d);
                })
            });

#if DEBUG
            TimeSpan delay = TimeSpan.FromSeconds(Plugin.Config.DebugConfig?.MinDownloadTime ?? 0) - TimeSpan.FromMilliseconds(sw.ElapsedMilliseconds);
            if (delay > TimeSpan.Zero)
            {
                Plugin.Log.Debug($"Waiting an additional {delay.ToString(TimeSpanFormat)} to 'finish' download.");
                await Task.Delay(delay);

                Plugin.Log.Debug($"Delay finished.");
            }
#endif
            string folderPath = Utils.GetSongDirectoryName(bm.Key, bm.Metadata.SongName, bm.Metadata.LevelAuthorName);
            folderPath = Path.Combine(CustomLevelsFolder, folderPath);
            using (var ms = new MemoryStream(beatmapBytes))
            {
                var result = await ZipUtils.ExtractZip(ms, folderPath);

                if (folderPath != result.OutputDirectory)
                {
                    folderPath = result.OutputDirectory ?? throw new Exception("Zip extract failed, no output directory.");
                }
                if (result.Exception != null)
                {
                    throw result.Exception;
                }
            }
            sw.Stop();
            Plugin.Log.Info($"Downloaded song to '{folderPath}' after {sw.Elapsed.ToString(TimeSpanFormat)}");

            using (var awaiter = new EventAwaiter <SongCore.Loader, ConcurrentDictionary <string, CustomPreviewBeatmapLevel> >(cancellationToken))
            {
                try
                {
                    SongCore.Loader.SongsLoadedEvent += awaiter.OnEvent;

                    SongCore.Collections.AddSong($"custom_level_{hash}", folderPath);
                    SongCore.Loader.Instance.RefreshSongs(false);
                    await awaiter.Task;
                    Plugin.DebugLog("SongCore has finished refreshing");
                }
                catch (OperationCanceledException)
                {
                    return(null);
                }
                catch (Exception e)
                {
                    Plugin.Log?.Error($"Error waiting for songs to load: {e.Message}");
                    Plugin.Log?.Debug(e);
                    throw;
                }
                finally
                {
                    SongCore.Loader.SongsLoadedEvent -= awaiter.OnEvent;
                }
            }

            CustomPreviewBeatmapLevel?beatmap = SongCore.Loader.GetLevelByHash(hash);
            if (beatmap == null)
            {
                Plugin.Log?.Warn($"Couldn't get downloaded beatmap '{bm?.Metadata?.SongName ?? hash}' from SongCore, this shouldn't happen.");
            }
            return(beatmap);
        }