From 93b8bca018345bbea8994f42216c3f782a494d20 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Thu, 23 Dec 2021 08:02:23 +0700 Subject: [PATCH] Switch to discord.net 3.0.0 --- src/NadekoBot/Bot.cs | 3 +- src/NadekoBot/Common/Attributes/BotPerm.cs | 12 - src/NadekoBot/Common/Attributes/UserPerm.cs | 24 +- src/NadekoBot/Common/GuildPerm.cs | 250 ------------------ .../Common/SocketMessageEventWrapper.cs | 17 +- src/NadekoBot/GlobalUsings.cs | 5 + .../Modules/Administration/Administration.cs | 4 +- .../Modules/Administration/SelfCommands.cs | 2 +- .../Administration/ServerGreetCommands.cs | 2 +- .../Services/GameVoiceChannelService.cs | 14 +- .../Services/LogCommandService.cs | 24 +- .../Services/RoleCommandsService.cs | 12 +- .../Administration/Services/SelfService.cs | 2 +- .../Administration/UserPunishCommands.cs | 11 +- .../Extensions/CustomReactionExtensions.cs | 2 +- .../Gambling/Common/Events/GameStatusEvent.cs | 2 +- .../Gambling/Common/Events/ReactionEvent.cs | 4 +- .../Modules/Gambling/ShopCommands.cs | 2 +- src/NadekoBot/Modules/Help/Help.cs | 2 +- .../Modules/Help/Services/HelpService.cs | 4 +- .../Music/Services/AyuVoiceStateService.cs | 4 +- .../Modules/Utility/InviteCommands.cs | 8 +- .../Utility/Services/PatreonRewardsService.cs | 3 +- .../Modules/Utility/Services/RemindService.cs | 2 +- .../Utility/Services/StreamRoleService.cs | 2 +- src/NadekoBot/Modules/Utility/Utility.cs | 14 +- .../Modules/Xp/Services/XpService.cs | 6 +- src/NadekoBot/NadekoBot.csproj | 4 +- src/NadekoBot/Services/CommandHandler.cs | 2 +- .../Services/GreetSettingsService.cs | 27 +- .../Services/Impl/CurrencyService.cs | 2 +- src/NadekoBot/_Extensions/Extensions.cs | 22 +- .../_Extensions/IMessageChannelExtensions.cs | 19 +- src/NadekoBot/_Extensions/IUserExtensions.cs | 30 ++- 34 files changed, 159 insertions(+), 384 deletions(-) delete mode 100644 src/NadekoBot/Common/Attributes/BotPerm.cs delete mode 100644 src/NadekoBot/Common/GuildPerm.cs diff --git a/src/NadekoBot/Bot.cs b/src/NadekoBot/Bot.cs index 73f14e002..1ca08c0e6 100644 --- a/src/NadekoBot/Bot.cs +++ b/src/NadekoBot/Bot.cs @@ -51,7 +51,8 @@ public sealed class Bot TotalShards = _creds.TotalShards, ShardId = shardId, AlwaysDownloadUsers = false, - ExclusiveBulkDelete = true, + AlwaysResolveStickers = false, + AlwaysDownloadDefaultStickers = false, }); _commandService = new(new() diff --git a/src/NadekoBot/Common/Attributes/BotPerm.cs b/src/NadekoBot/Common/Attributes/BotPerm.cs deleted file mode 100644 index 837d7e408..000000000 --- a/src/NadekoBot/Common/Attributes/BotPerm.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Discord; - -public class BotPermAttribute : RequireBotPermissionAttribute -{ - public BotPermAttribute(GuildPerm permission) : base((GuildPermission)permission) - { - } - - public BotPermAttribute(ChannelPerm permission) : base((ChannelPermission)permission) - { - } -} \ No newline at end of file diff --git a/src/NadekoBot/Common/Attributes/UserPerm.cs b/src/NadekoBot/Common/Attributes/UserPerm.cs index 5e10f6a0a..616143dd9 100644 --- a/src/NadekoBot/Common/Attributes/UserPerm.cs +++ b/src/NadekoBot/Common/Attributes/UserPerm.cs @@ -4,26 +4,22 @@ using NadekoBot.Modules.Administration.Services; namespace Discord; [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -public class UserPermAttribute : PreconditionAttribute +public class UserPermAttribute : RequireUserPermissionAttribute { - public RequireUserPermissionAttribute UserPermissionAttribute { get; } - - public UserPermAttribute(GuildPerm permission) - { - UserPermissionAttribute = new((GuildPermission)permission); - } - - public UserPermAttribute(ChannelPerm permission) - { - UserPermissionAttribute = new((ChannelPermission)permission); - } - public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services) { var permService = services.GetRequiredService(); if (permService.TryGetOverrides(context.Guild?.Id ?? 0, command.Name.ToUpperInvariant(), out var _)) return Task.FromResult(PreconditionResult.FromSuccess()); - return UserPermissionAttribute.CheckPermissionsAsync(context, command, services); + return base.CheckPermissionsAsync(context, command, services); + } + + public UserPermAttribute(GuildPerm permission) : base(permission) + { + } + + public UserPermAttribute(ChannelPerm permission) : base(permission) + { } } \ No newline at end of file diff --git a/src/NadekoBot/Common/GuildPerm.cs b/src/NadekoBot/Common/GuildPerm.cs deleted file mode 100644 index 9c4ba48fb..000000000 --- a/src/NadekoBot/Common/GuildPerm.cs +++ /dev/null @@ -1,250 +0,0 @@ -namespace Discord; -// just a copy paste from discord.net in order to rename it, for compatibility iwth v3 which is gonna use custom lib - -// Summary: -// Defines the available permissions for a channel. -[Flags] -public enum GuildPerm : ulong -{ - // - // Summary: - // Allows creation of instant invites. - CreateInstantInvite = 1, - // - // Summary: - // Allows kicking members. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - KickMembers = 2, - // - // Summary: - // Allows banning members. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - BanMembers = 4, - // - // Summary: - // Allows all permissions and bypasses channel permission overwrites. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - Administrator = 8, - // - // Summary: - // Allows management and editing of channels. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - ManageChannels = 16, - // - // Summary: - // Allows management and editing of the guild. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - ManageGuild = 32, - // - // Summary: - // Allows for the addition of reactions to messages. - AddReactions = 64, - // - // Summary: - // Allows for viewing of audit logs. - ViewAuditLog = 128, - PrioritySpeaker = 256, - ReadMessages = 1024, - ViewChannel = 1024, - SendMessages = 2048, - // - // Summary: - // Allows for sending of text-to-speech messages. - SendTTSMessages = 4096, - // - // Summary: - // Allows for deletion of other users messages. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - ManageMessages = 8192, - // - // Summary: - // Allows links sent by users with this permission will be auto-embedded. - EmbedLinks = 16384, - // - // Summary: - // Allows for uploading images and files. - AttachFiles = 32768, - // - // Summary: - // Allows for reading of message history. - ReadMessageHistory = 65536, - // - // Summary: - // Allows for using the @everyone tag to notify all users in a channel, and the - // @here tag to notify all online users in a channel. - MentionEveryone = 131072, - // - // Summary: - // Allows the usage of custom emojis from other servers. - UseExternalEmojis = 262144, - // - // Summary: - // Allows for joining of a voice channel. - Connect = 1048576, - // - // Summary: - // Allows for speaking in a voice channel. - Speak = 2097152, - // - // Summary: - // Allows for muting members in a voice channel. - MuteMembers = 4194304, - // - // Summary: - // Allows for deafening of members in a voice channel. - DeafenMembers = 8388608, - // - // Summary: - // Allows for moving of members between voice channels. - MoveMembers = 16777216, - // - // Summary: - // Allows for using voice-activity-detection in a voice channel. - UseVAD = 33554432, - // - // Summary: - // Allows for modification of own nickname. - ChangeNickname = 67108864, - // - // Summary: - // Allows for modification of other users nicknames. - ManageNicknames = 134217728, - // - // Summary: - // Allows management and editing of roles. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - ManageRoles = 268435456, - // - // Summary: - // Allows management and editing of webhooks. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - ManageWebhooks = 536870912, - // - // Summary: - // Allows management and editing of emojis. - // - // Remarks: - // This permission requires the owner account to use two-factor authentication when - // used on a guild that has server-wide 2FA enabled. - ManageEmojis = 1073741824 -} - -// -// Summary: -// Defines the available permissions for a channel. -[Flags] -public enum ChannelPerm : ulong -{ - // - // Summary: - // Allows creation of instant invites. - CreateInstantInvite = 1, - // - // Summary: - // Allows management and editing of channels. - ManageChannel = 16, - // - // Summary: - // Allows for the addition of reactions to messages. - AddReactions = 64, - PrioritySpeaker = 256, - // - // Summary: - // Allows for reading of messages. This flag is obsolete, use Discord.ChannelPermission.ViewChannel - // instead. - ReadMessages = 1024, - // - // Summary: - // Allows guild members to view a channel, which includes reading messages in text - // channels. - ViewChannel = 1024, - // - // Summary: - // Allows for sending messages in a channel. - SendMessages = 2048, - // - // Summary: - // Allows for sending of text-to-speech messages. - SendTTSMessages = 4096, - // - // Summary: - // Allows for deletion of other users messages. - ManageMessages = 8192, - // - // Summary: - // Allows links sent by users with this permission will be auto-embedded. - EmbedLinks = 16384, - // - // Summary: - // Allows for uploading images and files. - AttachFiles = 32768, - // - // Summary: - // Allows for reading of message history. - ReadMessageHistory = 65536, - // - // Summary: - // Allows for using the @everyone tag to notify all users in a channel, and the - // @here tag to notify all online users in a channel. - MentionEveryone = 131072, - // - // Summary: - // Allows the usage of custom emojis from other servers. - UseExternalEmojis = 262144, - // - // Summary: - // Allows for joining of a voice channel. - Connect = 1048576, - // - // Summary: - // Allows for speaking in a voice channel. - Speak = 2097152, - // - // Summary: - // Allows for muting members in a voice channel. - MuteMembers = 4194304, - // - // Summary: - // Allows for deafening of members in a voice channel. - DeafenMembers = 8388608, - // - // Summary: - // Allows for moving of members between voice channels. - MoveMembers = 16777216, - // - // Summary: - // Allows for using voice-activity-detection in a voice channel. - UseVAD = 33554432, - // - // Summary: - // Allows management and editing of roles. - ManageRoles = 268435456, - // - // Summary: - // Allows management and editing of webhooks. - ManageWebhooks = 536870912 -} \ No newline at end of file diff --git a/src/NadekoBot/Common/SocketMessageEventWrapper.cs b/src/NadekoBot/Common/SocketMessageEventWrapper.cs index 42b459134..77f8789ef 100644 --- a/src/NadekoBot/Common/SocketMessageEventWrapper.cs +++ b/src/NadekoBot/Common/SocketMessageEventWrapper.cs @@ -17,7 +17,9 @@ public sealed class ReactionEventWrapper : IDisposable _client.ReactionsCleared += Discord_ReactionsCleared; } - private Task Discord_ReactionsCleared(Cacheable msg, ISocketMessageChannel channel) + private Task Discord_ReactionsCleared( + Cacheable msg, + Cacheable channel) { Task.Run(() => { @@ -32,7 +34,9 @@ public sealed class ReactionEventWrapper : IDisposable return Task.CompletedTask; } - private Task Discord_ReactionRemoved(Cacheable msg, ISocketMessageChannel channel, SocketReaction reaction) + private Task Discord_ReactionRemoved( + Cacheable msg, + Cacheable cacheable, SocketReaction reaction) { Task.Run(() => { @@ -47,7 +51,10 @@ public sealed class ReactionEventWrapper : IDisposable return Task.CompletedTask; } - private Task Discord_ReactionAdded(Cacheable msg, ISocketMessageChannel channel, SocketReaction reaction) + private Task Discord_ReactionAdded( + Cacheable msg, + Cacheable cacheable, + SocketReaction reaction) { Task.Run(() => { @@ -56,7 +63,9 @@ public sealed class ReactionEventWrapper : IDisposable if (msg.Id == Message.Id) OnReactionAdded?.Invoke(reaction); } - catch { } + catch + { + } }); return Task.CompletedTask; diff --git a/src/NadekoBot/GlobalUsings.cs b/src/NadekoBot/GlobalUsings.cs index e1d897d25..bb2c231ae 100644 --- a/src/NadekoBot/GlobalUsings.cs +++ b/src/NadekoBot/GlobalUsings.cs @@ -6,10 +6,15 @@ global using NadekoBot; global using NadekoBot.Services; global using NadekoBot.Common; global using NadekoBot.Common.Attributes; +// todo global using Nadekobot.Extensions; global using Discord; global using Discord.Commands; global using Discord.Net; global using Discord.WebSocket; +global using GuildPerm = Discord.GuildPermission; +global using ChannelPerm = Discord.ChannelPermission; +global using BotPermAttribute = Discord.Commands.RequireBotPermissionAttribute; + global using System.Collections.Concurrent; \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index c5d7d234e..6799ceb37 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -34,8 +34,8 @@ public partial class Administration : NadekoModule [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] - [UserPerm(ChannelPerm.ManageChannel)] - [BotPerm(ChannelPerm.ManageChannel)] + [UserPerm(ChannelPerm.ManageChannels)] + [BotPerm(ChannelPerm.ManageChannels)] public async Task Slowmode(StoopidTime time = null) { var seconds = (int?)time?.Time.TotalSeconds ?? 0; diff --git a/src/NadekoBot/Modules/Administration/SelfCommands.cs b/src/NadekoBot/Modules/Administration/SelfCommands.cs index 1e7b04910..366af0184 100644 --- a/src/NadekoBot/Modules/Administration/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/SelfCommands.cs @@ -466,7 +466,7 @@ public partial class Administration if (user is null) return; - var ch = await user.GetOrCreateDMChannelAsync(); + var ch = await user.CreateDMChannelAsync(); text = rep.Replace(text); await ch.SendAsync(text); } diff --git a/src/NadekoBot/Modules/Administration/ServerGreetCommands.cs b/src/NadekoBot/Modules/Administration/ServerGreetCommands.cs index 0b7eeb826..f331c7539 100644 --- a/src/NadekoBot/Modules/Administration/ServerGreetCommands.cs +++ b/src/NadekoBot/Modules/Administration/ServerGreetCommands.cs @@ -253,7 +253,7 @@ public partial class Administration { user = user ?? (IGuildUser) ctx.User; - var channel = await user.GetOrCreateDMChannelAsync(); + var channel = await user.CreateDMChannelAsync(); var success = await _service.GreetDmTest(channel, user); if (success) await ctx.OkAsync(); diff --git a/src/NadekoBot/Modules/Administration/Services/GameVoiceChannelService.cs b/src/NadekoBot/Modules/Administration/Services/GameVoiceChannelService.cs index 1bfc4905d..8709e7b48 100644 --- a/src/NadekoBot/Modules/Administration/Services/GameVoiceChannelService.cs +++ b/src/NadekoBot/Modules/Administration/Services/GameVoiceChannelService.cs @@ -4,6 +4,7 @@ using NadekoBot.Db; namespace NadekoBot.Modules.Administration.Services; +// todo if any activity... public class GameVoiceChannelService : INService { public ConcurrentHashSet GameVoiceChannels { get; } = new ConcurrentHashSet(); @@ -24,7 +25,7 @@ public class GameVoiceChannelService : INService _client.GuildMemberUpdated += _client_GuildMemberUpdated; } - private Task _client_GuildMemberUpdated(SocketGuildUser before, SocketGuildUser after) + private Task _client_GuildMemberUpdated(Cacheable before, SocketGuildUser after) { var _ = Task.Run(async () => { @@ -32,15 +33,16 @@ public class GameVoiceChannelService : INService { //if the user is in the voice channel and that voice channel is gvc var vc = after.VoiceChannel; - if (vc is null || !GameVoiceChannels.Contains(vc.Id)) + if (vc is null || !GameVoiceChannels.Contains(vc.Id) || !before.HasValue) return; //if the activity has changed, and is a playing activity - if (before.Activity != after.Activity - && after.Activity is { Type: Discord.ActivityType.Playing }) + var oldActivity = before.Value.Activities.FirstOrDefault(); + var newActivity = after.Activities.FirstOrDefault(); + if (oldActivity != newActivity && newActivity is { Type: ActivityType.Playing }) { //trigger gvc - await TriggerGvc(after, after.Activity.Name); + await TriggerGvc(after, newActivity.Name); } } @@ -86,7 +88,7 @@ public class GameVoiceChannelService : INService if (!(usr is SocketGuildUser gUser)) return; - var game = gUser.Activity?.Name; + var game = gUser.Activities.FirstOrDefault()?.Name; if (oldState.VoiceChannel == newState.VoiceChannel || newState.VoiceChannel is null) diff --git a/src/NadekoBot/Modules/Administration/Services/LogCommandService.cs b/src/NadekoBot/Modules/Administration/Services/LogCommandService.cs index ad7212d6a..dcd151480 100644 --- a/src/NadekoBot/Modules/Administration/Services/LogCommandService.cs +++ b/src/NadekoBot/Modules/Administration/Services/LogCommandService.cs @@ -567,12 +567,17 @@ public sealed class LogCommandService : ILogCommandService return isDeleted; } - private Task _client_GuildUserUpdated(SocketGuildUser before, SocketGuildUser after) + private Task _client_GuildUserUpdated(Cacheable optBefore, SocketGuildUser after) { var _ = Task.Run(async () => { try { + var before = await optBefore.GetOrDownloadAsync(); + + if (before is null) + return; + if (!GuildLogSettings.TryGetValue(before.Guild.Id, out var logSetting) || logSetting.LogIgnores.Any(ilc => ilc.LogItemId == after.Id && ilc.ItemType == IgnoredItemType.User)) return; @@ -642,10 +647,10 @@ public sealed class LogCommandService : ILogCommandService return list; }); } - else if (before.Activity?.Name != after.Activity?.Name) + else if (before.Activities.FirstOrDefault()?.Name != after.Activities.FirstOrDefault()?.Name) { var str = - $"👾`{PrettyCurrentTime(after.Guild)}`👤__**{after.Username}**__ is now playing **{after.Activity?.Name ?? "-"}**."; + $"👾`{PrettyCurrentTime(after.Guild)}`👤__**{after.Username}**__ is now playing **{after.Activities.FirstOrDefault()?.Name ?? "-"}**."; PresenceUpdates.AddOrUpdate(logChannel, new List() {str}, (id, list) => { @@ -857,19 +862,19 @@ public sealed class LogCommandService : ILogCommandService return Task.CompletedTask; } - private Task _client_UserLeft(IGuildUser usr) + private Task _client_UserLeft(SocketGuild guild, SocketUser usr) { var _ = Task.Run(async () => { try { - if (!GuildLogSettings.TryGetValue(usr.Guild.Id, out var logSetting) + if (!GuildLogSettings.TryGetValue(guild.Id, out var logSetting) || logSetting.UserLeftId is null || logSetting.LogIgnores.Any(ilc => ilc.LogItemId == usr.Id && ilc.ItemType == IgnoredItemType.User)) return; ITextChannel logChannel; - if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserLeft) + if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserLeft) .ConfigureAwait(false)) is null) return; var embed = _eb.Create() @@ -877,7 +882,7 @@ public sealed class LogCommandService : ILogCommandService .WithTitle("❌ " + GetText(logChannel.Guild, strs.user_left)) .WithDescription(usr.ToString()) .AddField("Id", usr.Id.ToString()) - .WithFooter(CurrentTime(usr.Guild)); + .WithFooter(CurrentTime(guild)); if (Uri.IsWellFormedUriString(usr.GetAvatarUrl(), UriKind.Absolute)) embed.WithThumbnailUrl(usr.GetAvatarUrl()); @@ -1006,19 +1011,20 @@ public sealed class LogCommandService : ILogCommandService return Task.CompletedTask; } - private Task _client_MessageDeleted(Cacheable optMsg, ISocketMessageChannel ch) + private Task _client_MessageDeleted(Cacheable optMsg, Cacheable optCh) { var _ = Task.Run(async () => { try { - var msg = (optMsg.HasValue ? optMsg.Value : null) as IUserMessage; + var msg = optMsg.Value as IUserMessage; if (msg is null || msg.IsAuthor(_client)) return; if (_ignoreMessageIds.Contains(msg.Id)) return; + var ch = optCh.Value; if (!(ch is ITextChannel channel)) return; diff --git a/src/NadekoBot/Modules/Administration/Services/RoleCommandsService.cs b/src/NadekoBot/Modules/Administration/Services/RoleCommandsService.cs index a152dc2f7..d3476f929 100644 --- a/src/NadekoBot/Modules/Administration/Services/RoleCommandsService.cs +++ b/src/NadekoBot/Modules/Administration/Services/RoleCommandsService.cs @@ -34,14 +34,16 @@ public class RoleCommandsService : INService #endif } - private Task _client_ReactionAdded(Cacheable msg, ISocketMessageChannel chan, SocketReaction reaction) + private Task _client_ReactionAdded(Cacheable msg, + Cacheable chan, + SocketReaction reaction) { _ = Task.Run(async () => { if (!reaction.User.IsSpecified || reaction.User.Value.IsBot || reaction.User.Value is not SocketGuildUser gusr || - chan is not SocketGuildChannel gch || + chan.Value is not SocketGuildChannel gch || !_models.TryGetValue(gch.Guild.Id, out var confs)) return; @@ -93,7 +95,9 @@ public class RoleCommandsService : INService return Task.CompletedTask; } - private Task _client_ReactionRemoved(Cacheable msg, ISocketMessageChannel chan, SocketReaction reaction) + private Task _client_ReactionRemoved(Cacheable msg, + Cacheable chan, + SocketReaction reaction) { _ = Task.Run(async () => { @@ -104,7 +108,7 @@ public class RoleCommandsService : INService reaction.User.Value is not SocketGuildUser gusr) return; - if (chan is not SocketGuildChannel gch) + if (chan.Value is not SocketGuildChannel gch) return; if (!_models.TryGetValue(gch.Guild.Id, out var confs)) diff --git a/src/NadekoBot/Modules/Administration/Services/SelfService.cs b/src/NadekoBot/Modules/Administration/Services/SelfService.cs index f4c569204..938a6ac06 100644 --- a/src/NadekoBot/Modules/Administration/Services/SelfService.cs +++ b/src/NadekoBot/Modules/Administration/Services/SelfService.cs @@ -203,7 +203,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService if (user is null) return Task.FromResult(null); - return user.GetOrCreateDMChannelAsync(); + return user.CreateDMChannelAsync(); })).ConfigureAwait(false); ownerChannels = channels.Where(x => x != null) diff --git a/src/NadekoBot/Modules/Administration/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/UserPunishCommands.cs index b78652ac9..eda51ddf6 100644 --- a/src/NadekoBot/Modules/Administration/UserPunishCommands.cs +++ b/src/NadekoBot/Modules/Administration/UserPunishCommands.cs @@ -61,7 +61,7 @@ public partial class Administration var dmFailed = false; try { - await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).EmbedAsync(_eb.Create().WithErrorColor() + await user.EmbedAsync(_eb.Create().WithErrorColor() .WithDescription(GetText(strs.warned_on(ctx.Guild.ToString()))) .AddField(GetText(strs.moderator), ctx.User.ToString()) .AddField(GetText(strs.reason), reason ?? "-")) @@ -449,8 +449,7 @@ public partial class Administration var embed = _service.GetBanUserDmEmbed(Context, guildUser, defaultMessage, msg, time.Time); if (embed is not null) { - var userChannel = await guildUser.GetOrCreateDMChannelAsync(); - await userChannel.SendAsync(embed); + await guildUser.SendAsync(embed); } } catch @@ -520,8 +519,7 @@ public partial class Administration var embed = _service.GetBanUserDmEmbed(Context, user, defaultMessage, msg, null); if (embed is not null) { - var userChannel = await user.GetOrCreateDMChannelAsync(); - await userChannel.SendAsync(embed); + await ctx.User.SendAsync(embed); } } catch @@ -596,7 +594,6 @@ public partial class Administration private async Task InternalBanMessageTest(string reason, TimeSpan? duration) { - var dmChannel = await ctx.User.GetOrCreateDMChannelAsync(); var defaultMessage = GetText(strs.bandm(Format.Bold(ctx.Guild.Name), reason)); var embed = _service.GetBanUserDmEmbed(Context, (IGuildUser)ctx.User, @@ -612,7 +609,7 @@ public partial class Administration { try { - await dmChannel.SendAsync(embed); + await ctx.User.SendAsync(embed); } catch (Exception) { diff --git a/src/NadekoBot/Modules/CustomReactions/Extensions/CustomReactionExtensions.cs b/src/NadekoBot/Modules/CustomReactions/Extensions/CustomReactionExtensions.cs index aa95b28ae..ce6f2dd71 100644 --- a/src/NadekoBot/Modules/CustomReactions/Extensions/CustomReactionExtensions.cs +++ b/src/NadekoBot/Modules/CustomReactions/Extensions/CustomReactionExtensions.cs @@ -13,7 +13,7 @@ public static class CustomReactionExtensions DiscordSocketClient client, bool sanitize) { var channel = cr.DmResponse - ? await ctx.Author.GetOrCreateDMChannelAsync().ConfigureAwait(false) + ? await ctx.Author.CreateDMChannelAsync().ConfigureAwait(false) : ctx.Channel; var trigger = cr.Trigger.ResolveTriggerString(client); diff --git a/src/NadekoBot/Modules/Gambling/Common/Events/GameStatusEvent.cs b/src/NadekoBot/Modules/Gambling/Common/Events/GameStatusEvent.cs index b60fafd16..eef6a6d6c 100644 --- a/src/NadekoBot/Modules/Gambling/Common/Events/GameStatusEvent.cs +++ b/src/NadekoBot/Modules/Gambling/Common/Events/GameStatusEvent.cs @@ -120,7 +120,7 @@ public class GameStatusEvent : ICurrencyEvent return _embedFunc(CurrencyEvent.Type.GameStatus, _opts, pot); } - private async Task OnMessageDeleted(Cacheable msg, ISocketMessageChannel _) + private async Task OnMessageDeleted(Cacheable msg, Cacheable cacheable) { if (msg.Id == _msg.Id) { diff --git a/src/NadekoBot/Modules/Gambling/Common/Events/ReactionEvent.cs b/src/NadekoBot/Modules/Gambling/Common/Events/ReactionEvent.cs index b344e9972..47bea752e 100644 --- a/src/NadekoBot/Modules/Gambling/Common/Events/ReactionEvent.cs +++ b/src/NadekoBot/Modules/Gambling/Common/Events/ReactionEvent.cs @@ -123,7 +123,7 @@ public class ReactionEvent : ICurrencyEvent return _embedFunc(CurrencyEvent.Type.Reaction, _opts, pot); } - private async Task OnMessageDeleted(Cacheable msg, ISocketMessageChannel _) + private async Task OnMessageDeleted(Cacheable msg, Cacheable cacheable) { if (msg.Id == _msg.Id) { @@ -150,7 +150,7 @@ public class ReactionEvent : ICurrencyEvent } private Task HandleReaction(Cacheable msg, - ISocketMessageChannel ch, SocketReaction r) + Cacheable cacheable, SocketReaction r) { var _ = Task.Run(() => { diff --git a/src/NadekoBot/Modules/Gambling/ShopCommands.cs b/src/NadekoBot/Modules/Gambling/ShopCommands.cs index 2ae54c657..a0b4a3c54 100644 --- a/src/NadekoBot/Modules/Gambling/ShopCommands.cs +++ b/src/NadekoBot/Modules/Gambling/ShopCommands.cs @@ -160,7 +160,7 @@ public partial class Gambling } try { - await (await ctx.User.GetOrCreateDMChannelAsync().ConfigureAwait(false)) + await ctx.User .EmbedAsync(_eb.Create().WithOkColor() .WithTitle(GetText(strs.shop_purchase(ctx.Guild.Name))) .AddField(GetText(strs.item), item.Text, false) diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index 76eb4b729..5673d2cc3 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -274,7 +274,7 @@ public class Help : NadekoModule if (com is null) { var ch = channel is ITextChannel - ? await ((IGuildUser)ctx.User).GetOrCreateDMChannelAsync().ConfigureAwait(false) + ? await ctx.User.CreateDMChannelAsync().ConfigureAwait(false) : channel; try { diff --git a/src/NadekoBot/Modules/Help/Services/HelpService.cs b/src/NadekoBot/Modules/Help/Services/HelpService.cs index 15a75e90b..d5b80c0ed 100644 --- a/src/NadekoBot/Modules/Help/Services/HelpService.cs +++ b/src/NadekoBot/Modules/Help/Services/HelpService.cs @@ -132,9 +132,9 @@ public class HelpService : ILateExecutor, INService var userPermString = string.Empty; if (userPerm is not null) { - if (userPerm.UserPermissionAttribute.ChannelPermission is { } cPerm) + if (userPerm.ChannelPermission is { } cPerm) userPermString = GetPreconditionString((ChannelPerm) cPerm); - if (userPerm.UserPermissionAttribute.GuildPermission is { } gPerm) + if (userPerm.GuildPermission is { } gPerm) userPermString = GetPreconditionString((GuildPerm) gPerm); } diff --git a/src/NadekoBot/Modules/Music/Services/AyuVoiceStateService.cs b/src/NadekoBot/Modules/Music/Services/AyuVoiceStateService.cs index aaa64f090..510140df8 100644 --- a/src/NadekoBot/Modules/Music/Services/AyuVoiceStateService.cs +++ b/src/NadekoBot/Modules/Music/Services/AyuVoiceStateService.cs @@ -25,7 +25,9 @@ public sealed class AyuVoiceStateService : INService .GetProperties(BindingFlags.NonPublic | BindingFlags.Instance) .First(x => x.Name == "ApiClient" && x.PropertyType.Name == "DiscordSocketApiClient"); _dnetApiClient = prop.GetValue(_client, null); - _sendVoiceStateUpdateMethodInfo = _dnetApiClient.GetType().GetMethod("SendVoiceStateUpdateAsync"); + _sendVoiceStateUpdateMethodInfo = _dnetApiClient.GetType() + .GetMethod("SendVoiceStateUpdateAsync", + types: new[] { typeof(ulong), typeof(ulong?), typeof(bool), typeof(bool), typeof(RequestOptions) }); _client.LeftGuild += ClientOnLeftGuild; } diff --git a/src/NadekoBot/Modules/Utility/InviteCommands.cs b/src/NadekoBot/Modules/Utility/InviteCommands.cs index 044b10011..34141656f 100644 --- a/src/NadekoBot/Modules/Utility/InviteCommands.cs +++ b/src/NadekoBot/Modules/Utility/InviteCommands.cs @@ -27,8 +27,8 @@ public partial class Utility [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] - [BotPerm(ChannelPerm.ManageChannel)] - [UserPerm(ChannelPerm.ManageChannel)] + [BotPerm(ChannelPerm.ManageChannels)] + [UserPerm(ChannelPerm.ManageChannels)] public async Task InviteList(int page = 1, [Leftover]ITextChannel ch = null) { if (--page < 0) @@ -76,8 +76,8 @@ public partial class Utility [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] - [BotPerm(ChannelPerm.ManageChannel)] - [UserPerm(ChannelPerm.ManageChannel)] + [BotPerm(ChannelPerm.ManageChannels)] + [UserPerm(ChannelPerm.ManageChannels)] public async Task InviteDelete(int index) { if (--index < 0) diff --git a/src/NadekoBot/Modules/Utility/Services/PatreonRewardsService.cs b/src/NadekoBot/Modules/Utility/Services/PatreonRewardsService.cs index a59097c03..e509f1753 100644 --- a/src/NadekoBot/Modules/Utility/Services/PatreonRewardsService.cs +++ b/src/NadekoBot/Modules/Utility/Services/PatreonRewardsService.cs @@ -298,8 +298,7 @@ public class PatreonRewardsService : INService if (user is null) return; - var channel = await user.GetOrCreateDMChannelAsync(); - await channel.SendConfirmAsync(_eb, message); + await user.SendConfirmAsync(_eb, message); } catch { diff --git a/src/NadekoBot/Modules/Utility/Services/RemindService.cs b/src/NadekoBot/Modules/Utility/Services/RemindService.cs index b6265265d..e532323bb 100644 --- a/src/NadekoBot/Modules/Utility/Services/RemindService.cs +++ b/src/NadekoBot/Modules/Utility/Services/RemindService.cs @@ -152,7 +152,7 @@ public class RemindService : INService var user = _client.GetUser(r.ChannelId); if (user is null) return; - ch = await user.GetOrCreateDMChannelAsync().ConfigureAwait(false); + ch = await user.CreateDMChannelAsync(); } else { diff --git a/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs b/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs index 813bad895..b38c0546c 100644 --- a/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs +++ b/src/NadekoBot/Modules/Utility/Services/StreamRoleService.cs @@ -38,7 +38,7 @@ public class StreamRoleService : INService }); } - private Task Client_GuildMemberUpdated(SocketGuildUser before, SocketGuildUser after) + private Task Client_GuildMemberUpdated(Cacheable cacheable, SocketGuildUser after) { var _ = Task.Run(async () => { diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index e8059749a..d440617d1 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -66,7 +66,7 @@ public partial class Utility : NadekoModule } var rng = new NadekoRandom(); var arr = await Task.Run(() => socketGuild.Users - .Where(u => u.Activity?.Name?.ToUpperInvariant() == game) + .Where(u => u.Activities.FirstOrDefault()?.Name?.ToUpperInvariant() == game) .Select(u => u.Username) .OrderBy(x => rng.Next()) .Take(60) @@ -277,24 +277,24 @@ public partial class Utility : NadekoModule [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] - [BotPerm(GuildPerm.ManageEmojis)] - [UserPerm(GuildPerm.ManageEmojis)] + [BotPerm(GuildPerm.ManageEmojisAndStickers)] + [UserPerm(GuildPerm.ManageEmojisAndStickers)] [Priority(2)] public Task EmojiAdd(string name, Emote emote) => EmojiAdd(name, emote.Url); [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] - [BotPerm(GuildPerm.ManageEmojis)] - [UserPerm(GuildPerm.ManageEmojis)] + [BotPerm(GuildPerm.ManageEmojisAndStickers)] + [UserPerm(GuildPerm.ManageEmojisAndStickers)] [Priority(1)] public Task EmojiAdd(Emote emote) => EmojiAdd(emote.Name, emote.Url); [NadekoCommand, Aliases] [RequireContext(ContextType.Guild)] - [BotPerm(GuildPerm.ManageEmojis)] - [UserPerm(GuildPerm.ManageEmojis)] + [BotPerm(GuildPerm.ManageEmojisAndStickers)] + [UserPerm(GuildPerm.ManageEmojisAndStickers)] [Priority(0)] public async Task EmojiAdd(string name, string url = null) { diff --git a/src/NadekoBot/Modules/Xp/Services/XpService.cs b/src/NadekoBot/Modules/Xp/Services/XpService.cs index b12f8cced..4f1d0caa0 100644 --- a/src/NadekoBot/Modules/Xp/Services/XpService.cs +++ b/src/NadekoBot/Modules/Xp/Services/XpService.cs @@ -250,9 +250,7 @@ public class XpService : INService { if (x.NotifyType == XpNotificationLocation.Dm) { - var chan = await x.User.GetOrCreateDMChannelAsync(); - if (chan != null) - await chan.SendConfirmAsync(_eb, + await x.User.SendConfirmAsync(_eb, _strings.GetText(strs.level_up_dm( x.User.Mention, Format.Bold(x.Level.ToString()), Format.Bold(x.Guild.ToString() ?? "-")), @@ -272,7 +270,7 @@ public class XpService : INService IMessageChannel chan; if (x.NotifyType == XpNotificationLocation.Dm) { - chan = await x.User.GetOrCreateDMChannelAsync(); + chan = await x.User.CreateDMChannelAsync(); } else // channel { diff --git a/src/NadekoBot/NadekoBot.csproj b/src/NadekoBot/NadekoBot.csproj index 39310ad51..718282f10 100644 --- a/src/NadekoBot/NadekoBot.csproj +++ b/src/NadekoBot/NadekoBot.csproj @@ -12,11 +12,11 @@ - + - + diff --git a/src/NadekoBot/Services/CommandHandler.cs b/src/NadekoBot/Services/CommandHandler.cs index 0c36d241f..9e3062ffc 100644 --- a/src/NadekoBot/Services/CommandHandler.cs +++ b/src/NadekoBot/Services/CommandHandler.cs @@ -355,7 +355,7 @@ public class CommandHandler : INService var chosenOverload = successfulParses[0]; var execResult = (ExecuteResult)await chosenOverload.Key.ExecuteAsync(context, chosenOverload.Value, services).ConfigureAwait(false); - if (execResult.Exception != null && (!(execResult.Exception is HttpException he) || he.DiscordCode != 50013)) + if (execResult.Exception != null && (!(execResult.Exception is HttpException he) || he.DiscordCode != DiscordErrorCode.InsufficientPermissions)) { Log.Warning(execResult.Exception, "Command Error"); } diff --git a/src/NadekoBot/Services/GreetSettingsService.cs b/src/NadekoBot/Services/GreetSettingsService.cs index 7a60a5ae0..e919f135d 100644 --- a/src/NadekoBot/Services/GreetSettingsService.cs +++ b/src/NadekoBot/Services/GreetSettingsService.cs @@ -12,7 +12,7 @@ public class GreetSettingsService : INService private readonly DiscordSocketClient _client; private GreetGrouper greets = new GreetGrouper(); - private GreetGrouper byes = new GreetGrouper(); + private GreetGrouper byes = new GreetGrouper(); private readonly BotConfigService _bss; private readonly IEmbedBuilderService _eb; public bool GroupGreets => _bss.Data.GroupGreets; @@ -41,14 +41,15 @@ public class GreetSettingsService : INService _client.GuildMemberUpdated += ClientOnGuildMemberUpdated; } - private Task ClientOnGuildMemberUpdated(SocketGuildUser oldUser, SocketGuildUser newUser) + private Task ClientOnGuildMemberUpdated(Cacheable optOldUser, SocketGuildUser newUser) { // if user is a new booster // or boosted again the same server - if (oldUser is { PremiumSince: null } && newUser is { PremiumSince: not null } - || oldUser?.PremiumSince is { } oldDate - && newUser?.PremiumSince is { } newDate - && newDate > oldDate) + if ((optOldUser.Value is { PremiumSince: null } + && newUser is { PremiumSince: not null }) + || (optOldUser.Value?.PremiumSince is { } oldDate + && newUser?.PremiumSince is { } newDate + && newDate > oldDate)) { var conf = GetOrAddSettingsForGuild(newUser.Guild.Id); if (!conf.SendBoostMessage) return Task.CompletedTask; @@ -101,16 +102,16 @@ public class GreetSettingsService : INService return Task.CompletedTask; } - private Task UserLeft(IGuildUser user) + private Task UserLeft(SocketGuild guild, SocketUser user) { var _ = Task.Run(async () => { try { - var conf = GetOrAddSettingsForGuild(user.GuildId); + var conf = GetOrAddSettingsForGuild(guild.Id); if (!conf.SendChannelByeMessage) return; - var channel = (await user.Guild.GetTextChannelsAsync().ConfigureAwait(false)).SingleOrDefault(c => c.Id == conf.ByeMessageChannelId); + var channel = guild.TextChannels.FirstOrDefault(c => c.Id == conf.ByeMessageChannelId); if (channel is null) //maybe warn the server owner that the channel is missing return; @@ -120,7 +121,7 @@ public class GreetSettingsService : INService // if group is newly created, greet that user right away, // but any user which joins in the next 5 seconds will // be greeted in a group greet - if (byes.CreateOrAdd(user.GuildId, user)) + if (byes.CreateOrAdd(guild.Id, user)) { // greet single user await ByeUsers(conf, channel, new[] {user}); @@ -128,7 +129,7 @@ public class GreetSettingsService : INService while(!groupClear) { await Task.Delay(5000).ConfigureAwait(false); - groupClear = byes.ClearGroup(user.GuildId, 5, out var toBye); + groupClear = byes.ClearGroup(guild.Id, 5, out var toBye); await ByeUsers(conf, channel, toBye); } } @@ -290,9 +291,9 @@ public class GreetSettingsService : INService if (conf.SendDmGreetMessage) { - var channel = await user.GetOrCreateDMChannelAsync().ConfigureAwait(false); + var channel = await user.CreateDMChannelAsync(); - if (channel != null) + if (channel is not null) { await GreetDmUser(conf, channel, user); } diff --git a/src/NadekoBot/Services/Impl/CurrencyService.cs b/src/NadekoBot/Services/Impl/CurrencyService.cs index 4c9ea8f38..d3a5c9b00 100644 --- a/src/NadekoBot/Services/Impl/CurrencyService.cs +++ b/src/NadekoBot/Services/Impl/CurrencyService.cs @@ -75,7 +75,7 @@ public class CurrencyService : ICurrencyService, INService try { var sign = _gss.Data.Currency.Sign; - await (await user.GetOrCreateDMChannelAsync()) + await user .EmbedAsync(_eb.Create() .WithOkColor() .WithTitle($"Received Currency") diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index a9ccd178e..a63bd2fab 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -38,23 +38,6 @@ public static class Extensions }), _ => throw new ArgumentOutOfRangeException(nameof(text)) }; - - public static Task SendAsync(this IMessageChannel channel, string plainText, Embed embed, bool sanitizeAll = false) - { - plainText = sanitizeAll - ? plainText?.SanitizeAllMentions() ?? "" - : plainText?.SanitizeMentions() ?? ""; - - return channel.SendMessageAsync(plainText, embed: embed); - } - - public static Task SendAsync(this IMessageChannel channel, SmartText text, bool sanitizeAll = false) - => text switch - { - SmartEmbedText set => channel.SendAsync(set.PlainText, set.GetEmbed().Build(), sanitizeAll), - SmartPlainText st => channel.SendAsync(st.Text, null, sanitizeAll), - _ => throw new ArgumentOutOfRangeException(nameof(text)) - }; public static List GetGuildIds(this DiscordSocketClient client) => client.Guilds.Select(x => x.Id).ToList(); @@ -334,10 +317,9 @@ public static class Extensions public static async Task SendMessageToOwnerAsync(this IGuild guild, string message) { - var ownerPrivate = await (await guild.GetOwnerAsync().ConfigureAwait(false)).GetOrCreateDMChannelAsync() - .ConfigureAwait(false); + var owner = await guild.GetOwnerAsync(); - return await ownerPrivate.SendMessageAsync(message).ConfigureAwait(false); + return await owner.SendMessageAsync(message); } public static bool IsImage(this HttpResponseMessage msg) => IsImage(msg, out _); diff --git a/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs b/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs index fcebcce31..dc1468705 100644 --- a/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs +++ b/src/NadekoBot/_Extensions/IMessageChannelExtensions.cs @@ -5,6 +5,23 @@ public static class IMessageChannelExtensions public static Task EmbedAsync(this IMessageChannel ch, IEmbedBuilder embed, string msg = "") => ch.SendMessageAsync(msg, embed: embed.Build(), options: new() { RetryMode = RetryMode.AlwaysRetry }); + + public static Task SendAsync(this IMessageChannel channel, string plainText, Embed embed, bool sanitizeAll = false) + { + plainText = sanitizeAll + ? plainText?.SanitizeAllMentions() ?? "" + : plainText?.SanitizeMentions() ?? ""; + + return channel.SendMessageAsync(plainText, embed: embed); + } + + public static Task SendAsync(this IMessageChannel channel, SmartText text, bool sanitizeAll = false) + => text switch + { + SmartEmbedText set => channel.SendAsync(set.PlainText, set.GetEmbed().Build(), sanitizeAll), + SmartPlainText st => channel.SendAsync(st.Text, null, sanitizeAll), + _ => throw new ArgumentOutOfRangeException(nameof(text)) + }; // this is a huge problem, because now i don't have // access to embed builder service @@ -97,7 +114,7 @@ public static class IMessageChannelExtensions else if (addPaginatedFooter) embed.AddPaginatedFooter(currentPage, lastPage); - var msg = await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false) as IUserMessage; + var msg = await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false); if (lastPage == 0 || !canPaginate) return; diff --git a/src/NadekoBot/_Extensions/IUserExtensions.cs b/src/NadekoBot/_Extensions/IUserExtensions.cs index 55c45969f..9e3a8e99b 100644 --- a/src/NadekoBot/_Extensions/IUserExtensions.cs +++ b/src/NadekoBot/_Extensions/IUserExtensions.cs @@ -4,8 +4,26 @@ namespace NadekoBot.Extensions; public static class IUserExtensions { + public static async Task EmbedAsync(this IUser user, IEmbedBuilder embed, string msg = "") + { + var ch = await user.CreateDMChannelAsync(); + return await ch.EmbedAsync(embed, msg); + } + + public static async Task SendAsync(this IUser user, string plainText, Embed embed, bool sanitizeAll = false) + { + var ch = await user.CreateDMChannelAsync(); + return await ch.SendAsync(plainText, embed, sanitizeAll); + } + + 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 (await user.GetOrCreateDMChannelAsync()).SendMessageAsync("", embed: eb.Create() + => await user.SendMessageAsync("", embed: eb.Create() .WithOkColor() .WithDescription(text) .Build()); @@ -16,7 +34,7 @@ public static class IUserExtensions if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute)) embed.WithUrl(url); - return await (await user.GetOrCreateDMChannelAsync()).SendMessageAsync("", embed: embed.Build()); + return await user.SendMessageAsync("", embed: embed.Build()); } public static async Task SendErrorAsync(this IUser user, IEmbedBuilderService eb, string title, string error, string url = null) @@ -25,11 +43,11 @@ public static class IUserExtensions if (url != null && Uri.IsWellFormedUriString(url, UriKind.Absolute)) embed.WithUrl(url); - return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync("", embed: embed.Build()).ConfigureAwait(false); + return await user.SendMessageAsync("", embed: embed.Build()).ConfigureAwait(false); } public static async Task SendErrorAsync(this IUser user, IEmbedBuilderService eb, string error) - => await (await user.GetOrCreateDMChannelAsync()) + => await user .SendMessageAsync("", embed: eb.Create() .WithErrorColor() .WithDescription(error) @@ -39,12 +57,12 @@ public static class IUserExtensions { await using (var file = File.Open(filePath, FileMode.Open)) { - return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(file, caption ?? "x", text, isTTS).ConfigureAwait(false); + return await user.SendFileAsync(file, caption ?? "x", text, isTTS).ConfigureAwait(false); } } public static async Task SendFileAsync(this IUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => - await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); + await user.SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); // This method is used by everything that fetches the avatar from a user public static Uri RealAvatarUrl(this IUser usr, ushort size = 128)