Added a toggle role command and a command to manage the roles that can be toggled

This commit is contained in:
Teriuihi 2022-09-16 22:52:31 +02:00
parent 40b126bbe8
commit accd875eaa
5 changed files with 342 additions and 3 deletions

View File

@ -34,6 +34,7 @@ public class CommandManager extends ListenerAdapter {
commandList.put("manage", new ArrayList<>(List.of(new ScopeInfo(CommandScope.GLOBAL, 0))));
loadCommands();
Logger.info("Loading commands...");
CommandSetToggleableRoles commandSetToggleableRoles = new CommandSetToggleableRoles(jda, this);
commands = List.of(
new CommandManage(jda, this, contextMenuManager),
new CommandHelp(jda, this),
@ -43,7 +44,9 @@ public class CommandManager extends ListenerAdapter {
new CommandUpdateCommands(jda, this),
new CommandEvidence(jda, modalManager, this),
new CommandFlag(jda, this),
new CommandHistory(jda, this));
new CommandHistory(jda, this),
commandSetToggleableRoles,
new CommandToggleRole(commandSetToggleableRoles, jda, this));
}
@Override

View File

@ -0,0 +1,147 @@
package com.alttd.commandManager.commands;
import com.alttd.commandManager.CommandManager;
import com.alttd.commandManager.DiscordCommand;
import com.alttd.database.queries.QueriesToggleableRoles;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.requests.RestAction;
import java.awt.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
public class CommandSetToggleableRoles extends DiscordCommand {
private final HashMap<Long, HashSet<Long>> guildToRolesMap;
private final CommandData commandData;
public CommandSetToggleableRoles(JDA jda, CommandManager commandManager) {
guildToRolesMap = QueriesToggleableRoles.getToggleableRoles();
commandData = Commands.slash(getName(), "Set which roles can be toggled")
.addOption(OptionType.ROLE, "role", "The role you want to toggle on/off", false)
.setDefaultPermissions(DefaultMemberPermissions.DISABLED);
Util.registerCommand(commandManager, jda, commandData, getName());
}
@Override
public String getName() {
return "settoggleableroles";
}
@Override
public void execute(SlashCommandInteractionEvent event) {
Guild guild = event.getGuild();
if (guild == null) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "This command has to be ran in a guild"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
List<OptionMapping> options = event.getInteraction().getOptions();
if (options.size() == 0) {
String toggleableRoles = getToggleableRoles(guild);
MessageEmbed messageEmbed = new EmbedBuilder()
.setTitle("Active roles")
.setColor(Color.GREEN)
.setDescription(toggleableRoles)
.build();
event.replyEmbeds(messageEmbed).setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
OptionMapping optionMapping = options.get(0);
Role role = optionMapping.getAsRole();
if (containsRole(role)) {
if (!QueriesToggleableRoles.removeRoleToggleable(role)) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to remove role from the database"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
removeRole(role);
event.replyEmbeds(Util.genericSuccessEmbed("Success", "Removed " + role.getAsMention() + " from the toggleable roles"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
} else {
if (role.hasPermission(Permission.ADMINISTRATOR) ||
role.hasPermission(Permission.MANAGE_ROLES) ||
role.hasPermission(Permission.MANAGE_CHANNEL) ||
role.hasPermission(Permission.MANAGE_THREADS) ||
role.hasPermission(Permission.MANAGE_WEBHOOKS) ||
role.hasPermission(Permission.MANAGE_SERVER) ||
role.hasPermission(Permission.MANAGE_PERMISSIONS) ||
role.hasPermission(Permission.MESSAGE_MANAGE) ||
role.hasPermission(Permission.MODERATE_MEMBERS)) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "For safety reason this bot can not add roles which have a manage or moderator permission"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
if (!QueriesToggleableRoles.addRoleToggleable(role)) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to store role in the database"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
addRole(role);
event.replyEmbeds(Util.genericSuccessEmbed("Success", "Added " + role.getAsMention() + " to the toggleable roles"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
}
}
private void addRole(Role role) {
long guild = role.getGuild().getIdLong();
HashSet<Long> set = guildToRolesMap.getOrDefault(guild, new HashSet<>());
set.add(role.getIdLong());
guildToRolesMap.put(guild, set);
}
private void removeRole(Role role) {
long guild = role.getGuild().getIdLong();
HashSet<Long> set = guildToRolesMap.getOrDefault(guild, new HashSet<>());
if (set.isEmpty())
return;
set.remove(role.getIdLong());
guildToRolesMap.put(guild, set);
}
public boolean containsRole(Role role) {
return guildToRolesMap.getOrDefault(role.getGuild().getIdLong(), new HashSet<>()).contains(role.getIdLong());
}
public String getToggleableRoles(Guild guild) {
HashSet<Long> roleIds = guildToRolesMap.get(guild.getIdLong());
return guild.getRoles().stream()
.filter(role -> roleIds.contains(role.getIdLong()))
.map(Role::getAsMention)
.collect(Collectors.joining("\n"));
}
@Override
public void suggest(CommandAutoCompleteInteractionEvent event) {
event.replyChoices(Collections.emptyList()).queue();
}
@Override
public String getHelpMessage() {
return null;
}
@Override
public CommandData getCommandData() {
return commandData;
}
}

View File

@ -0,0 +1,108 @@
package com.alttd.commandManager.commands;
import com.alttd.commandManager.CommandManager;
import com.alttd.commandManager.DiscordCommand;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.requests.RestAction;
import java.awt.*;
import java.util.Collections;
import java.util.List;
public class CommandToggleRole extends DiscordCommand {
private final CommandSetToggleableRoles commandSetToggleableRoles;
private final CommandData commandData;
public CommandToggleRole(CommandSetToggleableRoles commandSetToggleableRoles, JDA jda, CommandManager commandManager) {
this.commandSetToggleableRoles = commandSetToggleableRoles;
commandData = Commands.slash(getName(), "Toggle a role")
.addOption(OptionType.ROLE, "role", "The role you want to toggle on/off (run the command without this option to see all available roles)", false)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED);
Util.registerCommand(commandManager, jda, commandData, getName());
}
@Override
public String getName() {
return "togglerole";
}
@Override
public void execute(SlashCommandInteractionEvent event) {
Guild guild = event.getGuild();
if (guild == null) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "This command has to be ran in a guild"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
List<OptionMapping> options = event.getInteraction().getOptions();
if (options.size() == 0) {
String toggleableRoles = commandSetToggleableRoles.getToggleableRoles(guild);
MessageEmbed messageEmbed = new EmbedBuilder()
.setTitle("Toggleable roles")
.setColor(Color.GREEN)
.setDescription(toggleableRoles)
.build();
event.replyEmbeds(messageEmbed).setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
OptionMapping optionMapping = options.get(0);
Role role = optionMapping.getAsRole();
if (!commandSetToggleableRoles.containsRole(role)) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "This role is not toggleable!"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
Member member = event.getMember();
if (member == null) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "This command has to be ran in a guild"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
if (member.getRoles().contains(role)) {
guild.removeRoleFromMember(member, role).queue(success ->
event.replyEmbeds(Util.genericSuccessEmbed("Role removed", "You no longer have " + role.getAsMention() + "."))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure),
error -> event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to manage your roles."))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure));
} else {
guild.addRoleToMember(member, role).queue(success ->
event.replyEmbeds(Util.genericSuccessEmbed("Role add", "You now have " + role.getAsMention() + "."))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure),
error -> event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to manage your roles."))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure));
}
}
@Override
public void suggest(CommandAutoCompleteInteractionEvent event) {
event.replyChoices(Collections.emptyList()).queue();
}
@Override
public String getHelpMessage() {
return null;
}
@Override
public CommandData getCommandData() {
return commandData;
}
}

View File

@ -65,7 +65,7 @@ public class DatabaseTables {
connection.prepareStatement(sql).executeUpdate();
} catch (SQLException e) {
Logger.sql(e);
Logger.severe("Unable to create polls table, shutting down...");
Logger.severe("Unable to create commands table, shutting down...");
}
}
@ -81,7 +81,21 @@ public class DatabaseTables {
connection.prepareStatement(sql).executeUpdate();
} catch (SQLException e) {
Logger.sql(e);
Logger.severe("Unable to create polls table, shutting down...");
Logger.severe("Unable to create output channel table, shutting down...");
}
}
private void createToggleableRolesTable() {
String sql = "CREATE TABLE IF NOT EXISTS toggleable_roles(" +
"guild BIGINT NOT NULL, " +
"role BIGINT NOT NULL, " +
"PRIMARY KEY (guild, role)" +
")";
try {
connection.prepareStatement(sql).executeUpdate();
} catch (SQLException e) {
Logger.sql(e);
Logger.severe("Unable to create toggleable roles table, shutting down...");
}
}

View File

@ -0,0 +1,67 @@
package com.alttd.database.queries;
import com.alttd.database.Database;
import net.dv8tion.jda.api.entities.Role;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
public class QueriesToggleableRoles {
public static boolean addRoleToggleable(Role role) {
String sql = "INSERT INTO toggleable_roles (guild, role) VALUES (?, ?)";
try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
preparedStatement.setLong(1, role.getGuild().getIdLong());
preparedStatement.setLong(2, role.getIdLong());
return preparedStatement.executeUpdate() == 1;
} catch (SQLException exception) {
exception.printStackTrace();
}
return false;
}
public static boolean removeRoleToggleable(Role role) {
String sql = "DELETE FROM toggleable_roles WHERE guild = ? AND role = ?";
try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
preparedStatement.setLong(1, role.getGuild().getIdLong());
preparedStatement.setLong(2, role.getIdLong());
return preparedStatement.executeUpdate() == 1;
} catch (SQLException exception) {
exception.printStackTrace();
}
return false;
}
public static HashMap<Long, HashSet<Long>> getToggleableRoles() {
String sql = "SELECT * FROM toggleable_roles";
try {
HashMap<Long, HashSet<Long>> map = new HashMap<>();
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
long guild = resultSet.getLong("guild");
long role = resultSet.getLong("role");
HashSet<Long> roles = map.getOrDefault(guild, new HashSet<>());
roles.add(role);
map.put(guild, roles);
}
return map;
} catch (SQLException exception) {
exception.printStackTrace();
}
return null;
}
}