public async ValueTask <AdminCommandResult> EditMessageAsync(CachedTextChannel channel, ulong messageId, [Remainder] string text) { if (!(await channel.GetMessageAsync(messageId) is RestUserMessage message)) { return(CommandErrorLocalized("utility_edit_nomessage")); } if (message.Author.Id != Context.Client.CurrentUser.Id) { return(CommandErrorLocalized("utility_edit_nonowner")); } text = await text.FormatPlaceHoldersAsync(Context, random : Random); await message.ModifyAsync(x => { if (JsonEmbed.TryParse(text, out var embed)) { x.Content = embed.Text; x.Embed = embed.ToLocalEmbed(); return; } x.Content = text; }); await Context.Message.AddReactionAsync(EmojiTools.Checkmark); return(CommandSuccess()); }
public async ValueTask <AdminCommandResult> SetSuggestionChannel(CachedTextChannel newChannel) { if (await Context.Database.LoggingChannels.FindAsync(Context.Guild.Id.RawValue, LogType.Suggestion) is { } channel) { channel.Id = newChannel.Id; Context.Database.LoggingChannels.Update(channel); }
public override DiscordCommandContext CreateCommandContext( IPrefix prefix, string input, IGatewayUserMessage message, CachedTextChannel channel) { return(new MilkmanCommandContext(message, input, this, prefix)); }
public async Task SignupChannelAsync(CachedTextChannel channel = null) { ulong?channelId = DbContext.Guild.RaidSignupChannelId; if (channel is null && channelId is null) { await ReplyAsync("No raid signup channel exists."); }
public async ValueTask <AdminCommandResult> SetChannelAsync(CachedTextChannel newChannel) { if (!(await Context.Database.LoggingChannels.FindAsync(Context.Guild.Id.RawValue, LogType.Greeting) is { } channel)) { Context.Database.LoggingChannels.Add(new LoggingChannel(newChannel.Id, Context.Guild.Id, LogType.Greeting)); }
internal ReactionsClearedEventArgs( CachedTextChannel channel, FetchableSnowflakeOptional <IMessage> message, IReadOnlyDictionary <IEmoji, ReactionData> reactions) : base(channel.Client) { Channel = channel; Message = message; Reactions = reactions; }
public async ValueTask <AdminCommandResult> DeconstructMessageAsync(CachedTextChannel channel, ulong messageId) { if (!(await channel.GetMessageAsync(messageId) is RestUserMessage message)) { return(CommandErrorLocalized("utility_deconstruct_nomessage")); } return(await DeconstructMessageAsync(message)); }
internal EmojiReactionsClearedEventArgs( CachedTextChannel channel, FetchableSnowflakeOptional <IMessage> message, IEmoji emoji, ReactionData data) : base(channel.Client) { Channel = channel; Message = message; Emoji = emoji; Data = data; }
public EspeonCommandContext(IServiceScope scope, EspeonBot bot, IPrefix prefix, CachedUserMessage message) : base(bot, prefix, message, scope.ServiceProvider) { if (!(message.Author is CachedMember member && message.Channel is CachedTextChannel channel)) { throw new InvalidOperationException("Bot should not be used in dms"); } ServiceScope = scope; Bot = bot; Member = member; Channel = channel; }
public async Task HandleAsync(MemberUpdatedEventArgs args) { var oldMember = args.OldMember; var newMember = args.NewMember; using var ctx = new AdminDatabaseContext(_provider); var language = (await ctx.GetOrCreateGuildAsync(args.NewMember.Guild.Id)).Language; var builder = new LocalEmbedBuilder() .WithSuccessColor() .WithDescription(newMember.Format(false)) .WithTimestamp(DateTimeOffset.UtcNow); CachedTextChannel channel = null; // nickname if (!(newMember.Nick ?? string.Empty).Equals(oldMember.Nick ?? string.Empty, StringComparison.OrdinalIgnoreCase)) { channel = await ctx.GetLoggingChannelAsync(oldMember.Guild.Id, LogType.NicknameUpdate); builder.WithTitle(_localization.Localize(language, "logging_member_nickname")) .AddField(_localization.Localize(language, "logging_member_prevnick"), oldMember.Nick?.Sanitize() ?? Markdown.Italics(_localization.Localize(language, "logging_member_noprevnick"))) .AddField(_localization.Localize(language, "logging_member_newnick"), newMember.Nick?.Sanitize() ?? Markdown.Italics(_localization.Localize(language, "logging_member_nonewnick"))); } // role update else if (newMember.Roles.Count != oldMember.Roles.Count) { channel = await ctx.GetLoggingChannelAsync(oldMember.Guild.Id, LogType.UserRoleUpdate); var removedRoles = oldMember.Roles.Values.Where(x => !newMember.Roles.ContainsKey(x.Id)).ToList(); var addedRoles = newMember.Roles.Values.Where(x => !oldMember.Roles.ContainsKey(x.Id)).ToList(); builder.WithTitle(_localization.Localize(language, "logging_member_roleupdate")); if (addedRoles.Count > 0) { builder.AddField(_localization.Localize(language, "logging_member_addedroles"), string.Join('\n', addedRoles.Select(x => x.Format(false)))); } if (removedRoles.Count > 0) { builder.AddField(_localization.Localize(language, "logging_member_removedroles"), string.Join('\n', removedRoles.Select(x => x.Format(false)))); } } if (channel is { })
public async Task DeleteTextChannelAsync([Remainder] CachedTextChannel channel) { if (!ChannelExtensions.CheckViewChannelPermission(Context.CurrentMember !, channel)) { await ReplyErrorAsync(Localization.AdministrationTextChannelNoViewPermission); return; } await channel.DeleteAsync(); if (channel.Id != Context.Channel.Id) { await ReplyConfirmationAsync(Localization.AdministrationTextChannelDeleted, channel.Name); } }
public async ValueTask <AdminCommandResult> SendMessageAsync(CachedTextChannel channel, [Remainder] string text = null) { if (string.IsNullOrWhiteSpace(text) && Context.Message.Attachments.Count == 0) { return(CommandErrorLocalized("utility_send_empty")); } if (!string.IsNullOrWhiteSpace(text)) { text = await text.FormatPlaceHoldersAsync(Context, random : Random); } var file = new MemoryStream(); var filename = string.Empty; if (Context.Message.Attachments.FirstOrDefault() is { } attachment) { await using var stream = await Http.GetStreamAsync(attachment.Url); await stream.CopyToAsync(file); file.Seek(0, SeekOrigin.Begin); filename = attachment.FileName; } if (JsonEmbed.TryParse(text, out var embed)) { await channel.SendMessageAsync( !string.IsNullOrWhiteSpace(filename)?new LocalAttachment(file, filename) : null, embed.Text, embed : embed.ToLocalEmbed()); return(CommandSuccess()); } if (!string.IsNullOrWhiteSpace(filename)) { await channel.SendMessageAsync(new LocalAttachment(file, filename), text); } else { await channel.SendMessageAsync(text); } return(CommandSuccess()); }
public override ValueTask <ChannelPinsUpdatedEventArgs> HandleDispatchAsync(IGatewayApiClient shard, ChannelPinsUpdateJsonModel model) { CachedTextChannel channel = null; if (model.GuildId.HasValue) { if (CacheProvider.TryGetChannels(model.GuildId.Value, out var cache)) { channel = cache.GetValueOrDefault(model.ChannelId) as CachedTextChannel; if (channel != null) { channel.LastPinTimestamp = model.LastPinTimestamp.GetValueOrDefault(); } } } var e = new ChannelPinsUpdatedEventArgs(model.GuildId.GetValueOrNullable(), model.ChannelId, channel); return(new(e)); }
public async ValueTask <AdminCommandResult> AddReactionRoleAsync(CachedTextChannel channel, ulong messageId, [RequireUsableEmoji] IEmoji emoji, [Remainder, RequireHierarchy] CachedRole role) { var guild = await Context.Database.GetOrCreateGuildAsync(Context.Guild.Id); if (await Context.Database.ReactionRoles.CountAsync(x => x.GuildId == guild.Id) >= guild.MaximumReactionRoles) { return(CommandErrorLocalized("reactionrole_add_maximum", args: guild.MaximumReactionRoles)); } var id = 0; if (await Context.Database.ReactionRoles.FirstOrDefaultAsync(x => x.MessageId == messageId && x.Emoji.Equals(emoji)) is { } reactionRole) { reactionRole.RoleId = role.Id; Context.Database.ReactionRoles.Update(reactionRole); await Context.Database.SaveChangesAsync(); id = reactionRole.Id; }
public override ValueTask <CheckResult> CheckAsync(DiscordGuildCommandContext context) { if (context.Channel is null) { throw new InvalidOperationException($"{nameof(RequireNsfwAttribute)} requires the context channel."); } var isNsfw = context.Channel switch { CachedTextChannel textChannel => textChannel.IsNsfw, CachedThreadChannel threadChannel => threadChannel.GetChannel()?.IsNsfw ?? false, _ => false }; if (isNsfw) { return(Success()); } return(Failure("This can only be executed in a NSFW channel.")); } }
public AdminCommandResult GetChannelInfo([Remainder] CachedGuildChannel channel = null) { channel ??= (CachedTextChannel)Context.Channel; var builder = new LocalEmbedBuilder() .WithSuccessColor() .AddField(Localize("info_id"), channel.Id) .AddField(Localize("info_created"), string.Join('\n', channel.Id.CreatedAt.ToString("g", Context.Language.Culture), (DateTimeOffset.UtcNow - channel.Id.CreatedAt).HumanizeFormatted(Localization, Context.Language, TimeUnit.Minute, true))); builder = channel switch { CachedTextChannel textChannel => builder .WithTitle(Localize(textChannel.IsNews ? "channel_info_news" : "channel_info_text", textChannel)) .WithDescription(Markdown.Italics(textChannel.Topic)) .AddField(Localize("info_mention"), textChannel.Mention) .AddField(Localize("channel_info_slowmode"), textChannel.Slowmode == 0 ? Localize("info_none") : TimeSpan.FromSeconds(textChannel.Slowmode).HumanizeFormatted(Localization, Context.Language, TimeUnit.Second)) .WithFooter(textChannel.Category is { }
public async Task SendLoggingRevocationEmbedAsync(RevocablePunishment punishment, IUser target, IUser moderator, CachedTextChannel logChannel, LocalizedLanguage language) { var typeName = punishment.GetType().Name.ToLower(); var builder = new LocalEmbedBuilder().WithWarnColor() .WithTitle(_localization.Localize(language, $"punishment_{typeName}") + $" - {_localization.Localize(language, "punishment_case", punishment.Id)}") .WithDescription(_localization.Localize(language, $"punishment_{typeName}_revoke_description_guild", $"**{target}** (`{target.Id}`)")) .AddField(_localization.Localize(language, "title_reason"), punishment.RevocationReason ?? _localization.Localize(language, "punishment_noreason")) .WithFooter(_localization.Localize(language, "punishment_moderator", moderator.Tag), moderator.GetAvatarUrl()) .WithTimestamp(punishment.RevokedAt ?? DateTimeOffset.UtcNow); if (punishment is Mute channelMute && channelMute.ChannelId.HasValue) { builder.AddField(_localization.Localize(language, "punishment_mute_channel"), _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value)?.Mention ?? "???"); } await logChannel.SendMessageAsync(embed : builder.Build()); }
protected override DiscordCommandContext CreateCommandContext(IPrefix prefix, IGatewayUserMessage message, CachedTextChannel channel) => new VCommandContext(this, prefix, message, channel, Services);
private async Task <IUserMessage> SendLoggingEmbedAsync(Punishment punishment, IUser target, IUser moderator, Punishment additionalPunishment, CachedTextChannel logChannel, LocalizedLanguage language) { var typeName = punishment.GetType().Name.ToLower(); var builder = new LocalEmbedBuilder() .WithErrorColor() .WithTitle(_localization.Localize(language, $"punishment_{typeName}") + $" - {_localization.Localize(language, "punishment_case", punishment.Id)}") .AddField(_localization.Localize(language, "title_reason"), punishment.Reason ?? _localization.Localize(language, "punishment_needsreason", Markdown.Code( $"{_config.DefaultPrefix}reason {punishment.Id} [{_localization.Localize(language, "title_reason").ToLower()}]"))) .WithFooter(_localization.Localize(language, "punishment_moderator", moderator.Tag), moderator.GetAvatarUrl()) .WithTimestamp(punishment.CreatedAt); builder = punishment switch { Ban ban => builder.AddField( _localization.Localize(language, "punishment_duration"), ban.Duration.HasValue ? ban.Duration.Value.Humanize(minUnit: TimeUnit.Second, culture: language.Culture) : _localization.Localize(language, "punishment_permanent")), Mute mute => builder.AddField( _localization.Localize(language, "punishment_duration"), mute.Duration.HasValue ? mute.Duration.Value.Humanize(minUnit: TimeUnit.Second, culture: language.Culture) : _localization.Localize(language, "punishment_permanent")), _ => builder }; if (punishment is Mute channelMute && channelMute.ChannelId.HasValue) { builder.AddField(_localization.Localize(language, "punishment_mute_channel"), _client.GetGuild(punishment.GuildId).GetTextChannel(channelMute.ChannelId.Value).Mention); } if (punishment is Warning) { using var ctx = new AdminDatabaseContext(_provider); var warningCount = await ctx.Punishments.OfType <Warning>().CountAsync(x => x.TargetId == target.Id && x.GuildId == punishment.GuildId && !x.RevokedAt.HasValue); builder.WithDescription(_localization.Localize(language, "punishment_warning_description_guild", $"**{target}** (`{target.Id}`)", Markdown.Bold(warningCount.ToOrdinalWords(language.Culture)))); if (!(additionalPunishment is null)) { builder.AddField(FormatAdditionalPunishment(additionalPunishment, language)); } } else { builder.WithDescription(_localization.Localize(language, $"punishment_{typeName}_description_guild", $"**{target}** (`{target.Id}`)")); } if (punishment.Format != ImageFormat.Default) { // TODO: Copying stream - is it necessary? var image = new MemoryStream(punishment.Image.ToArray()); builder.WithImageUrl($"attachment://attachment.{punishment.Format.ToString().ToLower()}"); return(await logChannel.SendMessageAsync(new LocalAttachment(image, $"attachment.{punishment.Format.ToString().ToLower()}"), embed : builder.Build())); } return(await logChannel.SendMessageAsync(embed : builder.Build())); }
public async ValueTask <AdminCommandResult> ReplyToModmailAsync(int id, [Remainder, MustBe(StringLength.ShorterThan, LocalEmbedBuilder.MAX_DESCRIPTION_LENGTH)] string message) { var modmail = await Context.Database.Modmails.FindAsync(id); if (modmail is null) { return(CommandErrorLocalized("modmail_notfound")); } if (Context.IsPrivate && modmail.UserId != Context.User.Id) { return(CommandErrorLocalized("modmail_notfound")); } if (!Context.IsPrivate && modmail.GuildId != Context.Guild.Id) { return(CommandErrorLocalized("modmail_notfound")); } CachedTextChannel loggingChannel = null; if (Context.IsPrivate) { if (!(await Context.Database.GetLoggingChannelAsync(modmail.GuildId, LogType.Modmail) is CachedTextChannel logChannel)) { return(CommandErrorLocalized("requireloggingchannel_notfound", args: LogType.Modmail)); } if (modmail.ClosedBy.HasValue) { return(modmail.ClosedBy.Value == ModmailTarget.User ? CommandErrorLocalized("modmail_closed_user") : CommandErrorLocalized("modmail_closed_guild")); } loggingChannel = logChannel; } else { if (modmail.ClosedBy.HasValue) { return(modmail.ClosedBy.Value == ModmailTarget.User ? CommandErrorLocalized("modmail_closed_user_guild") : CommandErrorLocalized("modmail_closed_guild")); } } Context.Database.ModmailMessages.Add(new ModmailMessage(Context.IsPrivate ? ModmailTarget.User : ModmailTarget.Modteam, message, modmail)); await Context.Database.SaveChangesAsync(); if (Context.IsPrivate) { await loggingChannel.SendMessageAsync(embed : new LocalEmbedBuilder() .WithColor(new Color(0x8ED0FF)) .WithAuthor(new LocalEmbedAuthorBuilder { IconUrl = modmail.IsAnonymous ? Discord.GetDefaultUserAvatarUrl(Context.User.Discriminator) : Context.User.GetAvatarUrl(), Name = modmail.IsAnonymous ? Context.Localize("modmail_anonymous") : Context.User.Tag.Sanitize() }) .WithDescription(message) .WithTitle(Context.Localize("modmail_title", modmail.Id)) .WithFooter(Context.Localize("modmail_reply_command", Markdown.Code($"{Context.Prefix}mm reply {modmail.Id} [...]"), Markdown.Code($"{Context.Prefix}mm close {modmail.Id}"))) .WithTimestamp(DateTimeOffset.UtcNow) .Build()); } else { _ = Task.Run(async() => { var user = await Context.Client.GetOrDownloadUserAsync(modmail.UserId); _ = user.SendMessageAsync(embed: new LocalEmbedBuilder() .WithColor(new Color(0x8ED0FF)) .WithAuthor(new LocalEmbedAuthorBuilder { IconUrl = Context.Guild.GetIconUrl(), Name = $"{Context.Guild.Name} modteam" }) .WithDescription(message) .WithTitle(Context.Localize("modmail_title", modmail.Id)) .WithFooter(Context.Localize("modmail_reply_command", Markdown.Code($"{Context.Prefix}mm reply {modmail.Id} [...]"), Markdown.Code($"{Context.Prefix}mm close {modmail.Id}"))) .WithTimestamp(DateTimeOffset.UtcNow) .Build()); }); } return(CommandSuccessLocalized("modmail_reply_success")); }
public ValueTask <AdminCommandResult> AddPermission([Remainder] CachedTextChannel channel) => AddPermissionAsync(null, Context.Path[1].Equals("enable"), PermissionFilter.Channel, channel.Id);
public ValueTask <AdminCommandResult> BlockUser([RequireHierarchy] CachedMember target, CachedTextChannel channel, TimeSpan duration, [Remainder] string reason = null) => BlockUserAsync(target, channel, duration, reason);
public async ValueTask <AdminCommandResult> UnblacklistChannelHighlightsAsync([Remainder] CachedTextChannel channel) { if (channel.Guild.GetMember(Context.User.Id) is null) { return(CommandErrorLocalized("highlight_blacklist_notmember")); } var user = await Context.Database.GetOrCreateGlobalUserAsync(Context.User.Id); user.HighlightBlacklist.Remove(channel.Id); Context.Database.GlobalUsers.Update(user); await Context.Database.SaveChangesAsync(); return(CommandSuccessLocalized("highlight_blacklist_remove", args: channel.Format())); }
private async ValueTask <AdminCommandResult> BlockUserAsync(CachedMember target, CachedTextChannel channel, TimeSpan?duration, string reason) { channel ??= (CachedTextChannel)Context.Channel; if (channel.Overwrites.Any(x => x.TargetId == target.Id)) { return(CommandErrorLocalized("moderation_alreadyblocked", args: Markdown.Bold(target.Tag))); } var guild = await Context.Database.GetOrCreateGuildAsync(Context.Guild.Id); Mute mute = null; if (guild.Settings.HasFlag(GuildSettings.Punishments)) { var image = new MemoryStream(); var format = ImageFormat.Default; if (Context.Message.Attachments.FirstOrDefault() is { } attachment&& attachment.FileName.HasImageExtension(out format)) { var stream = await Http.GetStreamAsync(attachment.Url); await stream.CopyToAsync(image); image.Seek(0, SeekOrigin.Begin); } mute = new Mute(Context.Guild.Id, target.Id, Context.User.Id, reason, duration, channel.Id, image, format); if (channel.Overwrites.FirstOrDefault(x => x.TargetId == target.Id) is CachedOverwrite overwrite) { mute.StoreOverwrite(overwrite); await channel.DeleteOverwriteAsync(target.Id); } mute = Context.Database.Punishments.Add(mute).Entity as Mute; await Context.Database.SaveChangesAsync(); await Punishments.LogMuteAsync(target, Context.Guild, Context.User, mute); } await channel.AddOrModifyOverwriteAsync(new LocalOverwrite(target, new OverwritePermissions().Deny(Permission.SendMessages).Deny(Permission.AddReactions))); return(duration.HasValue ? CommandSuccessLocalized("moderation_block_temporary", args: new object[] { (mute is { } ? $"`[#{mute.Id}]` " : string.Empty) + target.Format(),
public VCommandContext(VerificationBot bot, IPrefix prefix, IGatewayUserMessage message, CachedTextChannel channel, IServiceProvider services) : base(bot, prefix, message, channel, services) => Bot = bot;
internal MessagesBulkDeletedEventArgs(CachedTextChannel channel, IReadOnlyList <SnowflakeOptional <CachedUserMessage> > messages) : base(channel.Client) { Channel = channel; Messages = messages; }
public ValueTask <AdminCommandResult> RemoveFromBlacklistAsync(CachedTextChannel channel) => RemoveFromBlacklistAsync(channel.Id, false);