diff --git a/src/FMBot.Bot/Builders/AlbumBuilders.cs b/src/FMBot.Bot/Builders/AlbumBuilders.cs index 40f97297..a9519dcd 100644 --- a/src/FMBot.Bot/Builders/AlbumBuilders.cs +++ b/src/FMBot.Bot/Builders/AlbumBuilders.cs @@ -1045,7 +1045,18 @@ public async Task CoverAsync( response.Embed.WithDescription(description.ToString()); - response.Embed.WithFooter(response.EmbedFooter); + response.Components = new ComponentBuilder() + .WithButton("Album", $"{InteractionConstants.Album.Info}-{databaseAlbum.Id}-{userSettings.DiscordUserId}-{context.ContextUser.DiscordUserId}", style: ButtonStyle.Secondary, emote: new Emoji("💽")) + .WithButton($"For {await this._userService.GetUserTitleAsync(context.DiscordGuild, context.DiscordUser)}", style: ButtonStyle.Secondary, disabled: true, customId: "0"); + + if (albumSearch.IsRandom) + { + response.Embed.WithFooter($"Random album #{albumSearch.RandomAlbumPosition} ({albumSearch.RandomAlbumPlaycount} {StringExtensions.GetPlaysString(albumSearch.RandomAlbumPlaycount)})"); + response.Components.WithButton("Reroll", + $"{InteractionConstants.Album.RandomCover}-{userSettings.DiscordUserId}-{context.ContextUser.DiscordUserId}", + style: ButtonStyle.Secondary, emote: new Emoji("🎲")); + } + response.Stream = image; response.FileName = $"cover-{StringExtensions.ReplaceInvalidChars($"{albumSearch.Album.ArtistName}_{albumSearch.Album.AlbumName}")}"; @@ -1057,10 +1068,6 @@ public async Task CoverAsync( await cacheStream.DisposeAsync(); - response.Components = new ComponentBuilder() - .WithButton("Album", $"{InteractionConstants.Album.Info}-{databaseAlbum.Id}-{userSettings.DiscordUserId}-{context.ContextUser.DiscordUserId}", style: ButtonStyle.Secondary, emote: new Emoji("💽")) - .WithButton($"For {await this._userService.GetUserTitleAsync(context.DiscordGuild, context.DiscordUser)}", style: ButtonStyle.Secondary, disabled: true, customId: "0"); - return response; } diff --git a/src/FMBot.Bot/Builders/PlayBuilders.cs b/src/FMBot.Bot/Builders/PlayBuilders.cs index 48d2a20a..f8cc6e95 100644 --- a/src/FMBot.Bot/Builders/PlayBuilders.cs +++ b/src/FMBot.Bot/Builders/PlayBuilders.cs @@ -840,7 +840,8 @@ public async Task MileStoneAsync( ContextModel context, UserSettingsModel userSettings, int mileStoneAmount, - long userTotalPlaycount) + long userTotalPlaycount, + bool isRandom = false) { var response = new ResponseModel { @@ -889,6 +890,13 @@ public async Task MileStoneAsync( } } + if (isRandom) + { + response.Components = new ComponentBuilder().WithButton("Reroll", + $"{InteractionConstants.RandomMilestone}-{userSettings.DiscordUserId}-{context.ContextUser.DiscordUserId}", + style: ButtonStyle.Secondary, emote: new Emoji("🎲")); + } + response.Embed.WithDescription(reply.ToString()); return response; diff --git a/src/FMBot.Bot/Resources/InteractionConstants.cs b/src/FMBot.Bot/Resources/InteractionConstants.cs index 93d41d3e..0355923c 100644 --- a/src/FMBot.Bot/Resources/InteractionConstants.cs +++ b/src/FMBot.Bot/Resources/InteractionConstants.cs @@ -77,8 +77,11 @@ public static class Album public const string Info = "album-info"; public const string Tracks = "album-tracks"; public const string Cover = "album-cover"; + public const string RandomCover = "randomalbum-cover"; } + public const string RandomMilestone = "random-milestone"; + public static class ModerationCommands { public const string CensorTypes = "admin-censor-*"; diff --git a/src/FMBot.Bot/Services/MusicBotService.cs b/src/FMBot.Bot/Services/MusicBotService.cs index 73d434db..136cd3a7 100644 --- a/src/FMBot.Bot/Services/MusicBotService.cs +++ b/src/FMBot.Bot/Services/MusicBotService.cs @@ -99,7 +99,7 @@ private async Task SendScrobbleMessage(ICommandContext context, TrackSearchResul embed.WithFooter($"Use '{prfx}botscrobbling' for more information."); _ = this.Interactivity.DelayedDeleteMessageAsync( - await context.Channel.SendMessageAsync(embed: embed.Build()), + await context.Channel.SendMessageAsync(embed: embed.Build(), flags: MessageFlags.SuppressNotification), TimeSpan.FromSeconds(120)); Log.Debug("BotScrobbling: Scrobbled {trackName} by {artistName} for {listenerCount} users in {guildName} / {guildId}", trackResult.TrackName, trackResult.ArtistName, listenerCount, context.Guild.Name, context.Guild.Id); diff --git a/src/FMBot.Bot/Services/SettingService.cs b/src/FMBot.Bot/Services/SettingService.cs index 8060065e..b561ed6a 100644 --- a/src/FMBot.Bot/Services/SettingService.cs +++ b/src/FMBot.Bot/Services/SettingService.cs @@ -1030,12 +1030,13 @@ public static long GetGoalAmount( return goalAmount; } - public static int GetMilestoneAmount( + public static (int amount, bool isRandom) GetMilestoneAmount( string extraOptions, long currentPlaycount) { var goalAmount = 100; var ownGoalSet = false; + var isRandom = false; if (extraOptions != null) { @@ -1072,6 +1073,7 @@ public static int GetMilestoneAmount( { goalAmount = RandomNumberGenerator.GetInt32(1, (int)currentPlaycount); ownGoalSet = true; + isRandom = true; break; } } @@ -1094,7 +1096,7 @@ public static int GetMilestoneAmount( goalAmount = 1; } - return goalAmount; + return (goalAmount, isRandom); } public static GuildRankingSettings SetGuildRankingSettings(GuildRankingSettings guildRankingSettings, string extraOptions) diff --git a/src/FMBot.Bot/Services/TimerService.cs b/src/FMBot.Bot/Services/TimerService.cs index faa0371d..7e8751a3 100644 --- a/src/FMBot.Bot/Services/TimerService.cs +++ b/src/FMBot.Bot/Services/TimerService.cs @@ -202,7 +202,7 @@ public async Task UpdateStatus() try { - if (this.CurrentFeatured.Status != null) + if (this.CurrentFeatured?.Status != null) { await this._client.SetCustomStatusAsync(this.CurrentFeatured.Status); return; diff --git a/src/FMBot.Bot/SlashCommands/AlbumSlashCommands.cs b/src/FMBot.Bot/SlashCommands/AlbumSlashCommands.cs index e7a4fb9f..c54191af 100644 --- a/src/FMBot.Bot/SlashCommands/AlbumSlashCommands.cs +++ b/src/FMBot.Bot/SlashCommands/AlbumSlashCommands.cs @@ -269,6 +269,39 @@ public async Task AlbumCoverAsync(string album, string discordUser, string reque } } + [ComponentInteraction($"{InteractionConstants.Album.RandomCover}-*-*")] + [UsernameSetRequired] + public async Task RandomAlbumCoverAsync(string discordUser, string requesterDiscordUser) + { + var discordUserId = ulong.Parse(discordUser); + var requesterDiscordUserId = ulong.Parse(requesterDiscordUser); + + if (this.Context.User.Id != requesterDiscordUserId) + { + await RespondAsync("🎲 Sorry, only the user that requested the random cover can reroll.", ephemeral: true); + return; + } + + _ = DeferAsync(); + await this.Context.DisableInteractionButtons(); + + var contextUser = await this._userService.GetUserWithDiscogs(requesterDiscordUserId); + var discordContextUser = await this.Context.Client.GetUserAsync(requesterDiscordUserId); + var userSettings = await this._settingService.GetOriginalContextUser(discordUserId, requesterDiscordUserId, this.Context.Guild, this.Context.User); + + try + { + var response = await this._albumBuilders.CoverAsync(new ContextModel(this.Context, contextUser, discordContextUser), userSettings, "random"); + + await this.Context.UpdateInteractionEmbed(response, this.Interactivity, false); + this.Context.LogCommandUsed(response.CommandResponse); + } + catch (Exception e) + { + await this.Context.HandleCommandException(e); + } + } + [SlashCommand("albumtracks", "Shows album info for the album you're currently listening to or searching for")] [UsernameSetRequired] [CommandContextType(InteractionContextType.BotDm, InteractionContextType.PrivateChannel, InteractionContextType.Guild)] diff --git a/src/FMBot.Bot/SlashCommands/PlaySlashCommands.cs b/src/FMBot.Bot/SlashCommands/PlaySlashCommands.cs index 393bdf5b..101f0ee5 100644 --- a/src/FMBot.Bot/SlashCommands/PlaySlashCommands.cs +++ b/src/FMBot.Bot/SlashCommands/PlaySlashCommands.cs @@ -16,6 +16,8 @@ using FMBot.Bot.Services.Guild; using FMBot.Domain.Interfaces; using FMBot.Domain.Models; +using FMBot.Subscriptions.Models; +using MetaBrainz.MusicBrainz.Interfaces; using SummaryAttribute = Discord.Interactions.SummaryAttribute; namespace FMBot.Bot.SlashCommands; @@ -101,7 +103,7 @@ await RespondAsync( try { - if (message != null && response.CommandResponse == CommandResponse.Ok) + if (message != null && this.Context.Channel != null && response.CommandResponse == CommandResponse.Ok) { if (contextUser.EmoteReactions != null && contextUser.EmoteReactions.Any() && SupporterService.IsSupporter(contextUser.UserType)) { @@ -311,7 +313,7 @@ public async Task MileStoneAsync( var mileStoneAmount = SettingService.GetMilestoneAmount(amount.ToString(), userInfo.Playcount); var response = await this._playBuilder.MileStoneAsync(new ContextModel(this.Context, contextUser), - userSettings, mileStoneAmount, userInfo.Playcount); + userSettings, mileStoneAmount.amount, userInfo.Playcount); await this.Context.SendFollowUpResponse(this.Interactivity, response); this.Context.LogCommandUsed(response.CommandResponse); @@ -322,6 +324,42 @@ public async Task MileStoneAsync( } } + [ComponentInteraction($"{InteractionConstants.RandomMilestone}-*-*")] + [UsernameSetRequired] + public async Task RandomMilestoneAsync(string discordUser, string requesterDiscordUser) + { + var discordUserId = ulong.Parse(discordUser); + var requesterDiscordUserId = ulong.Parse(requesterDiscordUser); + + if (this.Context.User.Id != requesterDiscordUserId) + { + await RespondAsync("🎲 Sorry, only the user that requested the random milestone can reroll.", ephemeral: true); + return; + } + + _ = DeferAsync(); + await this.Context.DisableInteractionButtons(); + + var contextUser = await this._userService.GetUserWithDiscogs(requesterDiscordUserId); + var userSettings = await this._settingService.GetOriginalContextUser(discordUserId, requesterDiscordUserId, this.Context.Guild, this.Context.User); + var targetUser = await this._userService.GetUserWithDiscogs(requesterDiscordUserId); + + try + { + var mileStoneAmount = SettingService.GetMilestoneAmount("random", targetUser.TotalPlaycount.GetValueOrDefault()); + + var response = await this._playBuilder.MileStoneAsync(new ContextModel(this.Context, contextUser), + userSettings, mileStoneAmount.amount, targetUser.TotalPlaycount.GetValueOrDefault(), mileStoneAmount.isRandom); + + await this.Context.UpdateInteractionEmbed(response, this.Interactivity, false); + this.Context.LogCommandUsed(response.CommandResponse); + } + catch (Exception e) + { + await this.Context.HandleCommandException(e); + } + } + [SlashCommand("year", "Shows an overview of your year")] [UsernameSetRequired] public async Task YearAsync( diff --git a/src/FMBot.Bot/TextCommands/GameCommands.cs b/src/FMBot.Bot/TextCommands/GameCommands.cs index 36b28098..a41bf37d 100644 --- a/src/FMBot.Bot/TextCommands/GameCommands.cs +++ b/src/FMBot.Bot/TextCommands/GameCommands.cs @@ -30,10 +30,10 @@ public GameCommands(IOptions botSettings, UserService userService, this.Interactivity = interactivity; } - [Command("jumble", RunMode = RunMode.Async)] - [Summary("Play the Jumble game.")] - [UsernameSetRequired] - [CommandCategories(CommandCategory.Friends)] + //[Command("jumble", RunMode = RunMode.Async)] + //[Summary("Play the Jumble game.")] + //[UsernameSetRequired] + //[CommandCategories(CommandCategory.Friends)] public async Task JumbleAsync() { _ = this.Context.Channel.TriggerTypingAsync(); diff --git a/src/FMBot.Bot/TextCommands/LastFM/PlayCommands.cs b/src/FMBot.Bot/TextCommands/LastFM/PlayCommands.cs index dfd5351c..ab37a885 100644 --- a/src/FMBot.Bot/TextCommands/LastFM/PlayCommands.cs +++ b/src/FMBot.Bot/TextCommands/LastFM/PlayCommands.cs @@ -352,7 +352,7 @@ public async Task MilestoneAsync([Remainder] string extraOptions = null) mileStoneAmount = SettingService.GetMilestoneAmount(this.Context.Message.ReferencedMessage.Content, userInfo.Playcount); } - var response = await this._playBuilder.MileStoneAsync(new ContextModel(this.Context, prfx, contextUser), userSettings, mileStoneAmount, userInfo.Playcount); + var response = await this._playBuilder.MileStoneAsync(new ContextModel(this.Context, prfx, contextUser), userSettings, mileStoneAmount.amount, userInfo.Playcount, mileStoneAmount.isRandom); await this.Context.SendResponse(this.Interactivity, response); this.Context.LogCommandUsed(response.CommandResponse);