Esempio n. 1
0
        public async Task TopOsuPlays(int num = 5, [Remainder] string player = null)
        {
            DataStorage.DbData.Models.User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            User osuUser;

            if (num < 1 || num > 7)
            {
                await SendBasicErrorEmbedAsync("Number of plays must be between 1 and 7.");

                return;
            }

            if (string.IsNullOrEmpty(player))
            {
                osuUser = await OsuBase.Client.GetUserByUserIdAsync(user.OsuId, GameMode.Standard);

                if (osuUser.UserId == 0)
                {
                    Embed.WithTitle($"osu! Top {num}");
                    Embed.WithDescription($"**{Context.User.Mention} Failed to acquire username. " +
                                          $"Please specify a player or set your osu! username with " +
                                          $"`{(await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id)).CommandPrefix}osuset`!**");

                    await ReplyAsync(embed : Embed.Build());

                    return;
                }
            }
            else
            {
                player  = player.Replace(' ', '_');
                osuUser = await OsuBase.Client.GetUserByUsernameAsync(player, GameMode.Standard);
            }

            if (osuUser == null)
            {
                throw new KaguyaSupportException($"Failed to download data for player. If no user was specified, " +
                                                 $"you must set your osu! username or user ID via " +
                                                 $"`{server.CommandPrefix}osuset <name/ID>`.\n\n" +
                                                 $"If a username was specified, it's likely that the user does not exist or " +
                                                 $"you are providing invalid data.");
            }

            IReadOnlyList <Score> playerBestObjectList = await OsuBase.Client.GetUserBestsByUserIdAsync(osuUser.UserId, GameMode.Standard, num);

            playerBestObjectList = playerBestObjectList.OrderByDescending(x => x.PerformancePoints).ToList().AsReadOnly();

            User playerUserObject = await OsuBase.Client.GetUserByUserIdAsync(osuUser.UserId, GameMode.Standard);

            string s = num == 1 ? "" : "s";

            Embed.WithAuthor(author =>
            {
                author.Name    = $"{playerUserObject.Username}'s Top {(num == 1 ? "" : num.ToString())} osu! Standard Play{s}";
                author.IconUrl = $"https://osu.ppy.sh/images/flags/{playerUserObject.Country}.png";
            });

            Embed.WithTitle($"**Top {num} plays for {playerUserObject.Username}:**");
            Embed.WithUrl($"https://osu.ppy.sh/u/{playerUserObject.UserId}");

            int    i             = 0;
            string topPlayString = "";

            foreach (Score playerBestObject in playerBestObjectList)
            {
                i++;
                Beatmap beatmap = await playerBestObject.GetBeatmapAsync();

                PerformanceData pp = await beatmap.GetPPAsync(playerBestObject.Mods, (float)playerBestObject.Accuracy);

                Debug.Assert(playerBestObject.Date != null, "playerBestObject.Date != null");
                topPlayString += $"\n{i}: ▸ **{OsuBase.OsuGradeEmote(playerBestObject.Rank)}" +
                                 $@"{playerBestObject.Mods.ToModeString(OsuBase.Client)
                                                     .Replace("No Mode", "No Mod")
                                                     .Replace("DTNC", "NC")}** ▸ " +
                                 $"{beatmap.BeatmapId} ▸ **[{beatmap.Title} " +
                                 $"[{beatmap.Difficulty}]](https://osu.ppy.sh/b/{beatmap.BeatmapId})** " +
                                 $"\n▸ **☆{beatmap.StarRating:N2}** ▸ **{playerBestObject.Accuracy:F}%** " +
                                 $"for **{pp.Pp:N}pp** " +
                                 $"\n▸ [Combo: {playerBestObject.MaxCombo}x / Max: {beatmap.MaxCombo}]" +
                                 $"\n▸ Play made {(DateTime.UtcNow - playerBestObject.Date.Value.DateTime).Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Year, precision: 3)} ago\n";
            }

            Embed.WithDescription(topPlayString);
            await ReplyAsync(embed : Embed.Build());
        }
Esempio n. 2
0
        public async Task OsuRecentCommand([Remainder] string player = null)
        {
            var       embed  = new KaguyaEmbedBuilder();
            OsuClient client = OsuBase.Client;

            User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            Server server = await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id);

            OsuSharp.User osuPlayer = player == null
                ? await client.GetUserByUserIdAsync(user.OsuId, GameMode.Standard)
                : await client.GetUserByUsernameAsync(player, GameMode.Standard);

            // Maybe the user provided an ID to search for.
            if (osuPlayer == null && long.TryParse(player, out long id))
            {
                osuPlayer = await client.GetUserByUserIdAsync(id, GameMode.Standard);
            }

            // If it's still null, they don't exist.
            if (osuPlayer == null)
            {
                embed.Description = $"{Context.User.Mention} Failed to acquire username! " +
                                    "Please specify a player or set your osu! username with " +
                                    $"`{server.CommandPrefix}osuset`!";

                await ReplyAsync(embed : embed.Build());

                return;
            }

            Score osuRecent = player == null
                ? (await client.GetUserRecentsByUserIdAsync(user.OsuId, GameMode.Standard, 1)).FirstOrDefault()
                : (await client.GetUserRecentsByUsernameAsync(player, GameMode.Standard, 1)).FirstOrDefault();

            if (osuRecent == null)
            {
                embed.WithAuthor(author =>
                {
                    author
                    .WithName($"{osuPlayer.Username} doesn't have any recent plays.")
                    .WithIconUrl("https://a.ppy.sh/" + osuPlayer.UserId);
                });

                await SendEmbedAsync(embed);

                return;
            }

            // Reset the embed as its values were changed in the above code.
            embed = new KaguyaEmbedBuilder();

            Beatmap beatmap = await osuRecent.GetBeatmapAsync();

            //Author
            embed.WithAuthor(author =>
            {
                author
                .WithName($"Recent: {osuPlayer.Username} | {beatmap.Title} [{beatmap.Difficulty}] by {beatmap.Author}")
                .WithIconUrl("https://a.ppy.sh/" + osuPlayer.UserId);
            });

            //Description
            PerformanceData scoredPerformance = await OppaiClient.GetPPAsync(osuRecent.BeatmapId, osuRecent.Mods, (float)osuRecent.Accuracy, osuRecent.MaxCombo);

            PerformanceData wouldbePerformance = await OppaiClient.GetPPAsync(osuRecent.BeatmapId, osuRecent.Mods, (float)osuRecent.Accuracy, beatmap.MaxCombo);

            string beatmapLink    = $"https://osu.ppy.sh/b/{beatmap.BeatmapId}";
            string discussionLink = $"https://osu.ppy.sh/beatmapsets/{beatmap.BeatmapsetId}/discussion";
            string downloadLink   = $"https://osu.ppy.sh/beatmapsets/{beatmap.BeatmapsetId}/download";
            var    descSb         = new StringBuilder();

            // Links (Row 0)
            descSb.AppendLine($"**Links:** [Listing]({beatmapLink}) ▸ [Modding]({discussionLink}) ▸ [Download]({downloadLink})");
            descSb.AppendLine();
            // Row 1
            descSb.AppendLine($@"• {OsuBase.OsuGradeEmote(osuRecent.Rank)} {osuRecent.Mods.ToModeString(OsuBase.Client)
                                                                                             .Replace("No Mode", "No Mod")
                                                                                             .Replace("DTNC", "NC")} | {scoredPerformance.Stars:N2}★");
            // Row 2
            descSb.Append($"• **Combo:** {osuRecent.MaxCombo:N0}x / {beatmap.MaxCombo:N0}x ▸ ");
            descSb.AppendLine($"**Accuracy:** {osuRecent.Accuracy:N2}% ▸ **Score:** {osuRecent.TotalScore:N0}");
            // Row 3
            descSb.Append($"• {osuRecent.Count300:N0} / {osuRecent.Count100:N0} / {osuRecent.Count50:N0} / {osuRecent.Miss:N0} ▸ ");
            descSb.AppendLine($"**BPM:** {beatmap.Bpm:N0} ▸ **Length:** {beatmap.TotalLength.TotalMinutes:00}:{beatmap.TotalLength.Seconds:00}");
            // Row 4
            descSb.Append($"• **CS:** {GetStatNumAsString(scoredPerformance.Cs)} ▸ **AR:** {GetStatNumAsString(scoredPerformance.Ar)} ▸ ");
            descSb.AppendLine($"**OD:** {GetStatNumAsString(scoredPerformance.Od)} ▸ **HP:** {GetStatNumAsString(scoredPerformance.Hp)}");
            // Row 5
            descSb.AppendLine($"• **Performance:** {scoredPerformance.Pp:N2}pp ({wouldbePerformance.Pp:N2}pp for {osuRecent.Accuracy:N2}% FC)");

            if (osuRecent.MaxCombo == beatmap.MaxCombo)
            {
                embed.SetColor(EmbedColor.GOLD);
                descSb.Append("Full combo!");
            }
            embed.Description = descSb.ToString();

            //Footer
            TimeSpan difference   = DateTime.UtcNow - osuRecent.Date.Value.DateTime;
            string   humanizedDif = difference.Humanize(2, minUnit: TimeUnit.Second);

            embed.WithFooter($"{osuPlayer.Username} performed this play {humanizedDif} ago.");

            await ReplyAsync(embed : embed.Build());
        }
Esempio n. 3
0
        //osutop extension for a specific top play. Almost the exact same thing as osutop.
        public async Task SpecificOsuTopPlay(int num, [Remainder] string player = null)
        {
            DataStorage.DbData.Models.User user = await DatabaseQueries.GetOrCreateUserAsync(Context.User.Id);

            User osuUser;

            if (num < 1 || num > 100)
            {
                await SendBasicErrorEmbedAsync("Play index must be between 1 and 100.");

                return;
            }

            if (string.IsNullOrEmpty(player))
            {
                osuUser = await OsuBase.Client.GetUserByUserIdAsync(user.OsuId, GameMode.Standard);

                if (osuUser == null)
                {
                    Embed.WithTitle($"osu! Top {num}");
                    Embed.WithDescription($"**{Context.User.Mention} Failed to acquire username. " +
                                          $"Please specify a player or set your osu! username with " +
                                          $"`{(await DatabaseQueries.GetOrCreateServerAsync(Context.Guild.Id)).CommandPrefix}osuset`!**");

                    await ReplyAsync(embed : Embed.Build());

                    return;
                }
            }
            else
            {
                player  = player.Replace(' ', '_');
                osuUser = await OsuBase.Client.GetUserByUsernameAsync(player, GameMode.Standard);

                if (osuUser == null)
                {
                    await SendBasicErrorEmbedAsync($"{Context.User.Mention} Failed to download data for `{player}`.");

                    return;
                }
            }

            IReadOnlyList <Score> playerBestObjectList = await OsuBase.Client.GetUserBestsByUserIdAsync(osuUser.UserId, GameMode.Standard);

            if (playerBestObjectList.Count < num)
            {
                await SendBasicErrorEmbedAsync($"The user does not have `{num}` top plays recorded. " +
                                               $"They only have `{playerBestObjectList.Count}`.");

                return;
            }

            Score playerBestObject = playerBestObjectList[num - 1];

            if (playerBestObject == null)
            {
                await SendBasicErrorEmbedAsync($"A play could not be found for this user at the given index.");

                return;
            }

            Embed.WithAuthor(author =>
            {
                author.Name    = $"{osuUser.Username}'s {num.Ordinalize()} Top osu! {playerBestObject.GameMode} Play";
                author.IconUrl = $"https://osu.ppy.sh/images/flags/{osuUser.Country}.png";
            });

            Embed.WithTitle($"**Top #{num} play for {osuUser.Username}:**");
            Embed.WithUrl($"https://osu.ppy.sh/u/{osuUser.UserId}");

            Beatmap beatmap = await playerBestObject.GetBeatmapAsync();

            PerformanceData pp = await beatmap.GetPPAsync(playerBestObject.Mods, (float)playerBestObject.Accuracy);

            string topPlayString =
                $"#{num}: ▸ **{OsuBase.OsuGradeEmote(playerBestObject.Rank)}{playerBestObject.Mods.ToModeString(OsuBase.Client).Replace("No Mode", "No Mod")}** ▸ " +
                $"{beatmap.BeatmapId} ▸ **[{beatmap.Title} " +
                $"[{beatmap.Difficulty}]](https://osu.ppy.sh/b/{beatmap.BeatmapId})** " +
                $"\n▸ **☆{beatmap.StarRating:N2}** ▸ **{playerBestObject.Accuracy:F}%** " +
                $"for **{pp.Pp:F}pp** " +
                $"\n▸ [Combo: {playerBestObject.MaxCombo}x / Max: {beatmap.MaxCombo}]" +
                $"\n▸ Play made {(DateTime.UtcNow - playerBestObject.Date.Value.DateTime).Humanize(minUnit: TimeUnit.Second, maxUnit: TimeUnit.Year, precision: 3)} ago\n";

            Embed.WithDescription(topPlayString);
            await ReplyAsync(embed : Embed.Build());
        }