Add CommandSyncNitro for synchronizing Nitro roles and update related database queries.

This commit is contained in:
akastijn 2025-11-08 20:24:07 +01:00
parent 2c1088ef2e
commit a0b3d2167a
5 changed files with 191 additions and 1 deletions

View File

@ -42,6 +42,7 @@ public class CommandManager extends ListenerAdapter {
new CommandHelp(jda, this),
new CommandPoll(jda, this, buttonManager),
new CommandSuggestion(jda, modalManager, this),
new CommandSyncNitro(jda, this),
new CommandSuggestCrateItem(jda, modalManager, this),
new CommandSetOutputChannel(jda, this),
new CommandUpdateCommands(jda, this),

View File

@ -0,0 +1,113 @@
package com.alttd.commandManager.commands;
import com.alttd.commandManager.CommandManager;
import com.alttd.commandManager.DiscordCommand;
import com.alttd.config.MessagesConfig;
import com.alttd.database.queries.QueriesUserByRole;
import com.alttd.database.queries.QueriesUserDiscordId;
import com.alttd.util.Util;
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.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
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 net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class CommandSyncNitro extends DiscordCommand {
private final CommandData commandData;
private final JDA jda;
public CommandSyncNitro(JDA jda, CommandManager commandManager) {
this.jda = jda;
commandData = Commands.slash(getName(), "Sync nitro users.")
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.DISABLED);
Util.registerCommand(commandManager, jda, commandData, getName());
}
@Override
public String getName() {
return "syncnitro";
}
@Override
public void execute(SlashCommandInteractionEvent event) {
Guild guildById = jda.getGuildById(141644560005595136L);
if (guildById == null) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to find guild."))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
ReplyCallbackAction replyCallbackAction = event.deferReply(true);
QueriesUserByRole.getUserIdsByRole("alpha").thenAcceptAsync(optionalUserIdList -> {
if (optionalUserIdList.isEmpty()) {
replyCallbackAction.setEmbeds(Util.genericErrorEmbed("Error", "No users found."))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
checkAllMembers(optionalUserIdList.get(), guildById, replyCallbackAction);
});
}
private void checkAllMembers(List<Long> userIdList, Guild guildById, ReplyCallbackAction replyCallbackAction) {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
for (int i = 0; i < userIdList.size(); i++) {
long userId = userIdList.get(i);
scheduler.schedule(() -> {
Member member = guildById.getMemberById(userId);
if (member == null) {
guildById.retrieveMemberById(userId)
.queue(retrievedMember -> checkMember(retrievedMember, userId));
} else {
checkMember(member, userId);
}
}, i, TimeUnit.SECONDS);
}
replyCallbackAction.setEmbeds(Util.genericSuccessEmbed("Success", "Syncing " + userIdList.size() + " users in background"));
scheduler.shutdown();
}
private void checkMember(Member member, long userId) {
if (member == null) {
QueriesUserDiscordId.removeLinkedUserByDiscordId(userId);
return;
}
boolean hasNitro = member.getRoles().stream().anyMatch(role -> role.getIdLong() == 585557866275012633L);
if (!hasNitro) {
QueriesUserDiscordId.removeRole(userId, "nitro");
}
}
@Override
public void suggest(CommandAutoCompleteInteractionEvent event) {
event.replyChoices(Collections.emptyList())
.queue(RestAction.getDefaultSuccess(), Util::handleFailure);
}
@Override
public String getHelpMessage() {
return MessagesConfig.HELP_SYNC_NITRO;
}
@Override
public CommandData getCommandData() {
return commandData;
}
}

View File

@ -18,11 +18,13 @@ public class MessagesConfig extends AbstractConfig {
public static String HELP_SUGGESTION = "`/suggestion`: Opens suggestion form";
public static String HELP_MESSAGE_TEMPLATE = "<commands>";
public static String HELP_SEEN = "<commands>";
public static String HELP_SYNC_NITRO = "Syncs the nitro ranks with the minecraft ranks";
private static void loadHelp() {
HELP_HELP = messagesConfig.getString("help.help", HELP_HELP);
HELP_SUGGESTION = messagesConfig.getString("help.suggestion", HELP_SUGGESTION);
HELP_MESSAGE_TEMPLATE = messagesConfig.getString("help.message-template", HELP_MESSAGE_TEMPLATE);
HELP_SEEN = messagesConfig.getString("help.seen", HELP_SEEN);
HELP_SYNC_NITRO = messagesConfig.getString("help.sync-alpha", HELP_SYNC_NITRO);
}
private static void loadPollHelp() {

View File

@ -0,0 +1,42 @@
package com.alttd.database.queries;
import com.alttd.database.Database;
import com.alttd.util.Logger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class QueriesUserByRole {
public static CompletableFuture<Optional<List<Long>>> getUserIdsByRole(String role) {
String sql = """
SELECT discord_id
FROM linked_accounts
JOIN account_roles ON linked_accounts.player_uuid = account_roles.uuid
WHERE account_roles.role_name = ?;
""";
return CompletableFuture.supplyAsync(() -> {
try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
preparedStatement.setString(1, role);
ResultSet resultSet = preparedStatement.executeQuery();
List<Long> discordIds = new ArrayList<>();
while (resultSet.next()) {
discordIds.add(resultSet.getLong("discord_id"));
}
return Optional.of(discordIds);
} catch (SQLException exception) {
Logger.altitudeLogs.error(exception);
}
return Optional.empty();
});
}
}

View File

@ -13,7 +13,7 @@ import java.util.concurrent.CompletableFuture;
public class QueriesUserDiscordId {
public static CompletableFuture<Optional<UUID>> getUUIDById(long userId) {
String sql = "SELECT player_uuid FROM linked_accounts WHERE discord_id = ?";
String sql = "SELECT player_uuid FROM linked_accounts WHERE discord_id = ? AND active = true";
return CompletableFuture.supplyAsync(() -> {
try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
@ -30,5 +30,37 @@ public class QueriesUserDiscordId {
});
}
public static CompletableFuture<Void> removeLinkedUserByDiscordId(long userId) {
String sql = "UPDATE linked_accounts SET active = false WHERE discord_id = ?";
return CompletableFuture.runAsync(() -> {
try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
preparedStatement.setLong(1, userId);
preparedStatement.executeUpdate();
} catch (SQLException exception) {
Logger.altitudeLogs.error(exception);
}
});
}
public static void removeRole(long userId, String role) {
String sql = """
DELETE FROM account_roles
WHERE uuid IN (
SELECT player_uuid
FROM linked_accounts
WHERE discord_id = ?
)
AND role_name = ?
""";
try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
preparedStatement.setLong(1, userId);
preparedStatement.setString(2, role);
preparedStatement.executeUpdate();
} catch (SQLException exception) {
Logger.altitudeLogs.error(exception);
}
}
}