diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 26d3352..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index fb832ba..0000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index fb7f4a8..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
deleted file mode 100644
index 7754215..0000000
--- a/.idea/gradle.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 6e1f504..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
deleted file mode 100644
index b3e9cbd..0000000
--- a/.idea/jarRepositories.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 4bc4fc6..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index d35b83d..0399ff8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -40,7 +40,9 @@ dependencies {
implementation group: 'com.electronwill.night-config', name: 'toml', version: nightconfig_version
implementation group: 'net.sf.jopt-simple', name: 'jopt-simple', version: jopt_version
implementation group: 'com.google.guava', name: 'guava', version: guava_version
- implementation group: 'com.google.code.gson', name: 'gson', version: gson_version
+ implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jackson_version
+ implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jackson_version
+ implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jackson_version
implementation group: 'org.apache.logging.log4j', name: 'log4j-to-slf4j', version: log4j_bridge_version
implementation group: 'ch.qos.logback', name: 'logback-classic', version: logback_version
implementation group: 'com.mojang', name: 'brigadier', version: brigadier_version
diff --git a/gradle.properties b/gradle.properties
index 5124242..90fffd0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,7 @@ jda_version=4.2.0_207
nightconfig_version=3.6.3
jopt_version=6.0-alpha-3
guava_version=29.0-jre
-gson_version=2.8.6
+jackson_version=2.11.2
log4j_bridge_version=2.13.3
logback_version=1.3.0-alpha5
brigadier_version=1.0.17
diff --git a/src/main/java/sciwhiz12/janitor/BotConsole.java b/src/main/java/sciwhiz12/janitor/BotConsole.java
index 4f2526a..ebb83c5 100644
--- a/src/main/java/sciwhiz12/janitor/BotConsole.java
+++ b/src/main/java/sciwhiz12/janitor/BotConsole.java
@@ -49,6 +49,11 @@ public class BotConsole {
bot.getTranslations().loadTranslations();
break outer;
}
+ case "messages": {
+ CONSOLE.info("Reloading messages");
+ bot.getMessages().loadMessages();
+ break outer;
+ }
}
}
default:
@@ -71,8 +76,7 @@ public class BotConsole {
while (!scanner.hasNextLine()) {
try {
Thread.sleep(150);
- }
- catch (InterruptedException e) {
+ } catch (InterruptedException e) {
CONSOLE.warn("Console thread is interrupted");
continue outer;
}
@@ -84,8 +88,7 @@ public class BotConsole {
}
CONSOLE.debug("Received command: {}", input);
BotConsole.this.parseCommand(input);
- }
- catch (Exception e) {
+ } catch (Exception e) {
CONSOLE.error("Error while running console thread", e);
}
}
diff --git a/src/main/java/sciwhiz12/janitor/BotStartup.java b/src/main/java/sciwhiz12/janitor/BotStartup.java
index 3dcfb0a..80a4563 100644
--- a/src/main/java/sciwhiz12/janitor/BotStartup.java
+++ b/src/main/java/sciwhiz12/janitor/BotStartup.java
@@ -1,5 +1,6 @@
package sciwhiz12.janitor;
+import com.google.common.base.Preconditions;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
@@ -12,7 +13,6 @@ import sciwhiz12.janitor.config.BotOptions;
import java.util.EnumSet;
-import static com.google.common.base.Preconditions.checkArgument;
import static sciwhiz12.janitor.Logging.JANITOR;
public class BotStartup {
@@ -21,7 +21,7 @@ public class BotStartup {
BotOptions options = new BotOptions(args);
BotConfig config = new BotConfig(options);
- checkArgument(!config.getToken().isEmpty(), "Supply a client token through config or command line");
+ Preconditions.checkArgument(!config.getToken().isEmpty(), "Supply a client token through config or command line");
JANITOR.info("Building bot instance and connecting to Discord...");
@@ -37,8 +37,7 @@ public class BotStartup {
}
})
.build();
- }
- catch (Exception ex) {
+ } catch (Exception ex) {
JANITOR.error("Error while building Discord connection", ex);
}
}
diff --git a/src/main/java/sciwhiz12/janitor/JanitorBot.java b/src/main/java/sciwhiz12/janitor/JanitorBot.java
index ecd8756..232e5fe 100644
--- a/src/main/java/sciwhiz12/janitor/JanitorBot.java
+++ b/src/main/java/sciwhiz12/janitor/JanitorBot.java
@@ -9,7 +9,9 @@ import net.dv8tion.jda.api.entities.User;
import sciwhiz12.janitor.commands.CommandRegistry;
import sciwhiz12.janitor.config.BotConfig;
import sciwhiz12.janitor.msg.Messages;
-import sciwhiz12.janitor.msg.Translations;
+import sciwhiz12.janitor.msg.TranslationMap;
+import sciwhiz12.janitor.msg.emote.ReactionManager;
+import sciwhiz12.janitor.msg.substitution.SubstitutionMap;
import sciwhiz12.janitor.storage.GuildStorage;
import sciwhiz12.janitor.utils.Util;
@@ -22,22 +24,27 @@ import static sciwhiz12.janitor.Logging.STATUS;
public class JanitorBot {
private final JDA discord;
private final BotConfig config;
- private final Messages messages;
- private BotConsole console;
+ private final BotConsole console;
private final GuildStorage storage;
private final GuildStorage.SavingThread storageSavingThread;
- private CommandRegistry cmdRegistry;
- private Translations translations;
+ private final CommandRegistry cmdRegistry;
+ private final TranslationMap translations;
+ private final SubstitutionMap substitutions;
+ private final Messages messages;
+ private final ReactionManager reactions;
public JanitorBot(JDA discord, BotConfig config) {
this.config = config;
+ this.discord = discord;
this.console = new BotConsole(this, System.in);
this.storage = new GuildStorage(this, Path.of(config.STORAGE_PATH.get()));
this.cmdRegistry = new CommandRegistry(this, config.getCommandPrefix());
- this.discord = discord;
- this.translations = new Translations(this, config.getTranslationsFile());
- this.messages = new Messages(this);
- discord.addEventListener(cmdRegistry);
+ this.translations = new TranslationMap(this, config.getTranslationsFile());
+ this.substitutions = new SubstitutionMap(this);
+ this.messages = new Messages(this, config.getTranslationsFile());
+ this.reactions = new ReactionManager(this);
+ // TODO: find which of these can be loaded in parallel before the bot JDA is ready
+ discord.addEventListener(cmdRegistry, reactions);
discord.getPresence().setPresence(OnlineStatus.ONLINE, Activity.playing(" n' sweeping n' testing!"));
discord.getGuilds().forEach(Guild::loadMembers);
JANITOR.info("Ready!");
@@ -65,7 +72,9 @@ public class JanitorBot {
return this.config;
}
- public Messages getMessages() { return this.messages; }
+ public Messages getMessages() {
+ return messages;
+ }
public GuildStorage getStorage() { return this.storage; }
@@ -73,10 +82,14 @@ public class JanitorBot {
return this.cmdRegistry;
}
- public Translations getTranslations() {
+ public TranslationMap getTranslations() {
return this.translations;
}
+ public ReactionManager getReactionManager() {
+ return this.reactions;
+ }
+
public void shutdown() {
JANITOR.info(STATUS, "Shutting down!");
getConfig().getOwnerID()
@@ -102,4 +115,8 @@ public class JanitorBot {
storage.save();
console.stop();
}
+
+ public SubstitutionMap getSubstitutions() {
+ return substitutions;
+ }
}
diff --git a/src/main/java/sciwhiz12/janitor/Logging.java b/src/main/java/sciwhiz12/janitor/Logging.java
index dc38a81..90a570e 100644
--- a/src/main/java/sciwhiz12/janitor/Logging.java
+++ b/src/main/java/sciwhiz12/janitor/Logging.java
@@ -9,6 +9,7 @@ public class Logging {
public static final Marker STATUS = MarkerFactory.getMarker("STATUS");
public static final Marker COMMANDS = MarkerFactory.getMarker("COMMANDS");
public static final Marker TRANSLATIONS = MarkerFactory.getMarker("TRANSLATIONS");
+ public static final Marker MESSAGES = MarkerFactory.getMarker("MESSAGES");
public static final Marker STORAGE = MarkerFactory.getMarker("STORAGE");
public static final Logger JANITOR = LoggerFactory.getLogger("janitor");
diff --git a/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java b/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java
index b3f0a48..f833510 100644
--- a/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java
+++ b/src/main/java/sciwhiz12/janitor/commands/CommandRegistry.java
@@ -84,8 +84,7 @@ public class CommandRegistry implements EventListener {
}
JANITOR.debug(COMMANDS, "Executing command.");
dispatcher.execute(parseResults);
- }
- catch (CommandSyntaxException ex) {
+ } catch (CommandSyntaxException ex) {
JANITOR.error(COMMANDS, "Error while parsing message and executing command", ex);
}
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/arguments/GuildMemberArgument.java b/src/main/java/sciwhiz12/janitor/commands/arguments/GuildMemberArgument.java
index 3f91b05..63f3c31 100644
--- a/src/main/java/sciwhiz12/janitor/commands/arguments/GuildMemberArgument.java
+++ b/src/main/java/sciwhiz12/janitor/commands/arguments/GuildMemberArgument.java
@@ -20,8 +20,10 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class GuildMemberArgument implements ArgumentType {
- public static final SimpleCommandExceptionType UNKNOWN_MEMBER_IDENTIFIER = new SimpleCommandExceptionType(new LiteralMessage("Unknown user identifier"));
- public static final SimpleCommandExceptionType MULTIPLE_MEMBERS = new SimpleCommandExceptionType(new LiteralMessage("Too many users, when only one is needed"));
+ public static final SimpleCommandExceptionType UNKNOWN_MEMBER_IDENTIFIER = new SimpleCommandExceptionType(
+ new LiteralMessage("Unknown user identifier"));
+ public static final SimpleCommandExceptionType MULTIPLE_MEMBERS = new SimpleCommandExceptionType(
+ new LiteralMessage("Too many users, when only one is needed"));
public static final Pattern USER_IDENTIFIER_PATTERN = Pattern.compile("<@!?([0-9]+)>");
@@ -105,7 +107,8 @@ public class GuildMemberArgument implements ArgumentType fromGuild(Guild guild) throws CommandSyntaxException {
final String nameLowercase = name.toLowerCase(Locale.ROOT);
final List members = guild.getMembers().stream()
- .filter(member -> member.getUser().getAsTag().replaceAll("\\s", "").toLowerCase(Locale.ROOT).startsWith(nameLowercase))
+ .filter(member -> member.getUser().getAsTag().replaceAll("\\s", "").toLowerCase(Locale.ROOT)
+ .startsWith(nameLowercase))
.collect(Collectors.toList());
if (!multiple && members.size() > 1) {
throw MULTIPLE_MEMBERS.create();
diff --git a/src/main/java/sciwhiz12/janitor/commands/misc/HelloCommand.java b/src/main/java/sciwhiz12/janitor/commands/misc/HelloCommand.java
index b8425ad..6ab00a6 100644
--- a/src/main/java/sciwhiz12/janitor/commands/misc/HelloCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/misc/HelloCommand.java
@@ -24,9 +24,8 @@ public class HelloCommand extends BaseCommand {
public LiteralArgumentBuilder getNode() {
return literal("greet")
- .then(
- argument("member", GuildMemberArgument.member())
- .executes(this::run)
+ .then(argument("member", GuildMemberArgument.member())
+ .executes(this::run)
);
}
@@ -35,11 +34,22 @@ public class HelloCommand extends BaseCommand {
final List memberList = getMembers("member", ctx).fromGuild(ctx.getSource().getGuild());
if (memberList.size() == 1) {
final Member member = memberList.get(0);
- ctx.getSource().getChannel().sendMessage("Hello " + member.getAsMention() + "!")
- .queue(
- success -> JANITOR.debug("Sent greeting message to {}, on cmd of {}", Util.toString(member.getUser()), Util.toString(ctx.getSource().getAuthor())),
- err -> JANITOR.error("Error while sending greeting message to {}, on cmd of {}", Util.toString(member.getUser()), Util.toString(ctx.getSource().getAuthor()))
- );
+ ctx.getSource().getChannel().sendMessage("Hello " + member.getAsMention() + "!").queue(
+ success -> {
+ JANITOR.debug("Sent greeting message to {}, on cmd of {}", Util.toString(member.getUser()),
+ Util.toString(ctx.getSource().getAuthor()));
+ getBot().getReactionManager().newMessage(success)
+ .add("\u274C", (msg, event) -> success.delete()
+ .flatMap(v -> event.getChannel()
+ .deleteMessageById(ctx.getSource().getMessageIdLong()))
+ .queue()
+ )
+ .owner(ctx.getSource().getAuthor().getIdLong())
+ .create();
+ },
+ err -> JANITOR.error("Error while sending greeting message to {}, on cmd of {}",
+ Util.toString(member.getUser()), Util.toString(ctx.getSource().getAuthor()))
+ );
}
}
return 1;
diff --git a/src/main/java/sciwhiz12/janitor/commands/misc/OKCommand.java b/src/main/java/sciwhiz12/janitor/commands/misc/OKCommand.java
index 3bcc4e1..501fa00 100644
--- a/src/main/java/sciwhiz12/janitor/commands/misc/OKCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/misc/OKCommand.java
@@ -26,7 +26,8 @@ public class OKCommand extends BaseCommand {
.addReaction("\uD83D\uDC4C")
.queue(
success -> JANITOR.debug("Reacted :ok_hand: to {}'s message", Util.toString(ctx.getSource().getAuthor())),
- err -> JANITOR.error("Error while reacting :ok_hand: to {}'s message", Util.toString(ctx.getSource().getAuthor()))
+ err -> JANITOR
+ .error("Error while reacting :ok_hand: to {}'s message", Util.toString(ctx.getSource().getAuthor()))
);
return 1;
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java
index fdeab26..4c624db 100644
--- a/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/moderation/BanCommand.java
@@ -8,14 +8,15 @@ 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 sciwhiz12.janitor.msg.MessageHelper;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
+import javax.annotation.Nullable;
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
@@ -60,43 +61,77 @@ public class BanCommand extends BaseCommand {
);
}
- public int run(CommandContext ctx, int days, @Nullable String reason) throws CommandSyntaxException {
- realRun(ctx, days, reason);
- return 1;
- }
-
- void realRun(CommandContext ctx, int days, @Nullable String reason) throws CommandSyntaxException {
+ int run(CommandContext ctx, int days, @Nullable String reason) throws CommandSyntaxException {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
- return;
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
+ return 1;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
final List members = getMembers("member", ctx).fromGuild(performer.getGuild());
- if (members.size() < 1) return;
+ if (members.size() < 1) { return 1; }
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.ERRORS.performerInsufficientPermissions(channel, performer, BAN_PERMISSION).queue();
- else if (!performer.canInteract(target))
- messages().MODERATION.ERRORS.cannotModerate(channel, performer, target).queue();
- else
+ if (guild.getSelfMember().equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_self")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (performer.equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_performer")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (!guild.getSelfMember().hasPermission(BAN_PERMISSION)) {
+ messages().getRegularMessage("general/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", BAN_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else if (!guild.getSelfMember().canInteract(target)) {
+ messages().getRegularMessage("general/error/cannot_interact")
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.hasPermission(BAN_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", BAN_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.canInteract(target)) {
+ messages().getRegularMessage("moderation/error/cannot_interact")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
+ } else {
target.getUser().openPrivateChannel()
- .flatMap(dm -> messages().MODERATION.bannedDM(dm, performer, reason))
+ .flatMap(dm -> messages().getRegularMessage("moderation/ban/dm")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .with("reason", () -> reason)
+ .send(getBot(), dm)
+ )
.mapToResult()
- .flatMap(res -> ModerationHelper.banUser(target.getGuild(), performer, target, days, reason)
- .flatMap(
- v -> messages().MODERATION.banUser(channel, performer, target, reason, days, res.isSuccess())))
+ .flatMap(res ->
+ ModerationHelper.banUser(target.getGuild(), performer, target, days, reason)
+ .flatMap(v -> messages().getRegularMessage("moderation/ban/info")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .with("private_message", () -> res.isSuccess() ? "✅" : "❌")
+ .with("delete_duration", () -> String.valueOf(days))
+ .with("reason", () -> reason)
+ .send(getBot(), channel)
+ )
+ )
.queue();
+ }
+ return 1;
}
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java
index 5996907..71d392b 100644
--- a/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/moderation/KickCommand.java
@@ -8,15 +8,16 @@ 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.CommandHelper;
import sciwhiz12.janitor.commands.util.ModerationHelper;
+import sciwhiz12.janitor.msg.MessageHelper;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
+import javax.annotation.Nullable;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
@@ -50,36 +51,72 @@ public class KickCommand extends BaseCommand {
private int runWithReason(CommandContext ctx, @Nullable String reason) throws CommandSyntaxException {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
return 1;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
+
final List members = getMembers("member", ctx).fromGuild(performer.getGuild());
- if (members.size() < 1) {
- return 1;
- }
+ if (members.size() < 1) { return 1; }
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(KICK_PERMISSION))
- messages().GENERAL.insufficientPermissions(channel, KICK_PERMISSION).queue();
- else if (!guild.getSelfMember().canInteract(target))
- messages().GENERAL.cannotInteract(channel, target).queue();
- else if (!performer.hasPermission(KICK_PERMISSION))
- messages().MODERATION.ERRORS.performerInsufficientPermissions(channel, performer, KICK_PERMISSION).queue();
- else if (!performer.canInteract(target))
- messages().MODERATION.ERRORS.cannotModerate(channel, performer, target).queue();
- else
+
+ if (guild.getSelfMember().equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_self")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (performer.equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_performer")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (!guild.getSelfMember().hasPermission(KICK_PERMISSION)) {
+ messages().getRegularMessage("general/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", KICK_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else if (!guild.getSelfMember().canInteract(target)) {
+ messages().getRegularMessage("general/error/cannot_interact")
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.hasPermission(KICK_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", KICK_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.canInteract(target)) {
+ messages().getRegularMessage("moderation/error/cannot_interact")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
+ } else {
target.getUser().openPrivateChannel()
- .flatMap(dm -> messages().MODERATION.kickedDM(dm, performer, target, reason))
+ .flatMap(dm -> messages().getRegularMessage("moderation/kick/dm")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .with("reason", () -> reason)
+ .send(getBot(), dm)
+ )
.mapToResult()
.flatMap(res -> ModerationHelper.kickUser(target.getGuild(), performer, target, reason)
- .flatMap(
- v -> messages().MODERATION.kickUser(channel, performer, target, reason, res.isSuccess())))
+ .flatMap(v -> messages().getRegularMessage("moderation/kick/info")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .with("private_message", () -> res.isSuccess() ? "✅" : "❌")
+ .with("reason", () -> reason)
+ .send(getBot(), channel)
+ )
+ )
.queue();
+ }
return 1;
}
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java
index d73ff39..7bde650 100644
--- a/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/moderation/NoteCommand.java
@@ -1,6 +1,6 @@
package sciwhiz12.janitor.commands.moderation;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -9,19 +9,21 @@ 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.moderation.notes.NoteEntry;
import sciwhiz12.janitor.moderation.notes.NoteStorage;
+import sciwhiz12.janitor.msg.MessageHelper;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
+import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
+import javax.annotation.Nullable;
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
@@ -32,6 +34,7 @@ import static sciwhiz12.janitor.commands.arguments.GuildMemberArgument.member;
import static sciwhiz12.janitor.commands.moderation.NoteCommand.ModeratorFilter.*;
import static sciwhiz12.janitor.commands.util.CommandHelper.argument;
import static sciwhiz12.janitor.commands.util.CommandHelper.literal;
+import static sciwhiz12.janitor.msg.MessageHelper.*;
public class NoteCommand extends BaseCommand {
public static EnumSet NOTE_PERMISSION = EnumSet.of(Permission.KICK_MEMBERS);
@@ -90,32 +93,56 @@ public class NoteCommand extends BaseCommand {
}
private int addNote(CommandContext ctx, String noteContents) throws CommandSyntaxException {
+ final MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(ctx.getSource().getChannel());
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
return 1;
}
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
final Guild guild = performer.getGuild();
- final MessageChannel channel = ctx.getSource().getChannel();
final List members = getMembers("target", ctx).fromGuild(guild);
if (members.size() < 1) return 1;
final Member target = members.get(0);
final OffsetDateTime dateTime = OffsetDateTime.now(ZoneOffset.UTC);
- if (guild.getSelfMember().equals(target))
- messages().GENERAL.cannotActionSelf(channel).queue();
- else if (performer.equals(target))
- messages().GENERAL.cannotActionPerformer(channel, performer).queue();
- else if (!performer.hasPermission(NOTE_PERMISSION))
- messages().MODERATION.ERRORS.performerInsufficientPermissions(channel, performer, NOTE_PERMISSION).queue();
- else {
+ if (guild.getSelfMember().equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_self")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (performer.equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_performer")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.hasPermission(NOTE_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", NOTE_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else {
final NoteStorage storage = NoteStorage.get(getBot().getStorage(), guild);
final int maxAmount = config().NOTES_MAX_AMOUNT_PER_MOD.get();
if (storage.getAmountOfNotes(target.getUser()) >= maxAmount) {
- messages().MODERATION.ERRORS.maxAmountOfNotes(channel, performer, target, maxAmount).queue();
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .with("notes_amount", () -> String.valueOf(maxAmount))
+ .send(getBot(), channel).queue();
+
} else {
- int noteID = storage.addNote(new NoteEntry(performer.getUser(), target.getUser(), dateTime, noteContents));
- messages().MODERATION.addNote(channel, performer, target, noteContents, dateTime, noteID).queue();
+ final NoteEntry entry = new NoteEntry(performer.getUser(), target.getUser(), dateTime, noteContents);
+ int noteID = storage.addNote(entry);
+
+ messages().getRegularMessage("moderation/note/add")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(noteEntry("note_entry", noteID, entry))
+ .send(getBot(), channel).queue();
+
}
}
return 1;
@@ -127,9 +154,12 @@ public class NoteCommand extends BaseCommand {
private int listNotes(CommandContext ctx, boolean filterTarget, ModeratorFilter modFilter)
throws CommandSyntaxException {
- MessageChannel channel = ctx.getSource().getChannel();
+ final MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
return 1;
}
final Guild guild = ctx.getSource().getGuild();
@@ -141,7 +171,10 @@ public class NoteCommand extends BaseCommand {
if (members.size() < 1) return 1;
final Member target = members.get(0);
if (guild.getSelfMember().equals(target)) {
- messages().GENERAL.cannotActionSelf(channel).queue();
+ messages().getRegularMessage("general/error/cannot_interact")
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
return 1;
}
predicate = predicate.and(e -> e.getValue().getTarget().getIdLong() == target.getIdLong());
@@ -156,44 +189,73 @@ public class NoteCommand extends BaseCommand {
case PERFORMER: {
predicate = predicate.and(e -> e.getValue().getPerformer().getIdLong() == performer.getIdLong());
}
+ case NONE: {}
}
- final OffsetDateTime dateTime = OffsetDateTime.now();
+ if (!performer.hasPermission(NOTE_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", NOTE_PERMISSION::toString)
+ .send(getBot(), channel).queue();
- if (!performer.hasPermission(NOTE_PERMISSION))
- messages().MODERATION.ERRORS.performerInsufficientPermissions(channel, performer, NOTE_PERMISSION).queue();
- else
- messages().MODERATION.noteList(channel, NoteStorage.get(getBot().getStorage(), guild)
- .getNotes()
- .entrySet().stream()
- .filter(predicate)
- .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue))
- ).queue();
+ } else {
+ messages().>getListingMessage("moderation/note/list")
+ .apply(MessageHelper.member("performer", performer))
+ .amountPerPage(8)
+ .setEntryApplier((entry, subs) -> subs
+ .with("note_entry.note_id", () -> String.valueOf(entry.getKey()))
+ .apply(user("note_entry.performer", entry.getValue().getPerformer()))
+ .apply(user("note_entry.target", entry.getValue().getTarget()))
+ .with("note_entry.date_time", () -> entry.getValue().getDateTime().format(DATE_TIME_FORMAT))
+ .with("note_entry.contents", entry.getValue()::getContents)
+ )
+ .build(channel, getBot(), ctx.getSource().getMessage(),
+ NoteStorage.get(getBot().getStorage(), guild)
+ .getNotes()
+ .entrySet().stream()
+ .filter(predicate)
+ .sorted(Comparator.>comparingInt(Map.Entry::getKey).reversed())
+ .collect(ImmutableList.toImmutableList())
+ );
+ }
return 1;
}
private int removeNote(CommandContext ctx, int noteID) {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
return 1;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
- final OffsetDateTime dateTime = OffsetDateTime.now();
+ if (!performer.hasPermission(NOTE_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", NOTE_PERMISSION::toString)
+ .send(getBot(), channel).queue();
- if (!performer.hasPermission(NOTE_PERMISSION))
- messages().MODERATION.ERRORS.performerInsufficientPermissions(channel, performer, NOTE_PERMISSION).queue();
- else {
+ } else {
final NoteStorage storage = NoteStorage.get(getBot().getStorage(), guild);
@Nullable
final NoteEntry entry = storage.getNote(noteID);
- if (entry == null)
- messages().MODERATION.ERRORS.noNoteFound(channel, performer, noteID).queue();
- else {
+ if (entry == null) {
+ messages().getRegularMessage("moderation/note/add")
+ .apply(MessageHelper.member("performer", performer))
+ .with("note_id", () -> String.valueOf(noteID))
+ .send(getBot(), channel).queue();
+
+ } else {
storage.removeNote(noteID);
- messages().MODERATION.removeNote(channel, performer, noteID, entry).queue();
+
+ messages().getRegularMessage("moderation/note/remove")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(noteEntry("note_entry", noteID, entry))
+ .send(getBot(), channel).queue();
}
}
return 1;
diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/UnbanCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/UnbanCommand.java
index e909e7c..7cdcfa8 100644
--- a/src/main/java/sciwhiz12/janitor/commands/moderation/UnbanCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/moderation/UnbanCommand.java
@@ -12,6 +12,7 @@ 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 sciwhiz12.janitor.msg.MessageHelper;
import java.util.EnumSet;
import java.util.Locale;
@@ -49,7 +50,10 @@ public class UnbanCommand extends BaseCommand {
void realNamedRun(CommandContext ctx) {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
return;
}
final Guild guild = ctx.getSource().getGuild();
@@ -62,10 +66,14 @@ public class UnbanCommand extends BaseCommand {
.startsWith(username))
.collect(Collectors.toList()))
.queue(bans -> {
- if (bans.size() > 1)
- messages().GENERAL.ambiguousMember(channel).queue();
- else if (bans.size() == 1)
+ if (bans.size() > 1) {
+ messages().getRegularMessage("general/error/ambiguous_member")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
+ } else if (bans.size() == 1) {
tryUnban(channel, guild, performer, bans.get(0).getUser());
+ }
});
}
@@ -77,7 +85,10 @@ public class UnbanCommand extends BaseCommand {
void realIdRun(CommandContext ctx) {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
return;
}
final Guild guild = ctx.getSource().getGuild();
@@ -97,13 +108,26 @@ public class UnbanCommand extends BaseCommand {
}
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.ERRORS.performerInsufficientPermissions(channel, performer, UNBAN_PERMISSION).queue();
- else
+ if (!guild.getSelfMember().hasPermission(UNBAN_PERMISSION)) {
+ messages().getRegularMessage("general/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", UNBAN_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.hasPermission(UNBAN_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", UNBAN_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else {
ModerationHelper.unbanUser(guild, target)
- .flatMap(v -> messages().MODERATION.unbanUser(channel, performer, target))
+ .flatMap(v -> messages().getRegularMessage("moderation/unban/info")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.user("target", target))
+ .send(getBot(), channel)
+ )
.queue();
+ }
}
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java
index 27eb3ec..0790e0b 100644
--- a/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/moderation/UnwarnCommand.java
@@ -8,15 +8,15 @@ 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.moderation.warns.WarningEntry;
import sciwhiz12.janitor.moderation.warns.WarningStorage;
+import sciwhiz12.janitor.msg.MessageHelper;
-import java.time.OffsetDateTime;
import java.util.EnumSet;
import java.util.Objects;
+import javax.annotation.Nullable;
import static sciwhiz12.janitor.commands.util.CommandHelper.argument;
import static sciwhiz12.janitor.commands.util.CommandHelper.literal;
@@ -45,34 +45,54 @@ public class UnwarnCommand extends BaseCommand {
void realRun(CommandContext ctx) {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
return;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
int caseID = IntegerArgumentType.getInteger(ctx, "caseId");
- final OffsetDateTime dateTime = OffsetDateTime.now();
+ if (!performer.hasPermission(WARN_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", WARN_PERMISSION::toString)
+ .send(getBot(), channel).queue();
- if (!performer.hasPermission(WARN_PERMISSION))
- messages().MODERATION.ERRORS.performerInsufficientPermissions(channel, performer, WARN_PERMISSION).queue();
- else {
+ } else {
final WarningStorage storage = WarningStorage.get(getBot().getStorage(), guild);
@Nullable
final WarningEntry entry = storage.getWarning(caseID);
Member temp;
- if (entry == null)
- messages().MODERATION.ERRORS.noWarnWithID(channel, performer, caseID).queue();
- else if (entry.getWarned().getIdLong() == performer.getIdLong()
- && !config().WARNINGS_REMOVE_SELF_WARNINGS.get())
- messages().MODERATION.ERRORS.cannotUnwarnSelf(channel, performer, caseID, entry).queue();
- else if (config().WARNINGS_RESPECT_MOD_ROLES.get()
- && (temp = guild.getMember(entry.getPerformer())) != null
- && !performer.canInteract(temp))
- messages().MODERATION.ERRORS.cannotRemoveHigherModerated(channel, performer, caseID, entry).queue();
- else {
+ if (entry == null) {
+ messages().getRegularMessage("moderation/error/unwarn/no_case_found")
+ .apply(MessageHelper.member("performer", performer))
+ .with("case_id", () -> String.valueOf(caseID))
+ .send(getBot(), channel).queue();
+
+ } else if (entry.getWarned().getIdLong() == performer.getIdLong()
+ && !config().WARNINGS_REMOVE_SELF_WARNINGS.get()) {
+ messages().getRegularMessage("moderation/error/unwarn/cannot_unwarn_self")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.warningEntry("warning_entry", caseID, entry))
+ .send(getBot(), channel).queue();
+
+ } else if (config().WARNINGS_RESPECT_MOD_ROLES.get()
+ && (temp = guild.getMember(entry.getPerformer())) != null && !performer.canInteract(temp)) {
+ messages().getRegularMessage("moderation/error/unwarn/cannot_remove_higher_mod")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.warningEntry("warning_entry", caseID, entry))
+ .send(getBot(), channel).queue();
+
+ } else {
storage.removeWarning(caseID);
- messages().MODERATION.unwarn(channel, performer, caseID, entry).queue();
+ messages().getRegularMessage("moderation/unwarn/info")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.warningEntry("warning_entry", caseID, entry))
+ .send(getBot(), channel).queue();
+
}
}
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/WarnCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/WarnCommand.java
index 70199fc..c0288a3 100644
--- a/src/main/java/sciwhiz12/janitor/commands/moderation/WarnCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/moderation/WarnCommand.java
@@ -12,6 +12,7 @@ import sciwhiz12.janitor.commands.BaseCommand;
import sciwhiz12.janitor.commands.CommandRegistry;
import sciwhiz12.janitor.moderation.warns.WarningEntry;
import sciwhiz12.janitor.moderation.warns.WarningStorage;
+import sciwhiz12.janitor.msg.MessageHelper;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
@@ -44,45 +45,70 @@ public class WarnCommand extends BaseCommand {
);
}
- public int run(CommandContext ctx, String reason) throws CommandSyntaxException {
- realRun(ctx, reason);
- return 1;
- }
-
- void realRun(CommandContext ctx, String reason) throws CommandSyntaxException {
+ int run(CommandContext ctx, String reason) throws CommandSyntaxException {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
- return;
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
+ return 1;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
final List members = getMembers("member", ctx).fromGuild(performer.getGuild());
- if (members.size() < 1) return;
+ if (members.size() < 1) { return 1; }
final Member target = members.get(0);
final OffsetDateTime dateTime = OffsetDateTime.now(ZoneOffset.UTC);
- if (guild.getSelfMember().equals(target))
- messages().GENERAL.cannotActionSelf(channel).queue();
- else if (performer.equals(target))
- messages().GENERAL.cannotActionPerformer(channel, performer).queue();
- else if (!performer.hasPermission(WARN_PERMISSION))
- messages().MODERATION.ERRORS.performerInsufficientPermissions(channel, performer, WARN_PERMISSION).queue();
- else if (!performer.canInteract(target))
- messages().MODERATION.ERRORS.cannotModerate(channel, performer, target).queue();
- else if (target.hasPermission(WARN_PERMISSION) && config().WARNINGS_PREVENT_WARNING_MODS.get())
- messages().MODERATION.ERRORS.cannotWarnMods(channel, performer, target).queue();
- else
+ if (guild.getSelfMember().equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_self")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (performer.equals(target)) {
+ messages().getRegularMessage("general/error/cannot_action_performer")
+ .apply(MessageHelper.member("performer", performer))
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.hasPermission(WARN_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", WARN_PERMISSION::toString)
+ .send(getBot(), channel).queue();
+
+ } else if (!performer.canInteract(target)) {
+ messages().getRegularMessage("moderation/error/cannot_interact")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
+ } else if (target.hasPermission(WARN_PERMISSION) && config().WARNINGS_PREVENT_WARNING_MODS.get()) {
+ messages().getRegularMessage("moderation/error/warn/cannot_warn_mods")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
+ } else {
+ WarningEntry entry = new WarningEntry(target.getUser(), performer.getUser(), dateTime, reason);
+ int caseId = WarningStorage.get(getBot().getStorage(), guild).addWarning(entry);
+
target.getUser().openPrivateChannel()
- .flatMap(dm -> messages().MODERATION.warnDM(dm, performer, target, reason, dateTime))
+ .flatMap(dm -> messages().getRegularMessage("moderation/warn/dm")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.warningEntry("warning_entry", caseId, entry))
+ .send(getBot(), dm)
+ )
.mapToResult()
- .flatMap(res -> {
- int caseId = WarningStorage.get(getBot().getStorage(), guild)
- .addWarning(new WarningEntry(target.getUser(), performer.getUser(), dateTime, reason));
- return messages().MODERATION
- .warnUser(channel, performer, target, reason, dateTime, caseId, res.isSuccess());
- })
+ .flatMap(res -> messages().getRegularMessage("moderation/warn/info")
+ .apply(MessageHelper.member("performer", performer))
+ .apply(MessageHelper.warningEntry("warning_entry", caseId, entry))
+ .with("private_message", () -> res.isSuccess() ? "✅" : "❌")
+ .send(getBot(), channel)
+ )
.queue();
+ }
+ return 1;
}
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java b/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java
index bfa4daf..0439c6e 100644
--- a/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java
+++ b/src/main/java/sciwhiz12/janitor/commands/moderation/WarnListCommand.java
@@ -1,6 +1,6 @@
package sciwhiz12.janitor.commands.moderation;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
@@ -13,8 +13,9 @@ import sciwhiz12.janitor.commands.BaseCommand;
import sciwhiz12.janitor.commands.CommandRegistry;
import sciwhiz12.janitor.moderation.warns.WarningEntry;
import sciwhiz12.janitor.moderation.warns.WarningStorage;
+import sciwhiz12.janitor.msg.MessageHelper;
-import java.time.OffsetDateTime;
+import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
@@ -25,6 +26,8 @@ import static sciwhiz12.janitor.commands.arguments.GuildMemberArgument.getMember
import static sciwhiz12.janitor.commands.arguments.GuildMemberArgument.member;
import static sciwhiz12.janitor.commands.util.CommandHelper.argument;
import static sciwhiz12.janitor.commands.util.CommandHelper.literal;
+import static sciwhiz12.janitor.msg.MessageHelper.DATE_TIME_FORMAT;
+import static sciwhiz12.janitor.msg.MessageHelper.user;
public class WarnListCommand extends BaseCommand {
public static final EnumSet WARN_PERMISSION = EnumSet.of(Permission.KICK_MEMBERS);
@@ -54,18 +57,15 @@ public class WarnListCommand extends BaseCommand {
.executes(ctx -> this.run(ctx, false, false));
}
- public int run(CommandContext ctx, boolean filterTarget, boolean filterModerator)
- throws CommandSyntaxException {
- realRun(ctx, filterTarget, filterModerator);
- return 1;
- }
-
- void realRun(CommandContext ctx, boolean filterTarget, boolean filterModerator)
+ int run(CommandContext ctx, boolean filterTarget, boolean filterModerator)
throws CommandSyntaxException {
MessageChannel channel = ctx.getSource().getChannel();
if (!ctx.getSource().isFromGuild()) {
- messages().GENERAL.guildOnlyCommand(channel).queue();
- return;
+ messages().getRegularMessage("general/error/guild_only_command")
+ .apply(MessageHelper.user("performer", ctx.getSource().getAuthor()))
+ .send(getBot(), channel).queue();
+
+ return 1;
}
final Guild guild = ctx.getSource().getGuild();
final Member performer = Objects.requireNonNull(ctx.getSource().getMember());
@@ -73,31 +73,50 @@ public class WarnListCommand extends BaseCommand {
if (filterTarget) {
final List members = getMembers("target", ctx).fromGuild(performer.getGuild());
- if (members.size() < 1) return;
+ if (members.size() < 1) return 1;
final Member target = members.get(0);
if (guild.getSelfMember().equals(target)) {
- messages().GENERAL.cannotActionSelf(channel).queue();
- return;
+ messages().getRegularMessage("general/error/cannot_interact")
+ .apply(MessageHelper.member("target", target))
+ .send(getBot(), channel).queue();
+
+ return 1;
}
predicate = predicate.and(e -> e.getValue().getWarned().getIdLong() == target.getIdLong());
}
if (filterModerator) {
final List members = getMembers("moderator", ctx).fromGuild(performer.getGuild());
- if (members.size() < 1) return;
+ if (members.size() < 1) return 1;
final Member mod = members.get(0);
predicate = predicate.and(e -> e.getValue().getPerformer().getIdLong() == mod.getIdLong());
}
- final OffsetDateTime dateTime = OffsetDateTime.now();
+ if (!performer.hasPermission(WARN_PERMISSION)) {
+ messages().getRegularMessage("moderation/error/insufficient_permissions")
+ .apply(MessageHelper.member("performer", performer))
+ .with("required_permissions", WARN_PERMISSION::toString)
+ .send(getBot(), channel).queue();
- if (!performer.hasPermission(WARN_PERMISSION))
- messages().MODERATION.ERRORS.performerInsufficientPermissions(channel, performer, WARN_PERMISSION).queue();
- else
- messages().MODERATION.warnList(channel, WarningStorage.get(getBot().getStorage(), guild)
- .getWarnings()
- .entrySet().stream()
- .filter(predicate)
- .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue))
- ).queue();
+ } else {
+ messages().>getListingMessage("moderation/warn/list")
+ .apply(MessageHelper.member("performer", performer))
+ .amountPerPage(8)
+ .setEntryApplier((entry, subs) -> subs
+ .with("warning_entry.case_id", () -> String.valueOf(entry.getKey()))
+ .apply(user("warning_entry.performer", entry.getValue().getPerformer()))
+ .apply(user("warning_entry.warned", entry.getValue().getWarned()))
+ .with("warning_entry.date_time", () -> entry.getValue().getDateTime().format(DATE_TIME_FORMAT))
+ .with("warning_entry.reason", entry.getValue()::getReason)
+ )
+ .build(channel, getBot(), ctx.getSource().getMessage(),
+ WarningStorage.get(getBot().getStorage(), guild)
+ .getWarnings()
+ .entrySet().stream()
+ .filter(predicate)
+ .sorted(Comparator.>comparingInt(Map.Entry::getKey).reversed())
+ .collect(ImmutableList.toImmutableList())
+ );
+ }
+ return 1;
}
}
diff --git a/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java b/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java
index 14ea445..069d503 100644
--- a/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java
+++ b/src/main/java/sciwhiz12/janitor/commands/util/ModerationHelper.java
@@ -4,12 +4,12 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.requests.restaction.AuditableRestAction;
-import org.checkerframework.checker.nullness.qual.Nullable;
import java.time.Instant;
import java.time.ZoneOffset;
-import java.time.format.DateTimeFormatter;
+import javax.annotation.Nullable;
+import static sciwhiz12.janitor.msg.MessageHelper.DATE_TIME_FORMAT;
import static sciwhiz12.janitor.utils.Util.nameFor;
public class ModerationHelper {
@@ -18,7 +18,7 @@ public class ModerationHelper {
auditReason.append("Kicked by ")
.append(nameFor(performer.getUser()))
.append(" on ")
- .append(Instant.now().atOffset(ZoneOffset.UTC).format(DateTimeFormatter.RFC_1123_DATE_TIME));
+ .append(Instant.now().atOffset(ZoneOffset.UTC).format(DATE_TIME_FORMAT));
if (reason != null)
auditReason.append(" for reason: ").append(reason);
return guild.kick(target, auditReason.toString());
@@ -30,7 +30,7 @@ public class ModerationHelper {
auditReason.append("Banned by ")
.append(nameFor(performer.getUser()))
.append(" on ")
- .append(Instant.now().atOffset(ZoneOffset.UTC).format(DateTimeFormatter.RFC_1123_DATE_TIME));
+ .append(Instant.now().atOffset(ZoneOffset.UTC).format(DATE_TIME_FORMAT));
if (reason != null)
auditReason.append(" for reason: ").append(reason);
return guild.ban(target, deleteDuration, auditReason.toString());
diff --git a/src/main/java/sciwhiz12/janitor/config/BotConfig.java b/src/main/java/sciwhiz12/janitor/config/BotConfig.java
index 8c73d3b..6dc0fb7 100644
--- a/src/main/java/sciwhiz12/janitor/config/BotConfig.java
+++ b/src/main/java/sciwhiz12/janitor/config/BotConfig.java
@@ -4,11 +4,11 @@ import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.file.FileNotFoundAction;
import com.electronwill.nightconfig.core.file.FileWatcher;
import com.electronwill.nightconfig.toml.TomlFormat;
-import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
+import javax.annotation.Nullable;
import static sciwhiz12.janitor.Logging.CONFIG;
import static sciwhiz12.janitor.Logging.JANITOR;
@@ -23,6 +23,7 @@ public class BotConfig {
public final CommentedConfigSpec.IntValue AUTOSAVE_INTERVAL;
public final CommentedConfigSpec.ConfigValue CUSTOM_TRANSLATION_FILE;
+ public final CommentedConfigSpec.ConfigValue CUSTOM_MESSAGES_DIRECTORY;
public final CommentedConfigSpec.ConfigValue COMMAND_PREFIX;
@@ -67,6 +68,10 @@ public class BotConfig {
.comment("A file which contains custom translation keys to load for messages.",
"If blank, no file shall be loaded.")
.define("messages.custom_translations", "");
+ CUSTOM_MESSAGES_DIRECTORY = builder
+ .comment("A folder containing custom messages, with a 'messages.json' key file.",
+ "If blank, no folder shall be loaded and defaults will be used.")
+ .define("messages.custom_messages", "");
COMMAND_PREFIX = builder
.comment("The prefix for commands.")
@@ -115,8 +120,7 @@ public class BotConfig {
spec.setConfig(config);
// TODO: config spec
FileWatcher.defaultInstance().addWatch(configPath, this::onFileChange);
- }
- catch (IOException ex) {
+ } catch (IOException ex) {
JANITOR.error("Error while building config from file {}", configPath, ex);
}
}
@@ -134,6 +138,15 @@ public class BotConfig {
.orElse(null);
}
+ @Nullable
+ public Path getMessagesFolder() {
+ return options.getMessagesFolder().
+ or(() -> CUSTOM_MESSAGES_DIRECTORY.get().isBlank() ?
+ Optional.empty() :
+ Optional.of(Path.of(CUSTOM_MESSAGES_DIRECTORY.get())))
+ .orElse(null);
+ }
+
public String getToken() {
return options.getToken().orElse(CLIENT_TOKEN.get());
}
@@ -157,8 +170,7 @@ public class BotConfig {
CONFIG.info("Reloading config due to file change {}", configPath);
config.load();
spec.setConfig(config);
- }
- catch (Exception ex) {
+ } catch (Exception ex) {
CONFIG.error("Error while reloading config from {}", configPath, ex);
}
}
diff --git a/src/main/java/sciwhiz12/janitor/config/BotOptions.java b/src/main/java/sciwhiz12/janitor/config/BotOptions.java
index a61fb0c..ff51f26 100644
--- a/src/main/java/sciwhiz12/janitor/config/BotOptions.java
+++ b/src/main/java/sciwhiz12/janitor/config/BotOptions.java
@@ -14,6 +14,7 @@ public class BotOptions {
private final OptionSet options;
private final ArgumentAcceptingOptionSpec configPath;
private final ArgumentAcceptingOptionSpec translationsPath;
+ private final ArgumentAcceptingOptionSpec messagesFolder;
private final ArgumentAcceptingOptionSpec token;
private final ArgumentAcceptingOptionSpec prefix;
private final ArgumentAcceptingOptionSpec owner;
@@ -28,6 +29,10 @@ public class BotOptions {
.accepts("translations", "The path to the translations file")
.withRequiredArg()
.withValuesConvertedBy(new PathConverter(FILE_EXISTING, READABLE));
+ this.messagesFolder = parser
+ .accepts("translations", "The path to the custom messages folder")
+ .withRequiredArg()
+ .withValuesConvertedBy(new PathConverter(DIRECTORY_EXISTING, READABLE));
this.token = parser
.accepts("token", "The Discord token for the bot user")
.withRequiredArg();
@@ -49,6 +54,10 @@ public class BotOptions {
return translationsPath.valueOptional(options);
}
+ public Optional getMessagesFolder() {
+ return messagesFolder.valueOptional(options);
+ }
+
public Optional getToken() {
return token.valueOptional(options);
}
diff --git a/src/main/java/sciwhiz12/janitor/config/CommentedConfigSpec.java b/src/main/java/sciwhiz12/janitor/config/CommentedConfigSpec.java
index ccfd34e..4236b1b 100644
--- a/src/main/java/sciwhiz12/janitor/config/CommentedConfigSpec.java
+++ b/src/main/java/sciwhiz12/janitor/config/CommentedConfigSpec.java
@@ -134,8 +134,7 @@ public class CommentedConfigSpec extends UnmodifiableConfigWrapper, JsonSerializer {
- private final JanitorBot bot;
+ public static class Serializer extends StdSerializer {
+ private static final long serialVersionUID = 1L;
- public Serializer(JanitorBot bot) {
+ public Serializer() {
+ super(NoteEntry.class);
+ }
+
+ @Override
+ public void serialize(NoteEntry value, JsonGenerator gen, SerializerProvider provider) throws IOException {
+ gen.writeStartObject();
+ gen.writeNumberField("performer", value.getPerformer().getIdLong());
+ gen.writeNumberField("target", value.getTarget().getIdLong());
+ gen.writeStringField("dateTime", value.getDateTime().toString());
+ gen.writeStringField("contents", value.getContents());
+ gen.writeEndObject();
+ }
+ }
+
+ public static class Deserializer extends StdDeserializer {
+ private static final long serialVersionUID = 1L;
+
+ private final Supplier bot;
+
+ public Deserializer(Supplier bot) {
+ super(NoteEntry.class);
this.bot = bot;
}
@Override
- public NoteEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
- throws JsonParseException {
- final JsonObject obj = json.getAsJsonObject();
- final User performer = bot.getDiscord().retrieveUserById(obj.get("performer").getAsLong()).complete();
- final User target = bot.getDiscord().retrieveUserById(obj.get("target").getAsLong()).complete();
- final OffsetDateTime dateTime = OffsetDateTime.parse(obj.get("dateTime").getAsString());
- final String reason = obj.get("contents").getAsString();
- return new NoteEntry(performer, target, dateTime, reason);
- }
-
- @Override
- public JsonElement serialize(NoteEntry src, Type typeOfSrc, JsonSerializationContext context) {
- final JsonObject obj = new JsonObject();
- obj.addProperty("performer", src.getPerformer().getId());
- obj.addProperty("target", src.getTarget().getId());
- obj.addProperty("dateTime", src.getDateTime().toString());
- obj.addProperty("contents", src.getContents());
- return obj;
+ public NoteEntry deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
+ final JsonNode obj = ctx.readTree(p);
+ User performer = bot.get().getDiscord().retrieveUserById(obj.get("performer").asLong()).complete();
+ User target = bot.get().getDiscord().retrieveUserById(obj.get("target").asLong()).complete();
+ OffsetDateTime dateTime = OffsetDateTime.parse(obj.get("dateTime").asText());
+ String contents = obj.get("contents").asText();
+ return new NoteEntry(performer, target, dateTime, contents);
}
}
}
diff --git a/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java b/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java
index 5b8f384..78a583a 100644
--- a/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java
+++ b/src/main/java/sciwhiz12/janitor/moderation/notes/NoteStorage.java
@@ -1,11 +1,11 @@
package sciwhiz12.janitor.moderation.notes;
import com.electronwill.nightconfig.core.utils.ObservedMap;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.reflect.TypeToken;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.User;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -14,28 +14,24 @@ import sciwhiz12.janitor.storage.GuildStorage;
import sciwhiz12.janitor.storage.JsonStorage;
import sciwhiz12.janitor.storage.StorageKey;
-import java.lang.reflect.Type;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class NoteStorage extends JsonStorage {
- private static final Type NOTE_MAP_TYPE = new TypeToken