aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp
diff options
context:
space:
mode:
authorEryk Ruta <70776766+kingstefan26@users.noreply.github.com>2022-11-01 15:51:30 +0100
committerGitHub <noreply@github.com>2022-11-01 23:51:30 +0900
commit292fbd05e13271ca3ad99ebe00ae4302e04848f3 (patch)
tree2a7aeb12ab95ff688479a4727f76e3e4152c30b5 /src/main/java/kr/syeyoung/dungeonsguide/mod/stomp
parentdd7a4209752715db544b2fef804da9762c532cdc (diff)
downloadSkyblock-Dungeons-Guide-292fbd05e13271ca3ad99ebe00ae4302e04848f3.tar.gz
Skyblock-Dungeons-Guide-292fbd05e13271ca3ad99ebe00ae4302e04848f3.tar.bz2
Skyblock-Dungeons-Guide-292fbd05e13271ca3ad99ebe00ae4302e04848f3.zip
3rd time is the charm (#70)
* Updated some dependencies, used my crusty skytils forgegradle fork + removed the IRRELEVANT hytils fixes. generally made the thing build * made the logs less annoying * temp fix so it doesn't throw an exception * FAT REFACTOR General refactor on Authenticator.java DungeonsGuide.java Main.java removed unnecessary imports where not needed to be removed DGInterface.java (no real reason to exist) in DungeonsGuide.java made the retry stomp a singe-thread executor, so it doesn't leak when offline added an "offline mode" so it doesn't just error when server down TODO: move auth to DungeonsGuide.java and make it retry when network down on launch * New auth implementation that should replace the old one: does all the things the old one did removed progressBar cuz it would make the impl 3x more complicated in the name of a splash screen added a token changed event (so now it supports re-logging with a different account) code is (should) be more readable / extensible TODO: surgically replace Authenticator.java with new impl AND support re-logging * Made the chat processor logger name less obnoxious * implemented my implementation of an implementation of auth can and is very buggy, essentially the loading of the remote classes but the mod works so idk TODO: MAKE STOMP NOT DO STUFF TILL STOMPCONNECTED IS EMITTED * fix for stomp client null bc forge events not going tru on pre-init TODO: make work and test the web loadable classes, then make all the stuff that relies on stomp not throw exceptions when stomp is not connected * move the create auth method into AuthProvider interface, so we don't clutter AuthManager with implementation details * Decouple AuthProviderUtil and DgAuth, move some stuff around and make it more readable * moved AuthUtil to make more sense * de-clutter the tree a little bit * Inline StompClientStatus.java / refactor * inline the useless interface * refactoringgg * fix ahUtils exeption spam * small StompClient refactor * fix GLCursors exeption spam + logger * make sure we are authenticated when downloading resources * new .destination("value") instead of .header("destination", "value") * StompMessageHandler -> StompMessageSubscription * Introduced StompManager * fix dungeon map not showing ppl heads * ehhh * wip (commit cuz im chekig out) * fix player profile not never loading in chat * remove this specific line * fix player profile not never loading in chat * cut out hychat like a cancer * ApiFetchur now caches whole players not single profiles, added a switch profile button in gui * ugh git * Revert "cut out hychat like a cancer" This reverts commit 2ee11afa * ugh git x2 * I tried, good luck maintaining this * forgot to uncomment hychat fix * make my new party ready work and look ok * change the look and add some "somewhere" locations * make stomp connection "null safe" * i hate git * introduce callbacks on parameter change for cleaner code add one example * impl new system, half way done * now shows which profile is now selected put button on top a lil refactor * fix player profile sometimes not loading * add players knowing who is using dg (try to) * announcing that we are a dg user will get reworked in the future * update deps * make it not spam logs * sanity check for premium features so it doesn't 403 * add YoMamaOutdated that checks if you are using outdated dg * hychat?? anyone * try catch in FeatureRegistry * added Ether transmission ability * chat shredder borken, disabled for now * party deserves its own folder * dungeon stuff in dungeon folder * events folders moved * fix score data collection hanging forever if stomp is not connected * fix stomp never connecting * re-add the removed * fix wonky rendering * server side implementation is not ready, canning this for a future release * attempt to fix heads loading on main thread * discord * me when sonar lint * new consumer based stomp subscriptions * replace old with new subscriptions * remove the remains of StompSubscription and replace CloseListener with a forge event * StompSubscription is now a functional interface * remove unnecessary event message chains, feature logic should be in the feature * fix events being set up wrongly * Revert "fix events being set up wrongly" This reverts commit e6ea7efa557a5f5c8a3ea33be998717bc024b8cb. * Revert "remove unnecessary event message chains," This reverts commit 96f508bae85b33cdcef6be19226c00fc52a1439b. * fix stomp client sending payload object instead of the actual payload * fix null pointer on empty party * fix players with cosmetics name being white in tab * added message when not connected to dg changed YoMamaOutdated to use CloudFlare workers added client sided message queue * the mod doesn't init when outdated * mcmod.info * dont busy wait in authmenager * test pepole crusty tests * chill out the authmanager * name the thread pool in auth manager * clear most compiler warnings * make outdated check allow to play without the mod initialized * make first startup VERY noticeable, move config creation to main * major dungeon package refactor * refactor checkpoint * refactor checkpoint #1 * final refactor checkpoint #2 * remove the player if from version check, made the version check not nesssery for playing Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove trap room fix that didnt fix anything Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make secret beacons optional Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make the checkmarks on map align with the rest of everyone Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * removed debug function Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move the menus to make more sense + make destination text on secrets optional Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * improve dungeonMap performance by ~90% temporarly disabled 9 slot map player location due to bugs fix DungeonContext not getting player from ScoreBoard Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * add epic countdown on dungeon start (still wip) Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added a option to cache blockstaes Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added TabListUtil Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fixed epic countdown Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * (i want to sleep) made all the dungeon room detection async TODO: fix ol the bugs i created by doing that Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * stuff still broken but almost playable, unlike last commit Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * upload build jar to discord Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * cache the deps for the love of god Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * who needs linux and 32bit windows anyway Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * only upload to discord on beta branch Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added "kick" when a member joins party Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move stuff that sends chat to player into a separate class Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * use our chat queue instead of calling `thePlayer.addChatMessage` to proxy ourselves from 1.8 code Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Added and implemented MortDetector2000.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * extract duplicate + make more readable Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * added dummy support in FeatureDebugTrap Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * gradle now puts version in mcmod.info Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove side effects from DgAuth.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move debug commands into debug CommandDgDebug.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fix key being wrong Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move epic countdown to dungeon huds, clean up Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Revert "who needs linux and 32bit windows anyway" This reverts commit 0f3c2d544a70fc799cd3215dad5e997c0c8b6c06. * make FeatureRegistry not static initialise to get rid of "ClassNotDefined" errors Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * null check on Exception since it threw NullPointers Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * finish up progress bar in DungeonsGuide.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * warn about null features Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move stuff around in SkyblockStatus, move the stuff that updates status into SkyblockStatus from DungeonListener Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * rename DungeonGodObject.java to DungeonFacade.java Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * add cleanChat clause in FeatureEpicCountdown Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * implement getPreRequisites and isComplete in ActionBreakWithSuperBoom Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * clean up FeatureParameter Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * eliminate possible state inconsistency in DungeonListener Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move percentage from DungeonFacade to DungeonContext Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move `purge` and `partymax` back into CommandDungeonsGuide Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * stop repeating ReceiveChatQueue in ChatTransmitter Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Clean up DungeonsGuide Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move `sendDebugChat` to `ChatTransmitter.java` Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * change CommandDgDebug into a `else if` from an `switch` because some bigot decided its better Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * duplicate code since it currently doesn't make sense, to be reworked Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fix typo Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove the trycatch so we fail fast Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * fix null pointer when trying to get fontRenderer before minecraft is initialised Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * broken checkpoint 0 Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * broken checkpoint 1 Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * Revert "broken checkpoint 1" This reverts commit 64985e6287c7b5650b509668e42b9803e25c419c. * Revert "broken checkpoint 0" This reverts commit 5f62e1345d9c8e7f66f1e5792004a05027913d92. * Revert "fix null pointer when trying to get fontRenderer before minecraft is initialised" This reverts commit 57d92a78d31c410f699b58c8995c94055d57e2a4. * Revert "remove the trycatch so we fail fast" This reverts commit 12772255ed575e411fb99edf37ec16d0e5f42924. * Revert "fix typo" This reverts commit aa96cc2436d3ead42d53ead78f3334fac5100713. * Revert "duplicate code since it currently doesn't make sense, to be reworked" This reverts commit 6d71b88e3102d23bcfd90d85e8996327776fd52f. * Revert "change CommandDgDebug into a `else if` from an `switch` because some bigot decided its better" This reverts commit ffea84d9b5fd4adbe034a88249bc920eafa7c53a. * Revert "move `sendDebugChat` to `ChatTransmitter.java`" This reverts commit 5b8b2e22fff33768134a01c15c7650100ebb9257. * Revert "Clean up DungeonsGuide" This reverts commit 2069ad3ebc4344eb1e778954dc1d8f6c9303de69. * fix typo Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> (cherry picked from commit aa96cc2436d3ead42d53ead78f3334fac5100713) * duplicate code since it currently doesn't make sense, to be reworked Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> (cherry picked from commit 6d71b88e3102d23bcfd90d85e8996327776fd52f) * change CommandDgDebug into a `else if` from an `switch` because some bigot decided its better Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> (cherry picked from commit ffea84d9b5fd4adbe034a88249bc920eafa7c53a) * move debug chat into ChatTransmitter Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * null pointer in SkyblockStatus bc context was not initialised yet Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move dungeon starting door detection up the tree since it was a duplicate in both children, inline MortDetector2000 Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move dungeon name to DungeonContext Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * clean up Main Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * separate the "loader" and "mod" Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * separate DungeonsGuide and Main even more Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * change singleton implementation of DungeonsGuide Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move classes since their paths are hardcoded into roomdatas Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * create CatacombsDataProvider.java and implement it Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove unnecessary `DungeonsGuide.getDungeonsGuide();` (IntelliJ refactor bug) Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * move `help` text in commands Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * a certain someone hates switch statements Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * remove my version check, since we have to wait for out lord and savior to make his own Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make `Main` and `DungeonsGuide` compatible with supported jar classloading Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * make the beta upload action run on push since it didnt get the secret on pull request and failed anyway, TODO: make the jar name not hardcoded Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> * upload all jar Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> Signed-off-by: kingstefan26 <70776766+kingstefan26@users.noreply.github.com> Co-authored-by: syeyoung <42869671+cyoung06@users.noreply.github.com>
Diffstat (limited to 'src/main/java/kr/syeyoung/dungeonsguide/mod/stomp')
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/FailedWebSocketConnection.java7
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompClient.java192
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompDiedEvent.java15
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompHeader.java24
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompManager.java73
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompPayload.java96
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompSubscription.java6
7 files changed, 413 insertions, 0 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/FailedWebSocketConnection.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/FailedWebSocketConnection.java
new file mode 100644
index 00000000..15f79dde
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/FailedWebSocketConnection.java
@@ -0,0 +1,7 @@
+package kr.syeyoung.dungeonsguide.mod.stomp;
+
+public class FailedWebSocketConnection extends RuntimeException{
+ public FailedWebSocketConnection(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompClient.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompClient.java
new file mode 100644
index 00000000..84705a1d
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompClient.java
@@ -0,0 +1,192 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.stomp;
+
+import lombok.Getter;
+import net.minecraftforge.common.MinecraftForge;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+public class StompClient extends WebSocketClient {
+
+ Logger logger = LogManager.getLogger("StompClient");
+ public StompClient(URI serverUri, final String token) throws InterruptedException {
+ super(serverUri);
+
+
+ addHeader("Authorization", token);
+
+ logger.info("connecting websocket");
+ if (!connectBlocking()) {
+ throw new FailedWebSocketConnection("Cant connect to ws");
+ }
+
+ logger.info("connected, stomp handshake");
+ while(this.stompClientStatus == StompClientStatus.CONNECTING);
+ logger.info("fully connected");
+ }
+
+
+ @Getter
+ private volatile StompClientStatus stompClientStatus = StompClientStatus.CONNECTING;
+
+ @Getter
+ private StompPayload errorPayload;
+
+ private ScheduledFuture heartbeat = null;
+
+ private static final ScheduledExecutorService ex = Executors.newScheduledThreadPool(1);
+ @Override
+ public void onOpen(ServerHandshake handshakedata) {
+ send(new StompPayload().method(StompHeader.CONNECT)
+ .header("accept-version","1.2")
+ .header("heart-beat", "30000,30000")
+ .header("host",uri.getHost()).getBuilt()
+ );
+ }
+
+ @Override
+ public void onMessage(String message) {
+ try {
+ StompPayload payload = StompPayload.parse(message);
+
+ switch (payload.method()){
+ case SEND:
+ case SUBSCRIBE:
+ case UNSUBSCRIBE:
+ case BEGIN:
+ case COMMIT:
+ case ABORT:
+ case ACK:
+ case NACK:
+ case DISCONNECT:
+ case STOMP:
+ break;
+ case CONNECTED:
+ stompClientStatus = StompClientStatus.CONNECTED;
+
+ String serverHeartbeat = payload.headers().get("heart-beat");
+ if (serverHeartbeat != null) {
+ int heartbeatMS = 30;
+ this.heartbeat = ex.scheduleAtFixedRate(() -> send("\n"), heartbeatMS-1, heartbeatMS-1, TimeUnit.SECONDS);
+ }
+
+ break;
+ case MESSAGE:
+ String subscriptionName = payload.headers().get("subscription");
+ int subscriptionId = Integer.parseInt(subscriptionName);
+ StompSubscription listener = stompSubscriptionMap.get(subscriptionId);
+
+ listener.process(this, payload.payload());
+
+ break;
+ case RECEIPT:
+ String receiptId = payload.headers().get("receipt-id");
+ StompPayload payload1 = receiptMap.remove(Integer.parseInt(receiptId));
+ if (payload1.method() == StompHeader.DISCONNECT) {
+ stompClientStatus = StompClientStatus.DISCONNECTED;
+ close();
+ }
+ break;
+ case ERROR:
+ errorPayload = payload;
+ stompClientStatus = StompClientStatus.ERROR;
+ this.close();
+ break;
+
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onClose(int code, String reason, boolean remote) {
+ if (heartbeat != null) heartbeat.cancel(true);
+
+ MinecraftForge.EVENT_BUS.post(new StompDiedEvent(code, reason, remote));
+
+ }
+
+ @Override
+ public void onError(Exception ex) {
+ if(ex != null){
+ ex.printStackTrace();
+ }
+ }
+
+
+ private final Map<Integer, StompSubscription> stompSubscriptionMap = new HashMap<>();
+ private final Map<Integer, StompPayload> receiptMap = new HashMap<>();
+
+ private int idIncrement = 0;
+
+ private void makeSureStompIsConnected() {
+ if (stompClientStatus != StompClientStatus.CONNECTED) throw new IllegalStateException("not connected");
+ }
+
+ public void sendfake(StompPayload payload) {
+ makeSureStompIsConnected();
+ payload.method(StompHeader.SEND);
+ if (payload.headers().get("receipt") != null)
+ receiptMap.put(Integer.parseInt(payload.headers().get("receipt")), payload);
+ send(payload.getBuilt());
+ }
+
+ public void subscribe(String destination, StompSubscription listener) {
+ makeSureStompIsConnected();
+ int id = ++idIncrement;
+
+ send(new StompPayload()
+ .method(StompHeader.SUBSCRIBE)
+ .header("id", String.valueOf(id))
+ .destination(destination)
+ .header("ack", "auto")
+ .getBuilt()
+ );
+
+ stompSubscriptionMap.put(id, listener);
+ }
+
+
+ public void disconnect() {
+ makeSureStompIsConnected();
+ stompClientStatus =StompClientStatus.DISCONNECTING;
+
+ StompPayload stompPayload = new StompPayload().method(StompHeader.DISCONNECT).header("receipt", String.valueOf(++idIncrement));
+
+ send(stompPayload.getBuilt());
+ receiptMap.put(idIncrement, stompPayload);
+ }
+
+
+ public enum StompClientStatus {
+ CONNECTING, CONNECTED, ERROR, DISCONNECTING, DISCONNECTED
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompDiedEvent.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompDiedEvent.java
new file mode 100644
index 00000000..33913424
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompDiedEvent.java
@@ -0,0 +1,15 @@
+package kr.syeyoung.dungeonsguide.mod.stomp;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import net.minecraftforge.fml.common.eventhandler.Event;
+
+@Data
+@EqualsAndHashCode(callSuper=false)
+@AllArgsConstructor
+public class StompDiedEvent extends Event {
+ int code;
+ String reason;
+ boolean remote;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompHeader.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompHeader.java
new file mode 100644
index 00000000..7755d8a6
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompHeader.java
@@ -0,0 +1,24 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.stomp;
+
+
+public enum StompHeader {
+ SEND, SUBSCRIBE, UNSUBSCRIBE, BEGIN, COMMIT, ABORT, ACK, NACK, DISCONNECT, CONNECT, STOMP, CONNECTED, MESSAGE, RECEIPT, ERROR
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompManager.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompManager.java
new file mode 100644
index 00000000..31b3b961
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompManager.java
@@ -0,0 +1,73 @@
+package kr.syeyoung.dungeonsguide.mod.stomp;
+
+import com.google.common.base.Throwables;
+import kr.syeyoung.dungeonsguide.auth.AuthManager;
+import kr.syeyoung.dungeonsguide.mod.events.impl.StompConnectedEvent;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.net.URI;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class StompManager {
+ Logger logger = LogManager.getLogger("StompManager");
+ public static final String STOMP_URL = "wss://dungeons.guide/ws";
+ // private String stompURL = "ws://localhost/ws";
+ static StompManager instance;
+
+ public static StompManager getInstance() {
+ if (instance == null) {
+ instance = new StompManager();
+ MinecraftForge.EVENT_BUS.register(instance);
+ }
+ return instance;
+ }
+
+ public void init() {
+ connectStomp();
+ }
+
+ private StompClient stompConnection;
+
+
+ public boolean isStompConnected(){
+ if(stompConnection != null && stompConnection.getStompClientStatus() == StompClient.StompClientStatus.CONNECTED) return true;
+ return false;
+ }
+
+ public void send(StompPayload payload){
+ if(stompConnection != null){
+ stompConnection.sendfake(payload);
+ } else {
+ logger.error("OOPS STOMP CONNECTION IS NULL AND SOMEONE TRIED TO SEND SOMETHING THIS SHOULD NOT HAPPEN");
+ }
+ }
+
+ ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
+
+ @SubscribeEvent
+ public void onStompDied(StompDiedEvent event) {
+ logger.info("Stomp Connection closed, trying to reconnect - {} - {}", event.reason, event.code);
+ connectStomp();
+ }
+
+ public void connectStomp() {
+ ex.schedule(() -> {
+ if (AuthManager.getInstance().getToken() == null) return;
+ try {
+ if (stompConnection != null) {
+ stompConnection.disconnect();
+ }
+ stompConnection = new StompClient(new URI(StompManager.STOMP_URL), AuthManager.getInstance().getToken());
+ MinecraftForge.EVENT_BUS.post(new StompConnectedEvent(stompConnection));
+ } catch (Exception e) {
+ logger.error("Failed to connect to Stomp with message: {}", String.valueOf(Throwables.getRootCause(e)));
+ }
+
+ }, 5L, TimeUnit.SECONDS);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompPayload.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompPayload.java
new file mode 100644
index 00000000..8bfb8543
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompPayload.java
@@ -0,0 +1,96 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2021 cyoung06
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.stomp;
+
+import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.*;
+
+@Data
+@Accessors(chain = true, fluent = true)
+public class StompPayload {
+ private StompHeader method;
+ private Map<String, String> headers = new HashMap<>();
+ private String payload;
+
+ public StompPayload header(String key, String value) {
+ headers.put(key, value);
+ return this;
+ }
+
+
+ public StompPayload destination(String value){
+ headers.put("destination", value);
+ return this;
+ }
+
+ public StompPayload id(String value){
+ headers.put("id", value);
+ return this;
+ }
+
+ public String getBuilt() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(method.name());
+ sb.append("\n");
+ for (Map.Entry<String, String> stringStringEntry : headers.entrySet()) {
+ sb.append(stringStringEntry.getKey());
+ sb.append(":");
+ sb.append(stringStringEntry.getValue());
+ sb.append("\n");
+ if (stringStringEntry.getKey().contains(":")) throw new IllegalStateException("Illegal Character : inside headers");
+ if (stringStringEntry.getValue().contains(":")) throw new IllegalStateException("Illegal Character : inside headers");
+ }
+ sb.append("\n");
+ if (payload != null)
+ sb.append(payload);
+ sb.append((char) 0);
+ if (FeatureRegistry.DEBUG.isEnabled()) System.out.println("Sending.. "+ sb);
+ return sb.toString();
+ }
+
+ public static StompPayload parse(String payload) {
+ if (FeatureRegistry.DEBUG.isEnabled()) System.out.println("Receving.. "+payload);
+
+ Scanner scanner = new Scanner(payload);
+ StompPayload stompPayload = new StompPayload();
+ stompPayload.method = StompHeader.valueOf(scanner.nextLine());
+ String line;
+ while (!(line = scanner.nextLine()).isEmpty()) {
+ int index = line.indexOf(":");
+ if (index == -1) throw new IllegalArgumentException("No : found in headers section");
+ String name = line.substring(0, index);
+ String value;
+ if (index == line.length() - 1)
+ value = "";
+ else
+ value = line.substring(index+1);
+ stompPayload.headers.put(name, value);
+ }
+
+ List<String> lines = new ArrayList<>();
+ while (scanner.hasNextLine() && !(line = scanner.nextLine()).equals("\0")) {
+ lines.add(line);
+ }
+ stompPayload.payload = String.join("\n", lines);
+ return stompPayload;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompSubscription.java b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompSubscription.java
new file mode 100644
index 00000000..965eaae9
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/mod/stomp/StompSubscription.java
@@ -0,0 +1,6 @@
+package kr.syeyoung.dungeonsguide.mod.stomp;
+
+@FunctionalInterface
+public interface StompSubscription {
+ void process(StompClient stompInterface, String stompPayload);
+}