protected override Drawable[] CreateText(IBeatmapInfo beatmapInfo)
            {
                var metadata = beatmapInfo.Metadata;

                Debug.Assert(metadata != null);

                return(new Drawable[]
                {
                    new OsuSpriteText
                    {
                        Text = new RomanisableString(metadata.TitleUnicode, metadata.Title),
                        Font = OsuFont.GetFont(weight: FontWeight.Bold)
                    },
                    new OsuSpriteText
                    {
                        Text = $" [{beatmapInfo.DifficultyName}]",
                        Font = OsuFont.GetFont(weight: FontWeight.Bold)
                    },
                    new OsuSpriteText
                    {
                        Text = " by ",
                        Font = OsuFont.GetFont(weight: FontWeight.Regular)
                    },
                    new OsuSpriteText
                    {
                        Text = new RomanisableString(metadata.ArtistUnicode, metadata.Artist),
                        Font = OsuFont.GetFont(weight: FontWeight.Regular)
                    },
                });
            }
Exemple #2
0
        protected BeatmapMetadataContainer(IBeatmapInfo beatmapInfo)
            : base(HoverSampleSet.Submit)
        {
            this.beatmapInfo = beatmapInfo;

            AutoSizeAxes = Axes.Both;
        }
Exemple #3
0
            protected override Drawable[] CreateText(IBeatmapInfo beatmapInfo)
            {
                var metadata = beatmapInfo.Metadata;

                Debug.Assert(metadata != null);

                return(new Drawable[]
                {
                    new OsuSpriteText
                    {
                        Anchor = Anchor.BottomLeft,
                        Origin = Anchor.BottomLeft,
                        Text = new RomanisableString(metadata.TitleUnicode, metadata.Title),
                        Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
                    },
                    new OsuSpriteText
                    {
                        Anchor = Anchor.BottomLeft,
                        Origin = Anchor.BottomLeft,
                        Text = " by ",
                        Font = OsuFont.GetFont(size: 12, italics: true)
                    },
                    new OsuSpriteText
                    {
                        Anchor = Anchor.BottomLeft,
                        Origin = Anchor.BottomLeft,
                        Text = new RomanisableString(metadata.ArtistUnicode, metadata.Artist),
                        Font = OsuFont.GetFont(size: 12, italics: true)
                    },
                });
            }
Exemple #4
0
            public PropagateHandler(BeatmapDownloadService service, IBeatmapInfo beatmapInfo)
            {
                _service   = service;
                _eventArgs = new BeatmapDownloadProgressChangedEventArgs(beatmapInfo);

                Report(0);
            }
Exemple #5
0
            public PlaylistDownloadButton(IBeatmapInfo beatmap)
                : base(beatmap.BeatmapSet)
            {
                this.beatmap = beatmap;

                Size  = new Vector2(width, 30);
                Alpha = 0;
            }
        /// <summary>
        /// Creates a new <see cref="BindableStarDifficulty"/> and triggers an initial value update.
        /// </summary>
        /// <param name="beatmapInfo">The <see cref="IBeatmapInfo"/> that star difficulty should correspond to.</param>
        /// <param name="initialRulesetInfo">The initial <see cref="IRulesetInfo"/> to get the difficulty with.</param>
        /// <param name="initialMods">The initial <see cref="Mod"/>s to get the difficulty with.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="IBeatmapInfo"/>.</param>
        /// <returns>The <see cref="BindableStarDifficulty"/>.</returns>
        private BindableStarDifficulty createBindable([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo initialRulesetInfo, [CanBeNull] IEnumerable <Mod> initialMods,
                                                      CancellationToken cancellationToken)
        {
            var bindable = new BindableStarDifficulty(beatmapInfo, cancellationToken);

            updateBindable(bindable, initialRulesetInfo, initialMods, cancellationToken);
            return(bindable);
        }
Exemple #7
0
        protected override APIRequest <MultiplayerScore> CreateSubmissionRequest(Score score, long token)
        {
            IBeatmapInfo beatmap = score.ScoreInfo.BeatmapInfo;

            Debug.Assert(beatmap.OnlineID > 0);

            return(new SubmitSoloScoreRequest(score.ScoreInfo, token, beatmap.OnlineID));
        }
        /// <summary>
        /// Retrieves a bindable containing the star difficulty of a <see cref="BeatmapInfo"/> that follows the currently-selected ruleset and mods.
        /// </summary>
        /// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
        /// <returns>A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state (but not during updates to ruleset and mods if a stale value is already propagated).</returns>
        public IBindable <StarDifficulty?> GetBindableDifficulty([NotNull] IBeatmapInfo beatmapInfo, CancellationToken cancellationToken = default)
        {
            var bindable = createBindable(beatmapInfo, currentRuleset.Value, currentMods.Value, cancellationToken);

            lock (bindableUpdateLock)
                trackedBindables.Add(bindable);

            return(bindable);
        }
Exemple #9
0
        private static string ResolveProviderName(IBeatmapInfo beatmapInfo)
        {
            if (beatmapInfo is CompositeBeatmapInfo compositeBeatmapInfo)
            {
                beatmapInfo = compositeBeatmapInfo.Unwrap();
            }

            return(beatmapInfo is BloodCatBeatmapInfo ? "BloodCat" : "osu!");
        }
Exemple #10
0
        /// <summary>
        /// A user-presentable display title representing this beatmap, with localisation handling for potentially romanisable fields.
        /// </summary>
        public static RomanisableString GetDisplayTitleRomanisable(this IBeatmapInfo beatmapInfo, bool includeDifficultyName = true, bool includeCreator = true)
        {
            var metadata = beatmapInfo.Metadata.GetDisplayTitleRomanisable(includeCreator);

            if (includeDifficultyName)
            {
                string versionString = getVersionString(beatmapInfo);
                return(new RomanisableString($"{metadata.GetPreferred(true)} {versionString}".Trim(), $"{metadata.GetPreferred(false)} {versionString}".Trim()));
            }

            return(new RomanisableString($"{metadata.GetPreferred(true)}".Trim(), $"{metadata.GetPreferred(false)}".Trim()));
        }
        public void TestOnlyLastItemChangedAfterGameplayFinished()
        {
            RunGameplay();

            IBeatmapInfo firstBeatmap = null;

            AddStep("get first playlist item beatmap", () => firstBeatmap = Client.APIRoom?.Playlist[0].Beatmap.Value);

            selectNewItem(() => OtherBeatmap);

            AddAssert("first playlist item hasn't changed", () => Client.APIRoom?.Playlist[0].Beatmap.Value == firstBeatmap);
            AddAssert("second playlist item changed", () => Client.APIRoom?.Playlist[1].Beatmap.Value != firstBeatmap);
        }
Exemple #12
0
        public TournamentBeatmapPanel(IBeatmapInfo beatmapInfo, string mod = null)
        {
            if (beatmapInfo == null)
            {
                throw new ArgumentNullException(nameof(beatmapInfo));
            }

            BeatmapInfo = beatmapInfo;
            this.mod    = mod;

            Width  = 400;
            Height = HEIGHT;
        }
Exemple #13
0
        /// <summary>
        /// Constructs a sample API beatmap with a populated beatmap set from a given source beatmap.
        /// </summary>
        /// <param name="original">The source beatmap.</param>
        public static APIBeatmap CreateAPIBeatmap(IBeatmapInfo original)
        {
            var beatmapSet = CreateAPIBeatmapSet(original);

            // Avoid circular reference.
            var beatmap = beatmapSet.Beatmaps.First();

            beatmapSet.Beatmaps = Array.Empty <APIBeatmap>();

            // Populate the set as that's generally what we expect from the API.
            beatmap.BeatmapSet = beatmapSet;

            return(beatmap);
        }
Exemple #14
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            SelectedItem.BindValueChanged(selected =>
            {
                bool isCurrent = selected.NewValue == Model;

                if (!valid.Value)
                {
                    // Don't allow selection when not valid.
                    if (isCurrent)
                    {
                        SelectedItem.Value = selected.OldValue;
                    }

                    // Don't update border when not valid (the border is displaying this fact).
                    return;
                }

                maskingContainer.BorderThickness = isCurrent ? 5 : 0;
            }, true);

            valid.BindValueChanged(_ => Scheduler.AddOnce(refresh));

            onScreenLoader.DelayedLoadStarted += _ =>
            {
                Task.Run(async() =>
                {
                    try
                    {
                        if (showItemOwner)
                        {
                            var foundUser = await userLookupCache.GetUserAsync(Item.OwnerID).ConfigureAwait(false);
                            Schedule(() => ownerAvatar.User = foundUser);
                        }

                        beatmap = await beatmapLookupCache.GetBeatmapAsync(Item.Beatmap.OnlineID).ConfigureAwait(false);

                        Scheduler.AddOnce(refresh);
                    }
                    catch (Exception e)
                    {
                        Logger.Log($"Error while populating playlist item {e}");
                    }
                });
            };

            refresh();
        }
Exemple #15
0
        private void RunTask(BeatmapDownloadTask task)
        {
            Log.Verbose("Detect {name} {id} downloading",
                        task.IsBeatmapSet ? "beatmapset" : "beatmap",
                        task.Id);

            IBeatmapInfo beatmapInfo = null;

            try
            {
                Task <IBeatmapInfo> infoTask = task.IsBeatmapSet ?
                                               _beatmapProvider.LookupBySetIdAsync(task.Id) :
                                               _beatmapProvider.LookupByIdAsync(task.Id);

                beatmapInfo = infoTask.Result ?? throw new BeatmapNotFoundException(task.Id);

                DownloadStarted?.Invoke(this, new BeatmapDownloadEventArgs(beatmapInfo));

                var option = new BeatmapDownloadOption();

                if (DownloadProgressChanged != null)
                {
                    option.Progress = new PropagateHandler(this, beatmapInfo);
                }

                var result = _beatmapProvider.DownloadAsync(beatmapInfo, option).Result;

                if (result.Exception != null)
                {
                    throw result.Exception;
                }

                if (File.Exists(_process.MainModule?.FileName))
                {
                    Process.Start(_process.MainModule !.FileName, result.FilePath);
                }

                DownloadCompleted?.Invoke(this, new BeatmapDownloadEventArgs(beatmapInfo));
            }
            catch (Exception e)
            {
                DownloadFailed?.Invoke(this, new BeatmapDownloadFailedEventArgs(beatmapInfo, e));

                var fallbackUrl = task.IsBeatmapSet ?
                                  $"https://osu.ppy.sh/beatmapsets/{task.Id}" :
                                  $"https://osu.ppy.sh/b/{task.Id}";

                Process.Start(fallbackUrl);
            }
        }
Exemple #16
0
        public GetScoresRequest(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable <IMod> mods = null)
        {
            if (beatmapInfo.OnlineID <= 0)
            {
                throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(IBeatmapInfo.OnlineID)}.");
            }

            if (scope == BeatmapLeaderboardScope.Local)
            {
                throw new InvalidOperationException("Should not attempt to request online scores for a local scoped leaderboard");
            }

            this.beatmapInfo = beatmapInfo;
            this.scope       = scope;
            this.ruleset     = ruleset ?? throw new ArgumentNullException(nameof(ruleset));
            this.mods        = mods ?? Array.Empty <IMod>();
        }
Exemple #17
0
        /// <summary>
        /// Retrieves the difficulty of a <see cref="IBeatmapInfo"/>.
        /// </summary>
        /// <param name="beatmapInfo">The <see cref="IBeatmapInfo"/> to get the difficulty of.</param>
        /// <param name="rulesetInfo">The <see cref="IRulesetInfo"/> to get the difficulty with.</param>
        /// <param name="mods">The <see cref="Mod"/>s to get the difficulty with.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops computing the star difficulty.</param>
        /// <returns>
        /// The requested <see cref="StarDifficulty"/>, if non-<see langword="null"/>.
        /// A <see langword="null"/> return value indicates that the difficulty process failed or was interrupted early,
        /// and as such there is no usable star difficulty value to be returned.
        /// </returns>
        public virtual Task <StarDifficulty?> GetDifficultyAsync([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo rulesetInfo = null,
                                                                 [CanBeNull] IEnumerable <Mod> mods = null, CancellationToken cancellationToken = default)
        {
            // In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
            rulesetInfo ??= beatmapInfo.Ruleset;

            var localBeatmapInfo = beatmapInfo as BeatmapInfo;
            var localRulesetInfo = rulesetInfo as RulesetInfo;

            // Difficulty can only be computed if the beatmap and ruleset are locally available.
            if (localBeatmapInfo?.IsManaged != true || localRulesetInfo == null)
            {
                // If not, fall back to the existing star difficulty (e.g. from an online source).
                return(Task.FromResult <StarDifficulty?>(new StarDifficulty(beatmapInfo.StarRating, (beatmapInfo as IBeatmapOnlineInfo)?.MaxCombo ?? 0)));
            }

            return(GetAsync(new DifficultyCacheLookup(localBeatmapInfo, localRulesetInfo, mods), cancellationToken));
        }
Exemple #18
0
        /// <summary>
        /// Constructs a sample API beatmap set containing a beatmap from a given source beatmap.
        /// </summary>
        /// <param name="original">The source beatmap.</param>
        public static APIBeatmapSet CreateAPIBeatmapSet(IBeatmapInfo original)
        {
            Debug.Assert(original.BeatmapSet != null);

            return(new APIBeatmapSet
            {
                OnlineID = original.BeatmapSet.OnlineID,
                Status = BeatmapOnlineStatus.Ranked,
                Covers = new BeatmapSetOnlineCovers
                {
                    Cover = "https://assets.ppy.sh/beatmaps/163112/covers/cover.jpg",
                    Card = "https://assets.ppy.sh/beatmaps/163112/covers/card.jpg",
                    List = "https://assets.ppy.sh/beatmaps/163112/covers/list.jpg"
                },
                Title = original.Metadata.Title,
                TitleUnicode = original.Metadata.TitleUnicode,
                Artist = original.Metadata.Artist,
                ArtistUnicode = original.Metadata.ArtistUnicode,
                Author = new APIUser
                {
                    Username = original.Metadata.Author.Username,
                    Id = original.Metadata.Author.OnlineID
                },
                Source = original.Metadata.Source,
                Tags = original.Metadata.Tags,
                Beatmaps = new[]
                {
                    new APIBeatmap
                    {
                        OnlineID = original.OnlineID,
                        OnlineBeatmapSetID = original.BeatmapSet.OnlineID,
                        Status = ((BeatmapInfo)original).Status,
                        Checksum = original.MD5Hash,
                        AuthorID = original.Metadata.Author.OnlineID,
                        RulesetID = original.Ruleset.OnlineID,
                        StarRating = original.StarRating,
                        DifficultyName = original.DifficultyName,
                    }
                }
            });
        }
        public static async Task <BeatmapDownloadResult> DownloadAsync(string url, IBeatmapInfo beatmapInfo, BeatmapDownloadOption option = null)
        {
            var filePath = Path.GetFullPath(option?.Path ?? $"{beatmapInfo.SetId}.osz");

            if (File.Exists(filePath))
            {
                return(new BeatmapDownloadResult(option, filePath));
            }

            using var client = new WebClient();

            if (option?.Progress != null)
            {
                int progress = -1;

                client.DownloadProgressChanged += (sender, args) =>
                {
                    if (progress >= args.ProgressPercentage)
                    {
                        return;
                    }

                    progress = args.ProgressPercentage;
                    option.Progress.Report(progress / 100d);
                };
            }

            try
            {
                await client.DownloadFileTaskAsync(url, filePath);

                return(new BeatmapDownloadResult(option, filePath));
            }
            catch (Exception e)
            {
                return(new BeatmapDownloadResult(option, e));
            }
        }
Exemple #20
0
 public InPlaylistGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
     : base(beatmapInfo, ruleset)
 {
 }
Exemple #21
0
 private static string getVersionString(IBeatmapInfo beatmapInfo) => string.IsNullOrEmpty(beatmapInfo.DifficultyName) ? string.Empty : $"[{beatmapInfo.DifficultyName}]";
Exemple #22
0
 public static string[] GetSearchableTerms(this IBeatmapInfo beatmapInfo) => new[]
 {
     beatmapInfo.DifficultyName
 }.Concat(beatmapInfo.Metadata.GetSearchableTerms()).Where(s => !string.IsNullOrEmpty(s)).ToArray();
Exemple #23
0
 /// <summary>
 /// A user-presentable display title representing this beatmap.
 /// </summary>
 public static string GetDisplayTitle(this IBeatmapInfo beatmapInfo) => $"{beatmapInfo.Metadata.GetDisplayTitle()} {getVersionString(beatmapInfo)}".Trim();
Exemple #24
0
 public DifficultyRetriever(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset, IReadOnlyList <Mod> mods)
 {
     this.beatmapInfo = beatmapInfo;
     this.ruleset     = ruleset;
     this.mods        = mods;
 }
Exemple #25
0
        public GetBeatmapRequest(IBeatmapInfo beatmapInfo)
        {
            this.beatmapInfo = beatmapInfo;

            filename = (beatmapInfo as BeatmapInfo)?.Path ?? string.Empty;
        }
Exemple #26
0
 public Editing(IBeatmapInfo info)
 {
     BeatmapInfo = info;
 }
Exemple #27
0
 public InMultiplayerGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
     : base(beatmapInfo, ruleset)
 {
 }
Exemple #28
0
 protected InGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
 {
     BeatmapInfo = beatmapInfo;
     Ruleset     = ruleset;
 }
Exemple #29
0
 public SpectatingMultiplayerGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
     : base(beatmapInfo, ruleset)
 {
 }
Exemple #30
0
 public InSoloGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset)
     : base(beatmapInfo, ruleset)
 {
 }