Skip to content
This repository was archived by the owner on Dec 1, 2021. It is now read-only.

Commit cc044d5

Browse files
authored
Merge pull request #12 from Java-Discord/andrew/warn
Add Preliminary /warn implementation
2 parents e337b26 + 5b0ddce commit cc044d5

File tree

12 files changed

+222
-69
lines changed

12 files changed

+222
-69
lines changed

src/main/java/net/javadiscord/javabot2/Bot.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@
22

33
import com.mongodb.MongoClient;
44
import com.mongodb.MongoClientURI;
5+
import com.mongodb.client.MongoDatabase;
6+
import com.mongodb.client.model.IndexModel;
7+
import com.mongodb.client.model.IndexOptions;
8+
import com.mongodb.client.model.Indexes;
59
import com.zaxxer.hikari.HikariConfig;
610
import com.zaxxer.hikari.HikariDataSource;
711
import net.javadiscord.javabot2.command.SlashCommandListener;
812
import net.javadiscord.javabot2.config.BotConfig;
13+
import org.bson.BsonString;
14+
import org.bson.Document;
915
import org.javacord.api.DiscordApi;
1016
import org.javacord.api.DiscordApiBuilder;
17+
import org.javacord.api.entity.intent.Intent;
1118

1219
import java.nio.file.Path;
20+
import java.util.List;
1321
import java.util.concurrent.Executors;
1422
import java.util.concurrent.ScheduledExecutorService;
1523

@@ -25,7 +33,12 @@ public class Bot {
2533
/**
2634
* A thread-safe MongoDB client that can be used to interact with MongoDB.
2735
*/
28-
public static MongoClient mongo;
36+
public static MongoClient mongoClient;
37+
38+
/**
39+
* The single Mongo database where all bot data is stored.
40+
*/
41+
public static MongoDatabase mongoDb;
2942

3043
/**
3144
* The bot's configuration.
@@ -47,11 +60,15 @@ private Bot() {}
4760
public static void main(String[] args) {
4861
initDataSources();
4962
asyncPool = Executors.newScheduledThreadPool(config.getSystems().getAsyncPoolSize());
50-
DiscordApi api = new DiscordApiBuilder().setToken(config.getSystems().getDiscordBotToken()).login().join();
63+
DiscordApi api = new DiscordApiBuilder()
64+
.setToken(config.getSystems().getDiscordBotToken())
65+
.setAllIntentsExcept(Intent.GUILD_MESSAGE_TYPING, Intent.GUILD_PRESENCES, Intent.GUILD_VOICE_STATES)
66+
.login().join();
5167
config.loadGuilds(api.getServers()); // Once we've logged in, load all guild config files.
5268
config.flush(); // Flush to save any new config files that are generated for new guilds.
5369
SlashCommandListener commandListener = new SlashCommandListener(
5470
api,
71+
args.length > 0 && args[0].equalsIgnoreCase("--register-commands"),
5572
"commands/moderation.yaml"
5673
);
5774
api.addSlashCommandCreateListener(commandListener);
@@ -75,6 +92,14 @@ private static void initDataSources() {
7592
hikariConfig.setMaximumPoolSize(hikariConfigSource.getMaximumPoolSize());
7693
hikariConfig.setConnectionInitSql(hikariConfigSource.getConnectionInitSql());
7794
hikariDataSource = new HikariDataSource(hikariConfig);
78-
mongo = new MongoClient(new MongoClientURI(config.getSystems().getMongoDatabaseUrl()));
95+
mongoDb = initMongoDatabase();
96+
}
97+
98+
private static MongoDatabase initMongoDatabase() {
99+
mongoClient = new MongoClient(new MongoClientURI(config.getSystems().getMongoDatabaseUrl()));
100+
var db = mongoClient.getDatabase("javabot");
101+
var warnCollection = db.getCollection("warn");
102+
warnCollection.createIndex(Indexes.ascending("userId"), new IndexOptions().unique(false));
103+
return db;
79104
}
80105
}

src/main/java/net/javadiscord/javabot2/command/ResponseException.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package net.javadiscord.javabot2.command;
22

33
import lombok.Getter;
4-
import org.javacord.api.interaction.callback.InteractionImmediateResponseBuilder;
54

65
import java.util.function.Supplier;
76

@@ -16,13 +15,14 @@ public class ResponseException extends Exception {
1615
* of an exception.
1716
*/
1817
@Getter
19-
private final InteractionImmediateResponseBuilder responseBuilder;
18+
private final Responses.ResponseBuilder responseBuilder;
2019

2120
/**
2221
* Constructs the exception.
2322
* @param responseBuilder The response builder to use.
2423
*/
25-
public ResponseException(InteractionImmediateResponseBuilder responseBuilder) {
24+
public ResponseException(Responses.ResponseBuilder responseBuilder) {
25+
super(responseBuilder.getMessage());
2626
this.responseBuilder = responseBuilder;
2727
}
2828

@@ -33,7 +33,7 @@ public ResponseException(InteractionImmediateResponseBuilder responseBuilder) {
3333
* @return The exception supplier.
3434
*/
3535
public static Supplier<ResponseException> warning(String message) {
36-
return () -> new ResponseException(Responses.deferredWarningBuilder().message(message).build());
36+
return () -> new ResponseException(Responses.deferredWarningBuilder().message(message));
3737
}
3838

3939
/**
@@ -43,6 +43,6 @@ public static Supplier<ResponseException> warning(String message) {
4343
* @return The exception supplier.
4444
*/
4545
public static Supplier<ResponseException> error(String message) {
46-
return () -> new ResponseException(Responses.deferredErrorBuilder().message(message).build());
46+
return () -> new ResponseException(Responses.deferredErrorBuilder().message(message));
4747
}
4848
}

src/main/java/net/javadiscord/javabot2/command/Responses.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ public ResponseBuilder message(String message) {
134134
return this;
135135
}
136136

137+
public String getMessage() {
138+
return this.message;
139+
}
140+
137141
/**
138142
* Makes this response publicly visible, i.e. not ephemeral.
139143
* @return The response builder.

src/main/java/net/javadiscord/javabot2/command/SlashCommandListener.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,39 @@
2121
@Slf4j
2222
public final class SlashCommandListener implements SlashCommandCreateListener {
2323
/**
24-
* The set of all slash command handlers, mapped by their ids.
24+
* The set of all slash command handlers, mapped by their names.
2525
*/
26-
private final Map<Long, SlashCommandHandler> commandHandlers = new HashMap<>();
26+
private final Map<String, SlashCommandHandler> commandHandlers;
2727

2828
/**
2929
* Constructs a new slash command listener using the given Discord api, and
3030
* loads commands from configuration YAML files according to the list of
3131
* resources.
3232
* @param api The Discord api to use.
33+
* @param sendUpdate Set to true if we should update the slash commands in
34+
* the API, or false if we should just assume it's done.
3335
* @param resources The list of classpath resources to load commands from.
3436
*/
35-
public SlashCommandListener(DiscordApi api, String... resources) {
36-
registerSlashCommands(api, resources)
37-
.thenAcceptAsync(commandHandlers::putAll);
37+
public SlashCommandListener(DiscordApi api, boolean sendUpdate, String... resources) {
38+
if (sendUpdate) {
39+
this.commandHandlers = new HashMap<>();
40+
registerSlashCommands(api, resources)
41+
.thenAcceptAsync(commandHandlers::putAll)
42+
.thenRun(() -> log.info("Registered all slash commands."));
43+
} else {
44+
this.commandHandlers = initializeHandlers(CommandDataLoader.load(resources));
45+
log.info("Registered all slash commands.");
46+
}
3847
}
3948

4049
@Override
4150
public void onSlashCommandCreate(SlashCommandCreateEvent event) {
42-
var handler = commandHandlers.get(event.getSlashCommandInteraction().getCommandId());
51+
var handler = commandHandlers.get(event.getSlashCommandInteraction().getCommandName());
4352
if (handler != null) {
4453
try {
4554
handler.handle(event.getSlashCommandInteraction()).respond();
4655
} catch (ResponseException e) {
47-
e.getResponseBuilder().respond();
56+
e.getResponseBuilder().respond(event.getSlashCommandInteraction());
4857
}
4958
} else {
5059
Responses.warningBuilder(event)
@@ -54,25 +63,21 @@ public void onSlashCommandCreate(SlashCommandCreateEvent event) {
5463
}
5564
}
5665

57-
private CompletableFuture<Map<Long, SlashCommandHandler>> registerSlashCommands(DiscordApi api, String... resources) {
66+
private CompletableFuture<Map<String, SlashCommandHandler>> registerSlashCommands(DiscordApi api, String... resources) {
5867
var commandConfigs = CommandDataLoader.load(resources);
5968
var handlers = initializeHandlers(commandConfigs);
6069
List<SlashCommandBuilder> commandBuilders = Arrays.stream(commandConfigs)
6170
.map(CommandConfig::toData).toList();
6271
return deleteAllSlashCommands(api)
6372
.thenComposeAsync(unused -> api.bulkOverwriteGlobalSlashCommands(commandBuilders))
6473
.thenComposeAsync(slashCommands -> {
65-
Map<Long, SlashCommandHandler> handlersById = new HashMap<>();
6674
Map<String, Long> nameToId = new HashMap<>();
6775
for (var slashCommand : slashCommands) {
68-
var handler = handlers.get(slashCommand.getName());
69-
handlersById.put(slashCommand.getId(), handler);
7076
nameToId.put(slashCommand.getName(), slashCommand.getId());
7177
}
72-
log.info("Registered all slash commands.");
7378
return updatePermissions(api, commandConfigs, nameToId)
7479
.thenRun(() -> log.info("Updated permissions for all slash commands."))
75-
.thenApplyAsync(unused -> handlersById);
80+
.thenApplyAsync(unused -> handlers);
7681
});
7782
}
7883

src/main/java/net/javadiscord/javabot2/command/data/CommandConfig.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import lombok.Data;
44
import org.javacord.api.interaction.SlashCommandBuilder;
55

6-
import java.util.Arrays;
76
import java.util.Objects;
87

98
/**
@@ -47,18 +46,6 @@ public SlashCommandBuilder toData() {
4746
return builder;
4847
}
4948

50-
@Override
51-
public String toString() {
52-
return "CommandConfig{" +
53-
"name='" + name + '\'' +
54-
", description='" + description + '\'' +
55-
", options=" + Arrays.toString(options) +
56-
", subCommands=" + Arrays.toString(subCommands) +
57-
", subCommandGroups=" + Arrays.toString(subCommandGroups) +
58-
", handler=" + handler +
59-
'}';
60-
}
61-
6249
@Override
6350
public boolean equals(Object o) {
6451
if (this == o) return true;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package net.javadiscord.javabot2.command.data;
2+
3+
import lombok.Data;
4+
import org.javacord.api.interaction.SlashCommandOptionChoice;
5+
import org.javacord.api.interaction.SlashCommandOptionChoiceBuilder;
6+
7+
/**
8+
* DTO for a choice that a slash command option can have.
9+
*/
10+
@Data
11+
public class OptionChoiceConfig {
12+
private String name;
13+
private String value;
14+
15+
/**
16+
* Converts this choice data into a Javacord object for use with the API.
17+
* @return The Javacord option choice object.
18+
*/
19+
public SlashCommandOptionChoice toData() {
20+
return new SlashCommandOptionChoiceBuilder()
21+
.setName(name)
22+
.setValue(value)
23+
.build();
24+
}
25+
}

src/main/java/net/javadiscord/javabot2/command/data/OptionConfig.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import lombok.Data;
44
import org.javacord.api.interaction.SlashCommandOptionBuilder;
5-
import org.javacord.api.interaction.SlashCommandOptionChoiceBuilder;
65
import org.javacord.api.interaction.SlashCommandOptionType;
76

7+
import java.util.Arrays;
8+
89
/**
910
* Simple DTO representing an option that can be given to a Discord slash
1011
* command or subcommand.
@@ -15,26 +16,21 @@ public class OptionConfig {
1516
private String description;
1617
private String type;
1718
private boolean required;
19+
private OptionChoiceConfig[] choices;
1820

1921
/**
2022
* Converts this config data into data that's ready for the Discord API.
2123
* @return The prepared data.
2224
*/
2325
public SlashCommandOptionBuilder toData() {
24-
return new SlashCommandOptionBuilder()
26+
var builder = new SlashCommandOptionBuilder()
2527
.setType(SlashCommandOptionType.valueOf(this.type.toUpperCase()))
2628
.setName(this.name)
2729
.setDescription(this.description)
2830
.setRequired(this.required);
29-
}
30-
31-
@Override
32-
public String toString() {
33-
return "OptionConfig{" +
34-
"name='" + name + '\'' +
35-
", description='" + description + '\'' +
36-
", type='" + type + '\'' +
37-
", required=" + required +
38-
'}';
31+
if (this.choices != null && this.choices.length > 0) {
32+
builder.setChoices(Arrays.stream(this.choices).map(OptionChoiceConfig::toData).toList());
33+
}
34+
return builder;
3935
}
4036
}

src/main/java/net/javadiscord/javabot2/command/data/SubCommandConfig.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import org.javacord.api.interaction.SlashCommandOptionBuilder;
55
import org.javacord.api.interaction.SlashCommandOptionType;
66

7-
import java.util.Arrays;
8-
97
/**
108
* Simple DTO for a Discord subcommand.
119
*/
@@ -31,13 +29,4 @@ public SlashCommandOptionBuilder toData() {
3129
}
3230
return builder;
3331
}
34-
35-
@Override
36-
public String toString() {
37-
return "SubCommandConfig{" +
38-
"name='" + name + '\'' +
39-
", description='" + description + '\'' +
40-
", options=" + Arrays.toString(options) +
41-
'}';
42-
}
4332
}

src/main/java/net/javadiscord/javabot2/command/data/SubCommandGroupConfig.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import org.javacord.api.interaction.SlashCommandOptionBuilder;
55
import org.javacord.api.interaction.SlashCommandOptionType;
66

7-
import java.util.Arrays;
8-
97
/**
108
* Simple DTO for a group of Discord subcommands.
119
*/
@@ -31,13 +29,4 @@ public SlashCommandOptionBuilder toData() {
3129
}
3230
return builder;
3331
}
34-
35-
@Override
36-
public String toString() {
37-
return "SubCommandGroupConfig{" +
38-
"name='" + name + '\'' +
39-
", description='" + description + '\'' +
40-
", subCommands=" + Arrays.toString(subCommands) +
41-
'}';
42-
}
4332
}

src/main/java/net/javadiscord/javabot2/config/SystemsConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class SystemsConfig {
1818
/**
1919
* The URL used to log in to the MongoDB instance which this bot uses.
2020
*/
21-
private String mongoDatabaseUrl = "mongodb://root:example@localhost:27171/javabot";
21+
private String mongoDatabaseUrl = "mongodb://root:example@localhost:27171";
2222

2323
/**
2424
* The number of threads to allocate to the bot's general purpose async

0 commit comments

Comments
 (0)