1
0
mirror of https://github.com/sciwhiz12/Janitor.git synced 2024-09-19 23:24:03 +00:00

Add ban and unban commands

This commit is contained in:
Arnold Alejo Nunag 2020-09-30 07:25:12 +08:00
parent 48f0aeb5b1
commit 805ae844ed
Signed by: sciwhiz12
GPG Key ID: 622CF446534317E1
8 changed files with 370 additions and 3 deletions

View File

@ -13,7 +13,9 @@ import sciwhiz12.janitor.commands.bot.ShutdownCommand;
import sciwhiz12.janitor.commands.misc.HelloCommand; import sciwhiz12.janitor.commands.misc.HelloCommand;
import sciwhiz12.janitor.commands.misc.OKCommand; import sciwhiz12.janitor.commands.misc.OKCommand;
import sciwhiz12.janitor.commands.misc.PingCommand; import sciwhiz12.janitor.commands.misc.PingCommand;
import sciwhiz12.janitor.commands.moderation.BanCommand;
import sciwhiz12.janitor.commands.moderation.KickCommand; import sciwhiz12.janitor.commands.moderation.KickCommand;
import sciwhiz12.janitor.commands.moderation.UnbanCommand;
import sciwhiz12.janitor.utils.Util; import sciwhiz12.janitor.utils.Util;
import java.util.HashMap; import java.util.HashMap;
@ -38,6 +40,8 @@ public class CommandRegistry implements EventListener {
addCommand(new OKCommand(this)); addCommand(new OKCommand(this));
addCommand(new HelloCommand(this)); addCommand(new HelloCommand(this));
addCommand(new KickCommand(this)); addCommand(new KickCommand(this));
addCommand(new BanCommand(this));
addCommand(new UnbanCommand(this));
if (bot.getConfig().getOwnerID().isPresent()) { if (bot.getConfig().getOwnerID().isPresent()) {
addCommand(new ShutdownCommand(this, bot.getConfig().getOwnerID().get())); addCommand(new ShutdownCommand(this, bot.getConfig().getOwnerID().get()));
} }

View File

@ -0,0 +1,88 @@
package sciwhiz12.janitor.commands.arguments;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import sciwhiz12.janitor.utils.StringReaderUtil;
import java.util.Collection;
public class CustomStringArgumentType implements ArgumentType<String> {
private final StringArgumentType.StringType type;
private CustomStringArgumentType(final StringArgumentType.StringType type) {
this.type = type;
}
public static CustomStringArgumentType word() {
return new CustomStringArgumentType(
StringArgumentType.StringType.SINGLE_WORD);
}
public static CustomStringArgumentType string() {
return new CustomStringArgumentType(
StringArgumentType.StringType.QUOTABLE_PHRASE);
}
public static CustomStringArgumentType greedyString() {
return new CustomStringArgumentType(
StringArgumentType.StringType.GREEDY_PHRASE);
}
public static String getString(final CommandContext<?> context, final String name) {
return context.getArgument(name, String.class);
}
public StringArgumentType.StringType getType() {
return type;
}
@Override
public String parse(final StringReader reader) throws CommandSyntaxException {
if (type == StringArgumentType.StringType.GREEDY_PHRASE) {
final String text = reader.getRemaining();
reader.setCursor(reader.getTotalLength());
return text;
} else if (type == StringArgumentType.StringType.SINGLE_WORD) {
return StringReaderUtil.readUnquotedString(reader);
} else {
return StringReaderUtil.readString(reader);
}
}
@Override
public String toString() {
return "string()";
}
@Override
public Collection<String> getExamples() {
return type.getExamples();
}
public static String escapeIfRequired(final String input) {
for (final char c : input.toCharArray()) {
if (!StringReader.isAllowedInUnquotedString(c)) {
return escape(input);
}
}
return input;
}
private static String escape(final String input) {
final StringBuilder result = new StringBuilder("\"");
for (int i = 0; i < input.length(); i++) {
final char c = input.charAt(i);
if (c == '\\' || c == '"') {
result.append('\\');
}
result.append(c);
}
result.append("\"");
return result.toString();
}
}

View File

@ -105,7 +105,7 @@ public class GuildMemberArgument implements ArgumentType<GuildMemberArgument.IMe
public List<Member> fromGuild(Guild guild) throws CommandSyntaxException { public List<Member> fromGuild(Guild guild) throws CommandSyntaxException {
final String nameLowercase = name.toLowerCase(Locale.ROOT); final String nameLowercase = name.toLowerCase(Locale.ROOT);
final List<Member> members = guild.getMembers().stream() final List<Member> members = guild.getMembers().stream()
.filter(member -> (member.getUser().getName() + '#' + member.getUser().getDiscriminator()).replaceAll("\\s", "").toLowerCase(Locale.ROOT).startsWith(nameLowercase)) .filter(member -> member.getUser().getAsTag().replaceAll("\\s", "").toLowerCase(Locale.ROOT).startsWith(nameLowercase))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!multiple && members.size() > 1) { if (!multiple && members.size() > 1) {
throw MULTIPLE_MEMBERS.create(); throw MULTIPLE_MEMBERS.create();

View File

@ -0,0 +1,102 @@
package sciwhiz12.janitor.commands.moderation;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import org.checkerframework.checker.nullness.qual.Nullable;
import sciwhiz12.janitor.commands.BaseCommand;
import sciwhiz12.janitor.commands.CommandRegistry;
import sciwhiz12.janitor.commands.util.ModerationHelper;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
import static sciwhiz12.janitor.commands.arguments.GuildMemberArgument.getMembers;
import static sciwhiz12.janitor.commands.arguments.GuildMemberArgument.member;
import static sciwhiz12.janitor.commands.util.CommandHelper.argument;
import static sciwhiz12.janitor.commands.util.CommandHelper.literal;
public class BanCommand extends BaseCommand {
public static final EnumSet<Permission> BAN_PERMISSION = EnumSet.of(Permission.BAN_MEMBERS);
/*
ban command
!ban <user> [reason]
!ban delete <number of days> <user> [reason]
*/
public BanCommand(CommandRegistry registry) {
super(registry);
}
@Override
public LiteralArgumentBuilder<MessageReceivedEvent> getNode() {
return literal("ban")
.then(argument("member", member())
.then(argument("reason", greedyString())
.executes(ctx -> this.run(ctx, 0, getString(ctx, "reason")))
)
.executes(ctx -> this.run(ctx, 0, null))
)
.then(literal("delete")
.then(argument("days", integer(0, 7))
.then(argument("member", member())
.then(argument("reason", greedyString())
.executes(ctx -> this.run(ctx, getInteger(ctx, "days"), getString(ctx, "reason")))
)
.executes(ctx -> this.run(ctx, getInteger(ctx, "days"), null))
)
)
);
}
public int run(CommandContext<MessageReceivedEvent> ctx, int days, @Nullable String reason) throws CommandSyntaxException {
realRun(ctx, days, reason);
return 1;
}
void realRun(CommandContext<MessageReceivedEvent> ctx, int days, @Nullable String reason) throws CommandSyntaxException {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
messages().GENERAL.guildOnlyCommand(channel).queue();
return;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
final List<Member> members = getMembers("member", ctx).fromGuild(performer.getGuild());
if (members.size() < 1) return;
final Member target = members.get(0);
if (guild.getSelfMember().equals(target))
messages().GENERAL.cannotActionSelf(channel).queue();
else if (performer.equals(target))
messages().GENERAL.cannotActionPerformer(channel, performer).queue();
else if (!guild.getSelfMember().hasPermission(BAN_PERMISSION))
messages().GENERAL.insufficientPermissions(channel, BAN_PERMISSION).queue();
else if (!guild.getSelfMember().canInteract(target))
messages().GENERAL.cannotInteract(channel, target).queue();
else if (!performer.hasPermission(BAN_PERMISSION))
messages().MODERATION.performerInsufficientPermissions(channel, performer, BAN_PERMISSION).queue();
else if (!performer.canInteract(target))
messages().MODERATION.cannotModerate(channel, performer, target).queue();
else
target.getUser().openPrivateChannel()
.flatMap(dm -> messages().MODERATION.bannedDM(dm, performer, target, reason))
.mapToResult()
.flatMap(res -> ModerationHelper.banUser(target.getGuild(), performer, target, days, reason)
.flatMap(
v -> messages().MODERATION.banUser(channel, performer, target, reason, days, res.isSuccess())))
.queue();
}
}

View File

@ -0,0 +1,109 @@
package sciwhiz12.janitor.commands.moderation;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import sciwhiz12.janitor.commands.BaseCommand;
import sciwhiz12.janitor.commands.CommandRegistry;
import sciwhiz12.janitor.commands.util.ModerationHelper;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.mojang.brigadier.arguments.LongArgumentType.getLong;
import static com.mojang.brigadier.arguments.LongArgumentType.longArg;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static sciwhiz12.janitor.commands.util.CommandHelper.argument;
import static sciwhiz12.janitor.commands.util.CommandHelper.literal;
public class UnbanCommand extends BaseCommand {
public static final EnumSet<Permission> UNBAN_PERMISSION = EnumSet.of(Permission.BAN_MEMBERS);
public UnbanCommand(CommandRegistry registry) {
super(registry);
}
@Override
public LiteralArgumentBuilder<MessageReceivedEvent> getNode() {
return literal("unban")
.then(argument("user", StringArgumentType.string())
.executes(this::namedRun)
).then(argument("userID", longArg())
.executes(this::idRun)
);
}
public int namedRun(CommandContext<MessageReceivedEvent> ctx) {
realNamedRun(ctx);
return 1;
}
void realNamedRun(CommandContext<MessageReceivedEvent> ctx) {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
messages().GENERAL.guildOnlyCommand(channel).queue();
return;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
final String username = getString(ctx, "user").toLowerCase(Locale.ROOT);
guild.retrieveBanList()
.map(list -> list.stream().parallel()
.filter(ban -> ban.getUser().getAsTag().replaceAll("\\s", "").toLowerCase(Locale.ROOT)
.startsWith(username))
.collect(Collectors.toList()))
.queue(bans -> {
if (bans.size() > 1)
messages().GENERAL.ambiguousMember(channel);
else if (bans.size() == 1)
tryUnban(channel, guild, performer, bans.get(0).getUser());
});
}
public int idRun(CommandContext<MessageReceivedEvent> ctx) {
realIdRun(ctx);
return 1;
}
void realIdRun(CommandContext<MessageReceivedEvent> ctx) {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
messages().GENERAL.guildOnlyCommand(channel).queue();
return;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
final long id = getLong(ctx, "userID");
guild.retrieveBanList()
.map(list -> list.stream().parallel()
.filter(ban -> ban.getUser().getIdLong() == id)
.collect(Collectors.toList()))
.queue(bans -> {
if (bans.size() != 1) {
return;
}
tryUnban(channel, guild, performer, bans.get(0).getUser());
});
}
void tryUnban(MessageChannel channel, Guild guild, Member performer, User target) {
if (!guild.getSelfMember().hasPermission(UNBAN_PERMISSION))
messages().GENERAL.insufficientPermissions(channel, UNBAN_PERMISSION).queue();
else if (!performer.hasPermission(UNBAN_PERMISSION))
messages().MODERATION.performerInsufficientPermissions(channel, performer, UNBAN_PERMISSION).queue();
else
ModerationHelper.unbanUser(guild, target)
.flatMap(v -> messages().MODERATION.unbanUser(channel, performer, target))
.queue();
}
}

View File

@ -2,6 +2,7 @@ package sciwhiz12.janitor.commands.util;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; import net.dv8tion.jda.api.requests.restaction.AuditableRestAction;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -15,4 +16,17 @@ public class ModerationHelper {
auditReason.append(" for reason: ").append(reason); auditReason.append(" for reason: ").append(reason);
return guild.kick(target, auditReason.toString()); return guild.kick(target, auditReason.toString());
} }
public static AuditableRestAction<Void> banUser(Guild guild, Member performer, Member target, int deleteDuration,
@Nullable String reason) {
StringBuilder auditReason = new StringBuilder();
auditReason.append("Banned by ").append(nameFor(performer.getUser()));
if (reason != null)
auditReason.append(" for reason: ").append(reason);
return guild.ban(target, deleteDuration, auditReason.toString());
}
public static AuditableRestAction<Void> unbanUser(Guild guild, User target) {
return guild.unban(target);
}
} }

View File

@ -6,6 +6,7 @@ import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.MessageAction; import net.dv8tion.jda.api.requests.restaction.MessageAction;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -94,7 +95,8 @@ public class Messages {
new EmbedBuilder() new EmbedBuilder()
.setTitle(translate("general.cannot_action_performer.title")) .setTitle(translate("general.cannot_action_performer.title"))
.setDescription(translate("general.cannot_action_performer.desc")) .setDescription(translate("general.cannot_action_performer.desc"))
.addField(translate("general.cannot_action_performer.field.performer"), performer.getUser().getAsMention(), true) .addField(translate("general.cannot_action_performer.field.performer"), performer.getUser().getAsMention(),
true)
.setColor(General.FAILURE_COLOR) .setColor(General.FAILURE_COLOR)
.build() .build()
); );
@ -159,6 +161,42 @@ public class Messages {
embed.addField(translate("moderation.kick.dm.field.reason"), reason, false); embed.addField(translate("moderation.kick.dm.field.reason"), reason, false);
return channel.sendMessage(embed.setColor(MODERATION_COLOR).build()); return channel.sendMessage(embed.setColor(MODERATION_COLOR).build());
} }
public MessageAction banUser(MessageChannel channel, Member performer, Member target, @Nullable String reason,
int deletionDays, boolean sentDM) {
final EmbedBuilder embed = new EmbedBuilder()
.setAuthor(translate("moderation.ban.info.author"), null, GAVEL_ICON_URL)
.addField(translate("moderation.ban.info.field.performer"), performer.getUser().getAsMention(), true)
.addField(translate("moderation.ban.info.field.target"), target.getUser().getAsMention(), true)
.addField(translate("moderation.ban.info.field.sent_private_message"), sentDM ? "" : "", true);
if (deletionDays != 0)
embed.addField(translate("moderation.ban.info.field.delete_duration"),
String.valueOf(deletionDays).concat(" day(s)"), true);
if (reason != null)
embed.addField(translate("moderation.ban.info.field.reason"), reason, false);
return channel.sendMessage(embed.setColor(MODERATION_COLOR).build());
}
public MessageAction bannedDM(MessageChannel channel, Member performer, Member target, @Nullable String reason) {
final EmbedBuilder embed = new EmbedBuilder()
.setAuthor(performer.getGuild().getName(), null, performer.getGuild().getIconUrl())
.setTitle(translate("moderation.ban.dm.title"))
.addField(translate("moderation.ban.dm.field.performer"), performer.getUser().getAsMention(), true);
if (reason != null)
embed.addField(translate("moderation.ban.dm.field.reason"), reason, false);
return channel.sendMessage(embed.setColor(MODERATION_COLOR).build());
}
public MessageAction unbanUser(MessageChannel channel, Member performer, User target) {
return channel.sendMessage(
new EmbedBuilder()
.setAuthor(translate("moderation.unban.info.author"), null, GAVEL_ICON_URL)
.addField(translate("moderation.unban.info.field.performer"), performer.getUser().getAsMention(), true)
.addField(translate("moderation.unban.info.field.target"), target.getAsMention(), true)
.setColor(MODERATION_COLOR)
.build()
);
}
} }
} }

View File

@ -29,5 +29,17 @@
"moderation.kick.info.field.sent_private_message": "Sent DM", "moderation.kick.info.field.sent_private_message": "Sent DM",
"moderation.kick.dm.title": "You were kicked from this server.", "moderation.kick.dm.title": "You were kicked from this server.",
"moderation.kick.dm.field.performer": "Moderator", "moderation.kick.dm.field.performer": "Moderator",
"moderation.kick.dm.field.reason": "Reason" "moderation.kick.dm.field.reason": "Reason",
"moderation.ban.info.author": "Banned user from server.",
"moderation.ban.info.field.performer": "Performer",
"moderation.ban.info.field.target": "Target",
"moderation.ban.info.field.reason": "Reason",
"moderation.ban.info.field.sent_private_message": "Sent DM",
"moderation.ban.info.field.delete_duration": "Days of Message Deletion",
"moderation.ban.dm.title": "You were banned from this server.",
"moderation.ban.dm.field.performer": "Moderator",
"moderation.ban.dm.field.reason": "Reason",
"moderation.unban.info.author": "Unbanned user from server.",
"moderation.unban.info.field.performer": "Performer",
"moderation.unban.info.field.target": "Target"
} }