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()); }
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()); }
//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()); }