Skip to content

Commit

Permalink
Implement role-gating as a safeguard while the bot is being set up.
Browse files Browse the repository at this point in the history
  • Loading branch information
TheCurle committed Sep 4, 2022
1 parent 88faa48 commit 1fa8d82
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 27 deletions.
6 changes: 6 additions & 0 deletions src/main/java/tk/sciwhiz12/concord/ConcordConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public class ConcordConfig {

public static final ForgeConfigSpec.ConfigValue<String> TOKEN;
public static final ForgeConfigSpec.ConfigValue<String> GUILD_ID;
public static final ForgeConfigSpec.ConfigValue<String> CHANNEL_ID;
public static final ForgeConfigSpec.ConfigValue<String> MODERATOR_ROLE_ID;
public static final ForgeConfigSpec.ConfigValue<String> CHAT_CHANNEL_ID;
public static final ForgeConfigSpec.ConfigValue<String> REPORT_CHANNEL_ID;

Expand Down Expand Up @@ -110,6 +112,10 @@ public static void register() {
REPORT_CHANNEL_ID = builder.comment("The snowflake ID of the channel where this bot will post reports from in-game users.",
"If empty, reports will be disabled.")
.define("report_channel_id", "");
MODERATOR_ROLE_ID = builder.comment("The snowflake ID of the role that will be treated as a moderator role.",
"This role will be able to use Concord's Moderation slash commands on Discord - /kick, /ban, etc.",
"This should not be treated as an alternative to proper Discord permissions configuration, but exists as a safeguard so that random users may not ban you while you're setting up.")
.define("moderator_role_id", "");

builder.pop();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,6 @@ public class ConcordDiscordCommand {
private static JDA bot;
private static MinecraftServer server;

private static void listCommand(SlashCommandEvent listEvent) {
listEvent.replyEmbeds(new EmbedBuilder()
.setTitle("Concord Integrations")
.setDescription("There are currently " + server.getPlayerCount() + " people online.")
.addField("Online Players", String.join("\n", server.getPlayerNames()), false)
.setTimestamp(Instant.now())
.setColor(Color.CYAN)
.build()
).setEphemeral(true).queue();
}

private static void tpsCommand(SlashCommandEvent tpsEvent) {
double meanTickTime = Mth.average(server.tickTimes) * 1.0E-6D;;
double meanTPS = Math.min(1000.0/meanTickTime, 20);
Expand Down Expand Up @@ -82,22 +71,31 @@ private static void helpCommand(SlashCommandEvent helpEvent) {
// TODO
}

private static void stopCommand(SlashCommandEvent stopEvent) {
// Short-circuit if on integrated server
if(FMLLoader.getDist() == Dist.CLIENT) {
stopEvent.reply("Sorry! This command is disabled on Integrated servers.").setEphemeral(true).queue();
return;
}

stopEvent.reply("Shutting the server down..").queue();
Concord.BOT.getServer().halt(false);
}

public static void initialize(CommandDispatcher dispatcher) {
dispatcher.registerSingle("list", "List all online users.", "Show a count of online users, and their names.", ConcordDiscordCommand::listCommand);
dispatcher.registerSingle("list", "List all online users.", "Show a count of online users, and their names.", (listEvent) -> {
listEvent.replyEmbeds(new EmbedBuilder()
.setTitle("Concord Integrations")
.setDescription("There are currently " + server.getPlayerCount() + " people online.")
.addField("Online Players", String.join("\n", server.getPlayerNames()), false)
.setTimestamp(Instant.now())
.setColor(Color.CYAN)
.build()
).setEphemeral(true).queue();
});

dispatcher.registerSingle("tps", "Show the performance of the server.", "Display a breakdown of server performance, in current, average and separated by dimension.", ConcordDiscordCommand::tpsCommand);
dispatcher.registerSingle("stop", "Shut down your Minecraft server.", "Immediately schedule the shutdown of the Minecraft server, akin to /stop from in-game.", ConcordDiscordCommand::stopCommand);
dispatcher.registerSingle("help", "Show detailed information about every single available command.", "Show the help information you are currently reading.", ConcordDiscordCommand::helpCommand);
dispatcher.registerSingle("stop", "Shut down your Minecraft server.", "Immediately schedule the shutdown of the Minecraft server, akin to /stop from in-game.", (event) -> {
// Short-circuit if on integrated server
if(FMLLoader.getDist() == Dist.CLIENT) {
event.reply("Sorry! This command is disabled on Integrated servers.").setEphemeral(true).queue();
return;
}

event.reply("Shutting the server down..").queue();
Concord.BOT.getServer().halt(false);
});


dispatcher.registerSingle(KickCommand.INSTANCE);
dispatcher.registerSingle(BanCommand.INSTANCE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.requests.restaction.CommandCreateAction;
import net.minecraft.client.server.IntegratedServer;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.players.UserBanListEntry;
import net.minecraftforge.api.distmarker.Dist;
Expand Down Expand Up @@ -39,6 +38,24 @@ public BanCommand() {

@Override
public void execute(SlashCommandEvent event) {
var roleConfig = ConcordConfig.MODERATOR_ROLE_ID.get();
if (!roleConfig.isEmpty()) {
var role = Concord.BOT.getDiscord().getRoleById(roleConfig);
// If no role, then it's non-empty and invalid; disable the command
if (role == null) {
event.reply("Sorry, but this command is disabled by configuration. Check the moderator_role_id option in the config.").setEphemeral(true).queue();
return;
} else {
// If the member doesn't have the moderator role, then deny them the ability to use the command.
if (!event.getMember().getRoles().contains(role)) {
event.reply("Sorry, but you don't have permission to use this command.").setEphemeral(true).queue();
return;
}
// Fall-through; member has the role, so they can use the command.
}
// Fall-through; the role is empty, so all permissions are handled by Discord.
}

var user = event.getOption(USER_OPTION.getName()).getAsString();
var server = Concord.BOT.getServer();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.requests.restaction.CommandCreateAction;
import net.minecraft.client.server.IntegratedServer;
import net.minecraft.network.chat.TextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLLoader;
Expand Down Expand Up @@ -36,6 +35,25 @@ public KickCommand() {

@Override
public void execute(SlashCommandEvent event) {
// Check permissions.
var roleConfig = ConcordConfig.MODERATOR_ROLE_ID.get();
if (!roleConfig.isEmpty()) {
var role = Concord.BOT.getDiscord().getRoleById(roleConfig);
// If no role, then it's non-empty and invalid; disable the command
if (role == null) {
event.reply("Sorry, but this command is disabled by configuration. Check the moderator_role_id option in the config.").setEphemeral(true).queue();
return;
} else {
// If the member doesn't have the moderator role, then deny them the ability to use the command.
if (!event.getMember().getRoles().contains(role)) {
event.reply("Sorry, but you don't have permission to use this command.").setEphemeral(true).queue();
return;
}
// Fall-through; member has the role, so they can use the command.
}
// Fall-through; the role is empty, so all permissions are handled by Discord.
}

var user = event.getOption(USER_OPTION.getName()).getAsString();
var server = Concord.BOT.getServer();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.requests.restaction.CommandCreateAction;
import net.minecraft.client.server.IntegratedServer;
import net.minecraft.server.players.UserWhiteListEntry;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.loading.FMLLoader;
import tk.sciwhiz12.concord.Concord;
import tk.sciwhiz12.concord.ConcordConfig;

import java.util.Optional;

Expand Down Expand Up @@ -39,6 +39,24 @@ public WhitelistCommand() {

@Override
public void execute(SlashCommandEvent event) {
var roleConfig = ConcordConfig.MODERATOR_ROLE_ID.get();
if (!roleConfig.isEmpty()) {
var role = Concord.BOT.getDiscord().getRoleById(roleConfig);
// If no role, then it's non-empty and invalid; disable the command
if (role == null) {
event.reply("Sorry, but this command is disabled by configuration. Check the moderator_role_id option in the config.").setEphemeral(true).queue();
return;
} else {
// If the member doesn't have the moderator role, then deny them the ability to use the command.
if (!event.getMember().getRoles().contains(role)) {
event.reply("Sorry, but you don't have permission to use this command.").setEphemeral(true).queue();
return;
}
// Fall-through; member has the role, so they can use the command.
}
// Fall-through; the role is empty, so all permissions are handled by Discord.
}

var server = Concord.BOT.getServer();

// Short circuit for singleplayer worlds
Expand Down

0 comments on commit 1fa8d82

Please sign in to comment.