Compare commits

...
24 Commits
Author SHA1 Message Date
stijn 59065dddc8 Use @Slf4j in ReminderScheduler and Reminder, convert null checks to Optional, and enhance logging for error handling and unexpected channel types. 2026-07-12 22:24:03 +02:00
stijn cbe13d3033 Update Gradle wrapper to 9.6.1, upgrade dependencies (Spring Boot 4.1.0, JDA 6.5.0, and others), refine gradlew script, and adjust build configuration for compatibility. 2026-07-12 22:05:09 +02:00
stijn 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
stijn b0d3498d1c Add .queue() to embed action in CommandSyncNitro for proper execution 2025-11-08 20:48:56 +01:00
stijn 1bd6602421 Add .queue() to embed action in CommandSyncNitro for proper execution 2025-11-08 20:29:14 +01:00
stijn 7e26aba4ab Add .queue() to embed action in CommandSyncNitro for proper execution 2025-11-08 20:28:54 +01:00
stijn 47eb88cbae Use Lombok's @Slf4j in CommandSyncNitro and add logging for database changes during member checks. 2025-11-08 20:24:49 +01:00
stijn a0b3d2167a Add CommandSyncNitro for synchronizing Nitro roles and update related database queries. 2025-11-08 20:24:07 +01:00
stijn 2c1088ef2e Update from v5 -> v6 for JDA 2025-11-08 19:35:28 +01:00
stijn 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
stijn e947275409 Update CommandSeen: replace "grove" with "bayou" in valid servers, switch to InteractionContextType.GUILD. 2025-09-11 22:11:36 +02:00
stijn 0960795d40 Remove redundant jar task configuration in build.gradle.kts. 2025-08-08 23:31:57 +02:00
stijn 7863b3f62d Add AutoThread listener for creating threads in specific channels. 2025-08-08 22:38:05 +02:00
stijn 003c75c391 Replace Logger with Lombok's @Slf4j annotation in ContactEndpoint and update log method calls. 2025-08-08 21:01:34 +02:00
auto 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
auto 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
auto 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
auto 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
auto 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
auto 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
auto 8a65c27bac Add command for managing staff join dates
Implemented `CommandStaffJoinDate` to allow viewing and setting staff join dates. Included methods in `QueriesStaffJoinDate` for database interactions and defined the `JoinDate` record to encapsulate join date information.
2024-08-25 19:39:43 +02:00
auto cbf51f3fc8 Added Jenkins file
Added Jenkins file to automate builds
2024-08-07 00:26:11 +02:00
auto bd9ecc2677 Added Jenkins file
Added Jenkins file to automate builds
2024-08-07 00:25:57 +02:00
auto 0e0db7cb17 Added Jenkins file
Added Jenkins file to automate builds
2024-08-07 00:25:19 +02:00
65 changed files with 866 additions and 302 deletions
Vendored
+2 -2
View File
@@ -3,7 +3,7 @@ pipeline {
stages {
stage('Gradle') {
steps {
sh './gradlew build'
sh 'bash ./gradlew shadowJar'
}
}
stage('Archive') {
@@ -17,4 +17,4 @@ pipeline {
}
}
}
}
}
+28 -24
View File
@@ -1,9 +1,10 @@
plugins {
id("java")
id("com.github.johnrengelman.shadow") version "7.1.0"
id("org.springframework.boot") version("4.1.0")
id("io.spring.dependency-management") version "1.1.5"
id("maven-publish")
id("org.springframework.boot") version("2.7.8")
id("com.gradleup.shadow") version "9.5.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.5.0") {
exclude("opus-java") // exclude audio
}
// MySQL
implementation("mysql:mysql-connector-java:8.0.33")
implementation("com.mysql:mysql-connector-j:9.7.0")
// 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.5.1")
implementation("org.apache.poi:poi-ooxml:5.5.1")
// Other stuff?
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor("org.projectlombok:lombok:1.18.24")
compileOnly("org.projectlombok:lombok:1.18.46")
annotationProcessor("org.projectlombok:lombok:1.18.46")
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:4.1.0")
implementation("org.springframework.boot:spring-boot-starter-validation:4.1.0")
implementation("com.google.code.gson:gson:2.14.0")
testImplementation(platform("org.junit:junit-bom:6.1.1"))
testImplementation("org.junit.jupiter:junit-jupiter")
}
Binary file not shown.
+3 -1
View File
@@ -1,7 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+9 -10
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,10 +15,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
# gradlew start up script for POSIX generated by Gradle.
#
# Important for running:
#
@@ -27,7 +29,7 @@
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
# ksh gradlew
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -112,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -170,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -203,15 +203,14 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
Vendored
+24 -34
View File
@@ -13,16 +13,18 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem gradlew startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Set local scope for the variables, and ensure extensions are enabled
setlocal EnableExtensions
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@@ -43,13 +45,13 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
"%COMSPEC%" /c exit 1
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
@@ -57,36 +59,24 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
"%COMSPEC%" /c exit 1
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
@rem Execute gradlew
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
:exitWithErrorLevel
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
"%COMSPEC%" /c exit %ERRORLEVEL%
+1 -1
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,
@@ -0,0 +1,6 @@
package com.alttd.DTO;
import java.time.Instant;
public record JoinDate (long userId, Instant joinDate){
}
@@ -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);
}
}
@@ -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 {
@@ -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();
@@ -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.*;
@@ -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
@@ -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;
@@ -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;
@@ -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 {
@@ -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;
@@ -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;
@@ -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.*;
@@ -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),
@@ -55,6 +56,7 @@ public class CommandManager extends ListenerAdapter {
new CommandSoftLock(jda, this, lockedChannel),
new CommandDataSuggestions(jda, this),
new CommandAuction(jda, this, selectMenuManager),
new CommandStaffJoinDate(jda, this),
new CommandBal());
}
@@ -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)
@@ -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;
});
}
@@ -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());
}
@@ -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());
}
@@ -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());
}
@@ -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());
}
@@ -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());
}
@@ -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());
}
@@ -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());
@@ -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());
}
@@ -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());
}
@@ -0,0 +1,122 @@
package com.alttd.commandManager.commands;
import com.alttd.DTO.JoinDate;
import com.alttd.commandManager.CommandManager;
import com.alttd.commandManager.DiscordCommand;
import com.alttd.database.queries.QueriesStaffJoinDate;
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.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;
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 java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class CommandStaffJoinDate extends DiscordCommand {
private final CommandData commandData;
public CommandStaffJoinDate(JDA jda, CommandManager commandManager) {
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))
.setContexts(InteractionContextType.GUILD);
Util.registerCommand(commandManager, jda, commandData, getName());
}
@Override
public String getName() {
return "staff-join-date";
}
@Override
public void execute(SlashCommandInteractionEvent event) {
event.deferReply(true).queue(interactionHook -> processCommand(event, interactionHook));
}
private void processCommand(SlashCommandInteractionEvent event, InteractionHook interactionHook) {
OptionMapping staff = event.getOption("staff");
if (staff == null) {
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();
return;
}
OptionMapping option = event.getOption("join-time");
if (option == null) {
interactionHook.editOriginalEmbeds(getStaffEmbed(member.getIdLong())).queue();
return;
}
long time = option.getAsLong();
Instant instant = Instant.ofEpochSecond(time);
if (instant.isAfter(Instant.now())) {
interactionHook.editOriginalEmbeds(Util.genericErrorEmbed("Invalid time", "The time must be in the past")).queue();
return;
}
QueriesStaffJoinDate.setJoinDate(member.getIdLong(), instant);
interactionHook.editOriginalEmbeds(Util.genericSuccessEmbed(
String.format("Set join date for %s", member.getAsMention()),
String.format("Set to <t:%d:R>", instant.getEpochSecond())))
.queue();
}
private MessageEmbed getStaffEmbed(long userId) {
Optional<JoinDate> joinDate = QueriesStaffJoinDate.getJoinDate(userId);
return joinDate.map(date -> new EmbedBuilder()
.setTitle("Join date for %s".formatted(userId))
.setDescription(String.format("<t:%d:R>", date.joinDate().getEpochSecond()))
.build())
.orElseGet(() -> Util.genericErrorEmbed("No join date found", String.format("No join date found for <@%s>", userId)));
}
private MessageEmbed getFullStaffEmbed() {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle("All staff join dates");
List<JoinDate> allJoinDates = QueriesStaffJoinDate.getAllJoinDates();
if (allJoinDates == null || allJoinDates.isEmpty()) {
embedBuilder.setDescription("No staff join dates found.");
} else {
embedBuilder.setDescription(allJoinDates.stream().map(joinDate ->
"<@%d>: <t:%d:R>".formatted(joinDate.userId(), joinDate.joinDate().getEpochSecond()))
.collect(Collectors.joining("\n")));
}
return embedBuilder.build();
}
@Override
public void suggest(CommandAutoCompleteInteractionEvent event) {
event.replyChoiceStrings(List.of()).queue();
}
@Override
public String getHelpMessage() {
return null;
}
@Override
public CommandData getCommandData() {
return commandData;
}
}
@@ -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());
}
@@ -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());
}
@@ -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;
}
}
@@ -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());
}
@@ -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),
@@ -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();
}
@@ -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");
});
@@ -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() {
@@ -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));
}
}
@@ -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));
}
}
@@ -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));
}
@@ -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;
@@ -1,12 +1,15 @@
package com.alttd.database.queries.QueriesReminders;
import com.alttd.util.Logger;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel;
import org.jspecify.annotations.NonNull;
import java.util.Arrays;
import java.util.Optional;
@Slf4j
public record Reminder (int id, String title, String description, long userId, long guildId, long channelId,
long messageId, boolean shouldRepeat, long creationDate, long remindDate, ReminderType reminderType, byte[] data) {
@@ -26,34 +29,35 @@ public record Reminder (int id, String title, String description, long userId, l
reminder.data());
}
public Channel getChannel(JDA jda) {
Guild guildById = getGuild(jda);
if (guildById == null)
return null;
public Optional<Channel> getChannel(JDA jda) {
Optional<Guild> optionalGuild = getGuild(jda);
if (optionalGuild.isEmpty())
return Optional.empty();
Channel channelById = guildById.getTextChannelById(this.channelId);
Guild guild = optionalGuild.get();
Channel channelById = guild.getTextChannelById(this.channelId);
if (channelById == null)
channelById = guildById.getThreadChannelById(this.channelId);
channelById = guild.getThreadChannelById(this.channelId);
if (channelById == null) {
Logger.altitudeLogs.warning("Unable to find text channel for reminder, text channel id: [" + channelId + "]");
return null;
log.warn("Unable to find text channel for reminder, text channel id: [{}]", channelId);
return Optional.empty();
}
return channelById;
return Optional.of(channelById);
}
public Guild getGuild(JDA jda) {
public Optional<Guild> getGuild(JDA jda) {
Guild guildById = jda.getGuildById(guildId);
if (guildById == null) {
Logger.altitudeLogs.warning("Unable to find guild for reminder, guild id: [" + guildId + "]");
return null;
log.warn("Unable to find guild for reminder, guild id: [{}]", guildId);
return Optional.empty();
}
return guildById;
return Optional.of(guildById);
}
@Override
public String toString() {
public @NonNull String toString() {
return "Reminder{" +
"\nid=[" + id + "]" +
"\ntitle=[" + title + "]" +
@@ -0,0 +1,64 @@
package com.alttd.database.queries;
import com.alttd.DTO.JoinDate;
import com.alttd.database.Database;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class QueriesStaffJoinDate {
public static Optional<JoinDate> getJoinDate(long userId) {
String sql = "SELECT date FROM staff_join_date WHERE user_id = ?";
try (PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql)) {
preparedStatement.setLong(1, userId);
ResultSet resultSet = preparedStatement.executeQuery();
if (!resultSet.next())
return Optional.empty();
Instant date = Instant.ofEpochMilli(resultSet.getLong("date"));
if (date == null) {
return Optional.empty();
}
return Optional.of(new JoinDate(userId, date));
} catch (SQLException exception) {
exception.printStackTrace();
return Optional.empty();
}
}
public static void setJoinDate(long userId, Instant date) {
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);
preparedStatement.setLong(2, date.toEpochMilli());
preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static List<JoinDate> getAllJoinDates() {
String sql = "SELECT * FROM staff_join_date";
try (PreparedStatement preparedStatement = Database.getDatabase().getConnection().prepareStatement(sql)) {
ResultSet resultSet = preparedStatement.executeQuery();
List<JoinDate> joinDates = new ArrayList<>();
while (resultSet.next())
joinDates.add(new JoinDate(resultSet.getLong("user_id"), Instant.ofEpochMilli(resultSet.getLong("date"))));
return joinDates;
} catch (SQLException exception) {
exception.printStackTrace();
return null;
}
}
}
@@ -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();
});
}
}
@@ -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);
}
});
}
}
@@ -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);
@@ -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());
}
}
@@ -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();
@@ -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 {
@@ -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);
}
}
@@ -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();
}
@@ -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();
}
}
@@ -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();
}
}
@@ -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();
}
@@ -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();
}
}
@@ -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();
}
}
+24 -20
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);
}
@@ -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" -> {
@@ -4,6 +4,7 @@ import com.alttd.database.queries.QueriesReminders.QueriesReminders;
import com.alttd.database.queries.QueriesReminders.Reminder;
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.entities.Guild;
@@ -20,10 +21,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ReminderScheduler {
private static ReminderScheduler instance = null;
@@ -41,10 +44,11 @@ public class ReminderScheduler {
return;
}
reminders.sort(Comparator.comparingLong(Reminder::remindDate));
if (reminders.size() == 0)
if (reminders.isEmpty()) {
nextReminder = null;
else
nextReminder = reminders.get(0);
} else {
nextReminder = reminders.getFirst();
}
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay(new ReminderRun(), 0, 1, TimeUnit.MINUTES);
@@ -63,19 +67,22 @@ public class ReminderScheduler {
}
reminders.add(reminder);
reminders.sort(Comparator.comparingLong(Reminder::remindDate));
nextReminder = reminders.get(0);
nextReminder = reminders.getFirst();
}
public synchronized void removeReminder(Reminder reminder, boolean removeFromDatabase) {
Logger.altitudeLogs.debug("Removing reminder with messageId: " + reminder.messageId());
reminders.remove(reminder);
reminders.sort(Comparator.comparingLong(Reminder::remindDate));
if (reminders.size() == 0)
if (reminders.isEmpty()) {
nextReminder = null;
else
nextReminder = reminders.get(0);
if (removeFromDatabase)
QueriesReminders.removeReminder(reminder);
} else {
nextReminder = reminders.getFirst();
}
if (!removeFromDatabase) {
return;
}
QueriesReminders.removeReminder(reminder);
}
public synchronized void removeReminder(long messageId) {
@@ -92,13 +99,14 @@ public class ReminderScheduler {
public void run() {
long time = System.currentTimeMillis();
while (nextReminder != null && time > nextReminder.remindDate()) {
Channel channel = nextReminder.getChannel(jda);
if (channel == null) {
Optional<Channel> optionalChannel = nextReminder.getChannel(jda);
if (optionalChannel.isEmpty()) {
Logger.altitudeLogs.warning("Couldn't find channel, unable to run reminder: " + nextReminder.id() +
"\ntitle: [" + nextReminder.title() +
"]\ndescription: [" + nextReminder.description() + "]");
return;
}
Channel channel = optionalChannel.get();
sendEmbed(nextReminder, channel);
if (nextReminder.shouldRepeat()) {
Reminder repeatedReminder = new Reminder(
@@ -127,31 +135,38 @@ public class ReminderScheduler {
.setTitle(reminder.title())
.setDescription(reminder.description())
.appendDescription("\n\nRequested <t:" + TimeUnit.MILLISECONDS.toSeconds(reminder.creationDate()) + ":R>");
Guild guild = reminder.getGuild(jda);
if (guild == null) {
Optional<Guild> optionalGuild = reminder.getGuild(jda);
if (optionalGuild.isEmpty()) {
sendEmbed(reminder, channel, embedBuilder);
return;
}
Guild guild = optionalGuild.get();
guild.retrieveMemberById(reminder.userId()).queue(
member -> sendEmbed(reminder, channel, embedBuilder, member),
failed -> sendEmbed(reminder, channel, embedBuilder));
}
private MessageCreateAction getCreateAction(Channel channel, EmbedBuilder embedBuilder) {
switch (channel.getType()) {
private Optional<MessageCreateAction> getCreateAction(Channel channel, EmbedBuilder embedBuilder) {
return switch (channel.getType()) {
case TEXT, NEWS, FORUM -> {
if (channel instanceof TextChannel textChannel) {
return textChannel.sendMessageEmbeds(embedBuilder.build());
yield Optional.of(textChannel.sendMessageEmbeds(embedBuilder.build()));
}
Logger.altitudeLogs.warning("Received channel that is not a text channel " + channel.getType() + " can't send reminder...");
yield Optional.empty();
}
case GUILD_NEWS_THREAD, GUILD_PUBLIC_THREAD, GUILD_PRIVATE_THREAD -> {
if (channel instanceof ThreadChannel threadChannel) {
return threadChannel.sendMessageEmbeds(embedBuilder.build());
yield Optional.of(threadChannel.sendMessageEmbeds(embedBuilder.build()));
}
Logger.altitudeLogs.warning("Received thread that is not a guild thread " + channel.getType() + " can't send reminder...");
yield Optional.empty();
}
default -> Logger.altitudeLogs.warning("Received unexpected channel type " + channel.getType() + " can't send reminder...");
}
return null;
case PRIVATE, VOICE, GROUP, CATEGORY, STAGE, MEDIA, GUILD_DIRECTORY, UNKNOWN -> {
Logger.altitudeLogs.warning("Received unexpected channel type " + channel.getType() + " can't send reminder...");
yield Optional.empty();
}
};
}
private MessageCreateAction getCreateAction(Channel channel, String text) {
@@ -175,9 +190,11 @@ public class ReminderScheduler {
embedBuilder.setAuthor(member.getEffectiveName(), null, member.getEffectiveAvatarUrl());
switch (reminder.reminderType()) {
case NONE, MANUAL -> {
MessageCreateAction createAction = getCreateAction(channel, embedBuilder);
if (createAction == null)
Optional<MessageCreateAction> optionalCreateAction = getCreateAction(channel, embedBuilder);
if (optionalCreateAction.isEmpty())
return;
MessageCreateAction createAction = optionalCreateAction.get();
createAction.queue(RestAction.getDefaultSuccess(), Util::handleFailure);
}
case APPEAL -> {
@@ -189,12 +206,12 @@ public class ReminderScheduler {
try {
userId = dataInputStream.readLong();
} catch (IOException e) {
e.printStackTrace();
log.error("Failed to read user id from reminder data", e);
} finally {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
log.error("Failed to close data input stream", e);
}
}
MessageCreateAction messageCreateAction = getCreateAction(channel, "<@" + userId + ">");
@@ -210,9 +227,12 @@ public class ReminderScheduler {
private void sendEmbed(Reminder reminder, Channel channel, EmbedBuilder embedBuilder) {
embedBuilder.setAuthor(reminder.userId() + "");
MessageCreateAction createAction = getCreateAction(channel, embedBuilder);
if (createAction == null)
Optional<MessageCreateAction> optionalMessageCreateAction = getCreateAction(channel, embedBuilder);
if (optionalMessageCreateAction.isEmpty()) {
//Already logged
return;
}
MessageCreateAction createAction = optionalMessageCreateAction.get();
createAction.queue(RestAction.getDefaultSuccess(), Util::handleFailure);
}
}
@@ -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;
@@ -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();
@@ -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