From 851ecffe2a309407616682af5384216a1650db05 Mon Sep 17 00:00:00 2001 From: Plerx <50530305+Plerx2493@users.noreply.github.com> Date: Sun, 7 Jul 2024 22:20:24 +0200 Subject: [PATCH] Update to new DSP version --- .gitmodules | 4 + Libs/DSharpPlus | 1 + ModularAssistentForDiscordServer.sln | 26 +++ .../Commands/ContextMenu/TranslateMessage.cs | 22 +- .../Commands/Slash/About.cs | 2 +- .../Commands/Slash/BotStats.cs | 9 +- .../Commands/Slash/MessageSnipe.cs | 13 +- .../Commands/Slash/Ping.cs | 5 +- .../Commands/Slash/Purge.cs | 6 +- .../Commands/Slash/Reminder.cs | 8 +- .../Commands/Slash/StarboardConfig.cs | 2 +- .../Commands/Slash/Translation.cs | 26 +-- .../Commands/Slash/VoiceAlerts.cs | 42 ++-- .../Commands/Slash/moveEmoji.cs | 12 +- .../Commands/Text/Base/ExitGuild.cs | 11 +- .../CommandsChecks/EnsureDBEntitiesCheck.cs | 13 +- .../CommandsChecks/RequireOwnerAttribute.cs | 23 -- .../CommandsChecks/RequireOwnerCheck.cs | 37 ---- ModularAssistentForDiscordServer/Dockerfile | 4 +- .../EventListeners/EventListener.Zombied.cs | 2 +- .../Extensions/ContextExtensions.cs | 44 +--- .../Extensions/ExtensionMethods.cs | 5 +- .../ModularAssistentForDiscordServer.csproj | 11 +- .../ModularDiscordBot.cs | 13 +- ModularAssistentForDiscordServer/Program.cs | 13 +- .../Services/DiscordCommandService.cs | 3 +- .../Services/LoggingService.cs | 209 +++++------------- .../Services/MessageSnipeService.cs | 11 +- .../Services/StarboardService.cs | 17 +- .../Services/UserManagerService.cs | 3 +- .../Services/VoiceAlertService.cs | 5 +- 31 files changed, 229 insertions(+), 373 deletions(-) create mode 100644 .gitmodules create mode 160000 Libs/DSharpPlus delete mode 100644 ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerAttribute.cs delete mode 100644 ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerCheck.cs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..54a0384 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "Libs/DSharpPlus"] + path = Libs/DSharpPlus + url = https://github.com/DSharpPlus/DSharpPlus.git + branch = aki/sharding diff --git a/Libs/DSharpPlus b/Libs/DSharpPlus new file mode 160000 index 0000000..039166a --- /dev/null +++ b/Libs/DSharpPlus @@ -0,0 +1 @@ +Subproject commit 039166ab1b5fba02065ce8109146c38a4b65c273 diff --git a/ModularAssistentForDiscordServer.sln b/ModularAssistentForDiscordServer.sln index 07cbd2a..9ceb790 100644 --- a/ModularAssistentForDiscordServer.sln +++ b/ModularAssistentForDiscordServer.sln @@ -10,6 +10,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{574BAEF3-5632-4726-A8E1-3A60997E3615}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus", "Libs\DSharpPlus\DSharpPlus\DSharpPlus.csproj", "{4621D464-9FA4-49A9-B83E-7151D0165323}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Commands", "Libs\DSharpPlus\DSharpPlus.Commands\DSharpPlus.Commands.csproj", "{68B430C9-249C-4166-B9A1-369596A4A964}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Interactivity", "Libs\DSharpPlus\DSharpPlus.Interactivity\DSharpPlus.Interactivity.csproj", "{4D977814-F030-4643-BF67-741FDA152D6A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSharpPlus.Rest", "Libs\DSharpPlus\DSharpPlus.Rest\DSharpPlus.Rest.csproj", "{C7A08C2E-6CB7-4B8F-BE22-BA835749D3F4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,6 +30,22 @@ Global {13E4FD67-0ADF-48D0-9EF7-837991B465A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {13E4FD67-0ADF-48D0-9EF7-837991B465A8}.Release|Any CPU.ActiveCfg = Release|Any CPU {13E4FD67-0ADF-48D0-9EF7-837991B465A8}.Release|Any CPU.Build.0 = Release|Any CPU + {4621D464-9FA4-49A9-B83E-7151D0165323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4621D464-9FA4-49A9-B83E-7151D0165323}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4621D464-9FA4-49A9-B83E-7151D0165323}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4621D464-9FA4-49A9-B83E-7151D0165323}.Release|Any CPU.Build.0 = Release|Any CPU + {68B430C9-249C-4166-B9A1-369596A4A964}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {68B430C9-249C-4166-B9A1-369596A4A964}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68B430C9-249C-4166-B9A1-369596A4A964}.Release|Any CPU.ActiveCfg = Release|Any CPU + {68B430C9-249C-4166-B9A1-369596A4A964}.Release|Any CPU.Build.0 = Release|Any CPU + {4D977814-F030-4643-BF67-741FDA152D6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D977814-F030-4643-BF67-741FDA152D6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D977814-F030-4643-BF67-741FDA152D6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D977814-F030-4643-BF67-741FDA152D6A}.Release|Any CPU.Build.0 = Release|Any CPU + {C7A08C2E-6CB7-4B8F-BE22-BA835749D3F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7A08C2E-6CB7-4B8F-BE22-BA835749D3F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7A08C2E-6CB7-4B8F-BE22-BA835749D3F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7A08C2E-6CB7-4B8F-BE22-BA835749D3F4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ModularAssistentForDiscordServer/Commands/ContextMenu/TranslateMessage.cs b/ModularAssistentForDiscordServer/Commands/ContextMenu/TranslateMessage.cs index aaedc94..f7291e7 100644 --- a/ModularAssistentForDiscordServer/Commands/ContextMenu/TranslateMessage.cs +++ b/ModularAssistentForDiscordServer/Commands/ContextMenu/TranslateMessage.cs @@ -34,16 +34,16 @@ public TranslateMessage(TranslateInformationService translateInformationService, _translateInformationService = translateInformationService; _translator = translator; } - + [SlashCommandTypes(DiscordApplicationCommandType.MessageContextMenu), Command("Translate message")] - public async Task TranslateAsync(SlashCommandContext ctx, DiscordMessage targetMessage) + public async Task TranslateAsync(SlashCommandContext ctx, DiscordMessage targetMessage) { await ctx.DeferAsync(true); string? preferredLanguage = await _translateInformationService.GetPreferredLanguageAsync(ctx.User.Id); bool isPreferredLanguageSet = !preferredLanguage.IsNullOrWhiteSpace(); - - if(!isPreferredLanguageSet) + + if (!isPreferredLanguageSet) { preferredLanguage = "en-US"; } @@ -54,15 +54,15 @@ public async Task TranslateAsync(SlashCommandContext ctx, DiscordMessage target if (messageContent.IsNullOrWhiteSpace()) { - await ctx.CreateResponse_Error("⚠️ Message is empty!"); + await ctx.RespondErrorAsync("⚠️ Message is empty!"); return; } - - TextResult translatedMessage = + + TextResult translatedMessage = await _translator.TranslateTextAsync(messageContent, null, preferredLanguage!); - + DiscordEmbedBuilder embed = new DiscordEmbedBuilder() - .WithAuthor(message.Author?.Username, + .WithAuthor(message.Author?.Username, message.Author?.AvatarUrl) .WithDescription(translatedMessage.Text) .WithColor(new DiscordColor(0, 255, 194)) @@ -83,8 +83,8 @@ public async Task TranslateAsync(SlashCommandContext ctx, DiscordMessage target .AddComponents(new DiscordButtonComponent(DiscordButtonStyle.Primary, "setLanguage", "Set your language to en-US") .AsActionButton(ActionDiscordButtonEnum.SetTranslationLanguage, "en-US")) .AsEphemeral(); - - + + await ctx.FollowupAsync(followUpMessage); } } \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/Commands/Slash/About.cs b/ModularAssistentForDiscordServer/Commands/Slash/About.cs index 78951d7..e65055f 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/About.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/About.cs @@ -53,7 +53,7 @@ public async Task AboutCommand(CommandContext ctx) .AddField("D#+ Version:", ctx.Client.VersionString) .AddField("Guilds", ctx.Client.Guilds.Count.ToString(), true) .AddField("Uptime", date.Humanize(), true) - .AddField("Ping", $"{ctx.Client.Ping} ms", true) + //.AddField("Ping", $"{ctx.Client.Ping} ms", true) .AddField("Add me", addMe); discordMessageBuilder.AddEmbed(discordEmbedBuilder.Build()); diff --git a/ModularAssistentForDiscordServer/Commands/Slash/BotStats.cs b/ModularAssistentForDiscordServer/Commands/Slash/BotStats.cs index 798e981..60cae1d 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/BotStats.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/BotStats.cs @@ -13,12 +13,14 @@ // limitations under the License. using System.ComponentModel; +using System.Configuration; using System.Diagnostics; using DSharpPlus; using DSharpPlus.Commands; using DSharpPlus.Entities; using Humanizer; using MADS.Entities; +using MADS.Extensions; using Microsoft.EntityFrameworkCore; namespace MADS.Commands.Slash; @@ -37,6 +39,7 @@ public BotStats(IDbContextFactory contextFactory, DiscordRestClient [Command("botstats"), Description("Get statistics about the bot")] public async Task GetBotStatsAsync(CommandContext ctx) { + await ctx.DeferAsync(true); await using MadsContext db = await _contextFactory.CreateDbContextAsync(); Stopwatch swDb = new(); Stopwatch swRest = new(); @@ -46,7 +49,7 @@ public async Task GetBotStatsAsync(CommandContext ctx) _ = await db.Guilds.FirstOrDefaultAsync(); swDb.Stop(); - _ = await _discordRestClient.GetChannelAsync(ctx.Guild.Channels.Values.First().Id); + _ = await _discordRestClient.GetChannelAsync(ctx.Channel.Id); swRest.Start(); _ = await _discordRestClient.GetChannelAsync(ctx.Channel.Id); swRest.Stop(); @@ -55,7 +58,7 @@ public async Task GetBotStatsAsync(CommandContext ctx) int members = db.Users.Count(); int guilds = db.Guilds.Count(); - int ping = ctx.Client.Ping; + //int ping = ctx.Client.Ping; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true, true); string heapMemory = $"{process.PrivateMemorySize64 / 1024 / 1024} MB"; @@ -66,7 +69,7 @@ public async Task GetBotStatsAsync(CommandContext ctx) .AddField("Membercount:", members.ToString("N0"), true) .AddField("Guildcount:", guilds.ToString("N0"), true) .AddField("Threads:", $"{ThreadPool.ThreadCount}", true) - .AddField("Websocket Latency:", ping.ToString("N0") + " ms", true) + //.AddField("Websocket Latency:", ping.ToString("N0") + " ms", true) .AddField("DB Latency:", swDb.ElapsedMilliseconds.ToString("N0") + " ms", true) .AddField("Rest Latency:", swRest.ElapsedMilliseconds.ToString("N0") + " ms", true) .AddField("Memory:", heapMemory, true) diff --git a/ModularAssistentForDiscordServer/Commands/Slash/MessageSnipe.cs b/ModularAssistentForDiscordServer/Commands/Slash/MessageSnipe.cs index d04655e..043be0a 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/MessageSnipe.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/MessageSnipe.cs @@ -15,6 +15,7 @@ using System.ComponentModel; using DSharpPlus; using DSharpPlus.Commands; +using DSharpPlus.Commands.ContextChecks; using DSharpPlus.Entities; using MADS.CustomComponents; using MADS.Extensions; @@ -31,13 +32,13 @@ public MessageSnipe(MessageSnipeService messageSnipeService) _messageSnipeService = messageSnipeService; } - [Command("snipe"), Description("Snipes the last deleted message.")] + [Command("snipe"), Description("Snipes the last deleted message."), RequireGuild] public async Task SnipeAsync(CommandContext ctx) { await DoSnipeAsync(ctx, false); } - [Command("snipeedit"), Description("Snipes the last edited message.")] + [Command("snipeedit"), Description("Snipes the last edited message."), RequireGuild] public async Task SnipeEditAsync(CommandContext ctx) { await DoSnipeAsync(ctx, true); @@ -53,7 +54,7 @@ private async Task DoSnipeAsync(CommandContext ctx, bool edit) if (!result || message is null) { - await ctx.EditResponse_Error( + await ctx.RespondAsync( "⚠️ No message to snipe! Either nothing was deleted, or the message has expired (12 hours)!"); return; } @@ -64,14 +65,14 @@ await ctx.EditResponse_Error( content = string.Concat(content.AsSpan(0, 497), "..."); } - DiscordMember? member = message.Author is not null ? await ctx.Guild.GetMemberAsync(message.Author.Id) : null; + DiscordMember? member = message.Author is not null ? await ctx.Guild!.GetMemberAsync(message.Author.Id) : null; DiscordEmbedBuilder embed = new DiscordEmbedBuilder() .WithAuthor( $"{member?.DisplayName ?? message.Author?.GlobalName}" + (edit ? " (Edited)" : ""), iconUrl: message.Author?.GetAvatarUrl(ImageFormat.Png)) .WithFooter( - $"{(edit ? "Edit" : "Deletion")} sniped by {ctx.Member.DisplayName}", + $"{(edit ? "Edit" : "Deletion")} sniped by {ctx.Member!.DisplayName}", ctx.User.AvatarUrl); if (!string.IsNullOrEmpty(content)) @@ -124,6 +125,6 @@ public async Task DeleteSnipeAsync(CommandContext ctx) _messageSnipeService.DeleteMessage(ctx.Channel.Id); _messageSnipeService.DeleteEditedMessage(ctx.Channel.Id); - await ctx.EditResponse_Success("✅ Snipe cache cleared!"); + await ctx.RespondSuccessAsync("✅ Snipe cache cleared!"); } } \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/Commands/Slash/Ping.cs b/ModularAssistentForDiscordServer/Commands/Slash/Ping.cs index d323cd6..6b87480 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/Ping.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/Ping.cs @@ -32,8 +32,9 @@ public async Task PingCommand(CommandContext ctx) .WithTitle("Status") .WithTimestamp(DateTime.Now) .WithColor(new DiscordColor(0, 255, 194)) - .AddField("Uptime", $"{DateTimeOffset.UtcNow.Subtract(process.StartTime).Humanize(3, minUnit: TimeUnit.Millisecond, maxUnit: TimeUnit.Day)}") - .AddField("Websocket ping", $"{ctx.Client.Ping} ms"); + .AddField("Uptime", + $"{DateTimeOffset.UtcNow.Subtract(process.StartTime).Humanize(3, minUnit: TimeUnit.Millisecond, maxUnit: TimeUnit.Day)}"); + //.AddField("Websocket ping", $"{ctx.Client.Ping} ms"); DiscordInteractionResponseBuilder responseBuilder = new(); responseBuilder.AddEmbed(discordEmbedBuilder).AsEphemeral(); diff --git a/ModularAssistentForDiscordServer/Commands/Slash/Purge.cs b/ModularAssistentForDiscordServer/Commands/Slash/Purge.cs index a8e2c55..5b5d1b9 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/Purge.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/Purge.cs @@ -32,15 +32,15 @@ public async Task PurgeMessages { if (amount > 100) { - await ctx.CreateResponse_Error("You cannot purge more than 100 messages at once", true); + await ctx.RespondErrorAsync("You cannot purge more than 100 messages at once", true); return; } await ctx.DeferAsync(); DiscordMessage? response = await ctx.GetResponseAsync()!; - + List messages = []; - await foreach (DiscordMessage msg in ctx.Channel.GetMessagesAsync((int) amount)) + await foreach (DiscordMessage msg in ctx.Channel.GetMessagesAsync((int)amount)) { messages.Add(msg); } diff --git a/ModularAssistentForDiscordServer/Commands/Slash/Reminder.cs b/ModularAssistentForDiscordServer/Commands/Slash/Reminder.cs index 7412a9a..26f8f33 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/Reminder.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/Reminder.cs @@ -53,7 +53,7 @@ public async Task AddReminder if (timeSpan is null) { - await ctx.EditResponse_Error("Invalid timespan (5s, 3m, 7h, 2d)"); + await ctx.RespondErrorAsync("Invalid timespan (5s, 3m, 7h, 2d)"); return; } @@ -71,7 +71,7 @@ public async Task AddReminder ReminderDbEntity reminder = await _reminderService.AddReminder(newReminder); - await ctx.EditResponse_Success($"Reminder created with id `{reminder.Id}`. I will remind you in {Formatter.Timestamp(timeSpan.Value)}"); + await ctx.RespondSuccessAsync($"Reminder created with id `{reminder.Id}`. I will remind you in {Formatter.Timestamp(timeSpan.Value)}"); } [Command("list"), Description("list your Reminder")] @@ -110,7 +110,7 @@ long id if (reminder is null) { - await ctx.EditResponse_Error("Reminder does not exists"); + await ctx.RespondErrorAsync("Reminder does not exists"); return; } @@ -118,7 +118,7 @@ long id if (!success) { - await ctx.EditResponse_Error("Something went wrong. Are you sure you own this reminder?"); + await ctx.RespondErrorAsync("Something went wrong. Are you sure you own this reminder?"); return; } diff --git a/ModularAssistentForDiscordServer/Commands/Slash/StarboardConfig.cs b/ModularAssistentForDiscordServer/Commands/Slash/StarboardConfig.cs index eba366e..642525e 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/StarboardConfig.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/StarboardConfig.cs @@ -53,7 +53,7 @@ public async Task StarboardConfigCommand MadsContext db = await _contextFactory.CreateDbContextAsync(); - GuildConfigDbEntity guildConfig = db.Configs.First(x => x.GuildId == ctx.Guild.Id); + GuildConfigDbEntity guildConfig = db.Configs.First(x => x.GuildId == ctx.Guild!.Id); if (!DiscordEmoji.TryFromUnicode(emojiString, out DiscordEmoji emoji)) { diff --git a/ModularAssistentForDiscordServer/Commands/Slash/Translation.cs b/ModularAssistentForDiscordServer/Commands/Slash/Translation.cs index 2211d5d..9a0289f 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/Translation.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/Translation.cs @@ -29,21 +29,21 @@ public class Translation { private readonly TranslateInformationService _translationUserInfo; private readonly Translator _translator; - + public Translation(TranslateInformationService translationUserInfo, Translator translator) { _translationUserInfo = translationUserInfo; _translator = translator; } - + [Command("info"), Description("Get your preferred language")] public async Task InfoAsync(CommandContext ctx) { string? lang = await _translationUserInfo.GetPreferredLanguageAsync(ctx.User.Id); - - await ctx.CreateResponse_Success($"Language set to `{lang ?? "null"}`"); + + await ctx.RespondSuccessAsync($"Language set to `{lang ?? "null"}`"); } - + [Command("setLanguage"), Description("Set your preferred language")] public async Task SetLanguageAsync ( @@ -54,15 +54,15 @@ public async Task SetLanguageAsync { if (string.IsNullOrWhiteSpace(language)) { - await ctx.CreateResponse_Error("⚠️ Language can't be empty!"); + await ctx.RespondErrorAsync("⚠️ Language can't be empty!"); return; } string code = TranslateInformationService.StandardizeLang(language); - + _translationUserInfo.SetPreferredLanguage(ctx.User.Id, code); - - await ctx.CreateResponse_Success($"✅ Language set to {code}"); + + await ctx.RespondSuccessAsync($"✅ Language set to {code}"); } [Command("translate"), Description("Translate a text")] @@ -78,22 +78,22 @@ public async Task TranslateText ) { await ctx.DeferAsync(); - + if (string.IsNullOrWhiteSpace(text)) { await ctx.EditResponseAsync(new DiscordWebhookBuilder() .WithContent("⚠️ Text can't be empty!")); return; } - + TextResult translatedText = await _translator.TranslateTextAsync(text, null, language); - + DiscordEmbedBuilder embed = new DiscordEmbedBuilder() .WithDescription(translatedText.Text) .WithColor(new DiscordColor(0, 255, 194)) .WithFooter($"Translated from {translatedText.DetectedSourceLanguageCode} to {language}") .WithTimestamp(DateTime.Now); - + DiscordInteractionResponseBuilder responseBuilder = new(); responseBuilder.AddEmbed(embed).AsEphemeral(!publicResult); diff --git a/ModularAssistentForDiscordServer/Commands/Slash/VoiceAlerts.cs b/ModularAssistentForDiscordServer/Commands/Slash/VoiceAlerts.cs index a06c17a..67b6274 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/VoiceAlerts.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/VoiceAlerts.cs @@ -30,37 +30,37 @@ namespace MADS.Commands.Slash; public sealed class VoiceAlerts { private readonly VoiceAlertService _voiceAlertService; - + public VoiceAlerts(VoiceAlertService voiceAlertService) { _voiceAlertService = voiceAlertService; } - + [Command("add"), Description("add a voicealert"), RequireGuild] public async Task AddAlert ( CommandContext ctx, - + [Description("channel which will be monitored"), ChannelTypes(DiscordChannelType.Voice, DiscordChannelType.Stage)] DiscordChannel channel, - + [Description("time which has to pass between alerts")] TimeSpan? minTimeBetween, - + [Description("If the alert should be repeated or one shot. (Defaults to false (one shot))")] bool repeat = false ) { if (channel.Type is not (DiscordChannelType.Voice or DiscordChannelType.Stage)) { - await ctx.CreateResponse_Error($"<#{channel.Id}> is not a voice channel", true); + await ctx.RespondErrorAsync($"{channel.Mention} is not a voice channel", true); return; } - + if (minTimeBetween is null) { - await ctx.CreateResponse_Error( + await ctx.RespondErrorAsync( "Invalid timespan (5s, 3m, 7h, 2d) - Use 0s if you want to get a alert everytime (Warning: This could lead to Spam)", true); return; @@ -69,16 +69,16 @@ await ctx.CreateResponse_Error( IEnumerable currentAlerts = await _voiceAlertService.GetVoiceAlertsAsync(ctx.User.Id); if (currentAlerts.Any(x => x.ChannelId == channel.Id)) { - await ctx.CreateResponse_Error($"<#{channel.Id}> is already in your VoiceAlerts", true); + await ctx.RespondErrorAsync($"<#{channel.Id}> is already in your VoiceAlerts", true); return; } - + await _voiceAlertService.AddVoiceAlertAsync(ctx.User.Id, channel.Id, ctx.Guild!.Id, repeat, minTimeBetween.Value); - - await ctx.CreateResponse_Success($"Added <#{channel.Id}> to your VoiceAlerts", true); + + await ctx.RespondSuccessAsync($"Added <#{channel.Id}> to your VoiceAlerts", true); } - + [Command("delete"), Description("delete a voicealerts")] public async Task RemoveAlert ( @@ -91,22 +91,22 @@ string channel bool isId = ulong.TryParse(channel, out ulong id); if (!isId) { - await ctx.CreateResponse_Error($"**{channel}** is not a valid id", true); + await ctx.RespondErrorAsync($"**{channel}** is not a valid id", true); return; } IEnumerable currentAlerts = await _voiceAlertService.GetVoiceAlertsAsync(ctx.User.Id); if (!currentAlerts.Any(x => x.ChannelId == id)) { - await ctx.CreateResponse_Error($"<#{id}> is not in your VoiceAlerts", true); + await ctx.RespondErrorAsync($"<#{id}> is not in your VoiceAlerts", true); return; } - await _voiceAlertService.RemoveVoiceAlertAsync(ctx.User.Id, id, ctx.Guild.Id); + await _voiceAlertService.RemoveVoiceAlertAsync(ctx.User.Id, id, ctx.Guild!.Id); - await ctx.CreateResponse_Success($"Removed <#{channel}> from your VoiceAlerts", true); + await ctx.RespondSuccessAsync($"Removed <#{channel}> from your VoiceAlerts", true); } - + [Command("list"), Description("list all voicealerts")] public async Task ListAlerts(CommandContext ctx) { @@ -116,15 +116,15 @@ public async Task ListAlerts(CommandContext ctx) { builder.AppendLine($"<#{alert.ChannelId}> {(alert.IsRepeatable ? "repeated" : "")}"); } - + if (builder.Length == 0) { builder.AppendLine("You have no VoiceAlerts"); } - + DiscordInteractionResponseBuilder responseBuilder = new(); responseBuilder.WithContent(builder.ToString()).AsEphemeral(); - + await ctx.RespondAsync(responseBuilder); } } \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/Commands/Slash/moveEmoji.cs b/ModularAssistentForDiscordServer/Commands/Slash/moveEmoji.cs index 62a314c..efe37bf 100644 --- a/ModularAssistentForDiscordServer/Commands/Slash/moveEmoji.cs +++ b/ModularAssistentForDiscordServer/Commands/Slash/moveEmoji.cs @@ -28,7 +28,7 @@ namespace MADS.Commands.Slash; public sealed partial class MoveEmoji { - [Command("MoveEmoji"), Description("Move emoji to your guild"), RequirePermissions(DiscordPermissions.ManageEmojis)] + [Command("MoveEmoji"), Description("Move emoji to your guild"), RequirePermissions(DiscordPermissions.ManageEmojis), RequireGuild] public async Task MoveEmojiAsync (CommandContext ctx, [Description("Emoji which should be moved")] string emoji) { @@ -38,7 +38,7 @@ public async Task MoveEmojiAsync if (!matches.Any()) { - await ctx.EditResponse_Error("There are no emojis in your input"); + await ctx.RespondErrorAsync("There are no emojis in your input"); return; } @@ -48,7 +48,7 @@ public async Task MoveEmojiAsync if (!ulong.TryParse(split, out ulong emojiId)) { - await ctx.EditResponse_Error("⚠️ Failed to fetch your new emoji."); + await ctx.RespondErrorAsync("⚠️ Failed to fetch your new emoji."); return; } @@ -71,7 +71,7 @@ public async Task MoveEmojiAsync if (!guilds.Any()) { - await ctx.EditResponse_Error("There are no guilds where you are able to add emojis"); + await ctx.RespondErrorAsync("There are no guilds where you are able to add emojis"); return; } @@ -86,7 +86,7 @@ public async Task MoveEmojiAsync //Get the initial response an wait for a component interaction DiscordMessage? response = await ctx.GetResponseAsync(); InteractivityResult selectResponse = await response!.WaitForSelectAsync( - ctx.Member, "moveEmojiChooseGuild-" + ctx.User.Id, + ctx.Member!, "moveEmojiChooseGuild-" + ctx.User.Id, TimeSpan.FromSeconds(60)); //Notify the user when the interaction times out and abort @@ -114,7 +114,7 @@ await ctx.EditResponseAsync(new DiscordWebhookBuilder await CopyEmoji(ctx.Client, emojiName, emojiId, animated, guildId); } - await ctx.EditResponse_Success("Emoji moved"); + await ctx.RespondSuccessAsync("Emoji moved"); } private static async Task CopyEmoji(DiscordClient client, string name, ulong id, bool animated, ulong targetGuild) diff --git a/ModularAssistentForDiscordServer/Commands/Text/Base/ExitGuild.cs b/ModularAssistentForDiscordServer/Commands/Text/Base/ExitGuild.cs index 54aeba4..679670b 100644 --- a/ModularAssistentForDiscordServer/Commands/Text/Base/ExitGuild.cs +++ b/ModularAssistentForDiscordServer/Commands/Text/Base/ExitGuild.cs @@ -23,17 +23,10 @@ namespace MADS.Commands.Text.Base; public class ExitGuild { - [Command("exit"), Description("Exit the bot"), RequirePermissions(DiscordPermissions.ManageGuild), RequireGuild] - public async Task ExitGuildCommand(TextCommandContext ctx) - { - await ctx.RespondAsync("Leaving server..."); - await ctx.Guild.LeaveAsync(); - } - - [Command("leave"), Description("Leave given server"), RequireGuild, RequireOwner] + [Command("leave"), Description("Leave given server"), RequireGuild, RequireApplicationOwner] public async Task LeaveGuildOwner(TextCommandContext ctx) { await ctx.Message.DeleteAsync(); - await ctx.Guild.LeaveAsync(); + await ctx.Guild!.LeaveAsync(); } } \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/CommandsChecks/EnsureDBEntitiesCheck.cs b/ModularAssistentForDiscordServer/CommandsChecks/EnsureDBEntitiesCheck.cs index 3cd7250..d727453 100644 --- a/ModularAssistentForDiscordServer/CommandsChecks/EnsureDBEntitiesCheck.cs +++ b/ModularAssistentForDiscordServer/CommandsChecks/EnsureDBEntitiesCheck.cs @@ -12,25 +12,31 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System.Diagnostics; using DSharpPlus.Commands; using DSharpPlus.Commands.ContextChecks; using DSharpPlus.Entities; using MADS.Entities; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; namespace MADS.CommandsChecks; public class EnsureDBEntitiesCheck : IContextCheck { private IDbContextFactory _contextFactory; + private readonly ILogger _logger; - public EnsureDBEntitiesCheck(IDbContextFactory dbContextFactory) + public EnsureDBEntitiesCheck(IDbContextFactory dbContextFactory, ILogger logger) { _contextFactory = dbContextFactory; + _logger = logger; } public async ValueTask ExecuteCheckAsync(UnconditionalCheckAttribute _, CommandContext context) { + Stopwatch sw = Stopwatch.StartNew(); + DiscordUser user = context.User; await using MadsContext dbContext = await _contextFactory.CreateDbContextAsync(); @@ -60,6 +66,11 @@ await dbContext.Guilds.Upsert(guildDbEntity) .RunAsync(); await dbContext.SaveChangesAsync(); + + sw.Stop(); + + _logger.LogTrace($"EnsureDBEntitiesCheck took {sw.ElapsedMilliseconds} ms"); + return null; } } \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerAttribute.cs b/ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerAttribute.cs deleted file mode 100644 index ae505e2..0000000 --- a/ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerAttribute.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2023 Plerx2493 -// -// Licensed under the Apache License, Version 2.0 (the "License") -// You may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using DSharpPlus.Commands.ContextChecks; - -namespace MADS.CommandsChecks; - -[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class), ] -public class RequireOwnerAttribute : ContextCheckAttribute -{ - -} \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerCheck.cs b/ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerCheck.cs deleted file mode 100644 index 22c6c60..0000000 --- a/ModularAssistentForDiscordServer/CommandsChecks/RequireOwnerCheck.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2023 Plerx2493 -// -// Licensed under the Apache License, Version 2.0 (the "License") -// You may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using DSharpPlus.Commands; -using DSharpPlus.Commands.ContextChecks; -using DSharpPlus.Entities; - -namespace MADS.CommandsChecks; - -public class RequireOwnerCheck : IContextCheck -{ - public ValueTask ExecuteCheckAsync(RequireOwnerAttribute attribute, CommandContext context) - { - DiscordApplication app = context.Client.CurrentApplication; - DiscordUser me = context.Client.CurrentUser; - - bool isOwner = app is not null ? app!.Owners!.Any(x => x.Id == context.User.Id) : context.User.Id == me.Id; - - if (!isOwner) - { - return ValueTask.FromResult("User must be on of the application owner"); - } - - return ValueTask.FromResult(null); - } -} \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/Dockerfile b/ModularAssistentForDiscordServer/Dockerfile index 0b0d9ab..503c1fa 100644 --- a/ModularAssistentForDiscordServer/Dockerfile +++ b/ModularAssistentForDiscordServer/Dockerfile @@ -1,9 +1,11 @@ # BUILD FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build +WORKDIR /Libs +COPY ../Libs ./ WORKDIR /src COPY ./ModularAssistentForDiscordServer ./ RUN dotnet restore -RUN dotnet publish -c Release -o out +RUN dotnet publish -c Debug -o out # RUNNER IMAGE FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine diff --git a/ModularAssistentForDiscordServer/EventListeners/EventListener.Zombied.cs b/ModularAssistentForDiscordServer/EventListeners/EventListener.Zombied.cs index d8c1acd..8bc34cb 100644 --- a/ModularAssistentForDiscordServer/EventListeners/EventListener.Zombied.cs +++ b/ModularAssistentForDiscordServer/EventListeners/EventListener.Zombied.cs @@ -22,7 +22,7 @@ internal static partial class EventListener { internal static async Task OnZombied(DiscordClient sender, ZombiedEventArgs e) { - await sender.ReconnectAsync(true); + await sender.ReconnectAsync(); } internal static Task OnGuildAvailable(DiscordClient sender, GuildCreatedEventArgs e) diff --git a/ModularAssistentForDiscordServer/Extensions/ContextExtensions.cs b/ModularAssistentForDiscordServer/Extensions/ContextExtensions.cs index 037b14a..f615987 100644 --- a/ModularAssistentForDiscordServer/Extensions/ContextExtensions.cs +++ b/ModularAssistentForDiscordServer/Extensions/ContextExtensions.cs @@ -27,61 +27,35 @@ public static async ValueTask DeferAsync(this CommandContext ctx, bool ephemeral await slashContext.DeferResponseAsync(ephemeral); return; } - + await ctx.DeferResponseAsync(); } - - public static async ValueTask CreateResponse_Error(this CommandContext ctx, string message, bool isEphemeral = false) + + public static async ValueTask RespondErrorAsync(this CommandContext ctx, string message, bool isEphemeral = false) { DiscordEmbedBuilder embed = new DiscordEmbedBuilder() .WithTitle("Error") .WithDescription(message) .WithColor(DiscordColor.Red); - + DiscordInteractionResponseBuilder response = new DiscordInteractionResponseBuilder() .AddEmbed(embed) .AsEphemeral(isEphemeral); - + await ctx.RespondAsync(response); } - - public static async ValueTask CreateResponse_Success(this CommandContext ctx, string message, bool isEphemeral = false) + + public static async ValueTask RespondSuccessAsync(this CommandContext ctx, string message, bool isEphemeral = false) { DiscordEmbedBuilder embed = new DiscordEmbedBuilder() .WithTitle("Success") .WithDescription(message) .WithColor(DiscordColor.Green); - + DiscordInteractionResponseBuilder response = new DiscordInteractionResponseBuilder() .AddEmbed(embed) .AsEphemeral(isEphemeral); - + await ctx.RespondAsync(response); } - - public static async ValueTask EditResponse_Error(this CommandContext ctx, string message) - { - DiscordEmbedBuilder embed = new DiscordEmbedBuilder() - .WithTitle("Error") - .WithDescription(message) - .WithColor(DiscordColor.Red); - - DiscordWebhookBuilder response = new DiscordWebhookBuilder() - .AddEmbed(embed); - - await ctx.EditResponseAsync(response); - } - - public static async ValueTask EditResponse_Success(this CommandContext ctx, string message) - { - DiscordEmbedBuilder embed = new DiscordEmbedBuilder() - .WithTitle("Success") - .WithDescription(message) - .WithColor(DiscordColor.Green); - - DiscordWebhookBuilder response = new DiscordWebhookBuilder() - .AddEmbed(embed); - - await ctx.EditResponseAsync(response); - } } \ No newline at end of file diff --git a/ModularAssistentForDiscordServer/Extensions/ExtensionMethods.cs b/ModularAssistentForDiscordServer/Extensions/ExtensionMethods.cs index 8aff7d2..0dd6480 100644 --- a/ModularAssistentForDiscordServer/Extensions/ExtensionMethods.cs +++ b/ModularAssistentForDiscordServer/Extensions/ExtensionMethods.cs @@ -29,11 +29,10 @@ public static IServiceCollection AddDiscordRestClient(this IServiceCollection se { DiscordConfiguration discordRestConfig = new() { - Token = config.Token, - LoggerFactory = new LoggerFactory().AddSerilog() + }; - serviceCollection.AddSingleton(new DiscordRestClient(discordRestConfig)); + serviceCollection.AddSingleton(new DiscordRestClient(discordRestConfig, config.Token, TokenType.Bot)); return serviceCollection; } diff --git a/ModularAssistentForDiscordServer/ModularAssistentForDiscordServer.csproj b/ModularAssistentForDiscordServer/ModularAssistentForDiscordServer.csproj index a186812..eb21136 100644 --- a/ModularAssistentForDiscordServer/ModularAssistentForDiscordServer.csproj +++ b/ModularAssistentForDiscordServer/ModularAssistentForDiscordServer.csproj @@ -25,10 +25,6 @@ - - - - @@ -54,4 +50,11 @@ + + + + + + + diff --git a/ModularAssistentForDiscordServer/ModularDiscordBot.cs b/ModularAssistentForDiscordServer/ModularDiscordBot.cs index 48629af..53a84d7 100644 --- a/ModularAssistentForDiscordServer/ModularDiscordBot.cs +++ b/ModularAssistentForDiscordServer/ModularDiscordBot.cs @@ -14,8 +14,8 @@ using DeepL; using DSharpPlus; +using DSharpPlus.Clients; using DSharpPlus.Extensions; -using DSharpPlus.Net; using MADS.Entities; using MADS.EventListeners; using MADS.Extensions; @@ -38,11 +38,18 @@ public async Task RunAsync() { await Host.CreateDefaultBuilder() .UseSerilog() - .ConfigureServices((_, services) => + .ConfigureServices((ctx, services) => { MadsConfig config = DataProvider.GetConfig(); services - .AddLogging(logging => logging.ClearProviders().AddSerilog()) + .AddLogging(logging => + { + logging + .SetMinimumLevel(LogLevel.Trace) + .AddFilter("Microsoft.EntityFrameworkCore", LogLevel.Warning) + .AddFilter("Quartz", LogLevel.Warning) + .AddConsole(); + }) .AddSingleton(config) .AddDiscordClient(config.Token, DiscordIntents.All ^ DiscordIntents.GuildPresences) .AddDiscordRestClient(config) diff --git a/ModularAssistentForDiscordServer/Program.cs b/ModularAssistentForDiscordServer/Program.cs index 340847e..960f17b 100644 --- a/ModularAssistentForDiscordServer/Program.cs +++ b/ModularAssistentForDiscordServer/Program.cs @@ -31,20 +31,21 @@ internal static class MainProgram public static async Task Main() { - await Task.Delay(10000); //Delay to give the databases time to start + await Task.Delay(20_000); //Delay to give the databases time to start Log.Logger = new LoggerConfiguration() - .WriteTo.Console() - .MinimumLevel.Verbose() - .MinimumLevel.Override("Quartz", LogEventLevel.Warning) - .CreateLogger(); + .WriteTo.Console() + .MinimumLevel.Verbose() + .MinimumLevel.Override("Quartz", LogEventLevel.Warning) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) + .CreateLogger(); //retrieves the config.json MadsConfig config = DataProvider.GetConfig(); //Create a discordWebhookClient and add the debug webhook from the config.json WebhookClient = new DiscordWebhookClient(); - Uri webhookUrl = new Uri(config.DiscordWebhook); + Uri webhookUrl = new(config.DiscordWebhook); await WebhookClient.AddWebhookAsync(webhookUrl); //Create a new instance of the bot diff --git a/ModularAssistentForDiscordServer/Services/DiscordCommandService.cs b/ModularAssistentForDiscordServer/Services/DiscordCommandService.cs index 4be8083..af76f64 100644 --- a/ModularAssistentForDiscordServer/Services/DiscordCommandService.cs +++ b/ModularAssistentForDiscordServer/Services/DiscordCommandService.cs @@ -38,7 +38,7 @@ public class DiscordCommandService : IHostedService public readonly DiscordClient DiscordClient; public DateTime StartTime; - private static ILogger _logger = Log.ForContext(); + private static readonly ILogger _logger = Log.ForContext(); public DiscordCommandService ( @@ -68,7 +68,6 @@ IDbContextFactory dbContextFactory Commands = DiscordClient.UseCommands(commandsConfiguration); Commands.AddCommands(commandTypes); Commands.AddCheck(); - Commands.AddCheck(); Commands.CommandErrored += EventListener.OnCommandsErrored; //Interactivity diff --git a/ModularAssistentForDiscordServer/Services/LoggingService.cs b/ModularAssistentForDiscordServer/Services/LoggingService.cs index 44f6627..7bdafd5 100644 --- a/ModularAssistentForDiscordServer/Services/LoggingService.cs +++ b/ModularAssistentForDiscordServer/Services/LoggingService.cs @@ -17,6 +17,7 @@ using System.Text.RegularExpressions; using DSharpPlus; using DSharpPlus.Entities; +using DSharpPlus.EventArgs; using DSharpPlus.Exceptions; using MADS.Entities; using MADS.Extensions; @@ -28,165 +29,83 @@ namespace MADS.Services; public class LoggingService { - private static readonly Regex PrettyNameRegex = new("PRETTY_NAME=(.*)", RegexOptions.Compiled); - private readonly string _dirPath = DataProvider.GetPath("Logs"); - private readonly string _logPath; - private DiscordRestClient _discordRestClient; - private DiscordCommandService? _modularDiscordBot; + private readonly DiscordCommandService? _modularDiscordBot; private DiscordWebhookClient _discordWebhookClient = new(); - private bool _isSetup; - private List _ownerChannel = []; - private static readonly Serilog.ILogger _logger = Log.ForContext(); - - public LoggingService() - { - Directory.CreateDirectory(_dirPath); - - DateTime startDate = DateTime.Now; - _logPath = DataProvider.GetPath("Logs", - $"{startDate.Day}-{startDate.Month}-{startDate.Year}_{startDate.Hour}-{startDate.Minute}-{startDate.Second}.log"); - - string osVersion = Environment.OSVersion.VersionString; - string os = osVersion.StartsWith("Unix") ? FetchLinuxName() : Environment.OSVersion.VersionString; - - File.AppendAllText(_logPath, $".Net: {RuntimeInformation.FrameworkDescription}\n", Encoding.UTF8); - File.AppendAllText(_logPath, $"Operating system: {os}\n", Encoding.UTF8); - File.AppendAllText(_logPath, "========== LOG START ==========\n\n", Encoding.UTF8); - } - - //Fetching Linux name by Naamloos. Can be found in Naamloos/Modcore - private static string FetchLinuxName() - { - try - { - string result = File.ReadAllText("/etc/os-release"); - Match match = PrettyNameRegex.Match(result); - return !match.Success ? Environment.OSVersion.VersionString : match.Groups[1].Value.Replace("\"", ""); - } - catch - { - return Environment.OSVersion.VersionString; - } - } - - public void Setup(DiscordCommandService modularDiscordBot) + public LoggingService(DiscordCommandService modularDiscordBot) { _modularDiscordBot = modularDiscordBot; - if (_isSetup) - { - return; - } + +#pragma warning disable DSP0001 // Type or member is obsolete + //Button response with modal + _modularDiscordBot.DiscordClient.ComponentInteractionCreated += HandleFeedbackButton; + + //Modal processing + _modularDiscordBot.DiscordClient.ModalSubmitted += HandleFeedbackModal; +#pragma warning restore DSP0001 // Type or member is obsolete - _discordRestClient = ModularDiscordBot.Services.GetRequiredService(); - AddOwnerChannels(); - SetupFeedback(); SetupWebhookLogging(); - - _isSetup = true; } - - private async void AddOwnerChannels() + + private async Task HandleFeedbackButton(DiscordClient _, ComponentInteractionCreatedEventArgs e) { - DiscordApplication? application = _modularDiscordBot?.DiscordClient.CurrentApplication; - DiscordUser[]? owners = application?.Owners?.ToArray(); - if (owners is null || owners.Length == 0) + if (e.Id != "feedback-button") { return; } - - _ownerChannel = new List(); - - foreach (DiscordUser owner in owners) - { - DiscordDmChannel ownerChannel; - try - { - ownerChannel = await _discordRestClient.CreateDmAsync(owner.Id); - } - catch (DiscordException) - { - continue; - } + DiscordInteractionResponseBuilder modal = new(); - _ownerChannel.Add(ownerChannel); - } - - _logger.Information( - "Found {OwnerChannel} dm Channel for {Owner} application owner", - _ownerChannel.Count, owners.Length); + modal + .WithTitle("Feedback") + .WithCustomId("feedback-modal") + .AddComponents(new DiscordTextInputComponent("Please enter your feedback:", "feedback-text", + required: true, + style: DiscordTextInputStyle.Paragraph)); + + await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.Modal, modal); } - - private void SetupFeedback() + + private async Task HandleFeedbackModal(DiscordClient _, ModalSubmittedEventArgs e) { - if (_modularDiscordBot is null) + if (e.Interaction.Data.CustomId != "feedback-modal") { - throw new Exception("LoggingService is not set up."); + return; } - - //Button response with modal - _modularDiscordBot.DiscordClient.ComponentInteractionCreated += async (_, e) => - { - if (e.Id != "feedback-button") - { - return; - } - DiscordInteractionResponseBuilder modal = new(); + DiscordInteractionResponseBuilder responseBuilder = new(); + DiscordEmbedBuilder embedBuilder = new(); - modal - .WithTitle("Feedback") - .WithCustomId("feedback-modal") - .AddComponents(new DiscordTextInputComponent("Please enter your feedback:", "feedback-text", - required: true, - style: DiscordTextInputStyle.Paragraph)); + embedBuilder + .WithTitle("Thank you for submitting your feedback") + .WithColor(DiscordColor.Green); - await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.Modal, modal); - }; - - //Modal processing - _modularDiscordBot.DiscordClient.ModalSubmitted += async (_, e) => - { - if (e.Interaction.Data.CustomId != "feedback-modal") - { - return; - } + responseBuilder + .AddEmbed(embedBuilder) + .AsEphemeral(); - DiscordInteractionResponseBuilder responseBuilder = new(); - DiscordEmbedBuilder embedBuilder = new(); + await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.ChannelMessageWithSource, + responseBuilder); - embedBuilder - .WithTitle("Thank you for submitting your feedback") - .WithColor(DiscordColor.Green); + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract + string guildName = + e.Interaction.Guild is null ? "Dms" : e.Interaction.Guild.Name; - responseBuilder - .AddEmbed(embedBuilder) - .AsEphemeral(); - - await e.Interaction.CreateResponseAsync(DiscordInteractionResponseType.ChannelMessageWithSource, - responseBuilder); - - // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - string guildName = - e.Interaction.Guild is null ? "Dms" : e.Interaction.Guild.Name; - - DiscordEmbedBuilder discordEmbed = new() + DiscordEmbedBuilder discordEmbed = new() + { + Title = "Feedback", + Description = e.Values["feedback-text"], + Color = new DiscordColor(0, 255, 194), + Timestamp = (DateTimeOffset)DateTime.Now, + Footer = new DiscordEmbedBuilder.EmbedFooter { - Title = "Feedback", - Description = e.Values["feedback-text"], - Color = new DiscordColor(0, 255, 194), - Timestamp = (DateTimeOffset)DateTime.Now, - Footer = new DiscordEmbedBuilder.EmbedFooter - { - Text = "Send by " + e.Interaction.User.Username + " from " + guildName - } - }; - - await _discordWebhookClient.BroadcastMessageAsync(new DiscordWebhookBuilder().AddEmbed(discordEmbed)); + Text = "Send by " + e.Interaction.User.Username + " from " + guildName + } }; + + await _discordWebhookClient.BroadcastMessageAsync(new DiscordWebhookBuilder().AddEmbed(discordEmbed)); } - + private void SetupWebhookLogging() { _discordWebhookClient = new DiscordWebhookClient(); @@ -195,30 +114,6 @@ private void SetupWebhookLogging() _discordWebhookClient.AddWebhookAsync(webhookUrl).GetAwaiter().GetResult(); } - public async Task> LogToOwner(string message, string sender, LogLevel logLevel) - { - DiscordEmbedBuilder discordEmbed = new() - { - Title = logLevel.ToString(), - Description = message, - Color = new DiscordColor(0, 255, 194), - Timestamp = DateTime.Now, - Footer = new DiscordEmbedBuilder.EmbedFooter - { - Text = "Send by " + sender - } - }; - - List messageList = []; - - foreach (DiscordDmChannel channel in _ownerChannel) - { - messageList.Add(await channel.SendMessageAsync(discordEmbed)); - } - - return messageList; - } - public async Task LogToWebhook(DiscordMessageBuilder message) { DiscordWebhookBuilder messageBuilder = new(message); diff --git a/ModularAssistentForDiscordServer/Services/MessageSnipeService.cs b/ModularAssistentForDiscordServer/Services/MessageSnipeService.cs index a6f0dcb..53fe630 100644 --- a/ModularAssistentForDiscordServer/Services/MessageSnipeService.cs +++ b/ModularAssistentForDiscordServer/Services/MessageSnipeService.cs @@ -41,22 +41,21 @@ public MessageSnipeService(IMemoryCache memoryCache, DiscordCommandService disco _options.SetAbsoluteExpiration(TimeSpan.FromHours(12)) .SetSize(1) .RegisterPostEvictionCallback(PostEvictionCallback); + +#pragma warning disable DSP0001 // Type or member is obsolete + Discord.MessageDeleted += MessageSniperDeleted; + Discord.MessageUpdated += MessageSniperEdited; +#pragma warning restore DSP0001 // Type or member is obsolete } public Task StartAsync(CancellationToken cancellationToken) { _logger.Warning("Sniper active!"); - Discord.MessageDeleted += MessageSniperDeleted; - Discord.MessageUpdated += MessageSniperEdited; - return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { - Discord.MessageDeleted -= MessageSniperDeleted; - Discord.MessageUpdated -= MessageSniperEdited; - return Task.CompletedTask; } diff --git a/ModularAssistentForDiscordServer/Services/StarboardService.cs b/ModularAssistentForDiscordServer/Services/StarboardService.cs index 8f5ce5d..d6aa128 100644 --- a/ModularAssistentForDiscordServer/Services/StarboardService.cs +++ b/ModularAssistentForDiscordServer/Services/StarboardService.cs @@ -41,15 +41,17 @@ public StarboardService(DiscordCommandService command, IDbContextFactory(); _dbFactory = dbFactory; - } - - public Task StartAsync(CancellationToken cancellationToken) - { + +#pragma warning disable DSP0001 _client.MessageReactionAdded += HandleReactionAdded; _client.MessageReactionRemoved += HandleReactionRemoved; _client.MessageReactionsCleared += HandleReactionsCleared; _client.MessageReactionRemovedEmoji += HandleReactionEmojiRemoved; - +#pragma warning restore DSP0001 + } + + public Task StartAsync(CancellationToken cancellationToken) + { _handleQueueTask = Task.Factory.StartNew(HandleQueueAsync, _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); @@ -59,11 +61,6 @@ public Task StartAsync(CancellationToken cancellationToken) public Task StopAsync(CancellationToken cancellationToken) { - _client.MessageReactionAdded -= HandleReactionAdded; - _client.MessageReactionRemoved -= HandleReactionRemoved; - _client.MessageReactionsCleared -= HandleReactionsCleared; - _client.MessageReactionRemovedEmoji -= HandleReactionEmojiRemoved; - _stopped = true; _logger.Information("Starboard stopped"); _cts.Cancel(); diff --git a/ModularAssistentForDiscordServer/Services/UserManagerService.cs b/ModularAssistentForDiscordServer/Services/UserManagerService.cs index f3d8b12..ac90fb9 100644 --- a/ModularAssistentForDiscordServer/Services/UserManagerService.cs +++ b/ModularAssistentForDiscordServer/Services/UserManagerService.cs @@ -42,8 +42,7 @@ public async ValueTask GetOrCreateUserAsync(DiscordUser discordUse user = new UserDbEntity { Id = discordUser.Id, - Username = discordUser.Username, - PreferedLanguage = "en" + Username = discordUser.Username }; await context.Users.AddAsync(user); diff --git a/ModularAssistentForDiscordServer/Services/VoiceAlertService.cs b/ModularAssistentForDiscordServer/Services/VoiceAlertService.cs index d850d30..80e0326 100644 --- a/ModularAssistentForDiscordServer/Services/VoiceAlertService.cs +++ b/ModularAssistentForDiscordServer/Services/VoiceAlertService.cs @@ -40,11 +40,13 @@ public VoiceAlertService(IDbContextFactory contextFactory, DiscordC _discordClient = discordCommandService.DiscordClient; _contextFactory = contextFactory; _eventChannel = Channel.CreateUnbounded(); +#pragma warning disable DSP0001 // Type or member is obsolete + _discordClient.VoiceStateUpdated += AddEvent; +#pragma warning restore DSP0001 // Type or member is obsolete } public Task StartAsync(CancellationToken cancellationToken) { - _discordClient.VoiceStateUpdated += AddEvent; _stopped = false; _handleQueueTask = Task.Factory.StartNew(HandleQueueAsync, _cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); @@ -54,7 +56,6 @@ public Task StartAsync(CancellationToken cancellationToken) public Task StopAsync(CancellationToken cancellationToken) { - _discordClient.VoiceStateUpdated -= AddEvent; _stopped = true; _cts.Cancel(); _handleQueueTask?.Dispose();