Compare commits

...

18 Commits

Author SHA1 Message Date
akastijn a396b13261 Use @Slf4j in QueriesUserByRole, improve query filtering by active accounts, and refine error handling in CommandSyncNitro. 2025-11-08 21:18:08 +01:00
akastijn b0d3498d1c Add .queue() to embed action in CommandSyncNitro for proper execution 2025-11-08 20:48:56 +01:00
akastijn 1bd6602421 Add .queue() to embed action in CommandSyncNitro for proper execution 2025-11-08 20:29:14 +01:00
akastijn 7e26aba4ab Add .queue() to embed action in CommandSyncNitro for proper execution 2025-11-08 20:28:54 +01:00
akastijn 47eb88cbae Use Lombok's @Slf4j in CommandSyncNitro and add logging for database changes during member checks. 2025-11-08 20:24:49 +01:00
akastijn a0b3d2167a Add CommandSyncNitro for synchronizing Nitro roles and update related database queries. 2025-11-08 20:24:07 +01:00
akastijn 2c1088ef2e Update from v5 -> v6 for JDA 2025-11-08 19:35:28 +01:00
akastijn 3d868a109d Refactor build.gradle.kts: reorder plugins, configure bootJar and shadowJar, optimize jar task setup, and update main class attribute. 2025-09-11 22:35:02 +02:00
akastijn e947275409 Update CommandSeen: replace "grove" with "bayou" in valid servers, switch to InteractionContextType.GUILD. 2025-09-11 22:11:36 +02:00
akastijn 0960795d40 Remove redundant jar task configuration in build.gradle.kts. 2025-08-08 23:31:57 +02:00
akastijn 7863b3f62d Add AutoThread listener for creating threads in specific channels. 2025-08-08 22:38:05 +02:00
akastijn 003c75c391 Replace Logger with Lombok's @Slf4j annotation in ContactEndpoint and update log method calls. 2025-08-08 21:01:34 +02:00
Teriuihi 81b53cd1f8 Update dependencies and build process
Upgraded multiple dependencies including Spring Boot, JDA, and Configurate to their latest versions. Updated Java toolchain to version 21. Added the Versions plugin for dependency version management. Modified Jenkins build process to use `shadowJar`.
2025-06-20 23:10:46 +02:00
Teriuihi 34f9559d10 Change join-time option type to INTEGER
Adjusted the option type for 'join-time' from NUMBER to INTEGER for clarity and accuracy. This ensures proper data representation and aligns with intended usage.
2024-08-26 20:25:04 +02:00
Teriuihi f2864ade8a Add UPSERT behavior to setJoinDate query
Modified the SQL query in the setJoinDate method to use "ON DUPLICATE KEY UPDATE" for updating the date if the userId already exists. This ensures that duplicate entries are handled correctly by updating the existing record rather than creating a new one.
2024-08-26 19:15:03 +02:00
Teriuihi cd356121b7 Update CommandStaffJoinDate descriptions
Improved the descriptions of the options for the CommandStaffJoinDate command. The "staff" and "join-time" options now have clearer descriptions, making their purposes more understandable for users.
2024-08-25 19:50:38 +02:00
Teriuihi 1f706b69b8 Refactor CommandStaffJoinDate initialization
Correctly initialize and return the CommandData object for cleaner code. This change ensures proper usage of the command data and handles the auto-complete interaction correctly.
2024-08-25 19:47:34 +02:00
Teriuihi 8f6d1137ae Remove autocomplete from command options
Disabled autocomplete for "staff" and "join-time" options in the CommandStaffJoinDate constructor. This change simplifies the command interface by eliminating unnecessary suggestions.
2024-08-25 19:45:58 +02:00
58 changed files with 582 additions and 223 deletions

4
Jenkinsfile vendored
View File

@ -3,7 +3,7 @@ pipeline {
stages {
stage('Gradle') {
steps {
sh 'bash ./gradlew build'
sh 'bash ./gradlew shadowJar'
}
}
stage('Archive') {
@ -17,4 +17,4 @@ pipeline {
}
}
}
}
}

View File

@ -1,9 +1,10 @@
plugins {
id("java")
id("com.github.johnrengelman.shadow") version "7.1.0"
id("org.springframework.boot") version("3.5.3")
id("io.spring.dependency-management") version "1.1.5"
id("maven-publish")
id("org.springframework.boot") version("2.7.8")
id("com.github.johnrengelman.shadow") version "8.1.1"
id("com.github.ben-manes.versions") version "0.52.0"
}
group = "com.alttd"
@ -12,7 +13,7 @@ description = "Altitude Discord Bot."
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(21))
}
}
@ -33,49 +34,52 @@ tasks {
options.encoding = Charsets.UTF_8.name()
}
withType<Jar> {
bootJar {
enabled = false // Disable the bootJar task
}
jar {
enabled = true // Enable the jar task
manifest {
// attributes["Main-Class"] = "BOOT-INF/classes/${rootProject.group}.${project.name}"
attributes["Main-Class"] = "org.springframework.boot.loader.JarLauncher"
attributes["Main-Class"] = "com.alttd.AltitudeBot"
}
}
shadowJar {
archiveFileName.set(rootProject.name + ".jar")
mergeServiceFiles()
manifest {
attributes["Main-Class"] = "org.springframework.boot.loader.JarLauncher"
attributes["Main-Class"] = "com.alttd.AltitudeBot" // Set your main class directly
}
}
build {
dependsOn(shadowJar)
}
jar {
enabled = false
}
}
dependencies {
// JDA
implementation("net.dv8tion:JDA:5.0.2") {
implementation("net.dv8tion:JDA:6.1.1") {
exclude("opus-java") // exclude audio
}
// MySQL
implementation("mysql:mysql-connector-java:8.0.33")
// Configurate
implementation("org.spongepowered:configurate-yaml:4.1.2")
implementation("org.spongepowered:configurate-yaml:4.2.0")
// Excel
implementation("org.apache.poi:poi:5.2.0")
implementation("org.apache.poi:poi-ooxml:5.2.0")
implementation("org.apache.poi:poi:5.4.1")
implementation("org.apache.poi:poi-ooxml:5.4.1")
// Other stuff?
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor("org.projectlombok:lombok:1.18.24")
compileOnly("org.projectlombok:lombok:1.18.38")
annotationProcessor("org.projectlombok:lombok:1.18.38")
implementation("com.alttd:AltitudeLogs:1.0")
implementation("org.springframework.boot:spring-boot-starter-web:3.2.1")
implementation("org.springframework.boot:spring-boot-starter-validation:3.2.1")
implementation("com.google.code.gson:gson:2.8.9")
}
implementation("org.springframework.boot:spring-boot-starter-web:3.5.3")
implementation("org.springframework.boot:spring-boot-starter-validation:3.5.3")
implementation("com.google.code.gson:gson:2.13.1")
testImplementation(platform("org.junit:junit-bom:5.13.1"))
testImplementation("org.junit.jupiter:junit-jupiter")
}

View File

@ -51,7 +51,7 @@ public class AltitudeBot {
jda = JDABuilder.createDefault(SettingsConfig.TOKEN,
GatewayIntent.GUILD_MEMBERS,
GatewayIntent.GUILD_MODERATION,
GatewayIntent.GUILD_EMOJIS_AND_STICKERS,
GatewayIntent.GUILD_EXPRESSIONS,
GatewayIntent.GUILD_WEBHOOKS,
GatewayIntent.GUILD_PRESENCES,
GatewayIntent.GUILD_MESSAGES,

View File

@ -8,9 +8,9 @@ import com.alttd.buttonManager.buttons.remindMeConfirm.ButtonRemindMeCancel;
import com.alttd.buttonManager.buttons.remindMeConfirm.ButtonRemindMeConfirm;
import com.alttd.buttonManager.buttons.suggestionReview.ButtonSuggestionReviewAccept;
import com.alttd.buttonManager.buttons.suggestionReview.ButtonSuggestionReviewDeny;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -44,7 +44,7 @@ public class ButtonManager extends ListenerAdapter {
@Override
public void onButtonInteraction(@NotNull ButtonInteractionEvent event) {
String buttonId = event.getButton().getId();
String buttonId = event.getButton().getCustomId();
Optional<DiscordButton> first = buttons.stream()
.filter(discordModal -> discordModal.getButtonId().equalsIgnoreCase(buttonId))
.findFirst();
@ -65,9 +65,7 @@ public class ButtonManager extends ListenerAdapter {
Optional<DiscordButton> first = buttons.stream()
.filter(discordButton -> discordButton.getButtonId().equalsIgnoreCase(buttonId))
.findFirst();
if (first.isEmpty())
return null;
return first.get().getButton();
return first.map(DiscordButton::getButton).orElse(null);
}
}

View File

@ -1,7 +1,7 @@
package com.alttd.buttonManager;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
public abstract class DiscordButton {

View File

@ -5,16 +5,15 @@ import com.alttd.schedulers.ReminderScheduler;
import com.alttd.util.Logger;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.awt.*;
import java.util.Collections;
import java.util.Objects;
public class ButtonAccepted extends DiscordButton {
@Override
@ -28,7 +27,7 @@ public class ButtonAccepted extends DiscordButton {
if (!ButtonReminderUtil.shouldExecute(message, event))
return;
Logger.altitudeLogs.debug("Accepting reminder");
MessageEmbed embed = message.getEmbeds().get(0);
MessageEmbed embed = message.getEmbeds().getFirst();
EmbedBuilder embedBuilder = new EmbedBuilder(embed).setColor(Color.GREEN);
ReminderScheduler.getInstance(event.getJDA()).removeReminder(message.getIdLong());
message.editMessageEmbeds(embedBuilder.build()).queue();

View File

@ -4,10 +4,10 @@ import com.alttd.buttonManager.DiscordButton;
import com.alttd.util.Logger;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.awt.*;

View File

@ -5,16 +5,15 @@ import com.alttd.schedulers.ReminderScheduler;
import com.alttd.util.Logger;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.awt.*;
import java.util.Collections;
import java.util.Objects;
public class ButtonRejected extends DiscordButton {
@Override

View File

@ -6,9 +6,9 @@ import com.alttd.database.queries.events.Event;
import com.alttd.util.Logger;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.time.Instant;
import java.util.List;

View File

@ -4,8 +4,8 @@ import com.alttd.buttonManager.DiscordButton;
import com.alttd.database.queries.Poll.Poll;
import com.alttd.database.queries.Poll.PollButtonClicksQueries;
import com.alttd.util.Util;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.util.HashSet;

View File

@ -1,13 +1,10 @@
package com.alttd.buttonManager.buttons.remindMeConfirm;
import com.alttd.buttonManager.DiscordButton;
import com.alttd.database.queries.QueriesReminders.Reminder;
import com.alttd.util.Util;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ButtonRemindMeCancel extends DiscordButton {

View File

@ -5,9 +5,9 @@ import com.alttd.database.queries.QueriesReminders.QueriesReminders;
import com.alttd.database.queries.QueriesReminders.Reminder;
import com.alttd.schedulers.ReminderScheduler;
import com.alttd.util.Util;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.util.HashMap;
import java.util.List;

View File

@ -6,6 +6,7 @@ import com.alttd.database.queries.commandOutputChannels.OutputType;
import com.alttd.util.Logger;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
@ -16,7 +17,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.entities.emoji.EmojiUnion;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;

View File

@ -5,13 +5,13 @@ import com.alttd.database.queries.commandOutputChannels.CommandOutputChannels;
import com.alttd.database.queries.commandOutputChannels.OutputType;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.requests.RestAction;
import java.awt.*;

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

@ -11,6 +11,7 @@ import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
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.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
@ -31,9 +32,9 @@ public class CommandManage extends DiscordCommand {
.addOption(OptionType.STRING, "command", "Name of the command to enable", true, true),
new SubcommandData("disable", "Disable a command")
.addOption(OptionType.STRING, "command", "Name of the command to disable", true, true)
)
)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR))
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerSubOptions(subOptionsMap,
new SubCommandEnable(commandManager, contextMenuManager, null, this),
new SubCommandDisable(commandManager, null, this)

View File

@ -10,8 +10,11 @@ import com.alttd.schedulers.AuctionScheduler;
import com.alttd.selectMenuManager.SelectMenuManager;
import com.alttd.util.Logger;
import com.alttd.util.Util;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.selections.SelectMenu;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
@ -25,7 +28,6 @@ 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.interactions.components.selections.SelectMenu;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
import net.dv8tion.jda.api.utils.AttachedFile;
@ -36,6 +38,7 @@ import java.time.Instant;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Slf4j
public class CommandAuction extends DiscordCommand {
private final CommandData commandData;
@ -127,7 +130,7 @@ public class CommandAuction extends DiscordCommand {
return;
}
message.editMessageComponents().setActionRow(selectMenu).queue();
message.editMessageComponents(ActionRow.of(selectMenu)).queue();
AuctionScheduler auctionScheduler = AuctionScheduler.getInstance();
if (auctionScheduler == null) {
@ -149,7 +152,7 @@ public class CommandAuction extends DiscordCommand {
file.delete();
}))
.exceptionally(e -> {
e.printStackTrace();
log.error("Failed to add screenshot to auction message", e);
return null;
});
}

View File

@ -7,7 +7,6 @@ import com.alttd.util.Util;
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.Message;
import net.dv8tion.jda.api.entities.MessageReaction;
import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel;
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
@ -15,6 +14,7 @@ import net.dv8tion.jda.api.entities.channel.forums.ForumTag;
import net.dv8tion.jda.api.entities.emoji.Emoji;
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.InteractionHook;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
@ -35,7 +35,7 @@ public class CommandDataSuggestions extends DiscordCommand {
this.commandManager = commandManager;
this.commandData = Commands.slash(getName(), "Get data about suggestions from the forum channel")
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR))
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -8,10 +8,11 @@ import com.alttd.util.Util;
import net.dv8tion.jda.api.JDA;
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.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import java.util.Collections;
@ -26,7 +27,7 @@ public class CommandEvidence extends DiscordCommand {
commandData = Commands.slash(getName(), "Open suggestion form.")
.setDefaultPermissions(DefaultMemberPermissions.DISABLED)
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -10,6 +10,7 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
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.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@ -32,7 +33,7 @@ public class CommandFlag extends DiscordCommand {
this.commandData = Commands.slash(getName(), "Show flags for a user")
.addOption(OptionType.STRING, "user", "The user to show flags for", true)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED)
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -11,6 +11,7 @@ import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@ -33,7 +34,7 @@ public class CommandHelp extends DiscordCommand {
commandData = Commands.slash(getName(), "Show info about all commands or a specific command.")
.addOption(OptionType.STRING, "command", "Command to get more info about", true , true)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED)
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -12,6 +12,7 @@ import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
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.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@ -20,8 +21,8 @@ import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.requests.RestAction;
import java.awt.*;
import java.util.List;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@ -34,7 +35,7 @@ public class CommandHistory extends DiscordCommand {
.addOption(OptionType.STRING, "user", "The user to show history for", true)
.addOption(OptionType.STRING, "type", "The type of punishment to show", false, true)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED)
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -11,12 +11,13 @@ import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
import net.dv8tion.jda.api.interactions.InteractionContextType;
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.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import java.util.Calendar;
import java.util.Collections;
@ -35,7 +36,7 @@ public class CommandRemindMe extends DiscordCommand {
.addOption(OptionType.CHANNEL, "channel", "The channel to send the reminder in", true)
.addOption(OptionType.STRING, "fromnow", "How long from now the reminder should send", true, true)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED)
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -13,6 +13,7 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
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.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@ -30,12 +31,12 @@ import java.util.concurrent.TimeUnit;
public class CommandSeen extends DiscordCommand {
private final CommandData commandData;
private static final List<String> validServers = List.of("lobby", "creative", "grove");
private static final List<String> validServers = List.of("lobby", "creative", "bayou");
public CommandSeen(JDA jda, CommandManager commandManager) {
commandData = Commands.slash(getName(), "Check when a player was last online.")
.addOption(OptionType.STRING, "playername", "The playername or uuid you want to check.", true, false)
.setGuildOnly(true)
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED);
Util.registerCommand(commandManager, jda, commandData, getName());

View File

@ -13,6 +13,7 @@ import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@ -34,7 +35,7 @@ public class CommandSetOutputChannel extends DiscordCommand {
.addOption(OptionType.STRING, "type", "The type of output channel", true, true)
.addOption(OptionType.CHANNEL, "channel", "The channel the specified output should go into", true)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR))
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -10,6 +10,7 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
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.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@ -31,7 +32,7 @@ public class CommandSoftLock extends DiscordCommand {
.addOption(OptionType.STRING, "state", "Set the soft lock \"on\" or \"off\"", true, true)
.addOption(OptionType.CHANNEL, "channel", "Channel to change soft lock state for", true)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR))
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -8,11 +8,11 @@ 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.IMentionable;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageEmbed;
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.InteractionHook;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
@ -27,12 +27,14 @@ import java.util.stream.Collectors;
public class CommandStaffJoinDate extends DiscordCommand {
private final CommandData commandData;
public CommandStaffJoinDate(JDA jda, CommandManager commandManager) {
CommandData commandData = Commands.slash(getName(), "View join date for staff members, or add them manually")
.addOption(OptionType.MENTIONABLE, "staff", "Set the soft lock \"on\" or \"off\"", false, true)
.addOption(OptionType.NUMBER, "join-time", "Channel to change soft lock state for", false, true)
this.commandData = Commands.slash(getName(), "View join date for staff members, or add them manually")
.addOption(OptionType.MENTIONABLE, "staff", "The staff member to set/check the join date for", false, false)
.addOption(OptionType.INTEGER, "join-time", "The join date to set", false, false)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR))
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}
@ -53,6 +55,7 @@ public class CommandStaffJoinDate extends DiscordCommand {
interactionHook.editOriginalEmbeds(getFullStaffEmbed()).queue();
return;
}
Member member = staff.getAsMember();
if (member == null) {
interactionHook.editOriginalEmbeds(Util.genericErrorEmbed("Invalid member", String.format("%s is not a valid member", staff.getAsMentionable().getAsMention()))).queue();
@ -104,7 +107,7 @@ public class CommandStaffJoinDate extends DiscordCommand {
@Override
public void suggest(CommandAutoCompleteInteractionEvent event) {
event.replyChoiceStrings(List.of()).queue();
}
@Override
@ -114,6 +117,6 @@ public class CommandStaffJoinDate extends DiscordCommand {
@Override
public CommandData getCommandData() {
return null;
return commandData;
}
}

View File

@ -7,10 +7,11 @@ import com.alttd.util.Util;
import net.dv8tion.jda.api.JDA;
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.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import java.util.Collections;
@ -24,7 +25,7 @@ public class CommandSuggestCrateItem extends DiscordCommand {
this.modalManager = modalManager;
commandData = Commands.slash(getName(), "Open crate item suggestion form.")
.setGuildOnly(true)
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -8,26 +8,25 @@ import com.alttd.util.Util;
import net.dv8tion.jda.api.JDA;
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.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import java.util.Collections;
public class CommandSuggestion extends DiscordCommand {
private final CommandManager commandManager;
private final CommandData commandData;
private final ModalManager modalManager;
public CommandSuggestion(JDA jda, ModalManager modalManager, CommandManager commandManager) {
this.commandManager = commandManager;
this.modalManager = modalManager;
commandData = Commands.slash(getName(), "Open suggestion form.")
.setGuildOnly(true)
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -0,0 +1,138 @@
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 lombok.extern.slf4j.Slf4j;
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.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.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;
@Slf4j
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("nitro").whenCompleteAsync((optionalUserIdList, error) -> {
if (error != null) {
log.error("Unable to retrieve user list.", error);
replyCallbackAction
.setEmbeds(Util.genericErrorEmbed("Error", "Unable to retrieve user list."))
.queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
if (optionalUserIdList.isEmpty()) {
replyCallbackAction.setEmbeds(Util.genericErrorEmbed("Error", "No users found."))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
checkAllMembers(optionalUserIdList.get(), guildById, replyCallbackAction);
});
Role roleById = guildById.getRoleById(585557866275012633L);
guildById.getMembersWithRoles(roleById).forEach(member -> {
QueriesUserDiscordId.addRoleIfMissing(member.getIdLong(), "nitro").thenAccept(success -> {
log.info("Added nitro role to user {}.", member.getIdLong());
});
});
}
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),
error -> checkMember(null, userId));
} else {
checkMember(member, userId);
}
}, i, TimeUnit.SECONDS);
}
replyCallbackAction.setEmbeds(Util.genericSuccessEmbed("Success", "Syncing " + userIdList.size() + " users in background"))
.queue(RestAction.getDefaultSuccess(), Util::handleFailure);
scheduler.shutdown();
}
private void checkMember(Member member, long userId) {
if (member == null) {
QueriesUserDiscordId.removeLinkedUserByDiscordId(userId).thenAccept(success -> {
log.info("User {} not found in guild. Removed from database.", userId);
});
log.info("User {} not found in guild. Removing from database.", userId);
return;
}
boolean hasNitro = member.getRoles().stream().anyMatch(role -> role.getIdLong() == 585557866275012633L);
if (!hasNitro) {
log.info("User {} does not have nitro. Removing nitro role from database.", userId);
QueriesUserDiscordId.removeRole(userId, "nitro").thenAccept(success -> {
log.info("User {} does not have nitro. Removed nitro role from database.", userId);
});
}
}
@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

@ -8,6 +8,7 @@ import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
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;
@ -27,7 +28,7 @@ public class CommandUpdateCommands extends DiscordCommand {
this.commandManager = commandManager;
this.commandData = Commands.slash(getName(), "Updates all commands for this bot in this guild")
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR))
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}

View File

@ -4,13 +4,13 @@ import com.alttd.buttonManager.ButtonManager;
import com.alttd.commandManager.CommandManager;
import com.alttd.commandManager.DiscordCommand;
import com.alttd.commandManager.SubOption;
import com.alttd.schedulers.PollTimerTask;
import com.alttd.util.Logger;
import com.alttd.util.Util;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.Permission;
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.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
@ -52,7 +52,7 @@ public class CommandPoll extends DiscordCommand {
new SubcommandData("update_total_votes", "Update the total vote count incase it's out of sync")
.addOption(OptionType.STRING, "message_id", "Id of the poll you want to update the total vote count for", true))
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR))
.setGuildOnly(true);
.setContexts(InteractionContextType.GUILD);
Util.registerSubOptions(subOptionsMap,
new SubCommandAdd(null,this),
new SubCommandAddButton(null, this, buttonManager),

View File

@ -12,12 +12,12 @@ import com.alttd.templates.Template;
import com.alttd.util.Logger;
import com.alttd.util.OptionMappingParsing;
import com.alttd.util.Util;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.actionrow.ActionRowChildComponent;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.ItemComponent;
import java.util.ArrayList;
import java.util.List;
@ -102,7 +102,9 @@ public class SubCommandAddButton extends SubCommand {
}
PollButton pollButton = any.get();
List<ActionRow> actionRows = message.getActionRows();
List<ActionRow> actionRows = message.getComponents().stream()
.filter(component -> component instanceof ActionRow)
.map(a -> (ActionRow) a).toList();
if (rowId > 1) {//todo fix if needed in the future
hook.editOriginalEmbeds(Util.genericErrorEmbed("Error",
"Polls have only been set up to handle 1 row if you need more than one row update the code."))
@ -110,14 +112,15 @@ public class SubCommandAddButton extends SubCommand {
return;
}
List<ItemComponent> components;
List<ActionRowChildComponent> components;
if (!actionRows.isEmpty()) {
components = actionRows.get(0).getComponents();
} else
components = new ArrayList<>(actionRows.getFirst().getComponents());
} else {
components = new ArrayList<>();
}
components.add(pollButton.getButton());
message.editMessageComponents().setActionRow(components).queue();
message.editMessageComponents(ActionRow.of(components)).queue();
hook.editOriginalEmbeds(Util.genericSuccessEmbed("Success", "Added a button")).queue();
}

View File

@ -3,6 +3,7 @@ package com.alttd.communication.contact;
import com.alttd.AltitudeBot;
import com.alttd.communication.formData.ContactFormData;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
@ -14,26 +15,25 @@ import org.springframework.web.bind.annotation.*;
import java.util.concurrent.CompletableFuture;
@Slf4j
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/api/contact")
public class ContactEndpoint {
private static final Logger logger = LoggerFactory.getLogger(ContactEndpoint.class);
@PostMapping("/submitContactForm")
public CompletableFuture<ResponseEntity<String>> sendFormToDiscord(@Valid @RequestBody ContactFormData formData) {
logger.debug("Sending form to Discord: " + formData);
log.debug("Sending form to Discord: {}", formData);
MessageEmbed messageEmbed = formData.toMessageEmbed();
Guild guild = AltitudeBot.getInstance().getJDA().getGuildById(514920774923059209L);
if (guild == null) {
logger.error("Unable to retrieve staff guild");
log.error("Unable to retrieve staff guild");
return CompletableFuture.completedFuture(ResponseEntity.internalServerError().body("Failed to submit form to Discord"));
}
TextChannel channel = guild.getChannelById(TextChannel.class, 514922567883292673L);
if (channel == null) {
logger.error("Unable to retrieve contact form channel");
log.error("Unable to retrieve contact form channel");
return CompletableFuture.completedFuture(ResponseEntity.internalServerError().body("Failed to submit form to Discord"));
}
@ -43,7 +43,7 @@ public class ContactEndpoint {
if (complete != null)
return ResponseEntity.ok("");
} catch (Exception exception) {
logger.error("Failed to send message to Discord", exception);
log.error("Failed to send message to Discord", exception);
}
return ResponseEntity.internalServerError().body("Failed to submit form to Discord");
});

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

@ -8,10 +8,11 @@ import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent;
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.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
public class ContextMenuCreateEvent extends DiscordContextMenu {
@ -62,7 +63,7 @@ public class ContextMenuCreateEvent extends DiscordContextMenu {
@Override
public CommandData getUserContextInteraction() {
return Commands.message(getContextMenuId())
.setGuildOnly(true)
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_SEND));
}
}

View File

@ -7,6 +7,7 @@ import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent;
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;
@ -46,7 +47,7 @@ public class ContextMenuForwardToKanboard extends DiscordContextMenu {
@Override
public CommandData getUserContextInteraction() {
return Commands.message(getContextMenuId())
.setGuildOnly(true)
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR));
}
}

View File

@ -15,10 +15,11 @@ import net.dv8tion.jda.api.entities.channel.unions.IThreadContainerUnion;
import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion;
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent;
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.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
public class ContextMenuRespondSuggestion extends DiscordContextMenu {
@ -63,7 +64,7 @@ public class ContextMenuRespondSuggestion extends DiscordContextMenu {
@Override
public CommandData getUserContextInteraction() {
return Commands.message(getContextMenuId())
.setGuildOnly(true)
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR));
}

View File

@ -6,15 +6,14 @@ import com.alttd.database.queries.QueriesAuctionActions.QueriesAuctionAction;
import com.alttd.selectMenuManager.DiscordSelectMenu;
import com.alttd.selectMenuManager.SelectMenuManager;
import com.alttd.util.Util;
import net.dv8tion.jda.api.components.selections.SelectMenu;
import net.dv8tion.jda.api.components.selections.SelectOption;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.LinkedList;

View File

@ -34,7 +34,7 @@ public class QueriesStaffJoinDate {
}
public static void setJoinDate(long userId, Instant date) {
String sql = "INSERT INTO staff_join_date (user_id, date) VALUES (?, ?)";
String sql = "INSERT INTO staff_join_date (user_id, date) VALUES (?, ?) ON DUPLICATE KEY UPDATE date = VALUES(date)";
try (PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql)) {
preparedStatement.setLong(1, userId);

View File

@ -0,0 +1,46 @@
package com.alttd.database.queries;
import com.alttd.database.Database;
import com.alttd.util.Logger;
import lombok.extern.slf4j.Slf4j;
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;
@Slf4j
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 = ?
AND linked_accounts.active = true;
""";
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) {
log.error("Failed to get user ids by role", exception);
Logger.altitudeLogs.error(exception);
}
return Optional.empty();
});
}
}

View File

@ -2,6 +2,7 @@ package com.alttd.database.queries;
import com.alttd.database.Database;
import com.alttd.util.Logger;
import net.dv8tion.jda.api.entities.Member;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -13,7 +14,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 +31,64 @@ 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 CompletableFuture<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 = ?
""";
return CompletableFuture.runAsync(() -> {
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);
}
});
}
public static CompletableFuture<Void> addRoleIfMissing(long userId, String role) {
String sql = """
INSERT INTO account_roles (uuid, role_name)
SELECT player_uuid, ?
FROM linked_accounts
WHERE discord_id = ?
AND NOT EXISTS (
SELECT 1
FROM account_roles
WHERE uuid = player_uuid
AND role_name = ?)
""";
return CompletableFuture.runAsync(() -> {
try {
PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql);
preparedStatement.setString(1, role);
preparedStatement.setLong(2, userId);
preparedStatement.setString(3, role);
preparedStatement.executeUpdate();
} catch (SQLException exception) {
Logger.altitudeLogs.error(exception);
}
});
}
}

View File

@ -8,6 +8,8 @@ import com.alttd.database.queries.QueriesReminders.ReminderType;
import com.alttd.schedulers.ReminderScheduler;
import com.alttd.util.Logger;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
@ -15,7 +17,6 @@ import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
@ -47,15 +48,15 @@ public class AppealRepost extends ListenerAdapter {
}
Message message = event.getMessage();
List<MessageEmbed> embeds = message.getEmbeds();
if (embeds.size() == 0) {
if (embeds.isEmpty()) {
return;
}
MessageEmbed messageEmbed = embeds.get(0);
MessageEmbed messageEmbed = embeds.getFirst();
List<MessageEmbed.Field> fields = messageEmbed.getFields();
if (fields.size() == 0) {
if (fields.isEmpty()) {
return;
}
String name = fields.get(0).getName();
String name = fields.getFirst().getName();
if (name == null || !name.equals("Punishment info")) {
return;
}
@ -89,7 +90,7 @@ public class AppealRepost extends ListenerAdapter {
return;
}
message.getChannel().sendMessageEmbeds(embed).queue(res -> {
res.editMessageComponents().setActionRow(reminderAccepted, reminderInProgress, reminderDenied).queue();
res.editMessageComponents(ActionRow.of(reminderAccepted, reminderInProgress, reminderDenied)).queue();
res.createThreadChannel("Appeal").queue((
threadChannel -> {
scheduleReminder(res, member, threadChannel);

View File

@ -0,0 +1,22 @@
package com.alttd.listeners;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.jetbrains.annotations.NonNls;
import java.util.List;
public class AutoThread extends ListenerAdapter {
List<Long> channels = List.of(1172922338023591956L);
@Override
public void onMessageReceived(@NonNls MessageReceivedEvent event) {
if (!channels.contains(event.getChannel().getIdLong())) {
return;
}
event.getMessage().createThreadChannel("Auto Thread").queue(threadChannel ->
threadChannel.sendMessage("Thread for community post by: " + event.getAuthor().getAsMention())
.queue());
}
}

View File

@ -42,13 +42,15 @@ public class JDAListener extends ListenerAdapter {
Logger.altitudeLogs.info("JDA ready to register commands.");
LockedChannel lockedChannel = new LockedChannel();
ButtonManager buttonManager = new ButtonManager();
AutoThread autoThread = new AutoThread();
TagAdded tagAdded = new TagAdded();
AppealRepost appealRepost = new AppealRepost(buttonManager);
ModalManager modalManager = new ModalManager(buttonManager);
ContextMenuManager contextMenuManager = new ContextMenuManager(modalManager);
SelectMenuManager selectMenuManager = new SelectMenuManager();
CommandManager commandManager = new CommandManager(jda, modalManager, contextMenuManager, lockedChannel, selectMenuManager, buttonManager);
jda.addEventListener(buttonManager, tagAdded, modalManager, commandManager, contextMenuManager, lockedChannel, appealRepost, selectMenuManager);
jda.addEventListener(buttonManager, tagAdded, modalManager, commandManager, contextMenuManager, lockedChannel,
appealRepost, selectMenuManager, autoThread);
PollQueries.loadPolls(buttonManager);
new Timer().scheduleAtFixedRate(new PollTimerTask(jda, Logger.altitudeLogs), TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(5));
new QueriesEvent().loadActiveEvents();

View File

@ -1,7 +1,7 @@
package com.alttd.modalManager;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
public abstract class DiscordModal {

View File

@ -4,7 +4,7 @@ import com.alttd.buttonManager.ButtonManager;
import com.alttd.modalManager.modals.*;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -48,8 +48,6 @@ public class ModalManager extends ListenerAdapter {
Optional<DiscordModal> first = modals.stream()
.filter(discordModal -> discordModal.getModalId().equalsIgnoreCase(modalId))
.findFirst();
if (first.isEmpty())
return null;
return first.get().getModal();
return first.map(DiscordModal::getModal).orElse(null);
}
}

View File

@ -5,16 +5,17 @@ import com.alttd.database.queries.commandOutputChannels.OutputType;
import com.alttd.modalManager.DiscordModal;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.label.Label;
import net.dv8tion.jda.api.components.textinput.TextInput;
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
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.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import java.awt.*;
@ -87,42 +88,42 @@ public class ModalCrateItem extends DiscordModal {
@Override
public Modal getModal() {
TextInput item = TextInput.create("item", "Item", TextInputStyle.SHORT)
TextInput item = TextInput.create("item", TextInputStyle.SHORT)
.setPlaceholder("Bone")
.setRequiredRange(1, 32)
.setRequired(true)
.build();
TextInput itemName = TextInput.create("item_name", "Item Name", TextInputStyle.SHORT)
TextInput itemName = TextInput.create("item_name", TextInputStyle.SHORT)
.setPlaceholder("Scruff's Bone")
.setRequiredRange(1, 32)
.setRequired(true)
.build();
TextInput lore = TextInput.create("lore", "Lore", TextInputStyle.PARAGRAPH)
TextInput lore = TextInput.create("lore", TextInputStyle.PARAGRAPH)
.setPlaceholder("A bone owned by the Altitude Mascot")
.setRequiredRange(1, 256)
.setRequired(true)
.build();
TextInput enchants = TextInput.create("enchants", "Enchants", TextInputStyle.PARAGRAPH)
TextInput enchants = TextInput.create("enchants", TextInputStyle.PARAGRAPH)
.setPlaceholder("Unbreaking 1")
.setRequiredRange(1, 256)
.setRequired(false)
.build();
TextInput explanation = TextInput.create("explanation", "The explanation behind your item", TextInputStyle.PARAGRAPH)
TextInput explanation = TextInput.create("explanation", TextInputStyle.PARAGRAPH)
.setPlaceholder("Scruff loves strong bones")
.setRequiredRange(1, 2000)
.setRequired(false)
.build();
return Modal.create(getModalId(), "Crate Item Suggestion")
.addActionRow(item)
.addActionRow(itemName)
.addActionRow(lore)
.addActionRow(enchants)
.addActionRow(explanation)
.addComponents(Label.of("Item", item))
.addComponents(Label.of("Item name", itemName))
.addComponents(Label.of("Lore", lore))
.addComponents(Label.of("Enchants", enchants))
.addComponents(Label.of("The explanation behind your item", explanation))
.build();
}

View File

@ -7,17 +7,18 @@ import com.alttd.modalManager.DiscordModal;
import com.alttd.util.UserToMessageTracker;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.components.label.Label;
import net.dv8tion.jda.api.components.textinput.TextInput;
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.RoleAction;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
@ -93,10 +94,15 @@ public class ModalCreateEvent extends DiscordModal {
.build();
Button eventButton = buttonManager.getButtonFor("event_button");
if (eventButton == null) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "Unable to find event button"))
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
try (MessageCreateData build = new MessageCreateBuilder()
.setEmbeds(messageEmbed)
.setActionRow(eventButton)
.setComponents(ActionRow.of(eventButton))
.build()) {
Guild guild = message.getGuild();
@ -129,14 +135,15 @@ public class ModalCreateEvent extends DiscordModal {
@Override
public Modal getModal() {
String currentTimestamp = String.valueOf(Instant.now().getEpochSecond());
TextInput time = TextInput.create("time", "Epoch time, see https://epochconverter.com/", TextInputStyle.SHORT)
TextInput time = TextInput.create("time", TextInputStyle.SHORT)
.setValue("Epoch time, see https://epochconverter.com/")
.setPlaceholder(currentTimestamp)
.setMinLength(currentTimestamp.length())
.setMaxLength(currentTimestamp.length() + 1)
.setRequired(true)
.build();
TextInput title = TextInput.create("title", "Event title", TextInputStyle.SHORT)
TextInput title = TextInput.create("title", TextInputStyle.SHORT)
.setPlaceholder("The title for your event")
.setMinLength(5)
.setMaxLength(128)
@ -144,7 +151,7 @@ public class ModalCreateEvent extends DiscordModal {
.build();
return Modal.create(getModalId(), "Create an event")
.addComponents(ActionRow.of(title), ActionRow.of(time))
.addComponents(Label.of("Event title", title), Label.of("time", time))
.build();
}
}

View File

@ -5,16 +5,17 @@ import com.alttd.database.queries.commandOutputChannels.OutputType;
import com.alttd.modalManager.DiscordModal;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.label.Label;
import net.dv8tion.jda.api.components.textinput.TextInput;
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
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.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
@ -85,35 +86,35 @@ public class ModalEvidence extends DiscordModal {
@Override
public Modal getModal() {
TextInput user = TextInput.create("user", "User", TextInputStyle.SHORT)
TextInput user = TextInput.create("user", TextInputStyle.SHORT)
.setPlaceholder("username/id")
.setRequiredRange(1, 256)
.setRequired(true)
.build();
TextInput punishmentType = TextInput.create("punishment-type", "Punishment Type", TextInputStyle.SHORT)
TextInput punishmentType = TextInput.create("punishment-type", TextInputStyle.SHORT)
.setPlaceholder("punishment type")
.setRequiredRange(3, 256)
.setRequired(true)
.build();
TextInput reason = TextInput.create("reason", "Reason", TextInputStyle.SHORT)
TextInput reason = TextInput.create("reason", TextInputStyle.SHORT)
.setPlaceholder("punishment reason")
.setRequiredRange(10, 256)
.setRequired(true)
.build();
TextInput evidence = TextInput.create("evidence", "Evidence", TextInputStyle.PARAGRAPH)
TextInput evidence = TextInput.create("evidence", TextInputStyle.PARAGRAPH)
.setPlaceholder("evidence")
.setRequiredRange(10, 1024)
.setRequired(true)
.build();
return Modal.create(getModalId(), "Evidence")
.addActionRow(user)
.addActionRow(punishmentType)
.addActionRow(reason)
.addActionRow(evidence)
.addComponents(Label.of("User", user))
.addComponents(Label.of("Punishment Type", punishmentType))
.addComponents(Label.of("Reason", reason))
.addComponents(Label.of("Evidence", evidence))
.build();
}
}

View File

@ -7,17 +7,17 @@ import com.alttd.database.queries.QueriesReminders.ReminderType;
import com.alttd.modalManager.DiscordModal;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.components.label.Label;
import net.dv8tion.jda.api.components.textinput.TextInput;
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.utils.TimeUtil;
import java.util.Date;
import java.util.HashMap;
@ -94,7 +94,7 @@ public class ModalRemindMe extends DiscordModal {
event.deferReply().setEphemeral(true).queue(defer -> {
ButtonRemindMeConfirm.putReminder(userId, defer, reminder);
defer.editOriginalEmbeds(messageEmbed).queue(message ->
defer.editOriginalComponents().setActionRow(remindMeConfirm, remindMeCancel)
defer.editOriginalComponents(ActionRow.of(remindMeConfirm, remindMeCancel))
.queue(RestAction.getDefaultSuccess(), Util::handleFailure));
});
}
@ -119,21 +119,22 @@ public class ModalRemindMe extends DiscordModal {
@Override
public Modal getModal() {
TextInput title = TextInput.create("title", "Title", TextInputStyle.SHORT)
TextInput title = TextInput.create("title", TextInputStyle.SHORT)
.setValue("Title")
.setPlaceholder("reminder title")
.setRequiredRange(1, 256)
.setRequired(true)
.build();
TextInput desc = TextInput.create("description", "Description", TextInputStyle.PARAGRAPH)
TextInput desc = TextInput.create("description", TextInputStyle.PARAGRAPH)
.setPlaceholder("optional reminder description")
.setRequiredRange(1, 4000)
.setRequired(false)
.build();
return Modal.create(getModalId(), "Remind Me")
.addActionRow(title)
.addActionRow(desc)
.addComponents(Label.of("Title", title))
.addComponents(Label.of("Description", desc))
.build();
}

View File

@ -3,13 +3,14 @@ package com.alttd.modalManager.modals;
import com.alttd.modalManager.DiscordModal;
import com.alttd.util.UserToMessageTracker;
import com.alttd.util.Util;
import net.dv8tion.jda.api.components.label.Label;
import net.dv8tion.jda.api.components.textinput.TextInput;
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
public class ModalReplySuggestion extends DiscordModal {
@ -67,14 +68,14 @@ public class ModalReplySuggestion extends DiscordModal {
@Override
public Modal getModal() {
TextInput body = TextInput.create("response", "Response", TextInputStyle.PARAGRAPH)
TextInput body = TextInput.create("response", TextInputStyle.PARAGRAPH)
.setPlaceholder("Response...")
.setRequiredRange(10, 1024)
.setRequired(true)
.build();
return Modal.create(getModalId(), "Suggestion Response")
.addActionRow(body)
.addComponents(Label.of("Response", body))
.build();
}
}

View File

@ -6,6 +6,11 @@ import com.alttd.database.queries.commandOutputChannels.OutputType;
import com.alttd.modalManager.DiscordModal;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.components.label.Label;
import net.dv8tion.jda.api.components.textinput.TextInput;
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
@ -13,11 +18,8 @@ import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
@ -97,7 +99,7 @@ public class ModalSuggestion extends DiscordModal {
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure);
return;
}
message.editMessageComponents().setActionRow(suggestionReviewAccept, suggestionReviewDeny).queue(
message.editMessageComponents(ActionRow.of(suggestionReviewAccept, suggestionReviewDeny)).queue(
success -> replyCallbackAction.setEmbeds(Util.genericSuccessEmbed("Success", "Your suggestion was submitted for review!"), suggestionToPlayer)
.setEphemeral(true).queue(RestAction.getDefaultSuccess(), Util::handleFailure),
failure -> replyCallbackAction.setEmbeds(Util.genericErrorEmbed("Error", "Couldn't prepare your suggestion for review."), suggestionToPlayer)
@ -106,21 +108,21 @@ public class ModalSuggestion extends DiscordModal {
@Override
public Modal getModal() {
TextInput title = TextInput.create("title", "Title", TextInputStyle.SHORT)
TextInput title = TextInput.create("title", TextInputStyle.SHORT)
.setPlaceholder("Your suggestion in one sentence")
.setRequiredRange(10, 100)
.setRequired(true)
.build();
TextInput body = TextInput.create("body", "Body", TextInputStyle.PARAGRAPH)
TextInput body = TextInput.create("body", TextInputStyle.PARAGRAPH)
.setPlaceholder("Suggestion...")
.setRequiredRange(30, 1024)
.setRequired(true)
.build();
return Modal.create(getModalId(), "Suggestion Form")
.addActionRow(title)
.addActionRow(body)
.addComponents(Label.of("Title", title))
.addComponents(Label.of("Body", body))
.build();
}
}

View File

@ -5,14 +5,15 @@ import com.alttd.util.Pair;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.components.label.Label;
import net.dv8tion.jda.api.components.textinput.TextInput;
import net.dv8tion.jda.api.components.textinput.TextInputStyle;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.text.TextInput;
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.requests.restaction.ThreadChannelAction;
import java.awt.*;
@ -25,24 +26,26 @@ public class Request {
public Modal modal(Member member) {
TextInput requestTitle = TextInput
.create("title", title, TextInputStyle.SHORT)
.create("title", TextInputStyle.SHORT)
.setPlaceholder(id)
.setRequired(false)
.build();
TextInput requestMessage = TextInput
.create("request", message, TextInputStyle.PARAGRAPH)
.create("request", TextInputStyle.PARAGRAPH)
.build();
return Modal.create("request:" + id, name)
.addActionRow(requestTitle)
.addActionRow(requestMessage)
.addComponents(Label.of(title, requestTitle))
.addComponents(Label.of(message, requestMessage))
.build();
}
public void createThread(Member member, String title, String request) {
TextChannel channel = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID).getTextChannelById(getChannel());
if (title == null || title.isEmpty()) title = id;
if (title == null || title.isEmpty()) {
title = id;
}
String finalTitle = title;
ThreadChannelAction threadChannelAction = channel.createThreadChannel(finalTitle);
threadChannelAction.queue(threadChannel -> {
@ -54,20 +57,21 @@ public class Request {
}
public void sendEmbed(ThreadChannel channel, String title, String request) {
// Pair<EmbedBuilder, ActionRow> pair = getRequestEmbed(channel.getId(), title, request);
// Pair<EmbedBuilder, ActionRow> pair = getRequestEmbed(channel.getId(), title, request);
// pairs are not really possible here :(
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle(title)
.addField(getName(), request, false)
.setColor(new Color(41, 43, 47));
channel.sendMessageEmbeds(embedBuilder.build()).queue(message1 ->
channel.editMessageEmbedsById(message1.getId(), embedBuilder.build())
.setActionRow(
Button.primary("request:" + getId() + ":" + channel.getId() + ":" + message1.getId() + ":progress", "in progress"),
Button.success("request:" + getId() + ":" + channel.getId() + ":" + message1.getId() + ":complete", "complete"),
Button.danger("request:" + getId() + ":" + channel.getId() + ":" + message1.getId() + ":denied", "denied")
).queue()
);
channel.sendMessageEmbeds(embedBuilder.build())
.queue(message1 ->
channel.editMessageEmbedsById(message1.getId(), embedBuilder.build())
.queue(message2 -> channel.editMessageComponentsById(message1.getId(), ActionRow.of(
Button.primary("request:" + getId() + ":" + channel.getId() + ":" + message1.getId() + ":progress", "in progress"),
Button.success("request:" + getId() + ":" + channel.getId() + ":" + message1.getId() + ":complete", "complete"),
Button.danger("request:" + getId() + ":" + channel.getId() + ":" + message1.getId() + ":denied", "denied")
)).queue())
);
}
public Pair<EmbedBuilder, ActionRow> getRequestEmbed(String channellId, String title, String request) {
@ -80,7 +84,7 @@ public class Request {
Button.primary("request:" + getId() + ":" + channellId + ":progress", "in progress"),
Button.success("request:" + getId() + ":" + channellId + ":complete", "complete"),
Button.danger("request:" + getId() + ":" + channellId + ":denied", "denied")
);
);
return new Pair<>(embedBuilder, actionRow);
}

View File

@ -2,22 +2,28 @@ package com.alttd.request;
import com.alttd.AltitudeBot;
import com.alttd.util.Pair;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.selections.StringSelectMenu;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
import java.awt.*;
@Slf4j
public class RequestManager {
public static void init() {
RequestConfig.reload();
if (RequestConfig.REQUEST_MESSAGE == null || RequestConfig.REQUEST_MESSAGE.isEmpty())
if (RequestConfig.REQUEST_MESSAGE == null || RequestConfig.REQUEST_MESSAGE.isEmpty()) {
sendRequestMessage();
}
}
public static Pair<EmbedBuilder, StringSelectMenu.Builder> getRequestEmbed() {
@ -36,20 +42,39 @@ public class RequestManager {
}
public static void sendRequestMessage() {
TextChannel channel = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID).getTextChannelById(RequestConfig.REQUEST_CHANNEL);
Guild guildById = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID);
if (guildById == null) {
log.error("Unable to find guild with id {} for sendRequestMessage", RequestConfig.REQUEST_GUILD_ID);
return;
}
TextChannel channel = guildById
.getTextChannelById(RequestConfig.REQUEST_CHANNEL);
if (channel == null) {
log.error("Unable to find channel with id {} for sendRequestMessage", RequestConfig.REQUEST_CHANNEL);
return;
}
Pair<EmbedBuilder, StringSelectMenu.Builder> pair = getRequestEmbed();
channel.sendMessageEmbeds(pair.getValue0().build()).setActionRow(
pair.getValue1().build()
).queue(m -> RequestConfig.setRequestMessage(m.getId()));
channel.sendMessageEmbeds(pair.getValue0().build())
.queue(message -> message.editMessageComponents(ActionRow.of(pair.getValue1().build()))
.queue(m -> RequestConfig.setRequestMessage(m.getId())));
}
public static void updateRequestMessage() {
TextChannel channel = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID).getTextChannelById(RequestConfig.REQUEST_CHANNEL);
Guild guildById = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID);
if (guildById == null) {
log.error("Unable to find guild with id for updateRequestMessage {}", RequestConfig.REQUEST_GUILD_ID);
return;
}
TextChannel channel = guildById
.getTextChannelById(RequestConfig.REQUEST_CHANNEL);
if (channel == null) {
log.error("Unable to find channel with id {} for updateRequestMessage", RequestConfig.REQUEST_CHANNEL);
return;
}
Pair<EmbedBuilder, StringSelectMenu.Builder> pair = getRequestEmbed();
channel.editMessageEmbedsById(RequestConfig.REQUEST_MESSAGE, pair.getValue0().build())
.setActionRow(
pair.getValue1().build()
).queue(m -> RequestConfig.setRequestMessage(m.getId()));
.queue(m -> m.editMessageComponents(ActionRow.of(pair.getValue1().build()))
.queue(m2 -> RequestConfig.setRequestMessage(m2.getId())));
}
public static Request getRequestById(String id) {
@ -59,7 +84,7 @@ public class RequestManager {
public static void onStringSelectInteraction(StringSelectInteractionEvent event) {
String[] actions = event.getComponentId().split(":");
if (actions[1].equals("create")) {
String[] selection = event.getSelectedOptions().get(0).getValue().split(":");
String[] selection = event.getSelectedOptions().getFirst().getValue().split(":");
if (selection[0].equals("request") && selection[1].equals("open")) {
String id = selection[2];
event.replyModal(getRequestById(id).modal(event.getMember())).queue();
@ -88,15 +113,43 @@ public class RequestManager {
case "denied" -> {
// TODO open a new modal to input a reason?
// could also do this by command?
event.reply("This request has been denied by " + event.getMember().getAsMention()).queue();
ThreadChannel threadChannel = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID).getThreadChannelById(threadId);
Member member = event.getMember();
if (member == null) {
event.reply("This request has been denied by an unknown member").queue();
} else {
event.reply("This request has been denied by " + member.getAsMention()).queue();
}
Guild guildById = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID);
if (guildById == null) {
log.error("Unable to find guild with id {} for denied", RequestConfig.REQUEST_GUILD_ID);
return;
}
ThreadChannel threadChannel = guildById.getThreadChannelById(threadId);
if (threadChannel == null) {
log.error("Unable to find thread channel with id {} for denied", threadId);
return;
}
threadChannel.getManager().setArchived(true).setLocked(true).queue();
}
case "complete" -> {
// TODO open a new modal to input a reason?
// could also do this by command?
event.reply("This request has been completed by " + event.getMember().getAsMention()).queue();
ThreadChannel threadChannel = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID).getThreadChannelById(threadId);
Member member = event.getMember();
if (member == null) {
event.reply("This request has been completed by an unknown member").queue();
} else {
event.reply("This request has been completed by " + member.getAsMention()).queue();
}
Guild guildById = AltitudeBot.getInstance().getJDA().getGuildById(RequestConfig.REQUEST_GUILD_ID);
if (guildById == null) {
log.error("Unable to find guild with id {} for complete", RequestConfig.REQUEST_GUILD_ID);
return;
}
ThreadChannel threadChannel = guildById.getThreadChannelById(threadId);
if (threadChannel == null) {
log.error("Unable to find thread channel with id {} for complete", threadId);
return;
}
threadChannel.getManager().setArchived(true).setLocked(true).queue();
}
case "progress" -> {

View File

@ -1,9 +1,8 @@
package com.alttd.selectMenuManager;
import net.dv8tion.jda.api.events.interaction.component.GenericSelectMenuInteractionEvent;
import net.dv8tion.jda.api.components.selections.SelectMenu;
import net.dv8tion.jda.api.components.selections.SelectOption;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
import java.util.List;

View File

@ -1,7 +1,6 @@
package com.alttd.selectMenuManager;
import com.alttd.selectMenuManager.selectMenus.SelectMenuAuction;
import net.dv8tion.jda.api.events.interaction.component.GenericSelectMenuInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.jetbrains.annotations.NotNull;
@ -20,7 +19,7 @@ public class SelectMenuManager extends ListenerAdapter {
@Override
public void onStringSelectInteraction(@NotNull StringSelectInteractionEvent event) {
String selectMenuId = event.getSelectMenu().getId();
String selectMenuId = event.getSelectMenu().getCustomId();
Optional<DiscordSelectMenu> first = buttons.stream()
.filter(discordModal -> discordModal.getSelectMenuId().equalsIgnoreCase(selectMenuId))
.findFirst();

View File

@ -8,18 +8,18 @@ import com.alttd.selectMenuManager.DiscordSelectMenu;
import com.alttd.selectMenuManager.SelectMenuManager;
import com.alttd.util.Util;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.selections.SelectMenu;
import net.dv8tion.jda.api.components.selections.SelectOption;
import net.dv8tion.jda.api.components.selections.StringSelectMenu;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class SelectMenuAuction extends DiscordSelectMenu {
@ -55,7 +55,9 @@ public class SelectMenuAuction extends DiscordSelectMenu {
return;
}
List<SelectOption> collect = event.getInteraction().getSelectedOptions().stream().filter(opt -> !opt.isDefault()).collect(Collectors.toList());
List<SelectOption> collect = event.getInteraction().getSelectedOptions().stream()
.filter(opt -> !opt.isDefault())
.toList();
if (collect.isEmpty()) {
event.replyEmbeds(Util.genericErrorEmbed("Error", "Received default input"))
.setEphemeral(true).queue();
@ -67,7 +69,7 @@ public class SelectMenuAuction extends DiscordSelectMenu {
return;
}
SelectOption selectOption = collect.get(0);
SelectOption selectOption = collect.getFirst();
String value = selectOption.getValue();
int bid;
try {
@ -132,7 +134,8 @@ public class SelectMenuAuction extends DiscordSelectMenu {
}
replyCallbackAction.setEmbeds(Util.genericSuccessEmbed("Success", "You successfully made the first bid on this item ($" + Util.formatNumber(currentBid) + ")!"))
.queue();
success.editMessageComponents().setActionRow(auction.getSelectMenu(selectMenuManager, true)).queue();
success.editMessageComponents(ActionRow.of(auction.getSelectMenu(selectMenuManager, true)))
.queue();
},
error -> replyCallbackAction.setEmbeds(Util.genericErrorEmbed("Error", "Unable to finish your bid")).queue())
);
@ -144,7 +147,7 @@ public class SelectMenuAuction extends DiscordSelectMenu {
.setEphemeral(true).queue();
return null;
}
return embeds.get(0);
return embeds.getFirst();
}
@Override