diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 659eb6af..f0c28feb 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -43,7 +43,7 @@ jobs: - name: Setup Java Version uses: actions/setup-java@v1 with: - java-version: 17 + java-version: 21 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/jitpack.yml b/jitpack.yml index 2125e583..fb967c48 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,5 +1,5 @@ before_install: - - sdk install java 17.0.4-open - - sdk use java 17.0.4-open + - sdk install java 21-open + - sdk use java 21-open jdk: - - openjdk17 + - openjdk21 diff --git a/pom.xml b/pom.xml index 0deec66b..bd3da7cc 100644 --- a/pom.xml +++ b/pom.xml @@ -9,9 +9,9 @@ b-1.1 - 17 - 17 - 17 + 21 + 21 + 21 @@ -59,18 +59,11 @@ - jitpack.io https://jitpack.io - - - dv8tion - m2-dv8tion - https://m2.dv8tion.net/releases - @@ -122,8 +115,8 @@ com.github.seailz - databaseapi - 2.3 + Database4J + 02941e7bef @@ -144,7 +137,7 @@ com.github.codahale xsalsa20poly1305 - v0.10.1 + v0.10.1 diff --git a/src/main/java/com/seailz/discordjar/action/interaction/followup/InteractionFollowupAction.java b/src/main/java/com/seailz/discordjar/action/interaction/followup/InteractionFollowupAction.java index e2a6fcf0..52c3215f 100644 --- a/src/main/java/com/seailz/discordjar/action/interaction/followup/InteractionFollowupAction.java +++ b/src/main/java/com/seailz/discordjar/action/interaction/followup/InteractionFollowupAction.java @@ -1,6 +1,7 @@ package com.seailz.discordjar.action.interaction.followup; import com.seailz.discordjar.DiscordJar; +import com.seailz.discordjar.action.interaction.MessageInteractionCallbackAction; import com.seailz.discordjar.model.component.DisplayComponent; import com.seailz.discordjar.model.embed.Embeder; import com.seailz.discordjar.model.interaction.callback.InteractionHandler; @@ -12,6 +13,7 @@ import com.seailz.discordjar.utils.rest.Response; import org.springframework.web.bind.annotation.RequestMethod; +import java.io.File; import java.util.HashMap; import java.util.List; @@ -139,6 +141,21 @@ public InteractionFollowupAction addEmbed(Embeder embed) { return this; } + public InteractionFollowupAction addFile(File file) { + this.getReply().addFile(file); + return this; + } + + public InteractionFollowupAction addFiles(File... files) { + this.getReply().addFiles(files); + return this; + } + + public InteractionFollowupAction addFiles(List files) { + this.getReply().addFiles(files); + return this; + } + public InteractionMessageResponse getReply() { return reply; } @@ -146,7 +163,7 @@ public InteractionMessageResponse getReply() { public Response run() { Response response = new Response<>(); try { - new DiscordRequest( + DiscordRequest req = new DiscordRequest( getReply().compile(), new HashMap<>(), URLS.POST.INTERACTIONS.FOLLOWUP @@ -155,7 +172,16 @@ public Response run() { discordJar, URLS.POST.INTERACTIONS.FOLLOWUP, RequestMethod.POST - ).invoke(); + ); + + if (getReply().useFiles()) { + List files = getReply().getFiles(); + File[] filesArray = new File[files.size()]; + filesArray = files.toArray(filesArray); + req.invokeWithFiles(filesArray); + } else { + req.invoke(); + } response.complete(InteractionHandler.from(token, id, discordJar)); } catch (DiscordRequest.UnhandledDiscordAPIErrorException e) { response.completeError(new Response.Error(e.getCode(), e.getMessage(), e.getBody())); diff --git a/src/main/java/com/seailz/discordjar/events/EventDispatcher.java b/src/main/java/com/seailz/discordjar/events/EventDispatcher.java index 2cc51adf..a7d13666 100644 --- a/src/main/java/com/seailz/discordjar/events/EventDispatcher.java +++ b/src/main/java/com/seailz/discordjar/events/EventDispatcher.java @@ -69,7 +69,7 @@ public void addListener(DiscordListener... listeners) { */ public void dispatchEvent(Event event, Class type, DiscordJar djv) { if (event == null) return; - new Thread(() -> { + DiscordJarThreadAllocator.requestVirtualThread(() -> { long start = System.currentTimeMillis(); List listenersForEventType = listenersByEventType.get(type); if (listenersForEventType == null) { @@ -91,7 +91,7 @@ public void dispatchEvent(Event event, Class type, DiscordJar d } method.setAccessible(true); - DiscordJarThreadAllocator.requestThread(() -> { + DiscordJarThreadAllocator.requestVirtualThread(() -> { try { method.invoke(listenerMethodPair.listener, event); } catch (IllegalAccessException | ArrayIndexOutOfBoundsException e) { @@ -104,6 +104,6 @@ public void dispatchEvent(Event event, Class type, DiscordJar d } }, "djar--EventDispatcher-inner"); } - }, "djar--EventDispatcher").start(); + }, "djar--EventDispatcher"); } } \ No newline at end of file diff --git a/src/main/java/com/seailz/discordjar/gateway/GatewayFactory.java b/src/main/java/com/seailz/discordjar/gateway/GatewayFactory.java index 1a506540..a0e0bd1d 100644 --- a/src/main/java/com/seailz/discordjar/gateway/GatewayFactory.java +++ b/src/main/java/com/seailz/discordjar/gateway/GatewayFactory.java @@ -13,6 +13,7 @@ import com.seailz.discordjar.utils.URLS; import com.seailz.discordjar.utils.rest.DiscordRequest; import com.seailz.discordjar.utils.rest.DiscordResponse; +import com.seailz.discordjar.utils.thread.DiscordJarThreadAllocator; import com.seailz.discordjar.voice.model.VoiceServerUpdate; import com.seailz.discordjar.voice.model.VoiceState; import com.seailz.discordjar.ws.ExponentialBackoffLogic; @@ -109,7 +110,7 @@ public GatewayFactory(DiscordJar discordJar, boolean debug, int shardId, int num ExponentialBackoffLogic backoffReconnectLogic = new ExponentialBackoffLogic(); socket.setReEstablishConnection(backoffReconnectLogic.getFunction()); backoffReconnectLogic.setAttemptReconnect((c) -> { - new Thread(discordJar::clearMemberCaches, "djar--clearing-member-caches").start(); + DiscordJarThreadAllocator.requestVirtualThread(discordJar::clearMemberCaches, "djar--clearing-member-caches"); return !shouldResume; }); @@ -352,7 +353,7 @@ private void handleDispatched(JSONObject payload) { } if (eventClass.equals(CommandInteractionEvent.class)) return; - new Thread(() -> { + DiscordJarThreadAllocator.requestVirtualThread(() -> { Event event; try { event = eventClass.getConstructor(DiscordJar.class, long.class, JSONObject.class) @@ -373,7 +374,7 @@ private void handleDispatched(JSONObject payload) { if (debug) { logger.info("[DISCORD.JAR - DEBUG] Event dispatched: " + eventClass.getName()); } - }, "djar--event-dispatch-gw").start(); + }, "djar--event-dispatch-gw"); if (Objects.requireNonNull(DispatchedEvents.getEventByName(payload.getString("t"))) == DispatchedEvents.READY) { this.sessionId = payload.getJSONObject("d").getString("session_id"); diff --git a/src/main/java/com/seailz/discordjar/utils/thread/DiscordJarThreadAllocator.java b/src/main/java/com/seailz/discordjar/utils/thread/DiscordJarThreadAllocator.java index f87b7ec8..49f8accd 100644 --- a/src/main/java/com/seailz/discordjar/utils/thread/DiscordJarThreadAllocator.java +++ b/src/main/java/com/seailz/discordjar/utils/thread/DiscordJarThreadAllocator.java @@ -31,6 +31,28 @@ public static Thread requestThread(Runnable runnable, String name) { return thread; } + public static Thread requestVirtualThread(Runnable runnable, String name) { + // First, let's check if we can actually use a virtual thread due to the JDK version. + int javaRelease; + try { + javaRelease = Integer.parseInt(System.getProperty("java.specification.version")); + } catch (NumberFormatException ex) { + Logger.getLogger("discord.jar-threading") + .warning("Could not parse java.specification.version, falling back to normal threads. This is usually a bug, so please report the following string to the discord.jar developers: " + System.getProperty("java.specification.version")); + return requestThread(runnable, name); + } + if (javaRelease < 21) { + Logger.getLogger("discord.jar-threading") + .warning("discord.jar virtual threads are only supported on JDK 21 and above, falling back to normal threads. It's recommended, if possible, that you upgrade your JDK to 21 or above."); + return requestThread(runnable, name); + } + + Thread virtualThread = Thread.ofVirtual() + .start(runnable); + virtualThread.setName(name); + return virtualThread; + } + private static void printThreads() { ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();