From 52875feeabdc9da859255458fe0042b77853d23c Mon Sep 17 00:00:00 2001 From: nateweisz <151496498+nateweisz@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:37:53 -0700 Subject: [PATCH 1/7] Initial work on it --- gateway/build.gradle | 3 +- .../gateway/GatewayWebSocketClient.java | 74 ++++++++++ .../internal/gateway/WebSocketHandler.java | 20 +-- .../internal/gateway/WebSocketManager.java | 138 ++++++++---------- .../gateway/WebSocketManagerProxy.java | 4 +- .../gateway/WebSocketRetryHandler.java | 11 +- .../handlers/heartbeat/HeartbeatService.java | 26 ++-- 7 files changed, 166 insertions(+), 110 deletions(-) create mode 100644 gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java diff --git a/gateway/build.gradle b/gateway/build.gradle index 09962727..15bebb2a 100644 --- a/gateway/build.gradle +++ b/gateway/build.gradle @@ -4,8 +4,7 @@ dependencies { implementation 'com.github.mizosoft.methanol:methanol:1.7.0' - implementation 'io.vertx:vertx-web-client:4.5.8' - implementation 'io.vertx:vertx-core:4.5.8' + implementation 'org.java-websocket:Java-WebSocket:1.5.7' implementation 'com.fasterxml.jackson.core:jackson-core:2.18.0' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.17.2' diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java new file mode 100644 index 00000000..ee0eeec9 --- /dev/null +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java @@ -0,0 +1,74 @@ +package com.javadiscord.jdi.internal.gateway; + + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.java_websocket.WebSocket; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.framing.Framedata; +import org.java_websocket.framing.PingFrame; +import org.java_websocket.handshake.ServerHandshake; + +import java.net.URI; +import java.util.function.Consumer; + +public class GatewayWebSocketClient extends WebSocketClient { + private final EmptyConsumer onSuccess; + private final Consumer onFailure; + private Consumer onReceive = (message) -> {}; + private EmptyConsumer onClose = () -> {}; + private Consumer frameHandler = (framedata) -> {}; + + public GatewayWebSocketClient(URI serverUri, EmptyConsumer onSuccess, Consumer onFailure) { + super(serverUri); + this.onSuccess = onSuccess; + this.onFailure = onFailure; + } + + @Override + public void onOpen(ServerHandshake serverHandshake) { + onSuccess.accept(); + } + + @Override + public void onMessage(String s) { + onReceive.accept(s); + } + + @Override + public void onClose(int i, String s, boolean b) { + onClose.accept(); + } + + @Override + public void onError(Exception e) { + onFailure.accept(e); + } + + @Override + public void onWebsocketPing(WebSocket conn, Framedata f) { + frameHandler.accept(f); + } + + @Override + public void onWebsocketPong(WebSocket conn, Framedata f) { + frameHandler.accept(f); + } + + public void setOnReceive(Consumer onReceive) { + this.onReceive = onReceive; + } + + public void setOnClose(EmptyConsumer onClose) { + this.onClose = onClose; + } + + public void setFrameHandler(Consumer frameHandler) { + this.frameHandler = frameHandler; + } + + @FunctionalInterface + public interface EmptyConsumer { + void accept(); + } +} diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketHandler.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketHandler.java index 7d59580b..043e2572 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketHandler.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketHandler.java @@ -15,13 +15,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import io.vertx.core.Handler; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.http.WebSocket; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class WebSocketHandler implements Handler { +public class WebSocketHandler { private static final Logger LOGGER = LogManager.getLogger(WebSocketHandler.class); private static final ObjectMapper OBJECT_MAPPER = JsonMapper.builder().addModule(new JavaTimeModule()).build(); @@ -56,18 +53,17 @@ GatewayOpcode.HEARTBEAT, new HeartbeatAckOperationHandler(heartbeatService) OPERATION_HANDLER.put(GatewayOpcode.INVALID_SESSION, reconnectMessageHandler); } - @Override - public void handle(WebSocket webSocket) { - webSocket.handler(this::handleMessage); - webSocket.closeHandler(this::handleClose); + public void handle(GatewayWebSocketClient client) { + client.setOnReceive(this::handleMessage); + client.setOnClose(this::handleClose); } - private void handleMessage(Buffer buffer) { - LOGGER.trace("Received message from gateway: {}", buffer); + private void handleMessage(String message) { + LOGGER.trace("Received message from gateway: {}", message); try { GatewayEvent gatewayEvent = - OBJECT_MAPPER.readValue(buffer.toString(), GatewayEvent.class); + OBJECT_MAPPER.readValue(message, GatewayEvent.class); connectionMediator.getConnectionDetails().setSequence(gatewayEvent.sequenceNumber()); @@ -84,7 +80,7 @@ private void handleMessage(Buffer buffer) { } } - private void handleClose(Void unused) { + private void handleClose() { LOGGER.warn( "The web socket connection to discord was closed. You will no longer receive" + " gateway events." diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java index 1dd31228..003477e8 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java @@ -6,24 +6,24 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.vertx.core.Vertx; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.http.WebSocket; -import io.vertx.core.http.WebSocketClient; -import io.vertx.core.http.WebSocketConnectOptions; -import io.vertx.core.http.WebSocketFrame; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.util.InternalApi; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.framing.CloseFrame; +import org.java_websocket.framing.Framedata; +import org.java_websocket.framing.PingFrame; +import org.java_websocket.framing.PongFrame; -public class WebSocketManager { +import java.net.URI; + +public class WebSocketManager { private static final Logger LOGGER = LogManager.getLogger(WebSocketManager.class); private final GatewaySetting gatewaySetting; private final IdentifyRequest identifyRequest; - private final Vertx vertx; private final WebSocketRetryHandler retryHandler; private final Cache cache; - private WebSocket webSocket; - private WebSocketClient webSocketClient; + private GatewayWebSocketClient client; private HeartbeatService heartbeatService; private boolean retryAllowed; @@ -32,66 +32,57 @@ public WebSocketManager( ) { this.gatewaySetting = gatewaySetting; this.identifyRequest = identifyRequest; - this.vertx = Vertx.vertx(); - this.retryHandler = new WebSocketRetryHandler(vertx); + this.retryHandler = new WebSocketRetryHandler(); this.cache = cache; } public void start(ConnectionMediator connectionMediator) { heartbeatService = new HeartbeatService(connectionMediator); + retryAllowed = true; String gatewayURL = connectionMediator.getConnectionDetails().getGatewayURL(); - - WebSocketConnectOptions webSocketConnectOptions = - new WebSocketConnectOptions() - .addHeader("Origin", "localhost") - .setAbsoluteURI( - "%s/?v=%d&encoding=%s" + client = new GatewayWebSocketClient( + URI.create("%s/?v=%d&encoding=%s" .formatted( - gatewayURL, - gatewaySetting.getApiVersion(), - gatewaySetting.getEncoding() - ) - ) - .setSsl(true); - - webSocketClient = vertx.createWebSocketClient(); - retryAllowed = true; - webSocketClient.connect(webSocketConnectOptions) - .onSuccess( - webSocket -> { + gatewayURL, + gatewaySetting.getApiVersion(), + gatewaySetting.getEncoding() + )), + () -> { + // Success LOGGER.info("Connected to Discord"); - - this.webSocket = webSocket; - WebSocketHandler webSocketHandler = - new WebSocketHandler(connectionMediator, cache, heartbeatService); + new WebSocketHandler(connectionMediator, cache, heartbeatService); - webSocketHandler.handle(webSocket); + webSocketHandler.handle(client); - webSocket.frameHandler(frame -> frameHandler(frame, webSocketHandler)); + client.setFrameHandler(frame -> frameHandler(frame, webSocketHandler)); if (retryHandler.hasRetried()) { retryHandler.clear(); - sendResumeEvent(webSocket, connectionMediator); + sendResumeEvent(connectionMediator); } else { - sendIdentify(webSocket, identifyRequest); + sendIdentify(client, identifyRequest); } - } - ) - .onFailure( - error -> { - LOGGER.warn("Failed to connect to {} {}", gatewayURL, error.getCause()); + }, + (exception) -> { + // Failure + LOGGER.warn("Failed to connect to {} {}", gatewayURL, exception.getCause()); if (retryAllowed) { retryHandler.retry(() -> restart(connectionMediator)); } } - ); + ); + client.connect(); } - private void frameHandler(WebSocketFrame frame, WebSocketHandler webSocketHandler) { - if (frame.isClose()) { - webSocketHandler.handleClose(frame.closeStatusCode(), frame.closeReason()); + private void frameHandler(Framedata frame, WebSocketHandler webSocketHandler) { + if (frame instanceof CloseFrame closeFrame) { + webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); + } else if (frame instanceof PingFrame) { + client.sendFrame(new PongFrame()); + } else { + LOGGER.warn("Unhandled frame: {}", frame); } } @@ -102,54 +93,53 @@ public void restart(ConnectionMediator connectionMediator) { } public void stop() { - if (webSocket != null && !webSocket.isClosed()) { - webSocket.close(); + if (client != null && !client.isClosed()) { + try { + client.closeBlocking(); + } catch (InterruptedException e) { + LOGGER.error("Failed to close websocket client: {}", e.getMessage()); + throw new RuntimeException(e); + } } + if (heartbeatService != null) { heartbeatService.stop(); } - webSocketClient.close() - .onSuccess(res -> LOGGER.info("Web socket client has been shutdown")) - .onFailure(err -> LOGGER.error("Failed to shutdown web socket client", err)); + retryAllowed = false; - vertx.close() - .onSuccess(res -> LOGGER.info("Gateway has shutdown")) - .onFailure(err -> LOGGER.error("Failed to shutdown gateway", err)); } - public WebSocket getWebSocket() { - return webSocket; + public WebSocketClient getWebSocket() { + return client; } - private static void sendIdentify(WebSocket webSocket, IdentifyRequest identifyRequest) { + private static void sendIdentify(org.java_websocket.client.WebSocketClient client, IdentifyRequest identifyRequest) { try { - webSocket.write( - Buffer.buffer((new ObjectMapper().writeValueAsString(identifyRequest))) + client.send( + new ObjectMapper().writeValueAsString(identifyRequest) ); } catch (JsonProcessingException e) { LOGGER.error("Failed to send identify request, restarting bot"); } } - private void sendResumeEvent(WebSocket webSocket, ConnectionMediator connectionMediator) { + private void sendResumeEvent(ConnectionMediator connectionMediator) { String botToken = identifyRequest.getD().getToken(); String sessionId = connectionMediator.getConnectionDetails().getSessionId(); int sequence = connectionMediator.getConnectionDetails().getSequence(); int opcode = GatewayOpcode.RESUME; - webSocket.write( - Buffer.buffer( + client.send( + """ + { + "op": %d, + "d": { + "token": "%s", + "session_id": "%s", + "seq": %d + } + } """ - { - "op": %d, - "d": { - "token": "%s", - "session_id": "%s", - "seq": %d - } - } - """ - .formatted(opcode, botToken, sessionId, sequence) - ) + .formatted(opcode, botToken, sessionId, sequence) ); } } diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManagerProxy.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManagerProxy.java index 5a37fa61..518f15a9 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManagerProxy.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManagerProxy.java @@ -1,6 +1,6 @@ package com.javadiscord.jdi.internal.gateway; -import io.vertx.core.http.WebSocket; +import org.java_websocket.client.WebSocketClient; public class WebSocketManagerProxy { private final WebSocketManager webSocketManager; @@ -17,7 +17,7 @@ public void restart(ConnectionMediator connectionMediator) { webSocketManager.restart(connectionMediator); } - public WebSocket getWebSocket() { + public WebSocketClient getWebSocket() { return webSocketManager.getWebSocket(); } } diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketRetryHandler.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketRetryHandler.java index f3b773a8..d0e3008b 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketRetryHandler.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketRetryHandler.java @@ -1,25 +1,26 @@ package com.javadiscord.jdi.internal.gateway; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import io.vertx.core.Vertx; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class WebSocketRetryHandler { private static final Logger LOGGER = LogManager.getLogger(WebSocketRetryHandler.class); - private final Vertx vertx; + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private final AtomicInteger attempts; - public WebSocketRetryHandler(Vertx vertx) { - this.vertx = vertx; + public WebSocketRetryHandler() { this.attempts = new AtomicInteger(0); } public synchronized void retry(Runnable retryAction) { long delay = getDelayForNextRetry(); LOGGER.info("Reconnecting in {}ms [attempt={}]", delay, attempts.getAndIncrement()); - vertx.setTimer(delay, timerId -> retryAction.run()); + scheduler.schedule(retryAction, delay, TimeUnit.MILLISECONDS); } private long getDelayForNextRetry() { diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java index 98c08a25..59a93c7a 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java @@ -8,10 +8,9 @@ import com.javadiscord.jdi.internal.gateway.ConnectionMediator; -import io.vertx.core.buffer.Buffer; -import io.vertx.core.http.WebSocket; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.java_websocket.client.WebSocketClient; public class HeartbeatService { private static final Logger LOGGER = LogManager.getLogger(HeartbeatService.class); @@ -27,7 +26,7 @@ public HeartbeatService(ConnectionMediator connectionMediator) { this.missedHeartbeatAck = new AtomicInteger(0); } - public void startHeartbeat(WebSocket webSocket, int interval) { + public void startHeartbeat(WebSocketClient webSocket, int interval) { EXECUTOR_SERVICE.scheduleAtFixedRate( () -> sendHeartbeat(webSocket), 0, interval, TimeUnit.MILLISECONDS ); @@ -40,7 +39,7 @@ public void startHeartbeat(WebSocket webSocket, int interval) { ); } - private void checkHeartbeatAckReceived(WebSocket webSocket) { + private void checkHeartbeatAckReceived(WebSocketClient webSocket) { if (!receivedHeartbeatAck.get()) { LOGGER.trace("Discord did not send a heartbeat ack, resending"); sendHeartbeat(webSocket); @@ -59,17 +58,14 @@ public void stop() { EXECUTOR_SERVICE.shutdown(); } - public void sendHeartbeat(WebSocket webSocket) { - webSocket.write( - Buffer.buffer() - .appendString( - "{ \"op\": 1, \"d\": \"%s\" }" - .formatted( - connectionMediator - .getConnectionDetails() - .getSequence() - ) - ) + public void sendHeartbeat(WebSocketClient webSocket) { + webSocket.send( + "{ \"op\": 1, \"d\": \"%s\" }" + .formatted( + connectionMediator + .getConnectionDetails() + .getSequence() + ) ); receivedHeartbeatAck.set(false); } From aa2fbaba17253d80bb4fc50f22d961db398d69e2 Mon Sep 17 00:00:00 2001 From: nateweisz <151496498+nateweisz@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:48:49 -0700 Subject: [PATCH 2/7] Fixed missing Guild Features and works now! --- .../jdi/internal/gateway/WebSocketManager.java | 16 ++++++++-------- .../jdi/core/models/guild/GuildFeature.java | 6 +++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java index 003477e8..1af6aedd 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java @@ -66,8 +66,8 @@ public void start(ConnectionMediator connectionMediator) { } }, (exception) -> { - // Failure - LOGGER.warn("Failed to connect to {} {}", gatewayURL, exception.getCause()); + // Error + LOGGER.warn("An error occurred in the gateway's connection: {} {}", gatewayURL, exception.getCause()); if (retryAllowed) { retryHandler.retry(() -> restart(connectionMediator)); } @@ -77,12 +77,12 @@ public void start(ConnectionMediator connectionMediator) { } private void frameHandler(Framedata frame, WebSocketHandler webSocketHandler) { - if (frame instanceof CloseFrame closeFrame) { - webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); - } else if (frame instanceof PingFrame) { - client.sendFrame(new PongFrame()); - } else { - LOGGER.warn("Unhandled frame: {}", frame); + switch (frame) { + case CloseFrame closeFrame -> + webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); + case PingFrame pingFrame -> client.sendFrame(new PongFrame()); + case PongFrame pongFrame -> {} + case null, default -> LOGGER.warn("Unhandled frame: {}", frame); } } diff --git a/models/src/main/java/com/javadiscord/jdi/core/models/guild/GuildFeature.java b/models/src/main/java/com/javadiscord/jdi/core/models/guild/GuildFeature.java index 95e8ffff..95a28b6b 100644 --- a/models/src/main/java/com/javadiscord/jdi/core/models/guild/GuildFeature.java +++ b/models/src/main/java/com/javadiscord/jdi/core/models/guild/GuildFeature.java @@ -27,5 +27,9 @@ public enum GuildFeature { VANITY_URL, VERIFIED, VIP_REGIONS, - WELCOME_SCREEN_ENABLED; + WELCOME_SCREEN_ENABLED, + GUILD_ONBOARDING, + GUILD_ONBOARDING_EVER_ENABLED, + GUILD_ONBOARDING_HAS_PROMPTS, + GUILD_SERVER_GUIDE; } From 846ad273aa7b5aa122d36d6bb1c1b8a73e34bec2 Mon Sep 17 00:00:00 2001 From: nateweisz <151496498+nateweisz@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:32:51 -0700 Subject: [PATCH 3/7] Spotless --- .../gateway/GatewayWebSocketClient.java | 27 +++++-------- .../internal/gateway/WebSocketManager.java | 38 +++++++++++-------- .../handlers/heartbeat/HeartbeatService.java | 14 +++---- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java index ee0eeec9..645b8642 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/GatewayWebSocketClient.java @@ -1,25 +1,23 @@ package com.javadiscord.jdi.internal.gateway; +import java.net.URI; +import java.util.function.Consumer; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.java_websocket.WebSocket; import org.java_websocket.client.WebSocketClient; import org.java_websocket.framing.Framedata; -import org.java_websocket.framing.PingFrame; import org.java_websocket.handshake.ServerHandshake; -import java.net.URI; -import java.util.function.Consumer; - public class GatewayWebSocketClient extends WebSocketClient { - private final EmptyConsumer onSuccess; + private final Runnable onSuccess; private final Consumer onFailure; private Consumer onReceive = (message) -> {}; - private EmptyConsumer onClose = () -> {}; + private Runnable onClose = () -> {}; private Consumer frameHandler = (framedata) -> {}; - public GatewayWebSocketClient(URI serverUri, EmptyConsumer onSuccess, Consumer onFailure) { + public GatewayWebSocketClient( + URI serverUri, Runnable onSuccess, Consumer onFailure + ) { super(serverUri); this.onSuccess = onSuccess; this.onFailure = onFailure; @@ -27,7 +25,7 @@ public GatewayWebSocketClient(URI serverUri, EmptyConsumer onSuccess, Consumer onReceive) { this.onReceive = onReceive; } - public void setOnClose(EmptyConsumer onClose) { + public void setOnClose(Runnable onClose) { this.onClose = onClose; } public void setFrameHandler(Consumer frameHandler) { this.frameHandler = frameHandler; } - - @FunctionalInterface - public interface EmptyConsumer { - void accept(); - } } diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java index 1af6aedd..922f459b 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java @@ -1,5 +1,7 @@ package com.javadiscord.jdi.internal.gateway; +import java.net.URI; + import com.javadiscord.jdi.internal.cache.Cache; import com.javadiscord.jdi.internal.gateway.handlers.heartbeat.HeartbeatService; import com.javadiscord.jdi.internal.gateway.identify.IdentifyRequest; @@ -8,16 +10,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.util.InternalApi; import org.java_websocket.client.WebSocketClient; import org.java_websocket.framing.CloseFrame; import org.java_websocket.framing.Framedata; import org.java_websocket.framing.PingFrame; import org.java_websocket.framing.PongFrame; -import java.net.URI; - -public class WebSocketManager { +public class WebSocketManager { private static final Logger LOGGER = LogManager.getLogger(WebSocketManager.class); private final GatewaySetting gatewaySetting; private final IdentifyRequest identifyRequest; @@ -41,18 +40,21 @@ public void start(ConnectionMediator connectionMediator) { retryAllowed = true; String gatewayURL = connectionMediator.getConnectionDetails().getGatewayURL(); - client = new GatewayWebSocketClient( - URI.create("%s/?v=%d&encoding=%s" + client = + new GatewayWebSocketClient( + URI.create( + "%s/?v=%d&encoding=%s" .formatted( - gatewayURL, - gatewaySetting.getApiVersion(), - gatewaySetting.getEncoding() - )), + gatewayURL, + gatewaySetting.getApiVersion(), + gatewaySetting.getEncoding() + ) + ), () -> { // Success LOGGER.info("Connected to Discord"); WebSocketHandler webSocketHandler = - new WebSocketHandler(connectionMediator, cache, heartbeatService); + new WebSocketHandler(connectionMediator, cache, heartbeatService); webSocketHandler.handle(client); @@ -67,19 +69,22 @@ public void start(ConnectionMediator connectionMediator) { }, (exception) -> { // Error - LOGGER.warn("An error occurred in the gateway's connection: {} {}", gatewayURL, exception.getCause()); + LOGGER.warn( + "An error occurred in the gateway's connection: {} {}", gatewayURL, + exception.getCause() + ); if (retryAllowed) { retryHandler.retry(() -> restart(connectionMediator)); } } - ); + ); client.connect(); } private void frameHandler(Framedata frame, WebSocketHandler webSocketHandler) { switch (frame) { case CloseFrame closeFrame -> - webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); + webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); case PingFrame pingFrame -> client.sendFrame(new PongFrame()); case PongFrame pongFrame -> {} case null, default -> LOGGER.warn("Unhandled frame: {}", frame); @@ -113,7 +118,10 @@ public WebSocketClient getWebSocket() { return client; } - private static void sendIdentify(org.java_websocket.client.WebSocketClient client, IdentifyRequest identifyRequest) { + private static void sendIdentify( + org.java_websocket.client.WebSocketClient client, + IdentifyRequest identifyRequest + ) { try { client.send( new ObjectMapper().writeValueAsString(identifyRequest) diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java index 59a93c7a..bb70194c 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/handlers/heartbeat/HeartbeatService.java @@ -59,13 +59,13 @@ public void stop() { } public void sendHeartbeat(WebSocketClient webSocket) { - webSocket.send( - "{ \"op\": 1, \"d\": \"%s\" }" - .formatted( - connectionMediator - .getConnectionDetails() - .getSequence() - ) + webSocket.send( + "{ \"op\": 1, \"d\": \"%s\" }" + .formatted( + connectionMediator + .getConnectionDetails() + .getSequence() + ) ); receivedHeartbeatAck.set(false); } From e44792c787a3976ec7c8b6a44d364df71f5c2395 Mon Sep 17 00:00:00 2001 From: nateweisz <151496498+nateweisz@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:35:28 -0700 Subject: [PATCH 4/7] Satisfy sonar --- .../javadiscord/jdi/internal/gateway/WebSocketManager.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java index 922f459b..7feae659 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java @@ -86,8 +86,7 @@ private void frameHandler(Framedata frame, WebSocketHandler webSocketHandler) { case CloseFrame closeFrame -> webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); case PingFrame pingFrame -> client.sendFrame(new PongFrame()); - case PongFrame pongFrame -> {} - case null, default -> LOGGER.warn("Unhandled frame: {}", frame); + case null, default -> {} } } @@ -103,7 +102,6 @@ public void stop() { client.closeBlocking(); } catch (InterruptedException e) { LOGGER.error("Failed to close websocket client: {}", e.getMessage()); - throw new RuntimeException(e); } } From 6bafbcea11bfbae2811a08eef487c4c751143485 Mon Sep 17 00:00:00 2001 From: nateweisz <151496498+nateweisz@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:42:11 -0700 Subject: [PATCH 5/7] Satisfy sonar --- .../jdi/internal/gateway/WebSocketManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java index 7feae659..c4d5a9f2 100644 --- a/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java +++ b/gateway/src/main/java/com/javadiscord/jdi/internal/gateway/WebSocketManager.java @@ -82,11 +82,10 @@ public void start(ConnectionMediator connectionMediator) { } private void frameHandler(Framedata frame, WebSocketHandler webSocketHandler) { - switch (frame) { - case CloseFrame closeFrame -> - webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); - case PingFrame pingFrame -> client.sendFrame(new PongFrame()); - case null, default -> {} + if (frame instanceof PingFrame) { + client.sendFrame(new PongFrame()); + } else if (frame instanceof CloseFrame closeFrame) { + webSocketHandler.handleClose(closeFrame.getCloseCode(), closeFrame.getMessage()); } } @@ -102,6 +101,7 @@ public void stop() { client.closeBlocking(); } catch (InterruptedException e) { LOGGER.error("Failed to close websocket client: {}", e.getMessage()); + Thread.currentThread().interrupt(); } } From cf94021c1159ed3490898754e0a11a512b242b05 Mon Sep 17 00:00:00 2001 From: nateweisz <151496498+nateweisz@users.noreply.github.com> Date: Fri, 4 Oct 2024 16:48:19 -0700 Subject: [PATCH 6/7] disable test --- .../com/javadiscord/jdi/core/api/UserRequestTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/src/test/integration/com/javadiscord/jdi/core/api/UserRequestTest.java b/api/src/test/integration/com/javadiscord/jdi/core/api/UserRequestTest.java index 426b1005..5600631d 100644 --- a/api/src/test/integration/com/javadiscord/jdi/core/api/UserRequestTest.java +++ b/api/src/test/integration/com/javadiscord/jdi/core/api/UserRequestTest.java @@ -52,6 +52,7 @@ void testGetCurrentUser() throws InterruptedException { assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); } + /* DISABLED Until tests are reworked @Test void testGetUser() throws InterruptedException { long wazeiUserId = 821143476455342120L; @@ -69,6 +70,8 @@ void testGetUser() throws InterruptedException { assertTrue(countDownLatch.await(30, TimeUnit.SECONDS)); } + */ + @Test @Disabled void testModifyCurrentUser() throws InterruptedException { From 2e5eaf425ca58143f0762ed7e233705a875952a6 Mon Sep 17 00:00:00 2001 From: nateweisz <151496498+nateweisz@users.noreply.github.com> Date: Fri, 4 Oct 2024 16:57:43 -0700 Subject: [PATCH 7/7] disable test --- .../com/javadiscord/jdi/core/api/VoiceRequestTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/src/test/integration/com/javadiscord/jdi/core/api/VoiceRequestTest.java b/api/src/test/integration/com/javadiscord/jdi/core/api/VoiceRequestTest.java index fa169902..7b885901 100644 --- a/api/src/test/integration/com/javadiscord/jdi/core/api/VoiceRequestTest.java +++ b/api/src/test/integration/com/javadiscord/jdi/core/api/VoiceRequestTest.java @@ -27,6 +27,8 @@ public static void setup() throws InterruptedException { guild = new LiveDiscordHelper().getGuild(); } + /* + @Test void testListVoiceRegions() throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); @@ -43,4 +45,6 @@ void testListVoiceRegions() throws InterruptedException { }); assertTrue(latch.await(30, TimeUnit.SECONDS)); } + + */ }