diff --git a/CHANGELOG.md b/CHANGELOG.md index 2843dd24a..374ffd360 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog. - `.poll` commands removed, discord added polls. - `.scpl` and other music soundcloud commands have been removed as soundcloud isn't issuing new api tokens for years now - Removed a lot of useless and nsfw commands +- Removed log voice presence TTS ## [4.3.22] - 23.04.2023 diff --git a/src/Nadeko.Medusa/Context/AnyContext.cs b/src/Nadeko.Medusa/Context/AnyContext.cs index f2bb17046..bcb8403e2 100644 --- a/src/Nadeko.Medusa/Context/AnyContext.cs +++ b/src/Nadeko.Medusa/Context/AnyContext.cs @@ -40,13 +40,4 @@ public abstract class AnyContext /// Arguments (if any) to format in /// A formatted localized string public abstract string GetText(string key, object[]? args = null); - - /// - /// Creates a context-aware instance - /// (future feature for guild-based embed colors) - /// Any code dealing with embeds should use it for future-proofness - /// instead of manually creating embedbuilder instances - /// - /// A context-aware instance - public abstract EmbedBuilder Embed(); } \ No newline at end of file diff --git a/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs b/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs index e5af4a1e1..ef26ae184 100644 --- a/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs +++ b/src/Nadeko.Medusa/Extensions/MedusaExtensions.cs @@ -14,13 +14,13 @@ // // // unlocalized // public static Task SendConfirmAsync(this IMessageChannel ch, AnyContext ctx, string msg) -// => ch.EmbedAsync(ctx.Embed().WithOkColor().WithDescription(msg)); +// => _sender.Response(ch).Embed(ctx.Embed().WithOkColor().WithDescription(msg)).SendAsync(); // // public static Task SendPendingAsync(this IMessageChannel ch, AnyContext ctx, string msg) -// => ch.EmbedAsync(ctx.Embed().WithPendingColor().WithDescription(msg)); +// => _sender.Response(ch).Embed(ctx.Embed().WithPendingColor().WithDescription(msg)).SendAsync(); // // public static Task SendErrorAsync(this IMessageChannel ch, AnyContext ctx, string msg) -// => ch.EmbedAsync(ctx.Embed().WithErrorColor().WithDescription(msg)); +// => _sender.Response(ch).Embed(ctx.Embed().WithErrorColor().WithDescription(msg)).SendAsync(); // // // unlocalized // public static Task SendConfirmAsync(this AnyContext ctx, string msg) diff --git a/src/Nadeko.Medusa/IEmbedBuilder.cs b/src/Nadeko.Medusa/IEmbedBuilder.cs deleted file mode 100644 index fa94ea6f4..000000000 --- a/src/Nadeko.Medusa/IEmbedBuilder.cs +++ /dev/null @@ -1,18 +0,0 @@ -ο»Ώusing Discord; - -namespace NadekoBot; - -public interface IEmbedBuilder -{ - EmbedBuilder WithDescription(string? desc); - EmbedBuilder WithTitle(string? title); - EmbedBuilder AddField(string title, object value, bool isInline = false); - EmbedBuilder WithFooter(string text, string? iconUrl = null); - EmbedBuilder WithAuthor(string name, string? iconUrl = null, string? url = null); - EmbedBuilder WithColor(EmbedColor color); - EmbedBuilder WithDiscordColor(Color color); - Embed Build(); - EmbedBuilder WithUrl(string url); - EmbedBuilder WithImageUrl(string url); - EmbedBuilder WithThumbnailUrl(string url); -} \ No newline at end of file diff --git a/src/NadekoBot/Db/Models/LogSetting.cs b/src/NadekoBot/Db/Models/LogSetting.cs index c957a6873..c899ee7ca 100644 --- a/src/NadekoBot/Db/Models/LogSetting.cs +++ b/src/NadekoBot/Db/Models/LogSetting.cs @@ -32,6 +32,7 @@ public class LogSetting : DbEntity //voicepresence public ulong? LogVoicePresenceId { get; set; } + public ulong? LogVoicePresenceTTSId { get; set; } public ulong? LogWarnsId { get; set; } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs b/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs index 8c3c6c335..6ee80891a 100644 --- a/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs +++ b/src/NadekoBot/Modules/Administration/GreetBye/GreetService.cs @@ -19,18 +19,21 @@ public class GreetService : INService, IReadyExecutor private readonly GreetGrouper _byes = new(); private readonly BotConfigService _bss; private readonly IReplacementService _repSvc; + private readonly IMessageSenderService _sender; public GreetService( DiscordSocketClient client, IBot bot, DbService db, BotConfigService bss, + IMessageSenderService sender, IReplacementService repSvc) { _db = db; _client = client; _bss = bss; _repSvc = repSvc; + _sender = sender; _guildConfigsCache = new(bot.AllGuildConfigs.ToDictionary(g => g.GuildId, GreetSettings.Create)); @@ -281,6 +284,7 @@ public class GreetService : INService, IReadyExecutor FullMode = BoundedChannelFullMode.DropNewest }); + private async Task GreetDmUser(GreetSettings conf, IGuildUser user) { var completionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); @@ -298,32 +302,32 @@ public class GreetService : INService, IReadyExecutor // .Build(); var repCtx = new ReplacementContext(client: _client, guild: user.Guild, users: user); - var text = SmartText.CreateFrom(conf.DmGreetMessageText); - text = await _repSvc.ReplaceAsync(text, repCtx); + var smartText = SmartText.CreateFrom(conf.DmGreetMessageText); + smartText = await _repSvc.ReplaceAsync(smartText, repCtx); - if (text is SmartPlainText pt) + if (smartText is SmartPlainText pt) { - text = new SmartEmbedText() + smartText = new SmartEmbedText() { Description = pt.Text }; } - if (text is SmartEmbedText set) + if (smartText is SmartEmbedText set) { - text = set with + smartText = set with { Footer = CreateFooterSource(user) }; } - else if (text is SmartEmbedTextArray seta) + else if (smartText is SmartEmbedTextArray seta) { // if the greet dm message is a text array var ebElem = seta.Embeds.LastOrDefault(); if (ebElem is null) { // if there are no embeds, add an embed with the footer - text = seta with + smartText = seta with { Embeds = new[] { @@ -355,7 +359,7 @@ public class GreetService : INService, IReadyExecutor } } - await user.SendAsync(text); + await _sender.Response(user).Text(smartText).SendAsync(); } catch { diff --git a/src/NadekoBot/Modules/Administration/Mute/MuteService.cs b/src/NadekoBot/Modules/Administration/Mute/MuteService.cs index 7a5db10d9..23b821d72 100644 --- a/src/NadekoBot/Modules/Administration/Mute/MuteService.cs +++ b/src/NadekoBot/Modules/Administration/Mute/MuteService.cs @@ -31,13 +31,13 @@ public class MuteService : INService private readonly DiscordSocketClient _client; private readonly DbService _db; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; - public MuteService(DiscordSocketClient client, DbService db, IEmbedBuilderService eb) + public MuteService(DiscordSocketClient client, DbService db, IMessageSenderService sender) { _client = client; _db = db; - _eb = eb; + _sender = sender; using (var uow = db.GetDbContext()) { @@ -122,13 +122,13 @@ public class MuteService : INService if (string.IsNullOrWhiteSpace(reason)) return; - _ = Task.Run(() => user.SendMessageAsync(embed: new EmbedBuilder() - .WithDescription( - $"You've been muted in {user.Guild} server") - .AddField("Mute Type", type.ToString()) - .AddField("Moderator", mod.ToString()) - .AddField("Reason", reason) - .Build())); + _ = Task.Run(() => _sender.Response(user) + .Embed(new EmbedBuilder() + .WithDescription($"You've been muted in {user.Guild} server") + .AddField("Mute Type", type.ToString()) + .AddField("Moderator", mod.ToString()) + .AddField("Reason", reason)) + .SendAsync()); } private void OnUserUnmuted( @@ -140,13 +140,13 @@ public class MuteService : INService if (string.IsNullOrWhiteSpace(reason)) return; - _ = Task.Run(() => user.SendMessageAsync(embed: new EmbedBuilder() - .WithDescription( - $"You've been unmuted in {user.Guild} server") - .AddField("Unmute Type", type.ToString()) - .AddField("Moderator", mod.ToString()) - .AddField("Reason", reason) - .Build())); + _ = Task.Run(() => _sender.Response(user) + .Embed(new EmbedBuilder() + .WithDescription($"You've been unmuted in {user.Guild} server") + .AddField("Unmute Type", type.ToString()) + .AddField("Moderator", mod.ToString()) + .AddField("Reason", reason)) + .SendAsync()); } private Task Client_UserJoined(IGuildUser usr) diff --git a/src/NadekoBot/Modules/Administration/Self/CheckForUpdatesService.cs b/src/NadekoBot/Modules/Administration/Self/CheckForUpdatesService.cs index e18b10092..f8bcb01d7 100644 --- a/src/NadekoBot/Modules/Administration/Self/CheckForUpdatesService.cs +++ b/src/NadekoBot/Modules/Administration/Self/CheckForUpdatesService.cs @@ -10,16 +10,16 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor private readonly IBotCredsProvider _bcp; private readonly IHttpClientFactory _httpFactory; private readonly DiscordSocketClient _client; - private readonly IEmbedBuilderService _ebs; + private readonly IMessageSenderService _sender; public CheckForUpdatesService(BotConfigService bcs, IBotCredsProvider bcp, IHttpClientFactory httpFactory, - DiscordSocketClient client, IEmbedBuilderService ebs) + DiscordSocketClient client, IMessageSenderService sender) { _bcs = bcs; _bcp = bcp; _httpFactory = httpFactory; _client = client; - _ebs = ebs; + _sender = sender; } public async Task OnReadyAsync() @@ -86,7 +86,7 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor .WithDescription(thisVersionChangelog.TrimTo(4096)) .WithFooter("You may disable these messages by typing '.conf bot checkforupdates false'"); - await user.EmbedAsync(eb); + await _sender.Response(user).Embed(eb).SendAsync(); }).WhenAll(); } } diff --git a/src/NadekoBot/Modules/Administration/Self/SelfService.cs b/src/NadekoBot/Modules/Administration/Self/SelfService.cs index 15e200c47..2d40b96ee 100644 --- a/src/NadekoBot/Modules/Administration/Self/SelfService.cs +++ b/src/NadekoBot/Modules/Administration/Self/SelfService.cs @@ -25,7 +25,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService private readonly IHttpClientFactory _httpFactory; private readonly BotConfigService _bss; private readonly IPubSub _pubSub; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; //keys private readonly TypedKey _activitySetKey; @@ -40,7 +40,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService IHttpClientFactory factory, BotConfigService bss, IPubSub pubSub, - IEmbedBuilderService eb) + IMessageSenderService sender) { _cmdHandler = cmdHandler; _db = db; @@ -50,7 +50,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService _httpFactory = factory; _bss = bss; _pubSub = pubSub; - _eb = eb; + _sender = sender; _activitySetKey = new("activity.set"); _guildLeaveKey = new("guild.leave"); @@ -225,7 +225,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService { try { - await ownerCh.Response(_strings, _eb).Confirm(title, toSend).SendAsync(); + await _sender.Response(ownerCh).Confirm(title, toSend).SendAsync(); } catch { @@ -238,7 +238,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService try { if (_client.GetChannel(cid) is ITextChannel ch) - await ch.Response(_strings, _eb).Confirm(title, toSend).SendAsync(); + await _sender.Response(ch).Confirm(title, toSend).SendAsync(); } catch { @@ -252,7 +252,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService { try { - await firstOwnerChannel.Response(_strings, _eb).Confirm(title, toSend).SendAsync(); + await _sender.Response(firstOwnerChannel).Confirm(title, toSend).SendAsync(); } catch { diff --git a/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommandService.cs b/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommandService.cs index 08c840ad3..447c8733f 100644 --- a/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommandService.cs +++ b/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommandService.cs @@ -22,7 +22,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor private readonly MuteService _mute; private readonly ProtectionService _prot; private readonly GuildTimezoneService _tz; - private readonly IEmbedBuilderService _eb; private readonly IMemoryCache _memoryCache; private readonly ConcurrentHashSet _ignoreMessageIds = new(); @@ -37,20 +36,18 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor ProtectionService prot, GuildTimezoneService tz, IMemoryCache memoryCache, - IEmbedBuilderService eb, UserPunishService punishService, IMessageSenderService sender) { _client = client; _memoryCache = memoryCache; - _eb = eb; + _sender = sender; _strings = strings; _db = db; _mute = mute; _prot = prot; _tz = tz; _punishService = punishService; - _sender = sender; using (var uow = db.GetDbContext()) { @@ -73,7 +70,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor _client.UserLeft += _client_UserLeft; // _client.PresenceUpdated += _client_UserPresenceUpdated; _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated; - _client.UserVoiceStateUpdated += _client_UserVoiceStateUpdated_TTS; _client.GuildMemberUpdated += _client_GuildUserUpdated; _client.PresenceUpdated += _client_PresenceUpdated; _client.UserUpdated += _client_UserUpdated; @@ -168,11 +164,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor var title = GetText(logChannel.Guild, strs.thread_deleted); - await logChannel.EmbedAsync(new EmbedBuilder() + await _sender.Response(logChannel).Embed(new EmbedBuilder() .WithOkColor() .WithTitle("πŸ—‘ " + title) .WithDescription($"{ch.Name} | {ch.Id}") - .WithFooter(CurrentTime(ch.Guild))); + .WithFooter(CurrentTime(ch.Guild))).SendAsync(); } catch (Exception) { @@ -198,11 +194,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor var title = GetText(logChannel.Guild, strs.thread_created); - await logChannel.EmbedAsync(new EmbedBuilder() + await _sender.Response(logChannel).Embed(new EmbedBuilder() .WithOkColor() .WithTitle("πŸ†• " + title) .WithDescription($"{ch.Name} | {ch.Id}") - .WithFooter(CurrentTime(ch.Guild))); + .WithFooter(CurrentTime(ch.Guild))).SendAsync(); } catch (Exception) { @@ -313,7 +309,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor logSetting.UserLeftId = logSetting.UserBannedId = logSetting.UserUnbannedId = logSetting.UserUpdatedId = logSetting.ChannelCreatedId = logSetting.ChannelDestroyedId = logSetting.ChannelUpdatedId = logSetting.LogUserPresenceId = logSetting.LogVoicePresenceId = logSetting.UserMutedId = - logSetting.LogVoicePresenceTTSId = logSetting.ThreadCreatedId = logSetting.ThreadDeletedId + logSetting.ThreadCreatedId = logSetting.ThreadDeletedId = logSetting.LogWarnsId = value ? channelId : null; await uow.SaveChangesAsync(); GuildLogSettings.AddOrUpdate(guildId, _ => logSetting, (_, _) => logSetting); @@ -339,7 +335,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor .AddField("Reason", string.IsNullOrWhiteSpace(arg.Reason) ? "-" : arg.Reason, true) .WithFooter(CurrentTime(g)); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } private Task _client_UserUpdated(SocketUser before, SocketUser uAfter) @@ -389,7 +385,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor else return; - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch { @@ -451,10 +447,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor case LogType.VoicePresence: channelId = logSetting.LogVoicePresenceId = logSetting.LogVoicePresenceId is null ? cid : default; break; - case LogType.VoicePresenceTts: - channelId = logSetting.LogVoicePresenceTTSId = - logSetting.LogVoicePresenceTTSId is null ? cid : default; - break; case LogType.UserWarned: channelId = logSetting.LogWarnsId = logSetting.LogWarnsId is null ? cid : default; break; @@ -472,48 +464,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor return channelId is not null; } - private Task _client_UserVoiceStateUpdated_TTS(SocketUser iusr, SocketVoiceState before, SocketVoiceState after) - { - _ = Task.Run(async () => - { - try - { - if (iusr is not IGuildUser usr) - return; - - var beforeVch = before.VoiceChannel; - var afterVch = after.VoiceChannel; - - if (beforeVch == afterVch) - return; - - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) - || logSetting.LogVoicePresenceTTSId is null) - return; - - ITextChannel? logChannel; - if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.VoicePresenceTts)) is null) - return; - - var str = string.Empty; - if (beforeVch?.Guild == afterVch?.Guild) - str = GetText(logChannel.Guild, strs.log_vc_moved(usr.Username, beforeVch?.Name, afterVch?.Name)); - else if (beforeVch is null) - str = GetText(logChannel.Guild, strs.log_vc_joined(usr.Username, afterVch?.Name)); - else if (afterVch is null) - str = GetText(logChannel.Guild, strs.log_vc_left(usr.Username, beforeVch.Name)); - - var toDelete = await logChannel.SendMessageAsync(str, true); - toDelete.DeleteAfter(5); - } - catch - { - // ignored - } - }); - return Task.CompletedTask; - } - private void MuteCommands_UserMuted( IGuildUser usr, IUser mod, @@ -551,7 +501,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor .WithFooter(CurrentTime(usr.Guild)) .WithOkColor(); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch { @@ -601,7 +551,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor if (!string.IsNullOrWhiteSpace(reason)) embed.WithDescription(reason); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch { @@ -653,7 +603,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor .WithFooter(CurrentTime(logChannel.Guild)) .WithOkColor(); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch { @@ -711,7 +661,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor .AddField(GetText(logChannel.Guild, strs.new_nick), $"{after.Nickname}#{after.Discriminator}"); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } else if (!before.Roles.SequenceEqual(after.Roles)) { @@ -721,7 +671,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor embed.WithAuthor("βš” " + GetText(logChannel.Guild, strs.user_role_add)) .WithDescription(string.Join(", ", diffRoles).SanitizeMentions()); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } else if (before.Roles.Count > after.Roles.Count) { @@ -735,7 +685,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor embed.WithAuthor("βš” " + GetText(logChannel.Guild, strs.user_role_rem)) .WithDescription(string.Join(", ", diffRoles).SanitizeMentions()); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } } } @@ -791,7 +741,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor else return; - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch { @@ -826,11 +776,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor else title = GetText(logChannel.Guild, strs.text_chan_destroyed); - await logChannel.EmbedAsync(new EmbedBuilder() + await _sender.Response(logChannel).Embed(new EmbedBuilder() .WithOkColor() .WithTitle("πŸ†• " + title) .WithDescription($"{ch.Name} | {ch.Id}") - .WithFooter(CurrentTime(ch.Guild))); + .WithFooter(CurrentTime(ch.Guild))).SendAsync(); } catch { @@ -862,11 +812,11 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor else title = GetText(logChannel.Guild, strs.text_chan_created); - await logChannel.EmbedAsync(new EmbedBuilder() + await _sender.Response(logChannel).Embed(new EmbedBuilder() .WithOkColor() .WithTitle("πŸ†• " + title) .WithDescription($"{ch.Name} | {ch.Id}") - .WithFooter(CurrentTime(ch.Guild))); + .WithFooter(CurrentTime(ch.Guild))).SendAsync(); } catch (Exception) { @@ -975,7 +925,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) embed.WithThumbnailUrl(usr.GetAvatarUrl()); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch { @@ -1014,7 +964,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) embed.WithThumbnailUrl(usr.GetAvatarUrl()); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch (Exception) { @@ -1049,7 +999,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) embed.WithThumbnailUrl(usr.GetAvatarUrl()); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch (Exception) { @@ -1099,7 +1049,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor if (Uri.IsWellFormedUriString(avatarUrl, UriKind.Absolute)) embed.WithThumbnailUrl(usr.GetAvatarUrl()); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch (Exception) { @@ -1152,7 +1102,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor string.Join(", ", msg.Attachments.Select(a => a.Url))); } - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch (Exception) { @@ -1212,7 +1162,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor .AddField("Id", after.Id.ToString()) .WithFooter(CurrentTime(channel.Guild)); - await logChannel.EmbedAsync(embed); + await _sender.Response(logChannel).Embed(embed).SendAsync(); } catch { @@ -1266,9 +1216,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor case LogType.VoicePresence: id = logSetting.LogVoicePresenceId; break; - case LogType.VoicePresenceTts: - id = logSetting.LogVoicePresenceTTSId; - break; case LogType.UserMuted: id = logSetting.UserMutedId; break; @@ -1348,9 +1295,6 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor case LogType.VoicePresence: newLogSetting.LogVoicePresenceId = null; break; - case LogType.VoicePresenceTts: - newLogSetting.LogVoicePresenceTTSId = null; - break; case LogType.UserWarned: newLogSetting.LogWarnsId = null; break; diff --git a/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs b/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs index e27a00536..d3c7be60b 100644 --- a/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs +++ b/src/NadekoBot/Modules/Administration/ServerLog/ServerLogCommands.cs @@ -145,8 +145,6 @@ public partial class Administration return l.LogUserPresenceId; case LogType.VoicePresence: return l.LogVoicePresenceId; - case LogType.VoicePresenceTts: - return l.LogVoicePresenceTTSId; case LogType.UserMuted: return l.UserMutedId; case LogType.UserWarned: diff --git a/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs index 3657a869c..6ba7ed294 100644 --- a/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs +++ b/src/NadekoBot/Modules/Administration/UserPunish/UserPunishCommands.cs @@ -65,11 +65,13 @@ public partial class Administration var dmFailed = false; try { - await user.EmbedAsync(new EmbedBuilder() - .WithErrorColor() - .WithDescription(GetText(strs.warned_on(ctx.Guild.ToString()))) - .AddField(GetText(strs.moderator), ctx.User.ToString()) - .AddField(GetText(strs.reason), reason ?? "-")); + await _sender.Response(user) + .Embed(new EmbedBuilder() + .WithErrorColor() + .WithDescription(GetText(strs.warned_on(ctx.Guild.ToString()))) + .AddField(GetText(strs.moderator), ctx.User.ToString()) + .AddField(GetText(strs.reason), reason ?? "-")) + .SendAsync(); } catch { @@ -84,7 +86,8 @@ public partial class Administration catch (Exception ex) { Log.Warning(ex, "Exception occured while warning a user"); - var errorEmbed = new EmbedBuilder().WithErrorColor().WithDescription(GetText(strs.cant_apply_punishment)); + var errorEmbed = new EmbedBuilder().WithErrorColor() + .WithDescription(GetText(strs.cant_apply_punishment)); if (dmFailed) errorEmbed.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user)); @@ -261,9 +264,9 @@ public partial class Administration }); return new EmbedBuilder() - .WithOkColor() - .WithTitle(GetText(strs.warnings_list)) - .WithDescription(string.Join("\n", ws)); + .WithOkColor() + .WithTitle(GetText(strs.warnings_list)) + .WithDescription(string.Join("\n", ws)); }, warnings.Length, 15); @@ -433,9 +436,10 @@ public partial class Administration try { var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), msg)); - var embed = await _service.GetBanUserDmEmbed(Context, guildUser, defaultMessage, msg, time.Time); - if (embed is not null) - await guildUser.SendAsync(embed); + var smartText = + await _service.GetBanUserDmEmbed(Context, guildUser, defaultMessage, msg, time.Time); + if (smartText is not null) + await Response().User(guildUser).Text(smartText).SendAsync(); } catch { @@ -447,13 +451,13 @@ public partial class Administration var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7; await _mute.TimedBan(ctx.Guild, userId, time.Time, (ctx.User + " | " + msg).TrimTo(512), banPrune); var toSend = new EmbedBuilder() - .WithOkColor() - .WithTitle("⛔️ " + GetText(strs.banned_user)) - .AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true) - .AddField("ID", userId.ToString(), true) - .AddField(GetText(strs.duration), - time.Time.Humanize(3, minUnit: TimeUnit.Minute, culture: Culture), - true); + .WithOkColor() + .WithTitle("⛔️ " + GetText(strs.banned_user)) + .AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true) + .AddField("ID", userId.ToString(), true) + .AddField(GetText(strs.duration), + time.Time.Humanize(3, minUnit: TimeUnit.Minute, culture: Culture), + true); if (dmFailed) toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user)); @@ -475,9 +479,9 @@ public partial class Administration await ctx.Guild.AddBanAsync(userId, banPrune, (ctx.User + " | " + msg).TrimTo(512)); await ctx.Channel.EmbedAsync(new EmbedBuilder() - .WithOkColor() - .WithTitle("⛔️ " + GetText(strs.banned_user)) - .AddField("ID", userId.ToString(), true)); + .WithOkColor() + .WithTitle("⛔️ " + GetText(strs.banned_user)) + .AddField("ID", userId.ToString(), true)); } else await Ban(user, msg); @@ -500,7 +504,7 @@ public partial class Administration var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), msg)); var embed = await _service.GetBanUserDmEmbed(Context, user, defaultMessage, msg, null); if (embed is not null) - await user.SendAsync(embed); + await Response().User(user).Text(embed).SendAsync(); } catch { @@ -511,10 +515,10 @@ public partial class Administration await ctx.Guild.AddBanAsync(user, banPrune, (ctx.User + " | " + msg).TrimTo(512)); var toSend = new EmbedBuilder() - .WithOkColor() - .WithTitle("⛔️ " + GetText(strs.banned_user)) - .AddField(GetText(strs.username), user.ToString(), true) - .AddField("ID", user.Id.ToString(), true); + .WithOkColor() + .WithTitle("⛔️ " + GetText(strs.banned_user)) + .AddField(GetText(strs.username), user.ToString(), true) + .AddField("ID", user.Id.ToString(), true); if (dmFailed) toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user)); @@ -594,19 +598,19 @@ public partial class Administration private async Task InternalBanMessageTest(string reason, TimeSpan? duration) { var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), reason)); - var embed = await _service.GetBanUserDmEmbed(Context, + var smartText = await _service.GetBanUserDmEmbed(Context, (IGuildUser)ctx.User, defaultMessage, reason, duration); - if (embed is null) + if (smartText is null) await Response().Confirm(strs.banmsg_disabled).SendAsync(); else { try { - await ctx.User.SendAsync(embed); + await Response().User(ctx.User).Text(smartText).SendAsync(); } catch (Exception) { @@ -692,7 +696,7 @@ public partial class Administration { await Response() .Channel(await user.CreateDMChannelAsync()) - .Error(GetText(strs.sbdm(Format.Bold(ctx.Guild.Name), msg))) + .Error(strs.sbdm(Format.Bold(ctx.Guild.Name), msg)) .SendAsync(); } catch @@ -706,10 +710,10 @@ public partial class Administration catch { await ctx.Guild.RemoveBanAsync(user); } var toSend = new EmbedBuilder() - .WithOkColor() - .WithTitle("☣ " + GetText(strs.sb_user)) - .AddField(GetText(strs.username), user.ToString(), true) - .AddField("ID", user.Id.ToString(), true); + .WithOkColor() + .WithTitle("☣ " + GetText(strs.sb_user)) + .AddField(GetText(strs.username), user.ToString(), true) + .AddField("ID", user.Id.ToString(), true); if (dmFailed) toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user)); @@ -761,10 +765,10 @@ public partial class Administration await user.KickAsync((ctx.User + " | " + msg).TrimTo(512)); var toSend = new EmbedBuilder() - .WithOkColor() - .WithTitle(GetText(strs.kicked_user)) - .AddField(GetText(strs.username), user.ToString(), true) - .AddField("ID", user.Id.ToString(), true); + .WithOkColor() + .WithTitle(GetText(strs.kicked_user)) + .AddField(GetText(strs.username), user.ToString(), true) + .AddField("ID", user.Id.ToString(), true); if (dmFailed) toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user)); @@ -792,9 +796,11 @@ public partial class Administration try { var dmMessage = GetText(strs.timeoutdm(Format.Bold(ctx.Guild.Name), msg)); - await user.EmbedAsync(new EmbedBuilder() - .WithPendingColor() - .WithDescription(dmMessage)); + await _sender.Response(user) + .Embed(new EmbedBuilder() + .WithPendingColor() + .WithDescription(dmMessage)) + .SendAsync(); } catch { @@ -804,10 +810,10 @@ public partial class Administration await user.SetTimeOutAsync(time.Time); var toSend = new EmbedBuilder() - .WithOkColor() - .WithTitle("⏳ " + GetText(strs.timedout_user)) - .AddField(GetText(strs.username), user.ToString(), true) - .AddField("ID", user.Id.ToString(), true); + .WithOkColor() + .WithTitle("⏳ " + GetText(strs.timedout_user)) + .AddField(GetText(strs.username), user.ToString(), true) + .AddField("ID", user.Id.ToString(), true); if (dmFailed) toSend.WithFooter("⚠️ " + GetText(strs.unable_to_dm_user)); @@ -865,9 +871,9 @@ public partial class Administration missStr = "-"; var toSend = new EmbedBuilder() - .WithDescription(GetText(strs.mass_ban_in_progress(banning.Count))) - .AddField(GetText(strs.invalid(missing.Count)), missStr) - .WithPendingColor(); + .WithDescription(GetText(strs.mass_ban_in_progress(banning.Count))) + .AddField(GetText(strs.invalid(missing.Count)), missStr) + .WithPendingColor(); var banningMessage = await Response().Embed(toSend).SendAsync(); @@ -885,11 +891,11 @@ public partial class Administration } await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder() - .WithDescription( - GetText(strs.mass_ban_completed(banning.Count()))) - .AddField(GetText(strs.invalid(missing.Count)), missStr) - .WithOkColor() - .Build()); + .WithDescription( + GetText(strs.mass_ban_completed(banning.Count()))) + .AddField(GetText(strs.invalid(missing.Count)), missStr) + .WithOkColor() + .Build()); } [Cmd] @@ -910,10 +916,10 @@ public partial class Administration //send a message but don't wait for it var banningMessageTask = ctx.Channel.EmbedAsync(new EmbedBuilder() - .WithDescription( - GetText(strs.mass_kill_in_progress(bans.Count()))) - .AddField(GetText(strs.invalid(missing)), missStr) - .WithPendingColor()); + .WithDescription( + GetText(strs.mass_kill_in_progress(bans.Count()))) + .AddField(GetText(strs.invalid(missing)), missStr) + .WithPendingColor()); var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7; //do the banning @@ -930,11 +936,11 @@ public partial class Administration var banningMessage = await banningMessageTask; await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder() - .WithDescription( - GetText(strs.mass_kill_completed(bans.Count()))) - .AddField(GetText(strs.invalid(missing)), missStr) - .WithOkColor() - .Build()); + .WithDescription( + GetText(strs.mass_kill_completed(bans.Count()))) + .AddField(GetText(strs.invalid(missing)), missStr) + .WithOkColor() + .Build()); } public class WarnExpireOptions : INadekoCommandOptions diff --git a/src/NadekoBot/Modules/Expressions/NadekoExpressionsService.cs b/src/NadekoBot/Modules/Expressions/NadekoExpressionsService.cs index d81da7bd4..d981951e6 100644 --- a/src/NadekoBot/Modules/Expressions/NadekoExpressionsService.cs +++ b/src/NadekoBot/Modules/Expressions/NadekoExpressionsService.cs @@ -71,7 +71,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor private readonly IBotStrings _strings; private readonly IBot _bot; private readonly IPubSub _pubSub; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly IReplacementService _repSvc; private readonly Random _rng; @@ -85,7 +85,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor DiscordSocketClient client, ICommandHandler cmd, IPubSub pubSub, - IEmbedBuilderService eb, + IMessageSenderService sender, IReplacementService repSvc, IPermissionChecker permChecker) { @@ -95,7 +95,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor _strings = strings; _bot = bot; _pubSub = pubSub; - _eb = eb; + _sender = sender; _repSvc = repSvc; _permChecker = permChecker; _rng = new NadekoRandom(); @@ -265,8 +265,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor try { - await msg.Channel - .Response(_strings, _eb) + await _sender.Response(msg.Channel) .Error(permissionMessage) .SendAsync(); } diff --git a/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs b/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs index ce001f7a6..ddae2edde 100644 --- a/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs +++ b/src/NadekoBot/Modules/Gambling/AnimalRacing/AnimalRacingCommands.cs @@ -169,7 +169,7 @@ public partial class Gambling } else await Response() - .Confirm(GetText(strs.animal_race_join(ctx.User.Mention, user.Animal.Icon))) + .Confirm(strs.animal_race_join(ctx.User.Mention, user.Animal.Icon)) .SendAsync(); } catch (ArgumentOutOfRangeException) diff --git a/src/NadekoBot/Modules/Gambling/Bank/BankCommands.cs b/src/NadekoBot/Modules/Gambling/Bank/BankCommands.cs index 5b827b5a0..4ad9d97b0 100644 --- a/src/NadekoBot/Modules/Gambling/Bank/BankCommands.cs +++ b/src/NadekoBot/Modules/Gambling/Bank/BankCommands.cs @@ -65,7 +65,7 @@ public partial class Gambling try { - await ctx.User.EmbedAsync(eb); + await Response().User(ctx.User).Embed(eb).SendAsync(); await ctx.OkAsync(); } catch diff --git a/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs b/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs index 9bc247229..9bf3d43b6 100644 --- a/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs +++ b/src/NadekoBot/Modules/Gambling/Connect4/Connect4Commands.cs @@ -109,7 +109,7 @@ public partial class Gambling RepostCounter++; if (RepostCounter == 0) { - try { msg = await ctx.Channel.SendMessageAsync("", embed: (Embed)msg.Embeds.First()); } + try { msg = await Response().Embed(msg.Embeds.First().ToEmbedBuilder()).SendAsync(); } catch { } } } diff --git a/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsService.cs b/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsService.cs index 944c99629..e61d787a2 100644 --- a/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsService.cs +++ b/src/NadekoBot/Modules/Gambling/Events/CurrencyEventsService.cs @@ -12,12 +12,15 @@ public class CurrencyEventsService : INService private readonly GamblingConfigService _configService; private readonly ConcurrentDictionary _events = new(); + private readonly IMessageSenderService _sender; - public CurrencyEventsService(DiscordSocketClient client, ICurrencyService cs, GamblingConfigService configService) + public CurrencyEventsService(DiscordSocketClient client, ICurrencyService cs, GamblingConfigService configService, + IMessageSenderService sender) { _client = client; _cs = cs; _configService = configService; + _sender = sender; } public async Task TryCreateEventAsync( @@ -34,9 +37,9 @@ public class CurrencyEventsService : INService ICurrencyEvent ce; if (type == CurrencyEvent.Type.Reaction) - ce = new ReactionEvent(_client, _cs, g, ch, opts, _configService.Data, embed); + ce = new ReactionEvent(_client, _cs, g, ch, opts, _configService.Data, _sender, embed); else if (type == CurrencyEvent.Type.GameStatus) - ce = new GameStatusEvent(_client, _cs, g, ch, opts, embed); + ce = new GameStatusEvent(_client, _cs, g, ch, opts, _sender, embed); else return false; diff --git a/src/NadekoBot/Modules/Gambling/Events/GameStatusEvent.cs b/src/NadekoBot/Modules/Gambling/Events/GameStatusEvent.cs index 40f35bace..37cfaa864 100644 --- a/src/NadekoBot/Modules/Gambling/Events/GameStatusEvent.cs +++ b/src/NadekoBot/Modules/Gambling/Events/GameStatusEvent.cs @@ -36,6 +36,7 @@ public class GameStatusEvent : ICurrencyEvent private readonly object _stopLock = new(); private readonly object _potLock = new(); + private readonly IMessageSenderService _sender; public GameStatusEvent( DiscordSocketClient client, @@ -43,6 +44,7 @@ public class GameStatusEvent : ICurrencyEvent SocketGuild g, ITextChannel ch, EventOptions opt, + IMessageSenderService sender, Func embedFunc) { _client = client; @@ -54,6 +56,7 @@ public class GameStatusEvent : ICurrencyEvent _isPotLimited = PotSize > 0; _channel = ch; _opts = opt; + _sender = sender; // generate code _code = new(_sneakyGameStatusChars.Shuffle().Take(5).ToArray()); @@ -106,7 +109,7 @@ public class GameStatusEvent : ICurrencyEvent public async Task StartEvent() { - msg = await _channel.EmbedAsync(GetEmbed(_opts.PotSize)); + msg = await _sender.Response(_channel).Embed(GetEmbed(_opts.PotSize)).SendAsync(); await _client.SetGameAsync(_code); _client.MessageDeleted += OnMessageDeleted; _client.MessageReceived += HandleMessage; diff --git a/src/NadekoBot/Modules/Gambling/Events/ReactionEvent.cs b/src/NadekoBot/Modules/Gambling/Events/ReactionEvent.cs index c0b558a4c..a41b9b4a8 100644 --- a/src/NadekoBot/Modules/Gambling/Events/ReactionEvent.cs +++ b/src/NadekoBot/Modules/Gambling/Events/ReactionEvent.cs @@ -30,6 +30,7 @@ public class ReactionEvent : ICurrencyEvent private readonly object _stopLock = new(); private readonly object _potLock = new(); + private readonly IMessageSenderService _sender; public ReactionEvent( DiscordSocketClient client, @@ -38,6 +39,7 @@ public class ReactionEvent : ICurrencyEvent ITextChannel ch, EventOptions opt, GamblingConfig config, + IMessageSenderService sender, Func embedFunc) { _client = client; @@ -51,6 +53,7 @@ public class ReactionEvent : ICurrencyEvent _noRecentlyJoinedServer = false; _opts = opt; _config = config; + _sender = sender; _t = new(OnTimerTick, null, Timeout.InfiniteTimeSpan, TimeSpan.FromSeconds(2)); if (_opts.Hours > 0) @@ -102,7 +105,7 @@ public class ReactionEvent : ICurrencyEvent emote = parsedEmote; else emote = new Emoji(_config.Currency.Sign); - msg = await _channel.EmbedAsync(GetEmbed(_opts.PotSize)); + msg = await _sender.Response(_channel).Embed(GetEmbed(_opts.PotSize)).SendAsync(); await msg.AddReactionAsync(emote); _client.MessageDeleted += OnMessageDeleted; _client.ReactionAdded += HandleReaction; diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index 73d6858b5..b582565b2 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -74,7 +74,7 @@ public partial class Gambling : GamblingModule var stats = await _gamblingTxTracker.GetAllAsync(); var eb = new EmbedBuilder() - .WithOkColor(); + .WithOkColor(); var str = "` Feature `|`   Bet  `|`Paid Out`|`  RoI  `\n"; str += "――――――――――――――――――――\n"; @@ -119,15 +119,15 @@ public partial class Gambling : GamblingModule // [21:03] Bob Page: Kinda remids me of US economy var embed = new EmbedBuilder() - .WithTitle(GetText(strs.economy_state)) - .AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot)) - .AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%") - .AddField(GetText(strs.currency_planted), N(ec.Planted)) - .AddField(GetText(strs.owned_waifus_total), N(ec.Waifus)) - .AddField(GetText(strs.bot_currency), N(ec.Bot)) - .AddField(GetText(strs.bank_accounts), N(ec.Bank)) - .AddField(GetText(strs.total), N(ec.Cash + ec.Planted + ec.Waifus + ec.Bank)) - .WithOkColor(); + .WithTitle(GetText(strs.economy_state)) + .AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot)) + .AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%") + .AddField(GetText(strs.currency_planted), N(ec.Planted)) + .AddField(GetText(strs.owned_waifus_total), N(ec.Waifus)) + .AddField(GetText(strs.bot_currency), N(ec.Bot)) + .AddField(GetText(strs.bank_accounts), N(ec.Bank)) + .AddField(GetText(strs.total), N(ec.Cash + ec.Planted + ec.Waifus + ec.Bank)) + .WithOkColor(); // ec.Cash already contains ec.Bot as it's the total of all values in the CurrencyAmount column of the DiscordUser table await Response().Embed(embed).SendAsync(); @@ -151,7 +151,7 @@ public partial class Gambling : GamblingModule GetText(strs.timely_time), ReminderType.Timely); - await smc.RespondConfirmAsync(_eb, GetText(strs.remind_timely(tt)), ephemeral: true); + await smc.RespondConfirmAsync(_sender, GetText(strs.remind_timely(tt)), ephemeral: true); } private NadekoInteraction CreateRemindMeInteraction(int period) @@ -311,9 +311,9 @@ public partial class Gambling : GamblingModule } var embed = new EmbedBuilder() - .WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString() - ?? $"{userId}"))) - .WithOkColor(); + .WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString() + ?? $"{userId}"))) + .WithOkColor(); var sb = new StringBuilder(); foreach (var tr in trs) @@ -415,7 +415,7 @@ public partial class Gambling : GamblingModule await N(balance) .Pipe(strs.bank_balance) .Pipe(GetText) - .Pipe(text => smc.RespondConfirmAsync(_eb, text, ephemeral: true)); + .Pipe(text => smc.RespondConfirmAsync(_sender, text, ephemeral: true)); } private NadekoInteraction CreateCashInteraction() @@ -460,7 +460,7 @@ public partial class Gambling : GamblingModule return; } - if (!await _cs.TransferAsync(_eb, ctx.User, receiver, amount, msg, N(amount))) + if (!await _cs.TransferAsync(_sender, ctx.User, receiver, amount, msg, N(amount))) { await Response().Error(strs.not_enough(CurrencySign)).SendAsync(); return; @@ -732,10 +732,10 @@ public partial class Gambling : GamblingModule } var eb = new EmbedBuilder() - .WithAuthor(ctx.User) - .WithDescription(Format.Bold(str)) - .AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture)) - .WithOkColor(); + .WithAuthor(ctx.User) + .WithDescription(Format.Bold(str)) + .AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture)) + .WithOkColor(); await Response().Embed(eb).SendAsync(); } @@ -923,11 +923,11 @@ public partial class Gambling : GamblingModule } var eb = new EmbedBuilder() - .WithOkColor() - .WithDescription(sb.ToString()) - .AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true) - .AddField(GetText(strs.won), $"{(long)result.Won}", true) - .WithAuthor(ctx.User); + .WithOkColor() + .WithDescription(sb.ToString()) + .AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true) + .AddField(GetText(strs.won), $"{(long)result.Won}", true) + .WithAuthor(ctx.User); await Response().Embed(eb).SendAsync(); diff --git a/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs b/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs index e494b86ac..201985e4e 100644 --- a/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs +++ b/src/NadekoBot/Modules/Gambling/Shop/ShopCommands.cs @@ -46,8 +46,8 @@ public partial class Gambling using var uow = _db.GetDbContext(); var entries = uow.GuildConfigsForId(ctx.Guild.Id, - set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items)) - .ShopEntries.ToIndexed(); + set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items)) + .ShopEntries.ToIndexed(); return ctx.SendPaginatedConfirmAsync(page, curPage => { @@ -116,7 +116,9 @@ public partial class Gambling var guser = (IGuildUser)ctx.User; if (!guser.RoleIds.Contains(reqRoleId)) { - await Response().Error(strs.shop_item_req_role_unfulfilled(Format.Bold(role.ToString()))).SendAsync(); + await Response() + .Error(strs.shop_item_req_role_unfulfilled(Format.Bold(role.ToString()))) + .SendAsync(); return; } } @@ -178,17 +180,20 @@ public partial class Gambling await using (var uow = _db.GetDbContext()) { uow.Set().Remove(item); - uow.SaveChanges(); + await uow.SaveChangesAsync(); } try { - await ctx.User.EmbedAsync(new EmbedBuilder() - .WithOkColor() - .WithTitle(GetText(strs.shop_purchase(ctx.Guild.Name))) - .AddField(GetText(strs.item), item.Text) - .AddField(GetText(strs.price), entry.Price.ToString(), true) - .AddField(GetText(strs.name), entry.Name, true)); + await Response() + .User(ctx.User) + .Embed(new EmbedBuilder() + .WithOkColor() + .WithTitle(GetText(strs.shop_purchase(ctx.Guild.Name))) + .AddField(GetText(strs.item), item.Text) + .AddField(GetText(strs.price), entry.Price.ToString(), true) + .AddField(GetText(strs.name), entry.Name, true)) + .SendAsync(); await _cs.AddAsync(entry.AuthorId, GetProfitAmount(entry.Price), @@ -200,9 +205,9 @@ public partial class Gambling await using (var uow = _db.GetDbContext()) { var entries = new IndexedCollection(uow.GuildConfigsForId(ctx.Guild.Id, - set => set.Include(x => x.ShopEntries) - .ThenInclude(x => x.Items)) - .ShopEntries); + set => set.Include(x => x.ShopEntries) + .ThenInclude(x => x.Items)) + .ShopEntries); entry = entries.ElementAtOrDefault(index); if (entry is not null) { @@ -242,16 +247,16 @@ public partial class Gambling { var cmd = entry.Command.Replace("%you%", ctx.User.Id.ToString()); var eb = new EmbedBuilder() - .WithPendingColor() - .WithTitle("Executing shop command") - .WithDescription(cmd); + .WithPendingColor() + .WithTitle("Executing shop command") + .WithDescription(cmd); var msgTask = Response().Embed(eb).SendAsync(); await _cs.AddAsync(entry.AuthorId, GetProfitAmount(entry.Price), new("shop", "sell", entry.Name)); - + await _cmdHandler.TryRunCommand(guild, channel, new DoAsUserMessage( @@ -264,9 +269,9 @@ public partial class Gambling { var pendingMsg = await msgTask; await pendingMsg.EditAsync(SmartEmbedText.FromEmbed(eb - .WithOkColor() - .WithTitle("Shop command executed") - .Build())); + .WithOkColor() + .WithTitle("Shop command executed") + .Build())); } catch { @@ -314,9 +319,9 @@ public partial class Gambling await using (var uow = _db.GetDbContext()) { var entries = new IndexedCollection(uow.GuildConfigsForId(ctx.Guild.Id, - set => set.Include(x => x.ShopEntries) - .ThenInclude(x => x.Items)) - .ShopEntries) + set => set.Include(x => x.ShopEntries) + .ThenInclude(x => x.Items)) + .ShopEntries) { entry }; @@ -346,9 +351,9 @@ public partial class Gambling await using (var uow = _db.GetDbContext()) { var entries = new IndexedCollection(uow.GuildConfigsForId(ctx.Guild.Id, - set => set.Include(x => x.ShopEntries) - .ThenInclude(x => x.Items)) - .ShopEntries) + set => set.Include(x => x.ShopEntries) + .ThenInclude(x => x.Items)) + .ShopEntries) { entry }; @@ -377,9 +382,9 @@ public partial class Gambling await using (var uow = _db.GetDbContext()) { var entries = new IndexedCollection(uow.GuildConfigsForId(ctx.Guild.Id, - set => set.Include(x => x.ShopEntries) - .ThenInclude(x => x.Items)) - .ShopEntries); + set => set.Include(x => x.ShopEntries) + .ThenInclude(x => x.Items)) + .ShopEntries); entry = entries.ElementAtOrDefault(index); if (entry is not null && (rightType = entry.Type == ShopEntryType.List)) { @@ -531,27 +536,27 @@ public partial class Gambling if (entry.Type == ShopEntryType.Role) { return embed - .AddField(GetText(strs.name), - GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name - ?? "MISSING_ROLE"))), - true) - .AddField(GetText(strs.price), N(entry.Price), true) - .AddField(GetText(strs.type), entry.Type.ToString(), true); + .AddField(GetText(strs.name), + GetText(strs.shop_role(Format.Bold(ctx.Guild.GetRole(entry.RoleId)?.Name + ?? "MISSING_ROLE"))), + true) + .AddField(GetText(strs.price), N(entry.Price), true) + .AddField(GetText(strs.type), entry.Type.ToString(), true); } if (entry.Type == ShopEntryType.List) { return embed.AddField(GetText(strs.name), entry.Name, true) - .AddField(GetText(strs.price), N(entry.Price), true) - .AddField(GetText(strs.type), GetText(strs.random_unique_item), true); + .AddField(GetText(strs.price), N(entry.Price), true) + .AddField(GetText(strs.type), GetText(strs.random_unique_item), true); } - + else if (entry.Type == ShopEntryType.Command) { return embed - .AddField(GetText(strs.name), Format.Code(entry.Command), true) - .AddField(GetText(strs.price), N(entry.Price), true) - .AddField(GetText(strs.type), entry.Type.ToString(), true); + .AddField(GetText(strs.name), Format.Code(entry.Command), true) + .AddField(GetText(strs.price), N(entry.Price), true) + .AddField(GetText(strs.type), entry.Type.ToString(), true); } //else if (entry.Type == ShopEntryType.Infinite_List) diff --git a/src/NadekoBot/Modules/Games/ChatterBot/ChatterbotService.cs b/src/NadekoBot/Modules/Games/ChatterBot/ChatterbotService.cs index 5ab1a15a3..eaf0d2c16 100644 --- a/src/NadekoBot/Modules/Games/ChatterBot/ChatterbotService.cs +++ b/src/NadekoBot/Modules/Games/ChatterBot/ChatterbotService.cs @@ -20,9 +20,7 @@ public class ChatterBotService : IExecOnMessage private readonly DiscordSocketClient _client; private readonly IPermissionChecker _perms; private readonly CommandHandler _cmd; - private readonly IBotStrings _strings; private readonly IBotCredentials _creds; - private readonly IEmbedBuilderService _eb; private readonly IHttpClientFactory _httpFactory; private readonly IPatronageService _ps; private readonly GamesConfigService _gcs; @@ -33,10 +31,8 @@ public class ChatterBotService : IExecOnMessage IPermissionChecker perms, IBot bot, CommandHandler cmd, - IBotStrings strings, IHttpClientFactory factory, IBotCredentials creds, - IEmbedBuilderService eb, IPatronageService ps, GamesConfigService gcs, IMessageSenderService sender) @@ -44,14 +40,12 @@ public class ChatterBotService : IExecOnMessage _client = client; _perms = perms; _cmd = cmd; - _strings = strings; _creds = creds; - _eb = eb; + _sender = sender; _httpFactory = factory; _ps = ps; _perms = perms; _gcs = gcs; - _sender = sender; _flKey = new FeatureLimitKey() { @@ -166,8 +160,7 @@ public class ChatterBotService : IExecOnMessage { if (ql.Quota == 0) { - await channel - .Response(_strings, _eb) + await _sender.Response(channel) .Error(null, text: "In order to use the cleverbot feature, the owner of this server should be [Patron Tier X](https://patreon.com/join/nadekobot) on patreon.", @@ -178,7 +171,7 @@ public class ChatterBotService : IExecOnMessage return true; } - await channel.Response(_strings, _eb) + await _sender.Response(channel) .Error( null!, $"You've reached your quota limit of **{ql.Quota}** responses {ql.QuotaPeriod.ToFullName()} for the cleverbot feature.", diff --git a/src/NadekoBot/Modules/Games/Hangman/HangmanCommands.cs b/src/NadekoBot/Modules/Games/Hangman/HangmanCommands.cs index bc3c9999f..b5324cb30 100644 --- a/src/NadekoBot/Modules/Games/Hangman/HangmanCommands.cs +++ b/src/NadekoBot/Modules/Games/Hangman/HangmanCommands.cs @@ -23,7 +23,7 @@ public partial class Games /-\ """; - public static EmbedBuilder GetEmbed(IEmbedBuilderService eb, HangmanGame.State state) + public static EmbedBuilder GetEmbed(HangmanGame.State state) { if (state.Phase == HangmanGame.Phase.Running) { @@ -60,7 +60,7 @@ public partial class Games return; } - var eb = GetEmbed(_eb, hangman); + var eb = GetEmbed(hangman); eb.WithDescription(GetText(strs.hangman_game_started)); await Response().Embed(eb).SendAsync(); } diff --git a/src/NadekoBot/Modules/Games/Hangman/HangmanService.cs b/src/NadekoBot/Modules/Games/Hangman/HangmanService.cs index 249c27dd8..6f580db20 100644 --- a/src/NadekoBot/Modules/Games/Hangman/HangmanService.cs +++ b/src/NadekoBot/Modules/Games/Hangman/HangmanService.cs @@ -9,7 +9,7 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand { private readonly ConcurrentDictionary _hangmanGames = new(); private readonly IHangmanSource _source; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly GamesConfigService _gcs; private readonly ICurrencyService _cs; private readonly IMemoryCache _cdCache; @@ -17,13 +17,13 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand public HangmanService( IHangmanSource source, - IEmbedBuilderService eb, + IMessageSenderService sender, GamesConfigService gcs, ICurrencyService cs, IMemoryCache cdCache) { _source = source; - _eb = eb; + _sender = sender; _gcs = gcs; _cs = cs; _cdCache = cdCache; @@ -116,7 +116,7 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand string content, HangmanGame.State state) { - var embed = Games.HangmanCommands.GetEmbed(_eb, state); + var embed = Games.HangmanCommands.GetEmbed(state); if (state.GuessResult == HangmanGame.GuessResult.Guess) embed.WithDescription($"{user} guessed the letter {content}!").WithOkColor(); else if (state.GuessResult == HangmanGame.GuessResult.Incorrect && state.Failed) @@ -131,6 +131,6 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand if (!string.IsNullOrWhiteSpace(state.ImageUrl) && Uri.IsWellFormedUriString(state.ImageUrl, UriKind.Absolute)) embed.WithImageUrl(state.ImageUrl); - return channel.EmbedAsync(embed); + return _sender.Response(channel).Embed(embed).SendAsync(); } } \ No newline at end of file diff --git a/src/NadekoBot/Modules/Games/SpeedTyping/TypingGame.cs b/src/NadekoBot/Modules/Games/SpeedTyping/TypingGame.cs index 3d676d808..297b4ceb5 100644 --- a/src/NadekoBot/Modules/Games/SpeedTyping/TypingGame.cs +++ b/src/NadekoBot/Modules/Games/SpeedTyping/TypingGame.cs @@ -78,10 +78,11 @@ public class TypingGame var time = _options.StartTime; - var msg = await Channel.SendMessageAsync($"Starting new typing contest in **{time}**..."); + var msg = await _sender.Response(Channel).Confirm($"Starting new typing contest in **{time}**...").SendAsync(); do { + // todo fix all modifies await Task.Delay(2000); time -= 2; try { await msg.ModifyAsync(m => m.Content = $"Starting new typing contest in **{time}**.."); } @@ -144,13 +145,15 @@ public class TypingGame var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60; _finishedUserIds.Add(msg.Author.Id); + var embed = new EmbedBuilder() + .WithOkColor() + .WithTitle($"{msg.Author} finished the race!") + .AddField("Place", $"#{_finishedUserIds.Count}", true) + .AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true) + .AddField("Errors", distance.ToString(), true); + await _sender.Response(Channel) - .Embed(eb => new EmbedBuilder() - .WithOkColor() - .WithTitle($"{msg.Author} finished the race!") - .AddField("Place", $"#{_finishedUserIds.Count}", true) - .AddField("WPM", $"{wpm:F1} *[{elapsed.TotalSeconds:F2}sec]*", true) - .AddField("Errors", distance.ToString(), true)) + .Embed(embed) .SendAsync(); if (_finishedUserIds.Count % 4 == 0) diff --git a/src/NadekoBot/Modules/Games/TicTacToe/TicTacToe.cs b/src/NadekoBot/Modules/Games/TicTacToe/TicTacToe.cs index 477dd89b1..279afc9f9 100644 --- a/src/NadekoBot/Modules/Games/TicTacToe/TicTacToe.cs +++ b/src/NadekoBot/Modules/Games/TicTacToe/TicTacToe.cs @@ -26,7 +26,7 @@ public class TicTacToe private readonly IBotStrings _strings; private readonly DiscordSocketClient _client; private readonly Options _options; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; public TicTacToe( IBotStrings strings, @@ -34,13 +34,13 @@ public class TicTacToe ITextChannel channel, IGuildUser firstUser, Options options, - IEmbedBuilderService eb) + IMessageSenderService sender) { _channel = channel; _strings = strings; _client = client; _options = options; - _eb = eb; + _sender = sender; _users = new[] { firstUser, null }; _state = new int?[,] { { null, null, null }, { null, null, null }, { null, null, null } }; @@ -115,13 +115,13 @@ public class TicTacToe { if (phase is Phase.Started or Phase.Ended) { - await _channel.Response(_strings, _eb).Error(user.Mention + GetText(strs.ttt_already_running)).SendAsync(); + await _sender.Response(_channel).Error(user.Mention + GetText(strs.ttt_already_running)).SendAsync(); return; } if (_users[0] == user) { - await _channel.Response(_strings, _eb).Error(user.Mention + GetText(strs.ttt_against_yourself)).SendAsync(); + await _sender.Response(_channel).Error(user.Mention + GetText(strs.ttt_against_yourself)).SendAsync(); return; } @@ -144,7 +144,7 @@ public class TicTacToe var del = previousMessage?.DeleteAsync(); try { - await _channel.EmbedAsync(GetEmbed(GetText(strs.ttt_time_expired))); + await _sender.Response(_channel).Embed(GetEmbed(GetText(strs.ttt_time_expired))).SendAsync(); if (del is not null) await del; } @@ -166,7 +166,7 @@ public class TicTacToe _client.MessageReceived += Client_MessageReceived; - previousMessage = await _channel.EmbedAsync(GetEmbed(GetText(strs.game_started))); + previousMessage = await _sender.Response(_channel).Embed(GetEmbed(GetText(strs.game_started))).SendAsync(); } private bool IsDraw() @@ -259,7 +259,7 @@ public class TicTacToe { var del1 = msg.DeleteAsync(); var del2 = previousMessage?.DeleteAsync(); - try { previousMessage = await _channel.EmbedAsync(GetEmbed(reason)); } + try { previousMessage = await _sender.Response(_channel).Embed(GetEmbed(reason)).SendAsync(); } catch { } try { await del1; } diff --git a/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs b/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs index ecf127e9a..60fdaa122 100644 --- a/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs +++ b/src/NadekoBot/Modules/Games/TicTacToe/TicTacToeCommands.cs @@ -35,7 +35,7 @@ public partial class Games return; } - game = new(Strings, _client, channel, (IGuildUser)ctx.User, options, _eb); + game = new(Strings, _client, channel, (IGuildUser)ctx.User, options, _sender); _service.TicTacToeGames.Add(channel.Id, game); await Response().Confirm(strs.ttt_created).SendAsync(); diff --git a/src/NadekoBot/Modules/Games/Trivia/Games.cs b/src/NadekoBot/Modules/Games/Trivia/Games.cs index 6949ce6b5..031dedd11 100644 --- a/src/NadekoBot/Modules/Games/Trivia/Games.cs +++ b/src/NadekoBot/Modules/Games/Trivia/Games.cs @@ -51,7 +51,7 @@ public partial class Games if (_service.RunningTrivias.TryGetValue(ctx.Guild.Id, out var tg)) { - await Response().Error(GetText(strs.trivia_already_running)).SendAsync(); + await Response().Error(strs.trivia_already_running).SendAsync(); await tg.TriggerQuestionAsync(); } } diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index fc43ee88f..90db86781 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -376,7 +376,7 @@ public sealed class Help : NadekoModule } var embed = _cus.GetCommandHelp(com, ctx.Guild); - await channel.EmbedAsync(embed); + await _sender.Response(channel).Embed(embed).SendAsync(); } [Cmd] @@ -510,7 +510,7 @@ public sealed class Help : NadekoModule private Task SelfhostAction(SocketMessageComponent smc, object _) - => smc.RespondConfirmAsync(_eb, + => smc.RespondConfirmAsync(_sender, """ - In case you don't want or cannot Donate to NadekoBot project, but you - NadekoBot is a completely free and fully [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own "selfhosted" instance on your computer or server for free. diff --git a/src/NadekoBot/Modules/Music/PlaylistCommands.cs b/src/NadekoBot/Modules/Music/PlaylistCommands.cs index 1a60dc1d0..3309a0cb3 100644 --- a/src/NadekoBot/Modules/Music/PlaylistCommands.cs +++ b/src/NadekoBot/Modules/Music/PlaylistCommands.cs @@ -51,10 +51,10 @@ public sealed partial class Music } var embed = new EmbedBuilder() - .WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL) - .WithDescription(string.Join("\n", - playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count))))) - .WithOkColor(); + .WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL) + .WithDescription(string.Join("\n", + playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count))))) + .WithOkColor(); await Response().Embed(embed).SendAsync(); } @@ -111,7 +111,9 @@ public sealed partial class Music mpl.Songs.Skip(cur * 20) .Take(20) .Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`")); - return new EmbedBuilder().WithTitle($"\"{mpl.Name}\" by {mpl.Author}").WithOkColor().WithDescription(str); + return new EmbedBuilder().WithTitle($"\"{mpl.Name}\" by {mpl.Author}") + .WithOkColor() + .WithDescription(str); }, mpl.Songs.Count, 20); @@ -151,11 +153,13 @@ public sealed partial class Music await uow.SaveChangesAsync(); } - await Response().Embed(new EmbedBuilder() - .WithOkColor() - .WithTitle(GetText(strs.playlist_saved)) - .AddField(GetText(strs.name), name) - .AddField(GetText(strs.id), playlist.Id.ToString())).SendAsync(); + await Response() + .Embed(new EmbedBuilder() + .WithOkColor() + .WithTitle(GetText(strs.playlist_saved)) + .AddField(GetText(strs.name), name) + .AddField(GetText(strs.id), playlist.Id.ToString())) + .SendAsync(); } [Cmd] @@ -208,8 +212,9 @@ public sealed partial class Music IUserMessage msg = null; try { - msg = await ctx.Channel.SendMessageAsync( - GetText(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString())))); + msg = await Response() + .Pending(strs.attempting_to_queue(Format.Bold(mpl.Songs.Count.ToString()))) + .SendAsync(); } catch (Exception) { diff --git a/src/NadekoBot/Modules/Music/Services/MusicService.cs b/src/NadekoBot/Modules/Music/Services/MusicService.cs index 77182d108..9ca232447 100644 --- a/src/NadekoBot/Modules/Music/Services/MusicService.cs +++ b/src/NadekoBot/Modules/Music/Services/MusicService.cs @@ -15,7 +15,7 @@ public sealed class MusicService : IMusicService private readonly IBotStrings _strings; private readonly IGoogleApiService _googleApiService; private readonly YtLoader _ytLoader; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly ConcurrentDictionary _players; private readonly ConcurrentDictionary _outputChannels; @@ -31,7 +31,7 @@ public sealed class MusicService : IMusicService IBotStrings strings, IGoogleApiService googleApiService, YtLoader ytLoader, - IEmbedBuilderService eb) + IMessageSenderService sender) { _voiceStateService = voiceStateService; _trackResolveProvider = trackResolveProvider; @@ -42,7 +42,7 @@ public sealed class MusicService : IMusicService _strings = strings; _googleApiService = googleApiService; _ytLoader = ytLoader; - _eb = eb; + _sender = sender; _players = new(); _outputChannels = new ConcurrentDictionary(); diff --git a/src/NadekoBot/Modules/Patronage/CurrencyRewardService.cs b/src/NadekoBot/Modules/Patronage/CurrencyRewardService.cs index 4f8788103..9e90c37f9 100644 --- a/src/NadekoBot/Modules/Patronage/CurrencyRewardService.cs +++ b/src/NadekoBot/Modules/Patronage/CurrencyRewardService.cs @@ -13,7 +13,7 @@ public sealed class CurrencyRewardService : INService, IDisposable private readonly ICurrencyService _cs; private readonly IPatronageService _ps; private readonly DbService _db; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly GamblingConfigService _config; private readonly DiscordSocketClient _client; @@ -21,14 +21,14 @@ public sealed class CurrencyRewardService : INService, IDisposable ICurrencyService cs, IPatronageService ps, DbService db, - IEmbedBuilderService eb, + IMessageSenderService sender, GamblingConfigService config, DiscordSocketClient client) { _cs = cs; _ps = ps; _db = db; - _eb = eb; + _sender = sender; _config = config; _client = client; @@ -175,7 +175,7 @@ public sealed class CurrencyRewardService : INService, IDisposable .WithOkColor() .WithDescription(message); - await user.EmbedAsync(eb); + await _sender.Response(user).Embed(eb).SendAsync(); } catch { diff --git a/src/NadekoBot/Modules/Patronage/PatronageCommands.cs b/src/NadekoBot/Modules/Patronage/PatronageCommands.cs index 3015a16be..c4401f202 100644 --- a/src/NadekoBot/Modules/Patronage/PatronageCommands.cs +++ b/src/NadekoBot/Modules/Patronage/PatronageCommands.cs @@ -31,10 +31,12 @@ public partial class Patronage : NadekoModule _ = ctx.Channel.TriggerTypingAsync(); var result = await _service.SendMessageToPatronsAsync(tierAndHigher, message); - await Response().Confirm(strs.patron_msg_sent( - Format.Code(tierAndHigher.ToString()), - Format.Bold(result.Success.ToString()), - Format.Bold(result.Failed.ToString()))).SendAsync(); + await Response() + .Confirm(strs.patron_msg_sent( + Format.Code(tierAndHigher.ToString()), + Format.Bold(result.Success.ToString()), + Format.Bold(result.Failed.ToString()))) + .SendAsync(); } // [OwnerOnly] @@ -69,9 +71,9 @@ public partial class Patronage : NadekoModule var quotaStats = await _service.GetUserQuotaStatistic(user.Id); var eb = new EmbedBuilder() - .WithAuthor(user) - .WithTitle(GetText(strs.patron_info)) - .WithOkColor(); + .WithAuthor(user) + .WithTitle(GetText(strs.patron_info)) + .WithOkColor(); if (quotaStats.Commands.Count == 0 && quotaStats.Groups.Count == 0 @@ -82,7 +84,7 @@ public partial class Patronage : NadekoModule else { eb.AddField(GetText(strs.tier), Format.Bold(patron.Tier.ToFullName()), true) - .AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true); + .AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true); if (patron.Tier != PatronTier.None) eb.AddField(GetText(strs.expires), patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(), true); @@ -114,7 +116,7 @@ public partial class Patronage : NadekoModule try { - await ctx.User.EmbedAsync(eb); + await Response().User(ctx.User).Embed(eb).SendAsync(); _ = ctx.OkAsync(); } catch diff --git a/src/NadekoBot/Modules/Patronage/PatronageService.cs b/src/NadekoBot/Modules/Patronage/PatronageService.cs index 46c98fa41..9af8d6f47 100644 --- a/src/NadekoBot/Modules/Patronage/PatronageService.cs +++ b/src/NadekoBot/Modules/Patronage/PatronageService.cs @@ -29,7 +29,6 @@ public sealed class PatronageService private readonly DbService _db; private readonly DiscordSocketClient _client; private readonly ISubscriptionHandler _subsHandler; - private readonly IEmbedBuilderService _eb; private static readonly TypedKey _quotaKey = new($"quota:last_hourly_reset"); @@ -43,7 +42,6 @@ public sealed class PatronageService DbService db, DiscordSocketClient client, ISubscriptionHandler subsHandler, - IEmbedBuilderService eb, IBotCache cache, IBotCredsProvider creds, IMessageSenderService sender) @@ -52,10 +50,9 @@ public sealed class PatronageService _db = db; _client = client; _subsHandler = subsHandler; - _eb = eb; + _sender = sender; _cache = cache; _creds = creds; - _sender = sender; } public Task OnReadyAsync() @@ -310,12 +307,12 @@ public sealed class PatronageService ins => { var eb = new EmbedBuilder() - .WithPendingColor() - .WithTitle("Insufficient Patron Tier") - .AddField("For", $"{ins.FeatureType}: `{ins.Feature}`", true) - .AddField("Required Tier", - $"[{ins.RequiredTier.ToFullName()}](https://patreon.com/join/nadekobot)", - true); + .WithPendingColor() + .WithTitle("Insufficient Patron Tier") + .AddField("For", $"{ins.FeatureType}: `{ins.Feature}`", true) + .AddField("Required Tier", + $"[{ins.RequiredTier.ToFullName()}](https://patreon.com/join/nadekobot)", + true); if (ctx.Guild is null || ctx.Guild?.OwnerId == ctx.User.Id) eb.WithDescription("You don't have the sufficent Patron Tier to run this command.") @@ -333,15 +330,15 @@ public sealed class PatronageService .Embed(eb) .SendAsync(); else - _ = ctx.User.EmbedAsync(eb); + _ = _sender.Response(ctx).User(ctx.User).Embed(eb).SendAsync(); return true; }, quota => { var eb = new EmbedBuilder() - .WithPendingColor() - .WithTitle("Quota Limit Reached"); + .WithPendingColor() + .WithTitle("Quota Limit Reached"); if (quota.IsOwnQuota || ctx.User.Id == ownerId) { @@ -369,7 +366,7 @@ public sealed class PatronageService .Embed(eb) .SendAsync(); else - _ = ctx.User.EmbedAsync(eb); + _ = _sender.Response(ctx).User(ctx.User).Embed(eb).SendAsync(); return true; }); @@ -782,30 +779,30 @@ public sealed class PatronageService return; var eb = new EmbedBuilder() - .WithOkColor() - .WithTitle("❀️ Thank you for supporting NadekoBot! ❀️") - .WithDescription( - "Your donation has been processed and you will receive the rewards shortly.\n" - + "You can visit to see rewards for your tier. πŸŽ‰") - .AddField("Tier", Format.Bold(patron.Tier.ToString()), true) - .AddField("Pledge", $"**{patron.Amount / 100.0f:N1}$**", true) - .AddField("Expires", - patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(), - true) - .AddField("Instructions", - """ - *- Within the next **1-2 minutes** you will have all of the benefits of the Tier you've subscribed to.* - *- You can check your benefits on * - *- You can use the `.patron` command in this chat to check your current quota usage for the Patron-only commands* - *- **ALL** of the servers that you **own** will enjoy your Patron benefits.* - *- You can use any of the commands available in your tier on any server (assuming you have sufficient permissions to run those commands)* - *- Any user in any of your servers can use Patron-only commands, but they will spend **your quota**, which is why it's recommended to use Nadeko's command cooldown system (.h .cmdcd) or permission system to limit the command usage for your server members.* - *- Permission guide can be found here if you're not familiar with it: * - """, - inline: false) - .WithFooter($"platform id: {patron.UniquePlatformUserId}"); + .WithOkColor() + .WithTitle("❀️ Thank you for supporting NadekoBot! ❀️") + .WithDescription( + "Your donation has been processed and you will receive the rewards shortly.\n" + + "You can visit to see rewards for your tier. πŸŽ‰") + .AddField("Tier", Format.Bold(patron.Tier.ToString()), true) + .AddField("Pledge", $"**{patron.Amount / 100.0f:N1}$**", true) + .AddField("Expires", + patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(), + true) + .AddField("Instructions", + """ + *- Within the next **1-2 minutes** you will have all of the benefits of the Tier you've subscribed to.* + *- You can check your benefits on * + *- You can use the `.patron` command in this chat to check your current quota usage for the Patron-only commands* + *- **ALL** of the servers that you **own** will enjoy your Patron benefits.* + *- You can use any of the commands available in your tier on any server (assuming you have sufficient permissions to run those commands)* + *- Any user in any of your servers can use Patron-only commands, but they will spend **your quota**, which is why it's recommended to use Nadeko's command cooldown system (.h .cmdcd) or permission system to limit the command usage for your server members.* + *- Permission guide can be found here if you're not familiar with it: * + """, + inline: false) + .WithFooter($"platform id: {patron.UniquePlatformUserId}"); - await user.EmbedAsync(eb); + await _sender.Response(user).Embed(eb).SendAsync(); } catch { @@ -830,7 +827,7 @@ public sealed class PatronageService try { var user = await _client.GetUserAsync(patron.UserId); - await user.SendAsync(text); + await _sender.Response(user).Text(text).SendAsync(); ++succ; } catch diff --git a/src/NadekoBot/Modules/Permissions/PermissionsService.cs b/src/NadekoBot/Modules/Permissions/PermissionsService.cs index 3db96b746..b73197aa3 100644 --- a/src/NadekoBot/Modules/Permissions/PermissionsService.cs +++ b/src/NadekoBot/Modules/Permissions/PermissionsService.cs @@ -17,7 +17,6 @@ public class PermissionService : IExecPreCommand, INService private readonly DbService _db; private readonly CommandHandler _cmd; private readonly IBotStrings _strings; - private readonly IEmbedBuilderService _eb; private readonly IMessageSenderService _sender; public PermissionService( @@ -25,13 +24,11 @@ public class PermissionService : IExecPreCommand, INService DbService db, CommandHandler cmd, IBotStrings strings, - IEmbedBuilderService eb, IMessageSenderService sender) { _db = db; _cmd = cmd; _strings = strings; - _eb = eb; _sender = sender; using var uow = _db.GetDbContext(); diff --git a/src/NadekoBot/Modules/Searches/Crypto/DefaultStockDataService.cs b/src/NadekoBot/Modules/Searches/Crypto/DefaultStockDataService.cs index b52c06889..9bb57c148 100644 --- a/src/NadekoBot/Modules/Searches/Crypto/DefaultStockDataService.cs +++ b/src/NadekoBot/Modules/Searches/Crypto/DefaultStockDataService.cs @@ -6,7 +6,6 @@ using System.Text.Json; namespace NadekoBot.Modules.Searches; -// todo fix stock public sealed class DefaultStockDataService : IStockDataService, INService { private readonly IHttpClientFactory _httpClientFactory; diff --git a/src/NadekoBot/Modules/Searches/Feeds/FeedsService.cs b/src/NadekoBot/Modules/Searches/Feeds/FeedsService.cs index 9dce27ef5..09f53783a 100644 --- a/src/NadekoBot/Modules/Searches/Feeds/FeedsService.cs +++ b/src/NadekoBot/Modules/Searches/Feeds/FeedsService.cs @@ -14,7 +14,7 @@ public class FeedsService : INService private readonly DbService _db; private readonly ConcurrentDictionary> _subs; private readonly DiscordSocketClient _client; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly ConcurrentDictionary _lastPosts = new(); private readonly Dictionary _errorCounters = new(); @@ -23,7 +23,7 @@ public class FeedsService : INService IBot bot, DbService db, DiscordSocketClient client, - IEmbedBuilderService eb) + IMessageSenderService sender) { _db = db; @@ -42,7 +42,7 @@ public class FeedsService : INService } _client = client; - _eb = eb; + _sender = sender; _ = Task.Run(TrackFeeds); } diff --git a/src/NadekoBot/Modules/Searches/MemegenCommands.cs b/src/NadekoBot/Modules/Searches/MemegenCommands.cs index 017903e43..b4682b7dc 100644 --- a/src/NadekoBot/Modules/Searches/MemegenCommands.cs +++ b/src/NadekoBot/Modules/Searches/MemegenCommands.cs @@ -69,7 +69,7 @@ public partial class Searches } memeUrl += ".png"; - await ctx.Channel.SendMessageAsync(memeUrl); + await Response().Text(memeUrl).SendAsync(); } private static string Replace(string input) diff --git a/src/NadekoBot/Modules/Searches/Search/SearchCommands.cs b/src/NadekoBot/Modules/Searches/Search/SearchCommands.cs index 1eb97dd7f..22e4fe975 100644 --- a/src/NadekoBot/Modules/Searches/Search/SearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Search/SearchCommands.cs @@ -165,7 +165,7 @@ public partial class Searches } await AddYoutubeUrlToCacheAsync(query, result.Url); - await ctx.Channel.SendMessageAsync(result.Url); + await Response().Text(result.Url).SendAsync(); } // [Cmd] diff --git a/src/NadekoBot/Modules/Searches/Searches.cs b/src/NadekoBot/Modules/Searches/Searches.cs index 00efa8d08..ad9085fe5 100644 --- a/src/NadekoBot/Modules/Searches/Searches.cs +++ b/src/NadekoBot/Modules/Searches/Searches.cs @@ -141,7 +141,7 @@ public partial class Searches : NadekoModule .AddField(GetText(strs.location), string.Join('\n', data.Address.Split(", ")), true) .AddField(GetText(strs.timezone), data.TimeZoneName, true); - await ctx.Channel.SendMessageAsync(embed: eb.Build()); + await Response().Embed(eb).SendAsync(); } [Cmd] @@ -441,7 +441,7 @@ public partial class Searches : NadekoModule if (data.Query.Pages[0].Missing || string.IsNullOrWhiteSpace(data.Query.Pages[0].FullUrl)) await Response().Error(strs.wiki_page_not_found).SendAsync(); else - await ctx.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl); + await Response().Text(data.Query.Pages[0].FullUrl).SendAsync(); } [Cmd] @@ -514,7 +514,7 @@ public partial class Searches : NadekoModule var url = Uri.EscapeDataString($"https://{target}.fandom.com/wiki/{title}"); var response = $@"`{GetText(strs.title)}` {title.SanitizeMentions()} `{GetText(strs.url)}:` {url}"; - await ctx.Channel.SendMessageAsync(response); + await Response().Text(response).SendAsync(); } catch { @@ -575,7 +575,7 @@ public partial class Searches : NadekoModule // .AddField(GetText(strs.price), gameData.IsFree ? GetText(strs.FREE) : game, true) // .AddField(GetText(strs.links), gameData.GetGenresString(), true) // .WithFooter(GetText(strs.recommendations(gameData.TotalRecommendations))); - await ctx.Channel.SendMessageAsync($"https://store.steampowered.com/app/{appId}"); + await Response().Text($"https://store.steampowered.com/app/{appId}").SendAsync(); } private async Task ValidateQuery([MaybeNullWhen(false)] string query) diff --git a/src/NadekoBot/Modules/Searches/StreamNotification/StreamNotificationService.cs b/src/NadekoBot/Modules/Searches/StreamNotification/StreamNotificationService.cs index a804de44b..8b5080b44 100644 --- a/src/NadekoBot/Modules/Searches/StreamNotification/StreamNotificationService.cs +++ b/src/NadekoBot/Modules/Searches/StreamNotification/StreamNotificationService.cs @@ -25,7 +25,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor private readonly ConcurrentHashSet _deleteOnOfflineServers; private readonly IPubSub _pubSub; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly SearchesConfigService _config; private readonly IReplacementService _repSvc; @@ -49,7 +49,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor IHttpClientFactory httpFactory, IBot bot, IPubSub pubSub, - IEmbedBuilderService eb, + IMessageSenderService sender, SearchesConfigService config, IReplacementService repSvc) { @@ -57,7 +57,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor _client = client; _strings = strings; _pubSub = pubSub; - _eb = eb; + _sender = sender; _config = config; _repSvc = repSvc; @@ -285,7 +285,10 @@ public sealed class StreamNotificationService : INService, IReadyExecutor ? "" : await _repSvc.ReplaceAsync(fs.Message, repCtx); - var msg = await textChannel.EmbedAsync(GetEmbed(fs.GuildId, stream, false), message); + var msg = await _sender.Response(textChannel) + .Embed(GetEmbed(fs.GuildId, stream, false)) + .Text(message) + .SendAsync(); // only cache the ids of channel/message pairs if (_deleteOnOfflineServers.Contains(fs.GuildId)) diff --git a/src/NadekoBot/Modules/Searches/Translate/TranslateService.cs b/src/NadekoBot/Modules/Searches/Translate/TranslateService.cs index 8c2b691aa..b3553e07b 100644 --- a/src/NadekoBot/Modules/Searches/Translate/TranslateService.cs +++ b/src/NadekoBot/Modules/Searches/Translate/TranslateService.cs @@ -12,7 +12,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady { private readonly IGoogleApiService _google; private readonly DbService _db; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly IBot _bot; private readonly ConcurrentDictionary _atcs = new(); @@ -21,12 +21,12 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady public TranslateService( IGoogleApiService google, DbService db, - IEmbedBuilderService eb, + IMessageSenderService sender, IBot bot) { _google = google; _db = db; - _eb = eb; + _sender = sender; _bot = bot; } @@ -77,7 +77,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady .AddField(langs.From, um.Content) .AddField(langs.To, output); - await tch.EmbedAsync(embed); + await _sender.Response(tch).Embed(embed).SendAsync(); try { diff --git a/src/NadekoBot/Modules/Utility/Giveaway/GiveawayService.cs b/src/NadekoBot/Modules/Utility/Giveaway/GiveawayService.cs index a97294625..ea9af2889 100644 --- a/src/NadekoBot/Modules/Utility/Giveaway/GiveawayService.cs +++ b/src/NadekoBot/Modules/Utility/Giveaway/GiveawayService.cs @@ -13,7 +13,7 @@ public sealed class GiveawayService : INService, IReadyExecutor private readonly DbService _db; private readonly IBotCredentials _creds; private readonly DiscordSocketClient _client; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly IBotStrings _strings; private readonly ILocalization _localization; private readonly IMemoryCache _cache; @@ -22,12 +22,12 @@ public sealed class GiveawayService : INService, IReadyExecutor private readonly ConcurrentDictionary _rerolls = new(); public GiveawayService(DbService db, IBotCredentials creds, DiscordSocketClient client, - IEmbedBuilderService eb, IBotStrings strings, ILocalization localization, IMemoryCache cache) + IMessageSenderService sender, IBotStrings strings, ILocalization localization, IMemoryCache cache) { _db = db; _creds = creds; _client = client; - _eb = eb; + _sender = sender; _strings = strings; _localization = localization; _cache = cache; @@ -317,8 +317,7 @@ public sealed class GiveawayService : INService, IReadyExecutor {Format.Code(winner.UserId.ToString())} """; - var eb = _eb - .Create() + var eb = new EmbedBuilder() .WithOkColor() .WithTitle(GetText(strs.giveaway_ended)) .WithDescription(ga.Message) @@ -334,7 +333,7 @@ public sealed class GiveawayService : INService, IReadyExecutor catch { _ = msg.DeleteAsync(); - await ch.EmbedAsync(eb); + await _sender.Response(ch).Embed(eb).SendAsync(); } } diff --git a/src/NadekoBot/Modules/Utility/Quote/QuoteCommands.cs b/src/NadekoBot/Modules/Utility/Quote/QuoteCommands.cs index d30f0da08..dc96e8ba9 100644 --- a/src/NadekoBot/Modules/Utility/Quote/QuoteCommands.cs +++ b/src/NadekoBot/Modules/Utility/Quote/QuoteCommands.cs @@ -133,23 +133,23 @@ public partial class Utility private async Task ShowQuoteData(Quote data) { var eb = new EmbedBuilder() - .WithOkColor() - .WithTitle($"{GetText(strs.quote_id($"#{data.Id}"))} | {GetText(strs.response)}:") - .WithDescription(Format.Sanitize(data.Text).Replace("](", "]\\(").TrimTo(4096)) - .AddField(GetText(strs.trigger), data.Keyword) - .WithFooter( - GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})"))) - .Build(); + .WithOkColor() + .WithTitle($"{GetText(strs.quote_id($"#{data.Id}"))} | {GetText(strs.response)}:") + .WithDescription(Format.Sanitize(data.Text).Replace("](", "]\\(").TrimTo(4096)) + .AddField(GetText(strs.trigger), data.Keyword) + .WithFooter( + GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})"))); if (!(data.Text.Length > 4096)) { - await ctx.Channel.SendMessageAsync(embed: eb); + await Response().Embed(eb).SendAsync(); return; } + // todo all send files should go through response system too await ctx.Channel.SendFileAsync( attachment: new FileAttachment(await data.Text.ToStream(), "quote.txt"), - embed: eb); + embed: eb.Build()); } private async Task QuoteSearchinternalAsync(string? keyword, string textOrAuthor) @@ -168,10 +168,12 @@ public partial class Utility if (quote is null) return; - await ctx.Channel.SendMessageAsync($"`#{quote.Id}` πŸ’¬ " - + quote.Keyword.ToLowerInvariant() - + ": " - + quote.Text.SanitizeAllMentions()); + await Response() + .Confirm($"`#{quote.Id}` πŸ’¬ ", + quote.Keyword.ToLowerInvariant() + + ": " + + quote.Text.SanitizeAllMentions()) + .SendAsync(); } [Cmd] @@ -204,7 +206,7 @@ public partial class Utility if (quote is null || quote.GuildId != ctx.Guild.Id) { - await Response().Error(GetText(strs.quotes_notfound)).SendAsync(); + await Response().Error(strs.quotes_notfound).SendAsync(); return; } diff --git a/src/NadekoBot/Modules/Utility/Remind/RemindService.cs b/src/NadekoBot/Modules/Utility/Remind/RemindService.cs index 7a36adf1a..824fd36ec 100644 --- a/src/NadekoBot/Modules/Utility/Remind/RemindService.cs +++ b/src/NadekoBot/Modules/Utility/Remind/RemindService.cs @@ -11,25 +11,26 @@ namespace NadekoBot.Modules.Utility.Services; public class RemindService : INService, IReadyExecutor, IRemindService { private readonly Regex _regex = - new(@"^(?:(?:at|on(?:\sthe)?)?\s*(?(?:\d{2}:\d{2}\s)?\d{1,2}\.\d{1,2}(?:\.\d{2,4})?)|(?:in\s?)?\s*(?:(?\d+)(?:\s?(?:months?|mos?),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:weeks?|w),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:days?|d),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:hours?|h),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:minutes?|mins?|m),?))?)\s+(?:to:?\s+)?(?(?:\r\n|[\r\n]|.)+)", + new( + @"^(?:(?:at|on(?:\sthe)?)?\s*(?(?:\d{2}:\d{2}\s)?\d{1,2}\.\d{1,2}(?:\.\d{2,4})?)|(?:in\s?)?\s*(?:(?\d+)(?:\s?(?:months?|mos?),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:weeks?|w),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:days?|d),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:hours?|h),?))?(?:(?:\sand\s|\s*)?(?\d+)(?:\s?(?:minutes?|mins?|m),?))?)\s+(?:to:?\s+)?(?(?:\r\n|[\r\n]|.)+)", RegexOptions.Compiled | RegexOptions.Multiline); - + private readonly DiscordSocketClient _client; private readonly DbService _db; private readonly IBotCredentials _creds; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly CultureInfo _culture; public RemindService( DiscordSocketClient client, DbService db, IBotCredentials creds, - IEmbedBuilderService eb) + IMessageSenderService sender) { _client = client; _db = db; _creds = creds; - _eb = eb; + _sender = sender; try { @@ -120,7 +121,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService if (!string.IsNullOrWhiteSpace(dateString)) { var now = DateTime.UtcNow; - + if (!DateTime.TryParse(dateString, _culture, DateTimeStyles.None, out var dt)) { Log.Warning("Invalid remind datetime format"); @@ -162,6 +163,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService values[groupName] = value; } + ts = new TimeSpan((30 * values["mo"]) + (7 * values["w"]) + values["d"], values["h"], values["m"], 0); } @@ -197,22 +199,24 @@ public class RemindService : INService, IReadyExecutor, IRemindService if (st is SmartEmbedText set) { - await ch.SendMessageAsync(null, embed: set.GetEmbed().Build()); + await _sender.Response(ch).Embed(set.GetEmbed()).SendAsync(); } else if (st is SmartEmbedTextArray seta) { - await ch.SendMessageAsync(null, embeds: seta.GetEmbedBuilders().Map(x => x.Build())); + await _sender.Response(ch).Embeds(seta.GetEmbedBuilders()).SendAsync(); } else { - await ch.EmbedAsync(new EmbedBuilder() - .WithOkColor() - .WithTitle("Reminder") - .AddField("Created At", - r.DateAdded.HasValue ? r.DateAdded.Value.ToLongDateString() : "?") - .AddField("By", - (await ch.GetUserAsync(r.UserId))?.ToString() ?? r.UserId.ToString()), - r.Message); + await _sender.Response(ch) + .Embed(new EmbedBuilder() + .WithOkColor() + .WithTitle("Reminder") + .AddField("Created At", + r.DateAdded.HasValue ? r.DateAdded.Value.ToLongDateString() : "?") + .AddField("By", + (await ch.GetUserAsync(r.UserId))?.ToString() ?? r.UserId.ToString())) + .Text(r.Message) + .SendAsync(); } } catch (Exception ex) @@ -227,7 +231,8 @@ public class RemindService : INService, IReadyExecutor, IRemindService public TimeSpan Time { get; set; } } - public async Task AddReminderAsync(ulong userId, + public async Task AddReminderAsync( + ulong userId, ulong targetId, ulong? guildId, bool isPrivate, @@ -242,7 +247,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService ServerId = guildId ?? 0, IsPrivate = isPrivate, When = time, - Message = message, + Message = message, Type = reminderType }; diff --git a/src/NadekoBot/Modules/Utility/Todo/TodoCommands.cs b/src/NadekoBot/Modules/Utility/Todo/TodoCommands.cs index 28116930b..e89ddeffc 100644 --- a/src/NadekoBot/Modules/Utility/Todo/TodoCommands.cs +++ b/src/NadekoBot/Modules/Utility/Todo/TodoCommands.cs @@ -1,4 +1,5 @@ ο»Ώusing NadekoBot.Db.Models; +using System.Text; namespace NadekoBot.Modules.Utility; @@ -86,8 +87,8 @@ public partial class Utility (curPage) => { var eb = new EmbedBuilder() - .WithOkColor() - .WithTitle(GetText(strs.todo_list)); + .WithOkColor() + .WithTitle(GetText(strs.todo_list)); ShowTodoItem(todos, curPage, eb); @@ -99,15 +100,15 @@ public partial class Utility private static void ShowTodoItem(IReadOnlyCollection todos, int curPage, EmbedBuilder eb) { + var sb = new StringBuilder(); foreach (var todo in todos.Skip(curPage * 9).Take(9)) { - // green circle and yellow circle emojis - eb.AddField($"-", - $"{(todo.IsDone - ? "βœ…" - : "🟑")} {Format.Code(new kwum(todo.Id).ToString())} {todo.Todo}", - false); + sb.AppendLine($"{(todo.IsDone ? "βœ”" : "β–‘")} {Format.Code(new kwum(todo.Id).ToString())} {todo.Todo}"); + + sb.AppendLine("---"); } + + eb.WithDescription(sb.ToString()); } [Group("archive")] @@ -150,8 +151,8 @@ public partial class Utility (curPage) => { var eb = new EmbedBuilder() - .WithTitle(GetText(strs.todo_archive_list)) - .WithOkColor(); + .WithTitle(GetText(strs.todo_archive_list)) + .WithOkColor(); foreach (var archivedList in archivedTodoLists.Skip(curPage * 9).Take(9)) { @@ -179,8 +180,8 @@ public partial class Utility (curPage) => { var eb = new EmbedBuilder() - .WithOkColor() - .WithTitle(GetText(strs.todo_list)); + .WithOkColor() + .WithTitle(GetText(strs.todo_list)); ShowTodoItem(list.Items, curPage, eb); diff --git a/src/NadekoBot/Modules/Utility/UnitConversion/UnitConversionCommands.cs b/src/NadekoBot/Modules/Utility/UnitConversion/UnitConversionCommands.cs index b1178ac6e..e6d7abf13 100644 --- a/src/NadekoBot/Modules/Utility/UnitConversion/UnitConversionCommands.cs +++ b/src/NadekoBot/Modules/Utility/UnitConversion/UnitConversionCommands.cs @@ -90,10 +90,10 @@ public partial class Utility res = Math.Round(res, 4); await Response() - .Confirm(GetText(strs.convert(value, + .Confirm(strs.convert(value, originUnit.Triggers.Last(), res, - targetUnit.Triggers.Last()))) + targetUnit.Triggers.Last())) .SendAsync(); } } diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index 61839723a..1143fcdc1 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -337,7 +337,7 @@ public partial class Utility : NadekoModule if (string.IsNullOrWhiteSpace(result)) await Response().Error(strs.showemojis_none).SendAsync(); else - await ctx.Channel.SendMessageAsync(result.TrimTo(2000)); + await Response().Text(result.TrimTo(2000)).SendAsync(); } [Cmd] @@ -613,7 +613,7 @@ public partial class Utility : NadekoModule try { var sw = Stopwatch.StartNew(); - var msg = await ctx.Channel.SendMessageAsync("πŸ“"); + var msg = await Response().Text("πŸ“").SendAsync(); sw.Stop(); msg.DeleteAfter(0); diff --git a/src/NadekoBot/Modules/Utility/VerboseErrorsService.cs b/src/NadekoBot/Modules/Utility/VerboseErrorsService.cs index 1dc393cf6..7fbf600aa 100644 --- a/src/NadekoBot/Modules/Utility/VerboseErrorsService.cs +++ b/src/NadekoBot/Modules/Utility/VerboseErrorsService.cs @@ -9,16 +9,19 @@ public class VerboseErrorsService : INService private readonly DbService _db; private readonly CommandHandler _ch; private readonly ICommandsUtilityService _hs; + private readonly IMessageSenderService _sender; public VerboseErrorsService( IBot bot, DbService db, CommandHandler ch, + IMessageSenderService sender, ICommandsUtilityService hs) { _db = db; _ch = ch; _hs = hs; + _sender = sender; _ch.CommandErrored += LogVerboseError; @@ -38,7 +41,7 @@ public class VerboseErrorsService : INService .WithFooter("Admin may disable verbose errors via `.ve` command") .WithErrorColor(); - await channel.EmbedAsync(embed); + await _sender.Response(channel).Embed(embed).SendAsync(); } catch { diff --git a/src/NadekoBot/Modules/Xp/XpService.cs b/src/NadekoBot/Modules/Xp/XpService.cs index 730defd35..8662dcff9 100644 --- a/src/NadekoBot/Modules/Xp/XpService.cs +++ b/src/NadekoBot/Modules/Xp/XpService.cs @@ -31,7 +31,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand private readonly IHttpClientFactory _httpFactory; private readonly XpConfigService _xpConfig; private readonly IPubSub _pubSub; - private readonly IEmbedBuilderService _eb; private readonly ConcurrentDictionary> _excludedRoles; private readonly ConcurrentDictionary> _excludedChannels; @@ -62,7 +61,6 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand IHttpClientFactory http, XpConfigService xpConfig, IPubSub pubSub, - IEmbedBuilderService eb, IPatronageService ps, IMessageSenderService sender) { @@ -75,14 +73,13 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand _httpFactory = http; _xpConfig = xpConfig; _pubSub = pubSub; - _eb = eb; + _sender = sender; _excludedServers = new(); _excludedChannels = new(); _client = client; _xpTemplateReloadKey = new("xp.template.reload"); _ps = ps; _c = c; - _sender = sender; InternalReloadXpTemplate(); @@ -393,11 +390,12 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand { if (notifyLoc == XpNotificationLocation.Dm) { - await user.SendConfirmAsync(_eb, - _strings.GetText(strs.level_up_dm(user.Mention, - Format.Bold(newLevel.ToString()), - Format.Bold(guild.ToString() ?? "-")), - guild.Id)); + await _sender.Response(user) + .Confirm(_strings.GetText(strs.level_up_dm(user.Mention, + Format.Bold(newLevel.ToString()), + Format.Bold(guild.ToString() ?? "-")), + guild.Id)) + .SendAsync(); } else // channel { diff --git a/src/NadekoBot/PermissionChecker.cs b/src/NadekoBot/PermissionChecker.cs index c49c88c86..4100a0e8b 100644 --- a/src/NadekoBot/PermissionChecker.cs +++ b/src/NadekoBot/PermissionChecker.cs @@ -8,20 +8,20 @@ public sealed class PermissionChecker : IPermissionChecker, INService private readonly PermissionService _perms; private readonly GlobalPermissionService _gperm; private readonly CmdCdService _cmdCds; - private readonly IEmbedBuilderService _ebs; + private readonly IMessageSenderService _sender; private readonly CommandHandler _ch; public PermissionChecker( PermissionService perms, GlobalPermissionService gperm, CmdCdService cmdCds, - IEmbedBuilderService ebs, + IMessageSenderService sender, CommandHandler ch) { _perms = perms; _gperm = gperm; _cmdCds = cmdCds; - _ebs = ebs; + _sender = sender; _ch = ch; } diff --git a/src/NadekoBot/_common/ILogCommandService.cs b/src/NadekoBot/_common/ILogCommandService.cs index 303aa5262..437aded87 100644 --- a/src/NadekoBot/_common/ILogCommandService.cs +++ b/src/NadekoBot/_common/ILogCommandService.cs @@ -26,7 +26,6 @@ public enum LogType ChannelUpdated, UserPresence, VoicePresence, - VoicePresenceTts, UserMuted, UserWarned, diff --git a/src/NadekoBot/_common/Medusa/Common/Adapters/DmContextAdapter.cs b/src/NadekoBot/_common/Medusa/Common/Adapters/DmContextAdapter.cs index 87fcbf8cb..4b265fe90 100644 --- a/src/NadekoBot/_common/Medusa/Common/Adapters/DmContextAdapter.cs +++ b/src/NadekoBot/_common/Medusa/Common/Adapters/DmContextAdapter.cs @@ -12,7 +12,6 @@ public sealed class DmContextAdapter : DmContext private readonly IServiceProvider _services; - private readonly Lazy _ebs; private readonly Lazy _botStrings; private readonly Lazy _localization; @@ -32,14 +31,10 @@ public sealed class DmContextAdapter : DmContext Bot = ctx.Client.CurrentUser; - _ebs = new(_services.GetRequiredService()); _botStrings = new(_services.GetRequiredService); _localization = new(_services.GetRequiredService()); } - public override EmbedBuilder Embed() - => new EmbedBuilder(); - public override string GetText(string key, object[]? args = null) { var cultureInfo = _localization.Value.GetCultureInfo(default(ulong?)); diff --git a/src/NadekoBot/_common/Medusa/Common/Adapters/GuildContextAdapter.cs b/src/NadekoBot/_common/Medusa/Common/Adapters/GuildContextAdapter.cs index 7f5896e15..8819e28ba 100644 --- a/src/NadekoBot/_common/Medusa/Common/Adapters/GuildContextAdapter.cs +++ b/src/NadekoBot/_common/Medusa/Common/Adapters/GuildContextAdapter.cs @@ -5,7 +5,6 @@ public sealed class GuildContextAdapter : GuildContext { private readonly IServiceProvider _services; private readonly ICommandContext _ctx; - private readonly Lazy _ebs; private readonly Lazy _botStrings; private readonly Lazy _localization; @@ -18,9 +17,6 @@ public sealed class GuildContextAdapter : GuildContext public override IGuildUser User { get; } - public override EmbedBuilder Embed() - => _ebs.Value.Create(); - public GuildContextAdapter(ICommandContext ctx, IMedusaStrings strings, IServiceProvider services) { if (ctx.Guild is not IGuild guild || ctx.Channel is not ITextChannel channel) @@ -33,7 +29,6 @@ public sealed class GuildContextAdapter : GuildContext Bot = ctx.Client.CurrentUser; _services = services; - _ebs = new(_services.GetRequiredService()); _botStrings = new(_services.GetRequiredService); _localization = new(_services.GetRequiredService()); diff --git a/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs b/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs index 45c26e122..9ffb4acd7 100644 --- a/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs +++ b/src/NadekoBot/_common/Medusa/Common/MedusaLoaderService.cs @@ -342,7 +342,6 @@ public sealed class MedusaLoaderService : IMedusaLoaderService, IReadyExecutor, var sis = LoadSneksFromAssembly(safeName, a); typeReaders = LoadTypeReadersFromAssembly(a, strings); - // todo allow this if (sis.Count == 0) { _kernel.Unload(safeName); diff --git a/src/NadekoBot/_common/NadekoModule.cs b/src/NadekoBot/_common/NadekoModule.cs index 4e6f79c39..f36b01164 100644 --- a/src/NadekoBot/_common/NadekoModule.cs +++ b/src/NadekoBot/_common/NadekoModule.cs @@ -16,7 +16,6 @@ public abstract class NadekoModule : ModuleBase public IBotStrings Strings { get; set; } public ICommandHandler _cmdHandler { get; set; } public ILocalization _localization { get; set; } - public IEmbedBuilderService _eb { get; set; } public INadekoInteractionService _inter { get; set; } public IReplacementService repSvc { get; set; } public IMessageSenderService _sender { get; set; } @@ -28,7 +27,7 @@ public abstract class NadekoModule : ModuleBase => Context; public ResponseBuilder Response() - => new ResponseBuilder(Strings, _eb) + => new ResponseBuilder(Strings) .Context(ctx); protected override void BeforeExecute(CommandInfo command) diff --git a/src/NadekoBot/_common/Sender/IMessageSenderService.cs b/src/NadekoBot/_common/Sender/IMessageSenderService.cs index 1a3453d4e..81ccf8edc 100644 --- a/src/NadekoBot/_common/Sender/IMessageSenderService.cs +++ b/src/NadekoBot/_common/Sender/IMessageSenderService.cs @@ -3,5 +3,8 @@ public interface IMessageSenderService { ResponseBuilder Response(IMessageChannel channel); - ResponseBuilder Response(ICommandContext hannel); + ResponseBuilder Response(ICommandContext ctx); + ResponseBuilder Response(IUser user); + + ResponseBuilder Response(SocketMessageComponent smc); } \ No newline at end of file diff --git a/src/NadekoBot/_common/Sender/MessageChannelExtensions.cs b/src/NadekoBot/_common/Sender/MessageChannelExtensions.cs index dde83f5cb..78369f8f1 100644 --- a/src/NadekoBot/_common/Sender/MessageChannelExtensions.cs +++ b/src/NadekoBot/_common/Sender/MessageChannelExtensions.cs @@ -2,10 +2,6 @@ public static class MessageChannelExtensions { - public static ResponseBuilder Response(this IMessageChannel channel, IBotStrings bs, IEmbedBuilderService ebs) - => new ResponseBuilder(bs, ebs) - .Channel(channel); - // main overload that all other send methods reduce to public static Task SendAsync( this IMessageChannel channel, @@ -92,7 +88,7 @@ public static class MessageChannelExtensions this IMessageChannel ch, EmbedBuilder? embed, string plainText = "", - IReadOnlyCollection? embeds = null, + IReadOnlyCollection? embeds = null, NadekoInteraction? inter = null, IUserMessage? replyTo = null) => ch.SendAsync(plainText, diff --git a/src/NadekoBot/_common/Sender/MessageSenderService.cs b/src/NadekoBot/_common/Sender/MessageSenderService.cs index cc91e926a..fb296af8c 100644 --- a/src/NadekoBot/_common/Sender/MessageSenderService.cs +++ b/src/NadekoBot/_common/Sender/MessageSenderService.cs @@ -5,20 +5,27 @@ namespace NadekoBot.Extensions; public sealed class MessageSenderService : IMessageSenderService, INService { private readonly IBotStrings _bs; - private readonly IEmbedBuilderService _ebs; - public MessageSenderService(IBotStrings bs, IEmbedBuilderService ebs) + public MessageSenderService(IBotStrings bs) { _bs = bs; - _ebs = ebs; } public ResponseBuilder Response(IMessageChannel channel) - => new ResponseBuilder(_bs, _ebs) + => new ResponseBuilder(_bs) .Channel(channel); public ResponseBuilder Response(ICommandContext ctx) - => new ResponseBuilder(_bs, _ebs) + => new ResponseBuilder(_bs) .Context(ctx); + + public ResponseBuilder Response(IUser user) + => new ResponseBuilder(_bs) + .User(user); + + // todo fix interactions + public ResponseBuilder Response(SocketMessageComponent smc) + => new ResponseBuilder(_bs) + .Channel(smc.Channel); } \ No newline at end of file diff --git a/src/NadekoBot/_common/Sender/ResponseBuilder.cs b/src/NadekoBot/_common/Sender/ResponseBuilder.cs index cff737fb3..ec46efa78 100644 --- a/src/NadekoBot/_common/Sender/ResponseBuilder.cs +++ b/src/NadekoBot/_common/Sender/ResponseBuilder.cs @@ -14,13 +14,14 @@ public sealed class ResponseBuilder private object[] locParams = []; private bool shouldReply = true; private readonly IBotStrings _bs; - private readonly IEmbedBuilderService _ebs; private EmbedBuilder? embedBuilder = null; + private NadekoInteraction? inter; + private Stream? fileStream = null; + private string? fileName = null; - public ResponseBuilder(IBotStrings bs, IEmbedBuilderService ebs) + public ResponseBuilder(IBotStrings bs) { _bs = bs; - _ebs = ebs; } private MessageReference? CreateMessageReference(IMessageChannel targetChannel) @@ -43,8 +44,9 @@ public sealed class ResponseBuilder failIfNotExists: false); } - public async Task SendAsync() + public async Task SendAsync(bool ephemeral = false) { + // todo use ephemeral in interactions var targetChannel = InternalResolveChannel() ?? throw new ArgumentNullException(nameof(channel)); var msgReference = CreateMessageReference(targetChannel); @@ -53,6 +55,15 @@ public sealed class ResponseBuilder if (sanitizeMentions) txt = txt?.SanitizeMentions(true); + if (this.fileStream is Stream stream) + return await targetChannel.SendFileAsync(stream, + filename: fileName, + txt, + embed: embed ?? embedBuilder?.Build(), + components: null, + allowedMentions: sanitizeMentions ? new(AllowedMentionTypes.Users) : AllowedMentions.All, + messageReference: msgReference); + return await targetChannel.SendMessageAsync( txt, embed: embed ?? embedBuilder?.Build(), @@ -65,6 +76,7 @@ public sealed class ResponseBuilder private ulong? InternalResolveGuildId(IMessageChannel? targetChannel) => ctx?.Guild?.Id ?? (targetChannel as ITextChannel)?.GuildId; + // todo not good, has to go to the user private IMessageChannel? InternalResolveChannel() => channel ?? ctx?.Channel ?? msg?.Channel; @@ -188,20 +200,14 @@ public sealed class ResponseBuilder private IUser? InternalResolveUser() => ctx?.User ?? user ?? msg?.Author; + // todo embed colors + public ResponseBuilder Embed(EmbedBuilder eb) { embedBuilder = eb; return this; } - public ResponseBuilder Embed(Func embedFactory) - { - // todo colors - this.embed = embedFactory(_ebs).Build(); - - return this; - } - public ResponseBuilder Channel(IMessageChannel channel) { this.channel = channel; @@ -238,9 +244,10 @@ public sealed class ResponseBuilder return this; } - public ResponseBuilder Interaction(NadekoInteraction inter) + public ResponseBuilder Interaction(NadekoInteraction? interaction) { // todo implement + inter = interaction; return this; } @@ -249,4 +256,11 @@ public sealed class ResponseBuilder embeds = inputEmbeds; return this; } + + public ResponseBuilder FileName(Stream fileStream, string fileName) + { + this.fileStream = fileStream; + this.fileName = fileName; + return this; + } } \ No newline at end of file diff --git a/src/NadekoBot/_common/Services/Currency/CurrencyServiceExtensions.cs b/src/NadekoBot/_common/Services/Currency/CurrencyServiceExtensions.cs index e5dcfa7ba..0bd9e64f9 100644 --- a/src/NadekoBot/_common/Services/Currency/CurrencyServiceExtensions.cs +++ b/src/NadekoBot/_common/Services/Currency/CurrencyServiceExtensions.cs @@ -9,11 +9,11 @@ public static class CurrencyServiceExtensions var wallet = await cs.GetWalletAsync(userId); return await wallet.GetBalance(); } - + // FUTURE should be a transaction public static async Task TransferAsync( this ICurrencyService cs, - IEmbedBuilderService ebs, + IMessageSenderService sender, IUser from, IUser to, long amount, @@ -29,17 +29,20 @@ public static class CurrencyServiceExtensions { try { - await to.SendConfirmAsync(ebs, - string.IsNullOrWhiteSpace(note) - ? $"Received {formattedAmount} from {from} " - : $"Received {formattedAmount} from {from}: {note}"); + await sender.Response(to) + .Confirm(string.IsNullOrWhiteSpace(note) + ? $"Received {formattedAmount} from {from} " + : $"Received {formattedAmount} from {from}: {note}") + .SendAsync(); } catch { //ignored } + return true; } + return false; } -} +} \ No newline at end of file diff --git a/src/NadekoBot/_common/Services/IEmbedBuilderService.cs b/src/NadekoBot/_common/Services/IEmbedBuilderService.cs index 80533b465..19b6a7f85 100644 --- a/src/NadekoBot/_common/Services/IEmbedBuilderService.cs +++ b/src/NadekoBot/_common/Services/IEmbedBuilderService.cs @@ -1,79 +1,17 @@ #nullable disable -using NadekoBot.Common.Configs; -// todo remove namespace NadekoBot.Services; -public interface IEmbedBuilderService +// todo remove +public sealed class DiscordEmbedBuilderWrapper { - EmbedBuilder Create(ICommandContext ctx = null); -} + // public EmbedBuilder WithColor(EmbedColor color) + // => color switch + // { + // EmbedColor.Ok => Wrap(embed.WithColor(_botConfig.Color.Ok.ToDiscordColor())), + // EmbedColor.Pending => Wrap(embed.WithColor(_botConfig.Color.Pending.ToDiscordColor())), + // EmbedColor.Error => Wrap(embed.WithColor(_botConfig.Color.Error.ToDiscordColor())), + // _ => throw new ArgumentOutOfRangeException(nameof(color), "Unsupported EmbedColor type") + // }; -public class EmbedBuilderService : IEmbedBuilderService, INService -{ - private readonly BotConfigService _botConfigService; - - public EmbedBuilderService(BotConfigService botConfigService) - => _botConfigService = botConfigService; - - public EmbedBuilder Create(ICommandContext ctx = null) - => new EmbedBuilder(); - -} - -public sealed class DiscordEmbedBuilderWrapper : IEmbedBuilder -{ - private readonly BotConfig _botConfig; - private EmbedBuilder embed; - - public DiscordEmbedBuilderWrapper(in BotConfig botConfig, EmbedBuilder embed = null) - { - _botConfig = botConfig; - this.embed = embed ?? new EmbedBuilder(); - } - - public EmbedBuilder WithDescription(string desc) - => Wrap(embed.WithDescription(desc)); - - public EmbedBuilder WithTitle(string title) - => Wrap(embed.WithTitle(title)); - - public EmbedBuilder AddField(string title, object value, bool isInline = false) - => Wrap(embed.AddField(title, value, isInline)); - - public EmbedBuilder WithFooter(string text, string iconUrl = null) - => Wrap(embed.WithFooter(text, iconUrl)); - - public EmbedBuilder WithAuthor(string name, string iconUrl = null, string url = null) - => Wrap(embed.WithAuthor(name, iconUrl, url)); - - public EmbedBuilder WithUrl(string url) - => Wrap(embed.WithUrl(url)); - - public EmbedBuilder WithImageUrl(string url) - => Wrap(embed.WithImageUrl(url)); - - public EmbedBuilder WithThumbnailUrl(string url) - => Wrap(embed.WithThumbnailUrl(url)); - - public EmbedBuilder WithColor(EmbedColor color) - => color switch - { - EmbedColor.Ok => Wrap(embed.WithColor(_botConfig.Color.Ok.ToDiscordColor())), - EmbedColor.Pending => Wrap(embed.WithColor(_botConfig.Color.Pending.ToDiscordColor())), - EmbedColor.Error => Wrap(embed.WithColor(_botConfig.Color.Error.ToDiscordColor())), - _ => throw new ArgumentOutOfRangeException(nameof(color), "Unsupported EmbedColor type") - }; - - public EmbedBuilder WithDiscordColor(Color color) - => Wrap(embed.WithColor(color)); - - public Embed Build() - => embed.Build(); - - private EmbedBuilder Wrap(EmbedBuilder eb) - { - embed = eb; - return eb; - } } \ No newline at end of file diff --git a/src/NadekoBot/_common/Services/Impl/CommandsUtilityService.cs b/src/NadekoBot/_common/Services/Impl/CommandsUtilityService.cs index 31f2002b6..8229eb960 100644 --- a/src/NadekoBot/_common/Services/Impl/CommandsUtilityService.cs +++ b/src/NadekoBot/_common/Services/Impl/CommandsUtilityService.cs @@ -8,7 +8,7 @@ public sealed class CommandsUtilityService : ICommandsUtilityService, INService private readonly CommandHandler _ch; private readonly IBotStrings _strings; private readonly DiscordPermOverrideService _dpos; - private readonly IEmbedBuilderService _eb; + private readonly IMessageSenderService _sender; private readonly ILocalization _loc; private readonly IMedusaLoaderService _medusae; @@ -16,14 +16,14 @@ public sealed class CommandsUtilityService : ICommandsUtilityService, INService CommandHandler ch, IBotStrings strings, DiscordPermOverrideService dpos, - IEmbedBuilderService eb, + IMessageSenderService sender, ILocalization loc, IMedusaLoaderService medusae) { _ch = ch; _strings = strings; _dpos = dpos; - _eb = eb; + _sender = sender; _loc = loc; _medusae = medusae; } diff --git a/src/NadekoBot/_common/_Extensions/SocketMessageComponentExtensions.cs b/src/NadekoBot/_common/_Extensions/SocketMessageComponentExtensions.cs index a6ea2d103..6ea0d99a1 100644 --- a/src/NadekoBot/_common/_Extensions/SocketMessageComponentExtensions.cs +++ b/src/NadekoBot/_common/_Extensions/SocketMessageComponentExtensions.cs @@ -60,31 +60,34 @@ public static class SocketMessageComponentExtensions public static Task RespondAsync( this SocketMessageComponent ch, - IEmbedBuilderService eb, + IMessageSenderService sender, string text, MsgType type, bool ephemeral = false, NadekoInteraction? inter = null) { - var builder = new EmbedBuilder().WithDescription(text); + var embed = new EmbedBuilder().WithDescription(text); - builder = (type switch + embed = (type switch { - MsgType.Error => builder.WithErrorColor(), - MsgType.Ok => builder.WithOkColor(), - MsgType.Pending => builder.WithPendingColor(), + MsgType.Error => embed.WithErrorColor(), + MsgType.Ok => embed.WithOkColor(), + MsgType.Pending => embed.WithPendingColor(), _ => throw new ArgumentOutOfRangeException(nameof(type)) }); - return ch.EmbedAsync(builder, inter: inter, ephemeral: ephemeral); + return sender.Response(ch) + .Embed(embed) + .Interaction(inter) + .SendAsync(ephemeral: ephemeral); } // embed title and optional footer overloads public static Task RespondConfirmAsync( this SocketMessageComponent smc, - IEmbedBuilderService eb, + IMessageSenderService sender, string text, bool ephemeral = false) - => smc.RespondAsync(eb, text, MsgType.Ok, ephemeral); + => smc.RespondAsync(sender, text, MsgType.Ok, ephemeral); } \ No newline at end of file diff --git a/src/NadekoBot/_common/_Extensions/UserExtensions.cs b/src/NadekoBot/_common/_Extensions/UserExtensions.cs index 37525e2d5..6718615c3 100644 --- a/src/NadekoBot/_common/_Extensions/UserExtensions.cs +++ b/src/NadekoBot/_common/_Extensions/UserExtensions.cs @@ -4,21 +4,6 @@ namespace NadekoBot.Extensions; public static class UserExtensions { - public static async Task EmbedAsync(this IUser user, EmbedBuilder embed, string msg = "") - { - var ch = await user.CreateDMChannelAsync(); - return await ch.EmbedAsync(embed, msg); - } - - public static async Task SendAsync(this IUser user, SmartText text, bool sanitizeAll = false) - { - var ch = await user.CreateDMChannelAsync(); - return await ch.SendAsync(text, sanitizeAll); - } - - public static async Task SendConfirmAsync(this IUser user, IEmbedBuilderService eb, string text) - => await user.SendMessageAsync("", embed: new EmbedBuilder().WithOkColor().WithDescription(text).Build()); - // This method is used by everything that fetches the avatar from a user public static Uri RealAvatarUrl(this IUser usr, ushort size = 256) => usr.AvatarId is null ? new(usr.GetDefaultAvatarUrl()) : new Uri(usr.GetAvatarUrl(ImageFormat.Auto, size));