aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.gradle19
-rwxr-xr-xsrc/main/java/kr/syeyoung/dungeonsguide/e.java36
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java1
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureBlah.java38
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/CloseListener.java5
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java136
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClientStatus.java5
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompHeader.java9
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompInterface.java8
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompMessageHandler.java5
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompPayload.java69
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/stomp/StompSubscription.java23
12 files changed, 350 insertions, 4 deletions
diff --git a/build.gradle b/build.gradle
index 84994348..a07e1efb 100755
--- a/build.gradle
+++ b/build.gradle
@@ -42,12 +42,12 @@ minecraft {
dependencies {
implementation 'org.jetbrains:annotations-java5:19.0.0'
-
+ compile "org.java-websocket:Java-WebSocket:1.5.1"
// you may put jars on which you depend on in ./libs
// or you may define them like so..
//compile "some.group:artifact:version:classifier"
//compile "some.group:artifact:version"
-
+
// real examples
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
@@ -89,4 +89,19 @@ processResources
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
+}
+
+shadowJar {
+ dependencies {
+ include(dependency('io.vertx:vertx-auth-common:4.0.2'))
+ include(dependency('io.vertx:vertx-bridge-common:4.0.2'))
+ include(dependency('io.vertx:vertx-core:4.0.2'))
+ include(dependency('io.vertx:vertx-stomp:4.0.2'))
+ }
+}
+
+reobf {
+ shadowJar {
+ mappingType = 'SEARGE'
+ }
} \ No newline at end of file
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/e.java b/src/main/java/kr/syeyoung/dungeonsguide/e.java
index 323e73e1..684d2fe9 100755
--- a/src/main/java/kr/syeyoung/dungeonsguide/e.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/e.java
@@ -7,6 +7,9 @@ import kr.syeyoung.dungeonsguide.eventlistener.DungeonListener;
import kr.syeyoung.dungeonsguide.eventlistener.FeatureListener;
import kr.syeyoung.dungeonsguide.eventlistener.PacketListener;
import kr.syeyoung.dungeonsguide.features.FeatureRegistry;
+import kr.syeyoung.dungeonsguide.stomp.CloseListener;
+import kr.syeyoung.dungeonsguide.stomp.StompClient;
+import kr.syeyoung.dungeonsguide.stomp.StompInterface;
import kr.syeyoung.dungeonsguide.utils.AhUtils;
import lombok.Getter;
import net.minecraft.client.Minecraft;
@@ -17,6 +20,7 @@ import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
+import net.minecraftforge.fml.common.ProgressManager;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import org.apache.commons.io.IOUtils;
@@ -25,13 +29,17 @@ import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Set;
-public class e implements c {
+public class e implements c, CloseListener {
private SkyblockStatus skyblockStatus;
@@ -41,6 +49,9 @@ public class e implements c {
@Getter
private b authenticator;
+ @Getter
+ private StompInterface stompConnection;
+
public e(b authenticator) {
this.authenticator = authenticator;
}
@@ -53,6 +64,17 @@ public class e implements c {
CommandReparty commandReparty;
public void init(FMLInitializationEvent event) {
+ ProgressManager.ProgressBar progressbar = ProgressManager.push("DungeonsGuide", 4);
+
+ progressbar.step("Opening connection");
+ try {
+ stompConnection = new StompClient(new URI("wss://dungeonsguide.kro.kr/ws"), authenticator.c(), this);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+
+ progressbar.step("Registering Events & Commands");
dungeonsGuide = this;
skyblockStatus = new SkyblockStatus();
@@ -72,6 +94,7 @@ public class e implements c {
AhUtils.registerTimer();
+ progressbar.step("Downloading Roomdatas");
try {
DungeonRoomInfoRegistry.loadAll(configDir);
} catch (BadPaddingException e) {
@@ -89,14 +112,16 @@ public class e implements c {
} catch (InvalidKeyException e) {
e.printStackTrace();
}
-
Keybinds.register();
+ progressbar.step("Downloading Roomdatas");
try {
Config.loadConfig( null );
} catch (IOException e) {
e.printStackTrace();
}
+
+ ProgressManager.pop(progressbar);
}
public void pre(FMLPreInitializationEvent event) {
configDir = new File(event.getModConfigurationDirectory(),"dungeonsguide");
@@ -129,4 +154,11 @@ public class e implements c {
public static e getDungeonsGuide() {
return dungeonsGuide;
}
+
+ @Override
+ public void onClose(int code, String reason, boolean remote) {
+ System.out.println("Stomp Connection closed, trying to reconnect - "+reason+ " - "+code);
+// stompConnection = new StompClient(new URL("wss://dungeonsguide.kro.kr/ws").toURI(), authenticator.c(), this);
+// Minecraft.getMinecraft().
+ }
}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java
index adbf15c4..fa1b3c92 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java
@@ -66,6 +66,7 @@ public class FeatureRegistry {
public static final FeatureRepartyCommand ETC_REPARTY = register(new FeatureRepartyCommand());
public static final FeatureDecreaseExplosionSound ETC_EXPLOSION_SOUND = register(new FeatureDecreaseExplosionSound());
public static final FeatureAutoAcceptReparty ETC_AUTO_ACCEPT_REPARTY = register(new FeatureAutoAcceptReparty());
+ public static final FeatureBlah ETC_TEST = register(new FeatureBlah());
public static final SimpleFeature FIX_SPIRIT_BOOTS = register(new SimpleFeature("Fixes", "Spirit Boots Fixer", "Fix Spirit boots messing up with inventory", "fixes.spirit", true));
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureBlah.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureBlah.java
new file mode 100644
index 00000000..16c99db2
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/etc/FeatureBlah.java
@@ -0,0 +1,38 @@
+package kr.syeyoung.dungeonsguide.features.impl.etc;
+
+import kr.syeyoung.dungeonsguide.e;
+import kr.syeyoung.dungeonsguide.features.SimpleFeature;
+import kr.syeyoung.dungeonsguide.features.listener.TickListener;
+import kr.syeyoung.dungeonsguide.stomp.StompInterface;
+import kr.syeyoung.dungeonsguide.stomp.StompMessageHandler;
+import kr.syeyoung.dungeonsguide.stomp.StompPayload;
+import kr.syeyoung.dungeonsguide.stomp.StompSubscription;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.ChatComponentText;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class FeatureBlah extends SimpleFeature implements StompMessageHandler, TickListener {
+ public FeatureBlah() {
+ super("ETC", "TEST","test.test");
+ e.getDungeonsGuide().getStompConnection().subscribe(StompSubscription.builder()
+ .destination("/topic/updates")
+ .ackMode(StompSubscription.AckMode.AUTO)
+ .stompMessageHandler(this).build());
+ }
+
+ Queue<StompPayload> stompPayloadQueue = new ConcurrentLinkedQueue<StompPayload>();
+ @Override
+ public void handle(StompInterface stompInterface, StompPayload stompPayload) {
+ stompPayloadQueue.add(stompPayload);
+ }
+
+
+ @Override
+ public void onTick() {
+ while (!stompPayloadQueue.isEmpty()) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(stompPayloadQueue.poll().payload()));
+ }
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/CloseListener.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/CloseListener.java
new file mode 100644
index 00000000..a9b21cb7
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/CloseListener.java
@@ -0,0 +1,5 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+public interface CloseListener {
+ void onClose(int code, String reason, boolean remote);
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java
new file mode 100644
index 00000000..248bf04b
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClient.java
@@ -0,0 +1,136 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+import lombok.Getter;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.handshake.ServerHandshake;
+import org.java_websocket.server.DefaultSSLWebSocketServerFactory;
+import sun.security.ssl.SSLSocketFactoryImpl;
+
+import javax.net.ssl.SSLContext;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+public class StompClient extends WebSocketClient implements StompInterface {
+ public StompClient(URI serverUri, final String token, CloseListener closeListener) throws Exception {
+ super(serverUri);
+ this.closeListener = closeListener;
+ addHeader("Authorization", token);
+
+ connectBlocking();
+ while(this.stompClientStatus == StompClientStatus.CONNECTING);
+ }
+ private CloseListener closeListener;
+
+ @Getter
+ private volatile StompClientStatus stompClientStatus = StompClientStatus.CONNECTING;
+
+ @Getter
+ private StompPayload errorPayload;
+
+ @Override
+ public void onOpen(ServerHandshake handshakedata) {
+ send(new StompPayload().method(StompHeader.CONNECT)
+ .header("accept-version","1.2")
+ .header("host",uri.getHost()).getBuilt()
+ );
+ }
+
+ @Override
+ public void onMessage(String message) {
+ try {
+ StompPayload payload = StompPayload.parse(message);
+ if (payload.method() == StompHeader.CONNECTED) {
+ stompClientStatus = StompClientStatus.CONNECTED;
+ } else if (payload.method() == StompHeader.ERROR) {
+ errorPayload = payload;
+ stompClientStatus = StompClientStatus.ERROR;
+ this.close();
+ } else if (payload.method() == StompHeader.MESSAGE) {
+ // mesage
+ StompSubscription stompSubscription = stompSubscriptionMap.get(Integer.parseInt(payload.headers().get("subscription")));
+ try {
+ stompSubscription.getStompMessageHandler().handle(this, payload);
+ if (stompSubscription.getAckMode() != StompSubscription.AckMode.AUTO) {
+ send(new StompPayload().method(StompHeader.ACK)
+ .header("id",payload.headers().get("ack")).getBuilt()
+ );
+ }
+ } catch (Exception e) {
+ send(new StompPayload().method(StompHeader.NACK)
+ .header("id",payload.headers().get("ack")).getBuilt()
+ );
+ e.printStackTrace();
+ }
+ } else if (payload.method() == StompHeader.RECEIPT) {
+ String receipt_id = payload.headers().get("receipt-id");
+ StompPayload payload1 = receiptMap.remove(Integer.parseInt(receipt_id));
+ if (payload1.method() == StompHeader.DISCONNECT) {
+ stompClientStatus = StompClientStatus.DISCONNECTED;
+ close();
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onClose(int code, String reason, boolean remote) {
+ closeListener.onClose(code, reason, remote);
+ }
+
+ @Override
+ public void onError(Exception ex) {
+
+ }
+
+ private Map<Integer, StompSubscription> stompSubscriptionMap = new HashMap<Integer, StompSubscription>();
+ private Map<Integer, StompPayload> receiptMap = new HashMap<Integer, StompPayload>();
+
+ private int idIncrement = 0;
+
+ @Override
+ public void send(StompPayload payload) {
+ if (stompClientStatus != StompClientStatus.CONNECTED) throw new IllegalStateException("not connected");
+ payload.method(StompHeader.SEND);
+ if (payload.headers().get("receipt") != null)
+ receiptMap.put(Integer.parseInt(payload.headers().get("receipt")), payload);
+ send(payload);
+ }
+
+ @Override
+ public void subscribe(StompSubscription stompSubscription) {
+ if (stompClientStatus != StompClientStatus.CONNECTED) throw new IllegalStateException("not connected");
+ stompSubscription.setId(++idIncrement);
+
+ send(new StompPayload().method(StompHeader.SUBSCRIBE)
+ .header("id",String.valueOf(stompSubscription.getId()))
+ .header("destination", stompSubscription.getDestination())
+ .header("ack", stompSubscription.getAckMode().getValue()).getBuilt()
+ );
+
+ stompSubscriptionMap.put(stompSubscription.getId(), stompSubscription);
+ }
+
+ @Override
+ public void unsubscribe(StompSubscription stompSubscription) {
+ if (stompClientStatus != StompClientStatus.CONNECTED) throw new IllegalStateException("not connected");
+ send(new StompPayload().method(StompHeader.UNSUBSCRIBE)
+ .header("id",String.valueOf(stompSubscription.getId())).getBuilt()
+ );
+ stompSubscriptionMap.remove(stompSubscription.getId());
+ }
+
+ @Override
+ public void disconnect() {
+ if (stompClientStatus != StompClientStatus.CONNECTED) throw new IllegalStateException("not connected");
+ StompPayload stompPayload;
+ stompClientStatus =StompClientStatus.DISCONNECTING;
+ send((stompPayload = new StompPayload().method(StompHeader.DISCONNECT)
+ .header("receipt", String.valueOf(++idIncrement)))
+ .getBuilt()
+ );
+ receiptMap.put(idIncrement, stompPayload);
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClientStatus.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClientStatus.java
new file mode 100644
index 00000000..b3f5cbc2
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompClientStatus.java
@@ -0,0 +1,5 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+public enum StompClientStatus {
+ CONNECTING, CONNECTED, ERROR, DISCONNECTING, DISCONNECTED;
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompHeader.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompHeader.java
new file mode 100644
index 00000000..0e9c4311
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompHeader.java
@@ -0,0 +1,9 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+
+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/stomp/StompInterface.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompInterface.java
new file mode 100644
index 00000000..e78f8ceb
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompInterface.java
@@ -0,0 +1,8 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+public interface StompInterface {
+ void send(StompPayload payload);
+ void subscribe(StompSubscription stompSubscription);
+ void unsubscribe(StompSubscription stompSubscription);
+ void disconnect();
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompMessageHandler.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompMessageHandler.java
new file mode 100644
index 00000000..7b13c1fd
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompMessageHandler.java
@@ -0,0 +1,5 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+public interface StompMessageHandler {
+ void handle(StompInterface stompInterface, StompPayload stompPayload);
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompPayload.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompPayload.java
new file mode 100644
index 00000000..9476241c
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompPayload.java
@@ -0,0 +1,69 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+import lombok.Data;
+import lombok.Singular;
+import lombok.experimental.Accessors;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+@Data
+@Accessors(chain = true, fluent = true)
+public class StompPayload {
+ private StompHeader method;
+ private Map<String, String> headers = new HashMap<String, String>();
+ private String payload;
+
+ public StompPayload header(String key, String value) {
+ headers.put(key, 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);
+ System.out.println("Probably sending "+sb.toString());
+ return sb.toString();
+ }
+
+ public static StompPayload parse(String payload) {
+ System.out.println("Parsing "+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);
+ }
+
+ StringBuilder payloadBuilder = new StringBuilder();
+ while (scanner.hasNextLine() && !(line = scanner.nextLine()).equals("\0")) {
+ payloadBuilder.append(line);
+ payloadBuilder.append("\n");
+ }
+ stompPayload.payload = payloadBuilder.toString();
+ return stompPayload;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompSubscription.java b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompSubscription.java
new file mode 100644
index 00000000..5ecbeb06
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/stomp/StompSubscription.java
@@ -0,0 +1,23 @@
+package kr.syeyoung.dungeonsguide.stomp;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+
+@Data
+@Builder
+public class StompSubscription {
+ private int id;
+ private String destination;
+ private StompMessageHandler stompMessageHandler;
+ private AckMode ackMode;
+
+ @AllArgsConstructor
+ public static enum AckMode {
+ AUTO("auto"), CLIENT("client"), CLIENT_INDIVIDUAL("client-individual");
+
+ @Getter
+ private String value;
+ }
+}