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 CommandHelp(jda, this),
new CommandPoll(jda, this, buttonManager), new CommandPoll(jda, this, buttonManager),
new CommandSuggestion(jda, modalManager, this), new CommandSuggestion(jda, modalManager, this),
new CommandSyncNitro(jda, this),
new CommandSuggestCrateItem(jda, modalManager, this), new CommandSuggestCrateItem(jda, modalManager, this),
new CommandSetOutputChannel(jda, this), new CommandSetOutputChannel(jda, this),
new CommandUpdateCommands(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_SUGGESTION = "`/suggestion`: Opens suggestion form";
public static String HELP_MESSAGE_TEMPLATE = "<commands>"; public static String HELP_MESSAGE_TEMPLATE = "<commands>";
public static String HELP_SEEN = "<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() { private static void loadHelp() {
HELP_HELP = messagesConfig.getString("help.help", HELP_HELP); HELP_HELP = messagesConfig.getString("help.help", HELP_HELP);
HELP_SUGGESTION = messagesConfig.getString("help.suggestion", HELP_SUGGESTION); HELP_SUGGESTION = messagesConfig.getString("help.suggestion", HELP_SUGGESTION);
HELP_MESSAGE_TEMPLATE = messagesConfig.getString("help.message-template", HELP_MESSAGE_TEMPLATE); HELP_MESSAGE_TEMPLATE = messagesConfig.getString("help.message-template", HELP_MESSAGE_TEMPLATE);
HELP_SEEN = messagesConfig.getString("help.seen", HELP_SEEN); HELP_SEEN = messagesConfig.getString("help.seen", HELP_SEEN);
HELP_SYNC_NITRO = messagesConfig.getString("help.sync-alpha", HELP_SYNC_NITRO);
} }
private static void loadPollHelp() { 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 class QueriesUserDiscordId {
public static CompletableFuture<Optional<UUID>> getUUIDById(long userId) { 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(() -> { return CompletableFuture.supplyAsync(() -> {
try { try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql); 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);
}
}
} }