diff --git a/pom.xml b/pom.xml
index 1e812fb..e2c5be2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
dev.koifysh
archipelago-client
- 0.1.13
+ 0.1.18
Archipelago Java Library
Library to connect to an Archipelago Server
@@ -48,7 +48,7 @@
com.google.code.gson
gson
- 2.8.9
+ 2.11.0
org.apache.httpcomponents.client5
@@ -60,11 +60,6 @@
httpcore5
5.2
-
- org.slf4j
- slf4j-nop
- 1.7.30
-
diff --git a/src/main/java/dev/koifysh/archipelago/Client.java b/src/main/java/dev/koifysh/archipelago/Client.java
index 312fe58..d093885 100644
--- a/src/main/java/dev/koifysh/archipelago/Client.java
+++ b/src/main/java/dev/koifysh/archipelago/Client.java
@@ -338,19 +338,6 @@ public void scoutLocations(ArrayList locationIDs) {
webSocket.scoutLocation(locationIDs);
}
- /**
- * Called when the server wishes to display a message to the user.
- *
- * Deprecated use {@link dev.koifysh.archipelago.events.PrintJSONEvent} instead
- * @see dev.koifysh.archipelago.events.PrintJSONEvent
- * @param apPrint list of message segments.
- * @param type the type of the received message.
- * @param player int id of the sending player.
- * @param item the network item that is involved with the message.
- */
- @Deprecated
- public abstract void onPrintJson(APPrint apPrint, String type, int player, NetworkItem item);
-
public abstract void onError(Exception ex);
public abstract void onClose(String Reason, int attemptingReconnect);
diff --git a/src/main/java/dev/koifysh/archipelago/EventManager.java b/src/main/java/dev/koifysh/archipelago/EventManager.java
index 3f6d1da..6fbd71c 100644
--- a/src/main/java/dev/koifysh/archipelago/EventManager.java
+++ b/src/main/java/dev/koifysh/archipelago/EventManager.java
@@ -5,6 +5,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
@@ -24,17 +25,39 @@ public class EventManager {
*/
public void registerListener(Object listener) {
for (Method method : listener.getClass().getMethods()) {
- if (!method.isAnnotationPresent(ArchipelagoEventListener.class))
- continue;
- if (method.getParameterTypes().length != 1)
- continue;
- if (!Event.class.isAssignableFrom(method.getParameterTypes()[0]))
- continue;
+ if (isEventListenerMethod(listener, method)) continue;
registeredListeners.put(method, listener);
}
}
+ /**
+ * Use to unregister for Events that come from the Archipelago server.
+ * supplied Object must have at least 1 method annotated with {@link ArchipelagoEventListener}
+ * and have 1 parameter that extends {@link Event}
+ * @param listener the object containing a listener method.
+ */
+ public void unRegisterListener(Object listener) {
+ for (Method method : listener.getClass().getMethods()) {
+ if (isEventListenerMethod(listener, method)) continue;
+
+ registeredListeners.remove(method, listener);
+ }
+ }
+
+ private boolean isEventListenerMethod(Object listener, Method method) {
+ if(listener instanceof Class>)
+ if (!Modifier.isStatic(method.getModifiers()))
+ return true;
+ if (!method.isAnnotationPresent(ArchipelagoEventListener.class))
+ return true;
+ if (method.getParameterTypes().length != 1)
+ return true;
+ if (!Event.class.isAssignableFrom(method.getParameterTypes()[0]))
+ return true;
+ return false;
+ }
+
public void callEvent(final Event event) {
for (Map.Entry methodObjectEntry : registeredListeners.entrySet()) {
Method method = methodObjectEntry.getKey();
diff --git a/src/main/java/dev/koifysh/archipelago/ItemManager.java b/src/main/java/dev/koifysh/archipelago/ItemManager.java
index 2a7276e..9766d00 100644
--- a/src/main/java/dev/koifysh/archipelago/ItemManager.java
+++ b/src/main/java/dev/koifysh/archipelago/ItemManager.java
@@ -34,7 +34,7 @@ public void receiveItems(ArrayList ids, int index) {
item.itemName = dp.getItem(item.itemID, client.getGame());
item.locationName = dp.getLocation(item.locationID, client.getSlotInfo().get(item.playerID).game);
item.playerName = client.getRoomInfo().getPlayer(myTeam,item.playerID).alias;
- client.getEventManager().callEvent(new ReceiveItemEvent(item, index));
+ client.getEventManager().callEvent(new ReceiveItemEvent(item, i+1));
}
this.index = receivedItems.size();
diff --git a/src/main/java/dev/koifysh/archipelago/Print/APPrint.java b/src/main/java/dev/koifysh/archipelago/Print/APPrint.java
index 822a508..9462b11 100644
--- a/src/main/java/dev/koifysh/archipelago/Print/APPrint.java
+++ b/src/main/java/dev/koifysh/archipelago/Print/APPrint.java
@@ -9,7 +9,7 @@ public class APPrint {
public APPrintPart[] parts;
@SerializedName("type")
- public String type;
+ public APPrintJsonType type;
@SerializedName("receiving")
public int receiving;
diff --git a/src/main/java/dev/koifysh/archipelago/Print/APPrintJsonType.java b/src/main/java/dev/koifysh/archipelago/Print/APPrintJsonType.java
new file mode 100644
index 0000000..ce1458c
--- /dev/null
+++ b/src/main/java/dev/koifysh/archipelago/Print/APPrintJsonType.java
@@ -0,0 +1,102 @@
+package dev.koifysh.archipelago.Print;
+
+import com.google.gson.annotations.SerializedName;
+
+public enum APPrintJsonType {
+
+ /**
+ * A player received an item.
+ */
+ @SerializedName("ItemSend")
+ ItemSend,
+
+ /**
+ * A player used the `!getitem` command.
+ */
+ @SerializedName("ItemCheat")
+ ItemCheat,
+
+ /**
+ * A player hinted.
+ */
+ @SerializedName("Hint")
+ Hint,
+
+ /**
+ * A player connected.
+ */
+ @SerializedName("Join")
+ Join,
+
+ /**
+ * A player disconnected.
+ */
+ @SerializedName("Part")
+ Part,
+
+ /**
+ * A player sent a chat message.
+ */
+ @SerializedName("Chat")
+ Chat,
+
+ /**
+ * The server broadcast a message.
+ */
+ @SerializedName("ServerChat")
+ ServerChat,
+
+ /**
+ * The client has triggered a tutorial message, such as when first connecting.
+ */
+ @SerializedName("entrance_name")
+ Tutorial,
+
+ /**
+ * A player changed their tags.
+ */
+ @SerializedName("TagsChanged")
+ TagsChanged,
+
+ /**
+ * Someone (usually the client) entered an ! command.
+ */
+ @SerializedName("CommandResult")
+ CommandResult,
+
+ /**
+ * The client entered an !admin command.
+ */
+ @SerializedName("AdminCommandResult")
+ AdminCommandResult,
+
+ /**
+ * A player reached their goal.
+ */
+ @SerializedName("Goal")
+ Goal,
+
+ /**
+ * A player released the remaining items in their world.
+ */
+ @SerializedName("Release")
+ Release,
+
+ /**
+ * A player collected the remaining items for their world.
+ */
+ @SerializedName("Collect")
+ Collect,
+
+ /**
+ * The current server countdown has progressed.
+ */
+ @SerializedName("Countdown")
+ Countdown,
+
+ /**
+ * The Message type was not set, or is invalid.
+ */
+ Unknown
+
+}
diff --git a/src/main/java/dev/koifysh/archipelago/WebSocket.java b/src/main/java/dev/koifysh/archipelago/WebSocket.java
index cdd814b..a66c191 100644
--- a/src/main/java/dev/koifysh/archipelago/WebSocket.java
+++ b/src/main/java/dev/koifysh/archipelago/WebSocket.java
@@ -5,6 +5,8 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import dev.koifysh.archipelago.Print.APPrint;
+import dev.koifysh.archipelago.Print.APPrintJsonType;
+import dev.koifysh.archipelago.Print.APPrintPart;
import dev.koifysh.archipelago.Print.APPrintType;
import dev.koifysh.archipelago.helper.DeathLink;
import dev.koifysh.archipelago.network.APPacket;
@@ -19,6 +21,7 @@
import dev.koifysh.archipelago.events.*;
import dev.koifysh.archipelago.network.server.*;
+import dev.koifysh.archipelago.parts.NetworkSlot;
import org.apache.hc.core5.net.URIBuilder;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
@@ -66,8 +69,8 @@ public void onMessage(String message) {
JsonArray cmdList = element.getAsJsonArray();
- for (int i = 0; cmdList.size() > i; ++i) {
- JsonElement packet = cmdList.get(i);
+ for (int commandNumber = 0; cmdList.size() > commandNumber; ++commandNumber) {
+ JsonElement packet = cmdList.get(commandNumber);
//parse the packet first to see what command has been sent.
APPacket cmd = gson.fromJson(packet, APPacket.class);
@@ -102,10 +105,19 @@ public void onMessage(String message) {
client.setTeam(connectedPacket.team);
client.setSlot(connectedPacket.slot);
+ connectedPacket.slotInfo.put(0, new NetworkSlot("Archipelago", "Archipelago", NetworkSlot.flags.SPECTATOR));
client.setSlotInfo(connectedPacket.slotInfo);
client.getRoomInfo().networkPlayers.addAll(connectedPacket.players);
- client.getRoomInfo().networkPlayers.add(new NetworkPlayer(connectedPacket.team, 0, "Archipelago"));
+ int teams = 1;
+ OptionalInt teamsOptional = client.getRoomInfo().networkPlayers.stream().mapToInt(player -> player.team).max();
+ if (teamsOptional.isPresent()) {
+ teams = teamsOptional.getAsInt() + 1;
+ }
+ for (int i = 0; i < teams; i++) {
+ client.getRoomInfo().networkPlayers.add( new NetworkPlayer(i, 0, "Archipelago"));
+ }
+
client.setAlias(client.getRoomInfo().getPlayer(connectedPacket.team, connectedPacket.slot).alias);
JsonElement slotData = packet.getAsJsonObject().get("slot_data");
@@ -129,7 +141,7 @@ public void onMessage(String message) {
}
break;
case ConnectionRefused:
- ConnectionRefusedPacket error = gson.fromJson(cmdList.get(i), ConnectionRefusedPacket.class);
+ ConnectionRefusedPacket error = gson.fromJson(cmdList.get(commandNumber), ConnectionRefusedPacket.class);
client.getEventManager().callEvent(new ConnectionResultEvent(error.errors[0]));
break;
case DataPackage:
@@ -142,27 +154,28 @@ public void onMessage(String message) {
case PrintJSON:
LOGGER.finest("PrintJSON packet");
APPrint print = gson.fromJson(packet, APPrint.class);
+ if (print.type == null) print.type = APPrintJsonType.Unknown;
//filter though all player IDs and replace id with alias.
- for (int p = 0; print.parts.length > p; ++p) {
- if (print.parts[p].type == APPrintType.playerID) {
- int playerID = Integer.parseInt((print.parts[p].text));
- NetworkPlayer player = client.getRoomInfo().getPlayer(client.getTeam(), playerID);
+ for (int partNumber = 0; print.parts.length > partNumber; ++partNumber) {
+ APPrintPart part = print.parts[partNumber];
- print.parts[p].text = player.alias;
- } else if (print.parts[p].type == APPrintType.itemID) {
- long itemID = Long.parseLong(print.parts[p].text);
- print.parts[p].text = client.getDataPackage().getItem(itemID, client.getSlotInfo().get(print.parts[i].player).game);
- } else if (print.parts[p].type == APPrintType.locationID) {
- long locationID = Long.parseLong(print.parts[p].text);
- print.parts[p].text = client.getDataPackage().getLocation(locationID, client.getSlotInfo().get(print.parts[i].player).game);
+ if (part.type == APPrintType.playerID) {
+ int playerID = Integer.parseInt(part.text);
+ NetworkPlayer player = client.getRoomInfo().getPlayer(client.getTeam(), playerID);
+ part.text = player.alias;
+ }
+ else if (part.type == APPrintType.itemID) {
+ long itemID = Long.parseLong(part.text);
+ part.text = client.getDataPackage().getItem(itemID, client.getSlotInfo().get(part.player).game);
+ }
+ else if (part.type == APPrintType.locationID) {
+ long locationID = Long.parseLong(part.text);
+ part.text = client.getDataPackage().getLocation(locationID, client.getSlotInfo().get(part.player).game);
}
}
client.getEventManager().callEvent(new PrintJSONEvent(print, print.type, print.receiving, print.item));
- //todo: remove next version
- client.onPrintJson(print, print.type, print.receiving, print.item);
-
break;
case RoomUpdate:
RoomUpdatePacket updatePacket = gson.fromJson(packet, RoomUpdatePacket.class);
@@ -205,15 +218,14 @@ public void onMessage(String message) {
}
}
} catch (Exception e) {
- LOGGER.warning("Error proccessing incoming packet: ");
- e.printStackTrace();
+ LOGGER.warning("Error proccessing incoming packet: " + e.getMessage());
+ //e.printStackTrace();
}
}
private void updateRoom(RoomUpdatePacket updateRoomPacket) {
if (!updateRoomPacket.networkPlayers.isEmpty()) {
client.getRoomInfo().networkPlayers = updateRoomPacket.networkPlayers;
- client.getRoomInfo().networkPlayers.add(new NetworkPlayer(client.getTeam(), 0, "Archipelago"));
}
client.setHintPoints(updateRoomPacket.hintPoints);
@@ -316,8 +328,8 @@ public void onError(Exception ex) {
return;
}
client.onError(ex);
- LOGGER.log(Level.WARNING, "Error in websocket connection");
- ex.printStackTrace();
+ LOGGER.log(Level.WARNING, "Error in websocket connection: " + ex.getMessage());
+ //ex.printStackTrace();
}
public void connect(boolean allowDowngrade) {
diff --git a/src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java b/src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java
index 01f639d..3ecf040 100644
--- a/src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java
+++ b/src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java
@@ -1,6 +1,7 @@
package dev.koifysh.archipelago.events;
import dev.koifysh.archipelago.Print.APPrint;
+import dev.koifysh.archipelago.Print.APPrintJsonType;
import dev.koifysh.archipelago.parts.NetworkItem;
/**
@@ -9,7 +10,7 @@
public class PrintJSONEvent implements Event {
public APPrint apPrint;
- public String type;
+ public APPrintJsonType type;
public int player;
public NetworkItem item;
@@ -19,7 +20,7 @@ public class PrintJSONEvent implements Event {
* @param player int id of the sending player.
* @param item the network item that is involved with the message.
*/
- public PrintJSONEvent(APPrint apPrint, String type, int player, NetworkItem item) {
+ public PrintJSONEvent(APPrint apPrint, APPrintJsonType type, int player, NetworkItem item) {
this.apPrint = apPrint;
this.type = type;
this.player = player;
diff --git a/src/main/java/dev/koifysh/archipelago/parts/NetworkSlot.java b/src/main/java/dev/koifysh/archipelago/parts/NetworkSlot.java
index bd494f4..813d210 100644
--- a/src/main/java/dev/koifysh/archipelago/parts/NetworkSlot.java
+++ b/src/main/java/dev/koifysh/archipelago/parts/NetworkSlot.java
@@ -38,4 +38,10 @@ public static class flags {
public final static int GROUP = 0b100;
}
+
+ public NetworkSlot(String name, String game, int type) {
+ this.name = name;
+ this.game = game;
+ this.type = type;
+ }
}