From c83729108193ae573205ca05c34de6ae23c99d60 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 20:30:52 -0700 Subject: [PATCH 01/17] convert from version based datapackage tracking to checksum based tracking. --- build.gradle | 3 +- .../archipelago/client/ArchipelagoClient.java | 16 ++++- .../client/ArchipelagoWebSocket.java | 68 ++++++++++--------- .../gg/archipelago/client/ItemManager.java | 4 +- .../gg/archipelago/client/Print/APPrint.java | 15 ++++ .../archipelago/client/Print/APPrintPart.java | 3 + .../network/client/GetDataPackagePacket.java | 6 +- .../network/server/ConnectedPacket.java | 4 ++ .../client/network/server/RoomInfoPacket.java | 18 +++-- .../network/server/RoomUpdatePacket.java | 4 +- .../archipelago/client/parts/DataPackage.java | 52 ++++++-------- .../gg/archipelago/client/parts/Game.java | 37 ++++++++-- .../archipelago/client/parts/NetworkSlot.java | 41 +++++++++++ 13 files changed, 181 insertions(+), 90 deletions(-) create mode 100644 src/main/java/gg/archipelago/client/parts/NetworkSlot.java diff --git a/build.gradle b/build.gradle index 7f54ef3..d779d50 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { archivesBaseName = "Archipelago.MultiClient.Java" group = 'gg.archipelago.APClient' -version = '1.12' +version = '1.13' java.toolchain.languageVersion = JavaLanguageVersion.of(8) @@ -23,6 +23,7 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.9' implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1' implementation 'org.apache.httpcomponents.core5:httpcore5:5.2' + implementation 'org.slf4j:slf4j-nop:1.7.30' } tasks.register('relocateShadowJar', ConfigureShadowRelocation) { diff --git a/src/main/java/gg/archipelago/client/ArchipelagoClient.java b/src/main/java/gg/archipelago/client/ArchipelagoClient.java index f29184d..7bf330f 100644 --- a/src/main/java/gg/archipelago/client/ArchipelagoClient.java +++ b/src/main/java/gg/archipelago/client/ArchipelagoClient.java @@ -1,5 +1,6 @@ package gg.archipelago.client; +import com.google.gson.annotations.SerializedName; import gg.archipelago.client.Print.APPrint; import gg.archipelago.client.helper.DeathLink; import gg.archipelago.client.network.client.*; @@ -7,14 +8,15 @@ import gg.archipelago.client.network.server.RoomInfoPacket; import gg.archipelago.client.parts.DataPackage; import gg.archipelago.client.parts.NetworkItem; +import gg.archipelago.client.parts.NetworkSlot; import gg.archipelago.client.parts.Version; import org.apache.hc.core5.net.URIBuilder; +import org.slf4j.event.Level; import java.io.*; import java.net.URI; import java.net.URISyntaxException; import java.util.*; -import java.util.logging.Level; import java.util.logging.Logger; public abstract class ArchipelagoClient { @@ -41,10 +43,11 @@ public abstract class ArchipelagoClient { private final ItemManager itemManager; private final EventManager eventManager; - public static final Version protocolVersion = new Version(0, 3, 7); + public static final Version protocolVersion = new Version(0, 4, 7); private int team; private int slot; + private HashMap slotInfo; private String name = "Name not set"; private String game = "Game not set"; private String alias; @@ -138,7 +141,7 @@ void saveDataPackage() { objectOut.close(); } catch (IOException e) { - LOGGER.log(Level.WARNING, "unable to save DataPackage.", e); + LOGGER.warning("unable to save DataPackage."); } } @@ -171,6 +174,10 @@ void setTeam(int team) { this.team = team; } + void setSlotInfo(HashMap slotInfo) { + this.slotInfo = slotInfo; + } + void setRoomInfo(RoomInfoPacket roomInfo) { this.roomInfo = roomInfo; } @@ -191,6 +198,8 @@ public RoomInfoPacket getRoomInfo() { return roomInfo; } + public HashMap getSlotInfo() {return slotInfo;} + public void connect(String address) throws URISyntaxException { URIBuilder builder = new URIBuilder((!address.contains("//")) ? "//" + address : address); if (builder.getPort() == -1) { //set default port if not included @@ -406,4 +415,5 @@ public int dataStorageGet(Collection keys) { archipelagoWebSocket.sendPacket(getPacket); return getPacket.getRequestID(); } + } diff --git a/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java b/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java index e558a5a..618641d 100644 --- a/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java +++ b/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java @@ -79,7 +79,7 @@ public void onMessage(String message) { //save room info archipelagoClient.setRoomInfo(roomInfo); - checkDataPackage(roomInfo.datapackageVersions); + checkDataPackage(roomInfo.datapackageChecksums, roomInfo.games); seedName = roomInfo.seedName; @@ -101,6 +101,7 @@ public void onMessage(String message) { archipelagoClient.setTeam(connectedPacket.team); archipelagoClient.setSlot(connectedPacket.slot); + archipelagoClient.setSlotInfo(connectedPacket.slotInfo); archipelagoClient.getRoomInfo().networkPlayers.addAll(connectedPacket.players); archipelagoClient.getRoomInfo().networkPlayers.add(new NetworkPlayer(connectedPacket.team, 0, "Archipelago")); @@ -138,14 +139,11 @@ public void onMessage(String message) { DataPackage dataPackage = gson.fromJson(data, DataPackage.class); dataPackage.uuid = archipelagoClient.getUUID(); archipelagoClient.updateDataPackage(dataPackage); - if (dataPackage.getVersion() != 0) { - archipelagoClient.saveDataPackage(); - } + archipelagoClient.saveDataPackage(); break; case PrintJSON: LOGGER.finest("PrintJSON packet"); APPrint print = gson.fromJson(packet, APPrint.class); - //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) { @@ -154,11 +152,11 @@ public void onMessage(String message) { print.parts[p].text = player.alias; } else if (print.parts[p].type == APPrintType.itemID) { - int itemID = Integer.parseInt((print.parts[p].text)); - print.parts[p].text = archipelagoClient.getDataPackage().getItem(itemID); + long itemID = Long.parseLong(print.parts[p].text); + print.parts[p].text = archipelagoClient.getDataPackage().getItem(itemID,archipelagoClient.getSlotInfo().get(print.parts[i].player).game); } else if (print.parts[p].type == APPrintType.locationID) { - int locationID = Integer.parseInt((print.parts[p].text)); - print.parts[p].text = archipelagoClient.getDataPackage().getLocation(locationID); + long locationID = Long.parseLong(print.parts[p].text); + print.parts[p].text = archipelagoClient.getDataPackage().getLocation(locationID,archipelagoClient.getSlotInfo().get(print.parts[i].player).game); } } archipelagoClient.onPrintJson(print, print.type, print.receiving, print.item); @@ -182,8 +180,8 @@ public void onMessage(String message) { case LocationInfo: LocationInfoPacket locations = gson.fromJson(packet, LocationInfoPacket.class); for (NetworkItem item : locations.locations) { - item.itemName = archipelagoClient.getDataPackage().getItem(item.itemID); - item.locationName = archipelagoClient.getDataPackage().getLocation(item.locationID); + item.itemName = archipelagoClient.getDataPackage().getItem(item.itemID, archipelagoClient.getSlotInfo().get(item.playerID).game); + item.locationName = archipelagoClient.getDataPackage().getLocation(item.locationID, archipelagoClient.getSlotInfo().get(archipelagoClient.getSlot()).game); item.playerName = archipelagoClient.getRoomInfo().getPlayer(archipelagoClient.getTeam(), item.playerID).alias; } archipelagoClient.getEventManager().callEvent(new LocationInfoEvent(locations.locations)); @@ -210,37 +208,38 @@ public void onMessage(String message) { } private void updateRoom(RoomUpdatePacket updateRoomPacket) { - if (updateRoomPacket.networkPlayers.size() != 0) { + if (!updateRoomPacket.networkPlayers.isEmpty()) { archipelagoClient.getRoomInfo().networkPlayers = updateRoomPacket.networkPlayers; archipelagoClient.getRoomInfo().networkPlayers.add(new NetworkPlayer(archipelagoClient.getTeam(), 0, "Archipelago")); } - checkDataPackage(updateRoomPacket.datapackageVersions); - archipelagoClient.setHintPoints(updateRoomPacket.hintPoints); archipelagoClient.setAlias(archipelagoClient.getRoomInfo().getPlayer(archipelagoClient.getTeam(), archipelagoClient.getSlot()).alias); archipelagoClient.getEventManager().callEvent(new CheckedLocationsEvent(updateRoomPacket.checkedLocations)); } - private void checkDataPackage(HashMap versions) { - HashSet exclusions = new HashSet<>(); - for (Map.Entry game : versions.entrySet()) { - //the game does NOT need updating add it to the exclusion list. - int myGameVersion = archipelagoClient.getDataPackage().getVersions().getOrDefault(game.getKey(), 0); - int newGameVersion = game.getValue(); - if (newGameVersion <= myGameVersion && newGameVersion != 0) { - exclusions.add(game.getKey()); - } + + private void checkDataPackage(HashMap versions, List games) { + Set gamesToUpdate = new HashSet<>(); + Map checksums = archipelagoClient.getDataPackage().getChecksums(); + for (Map.Entry game : versions.entrySet()) { + if (!games.contains(game.getKey())) + continue; + if (!checksums.containsKey(game.getKey())) + gamesToUpdate.add(game.getKey()); + if (!checksums.get(game.getKey()).equals(game.getValue())) + gamesToUpdate.add(game.getKey()); } - if (exclusions.size() != versions.size()) { - fetchDataPackageFromAP(exclusions); + + if (!gamesToUpdate.isEmpty()) { + fetchDataPackageFromAP(gamesToUpdate); } } - private void fetchDataPackageFromAP(Set exclusions) { - sendPacket(new GetDataPackagePacket(exclusions)); + private void fetchDataPackageFromAP(Set games) { + sendPacket(new GetDataPackagePacket(games)); } public void sendPacket(APPacket packet) { @@ -267,16 +266,16 @@ public void onClose(int code, String wsReason, boolean remote) { try { archipelagoClient.connect(new URIBuilder(uri).setScheme("ws").build()); } catch (URISyntaxException ignored) { - archipelagoClient.onClose(reason, 0); + archipelagoClient.onClose("(AP-275) " + reason, 0); } return; } - archipelagoClient.onClose(reason, 0); + archipelagoClient.onClose("(AP-279) " + reason, 0); return; } if (code == 1000) { reconnectTimer.cancel(); - archipelagoClient.onClose("Disconnected.", 0); + archipelagoClient.onClose("(AP-284) Disconnected.", 0); } if (code == 1006) { @@ -294,18 +293,21 @@ public void run() { reconnectTimer.cancel(); reconnectTimer = new Timer(); reconnectTimer.schedule(reconnectTask, reconnectDelay); - archipelagoClient.onClose(reason, reconnectDelay / 1000); + archipelagoClient.onClose("(AP-302) " + reason, reconnectDelay / 1000); return; } } reconnectTimer.cancel(); - archipelagoClient.onClose(reason, 0); + archipelagoClient.onClose("(AP-308) "+reason, 0); } @Override public void onError(Exception ex) { - if (ex instanceof SSLException) return; + if (ex instanceof SSLException) { + LOGGER.info(String.format("SSL Error: %s", ex.getMessage())); + return; + } archipelagoClient.onError(ex); LOGGER.log(Level.WARNING, "Error in websocket connection"); ex.printStackTrace(); diff --git a/src/main/java/gg/archipelago/client/ItemManager.java b/src/main/java/gg/archipelago/client/ItemManager.java index aa8bbbb..02a1d1e 100644 --- a/src/main/java/gg/archipelago/client/ItemManager.java +++ b/src/main/java/gg/archipelago/client/ItemManager.java @@ -31,8 +31,8 @@ public void receiveItems(ArrayList ids, int index) { int myTeam = archipelagoClient.getTeam(); for (int i = this.index; i < receivedItems.size(); i++) { NetworkItem item = receivedItems.get(i); - item.itemName = dp.getItem(item.itemID); - item.locationName = dp.getLocation(item.locationID); + item.itemName = dp.getItem(item.itemID, archipelagoClient.getGame()); + item.locationName = dp.getLocation(item.locationID, archipelagoClient.getSlotInfo().get(item.playerID).game); item.playerName = archipelagoClient.getRoomInfo().getPlayer(myTeam,item.playerID).alias; archipelagoClient.getEventManager().callEvent(new ReceiveItemEvent(item, index)); } diff --git a/src/main/java/gg/archipelago/client/Print/APPrint.java b/src/main/java/gg/archipelago/client/Print/APPrint.java index be47489..4f10c8d 100644 --- a/src/main/java/gg/archipelago/client/Print/APPrint.java +++ b/src/main/java/gg/archipelago/client/Print/APPrint.java @@ -20,4 +20,19 @@ public class APPrint { @SerializedName("found") public boolean found; + @SerializedName("team") + public String team; + + @SerializedName("slot") + public int slot; + + @SerializedName("message") + public String message; + + @SerializedName("tags") + public String[] tags; + + @SerializedName("countdown") + public int countdown; + } diff --git a/src/main/java/gg/archipelago/client/Print/APPrintPart.java b/src/main/java/gg/archipelago/client/Print/APPrintPart.java index ed5d53c..2cbcbe1 100644 --- a/src/main/java/gg/archipelago/client/Print/APPrintPart.java +++ b/src/main/java/gg/archipelago/client/Print/APPrintPart.java @@ -4,4 +4,7 @@ public class APPrintPart { public APPrintType type = APPrintType.text; public APPrintColor color = APPrintColor.none; public String text = ""; + public int player = 0; + public int flags = 0; + } diff --git a/src/main/java/gg/archipelago/client/network/client/GetDataPackagePacket.java b/src/main/java/gg/archipelago/client/network/client/GetDataPackagePacket.java index 2d6c77f..92c6053 100644 --- a/src/main/java/gg/archipelago/client/network/client/GetDataPackagePacket.java +++ b/src/main/java/gg/archipelago/client/network/client/GetDataPackagePacket.java @@ -7,14 +7,14 @@ public class GetDataPackagePacket extends APPacket { - Set exclusions; + Set games; public GetDataPackagePacket() { this(null); } - public GetDataPackagePacket(Set exclusions) { + public GetDataPackagePacket(Set games) { super(APPacketType.GetDataPackage); - this.exclusions = exclusions; + this.games = games; } } diff --git a/src/main/java/gg/archipelago/client/network/server/ConnectedPacket.java b/src/main/java/gg/archipelago/client/network/server/ConnectedPacket.java index 02e7c90..91215c2 100644 --- a/src/main/java/gg/archipelago/client/network/server/ConnectedPacket.java +++ b/src/main/java/gg/archipelago/client/network/server/ConnectedPacket.java @@ -4,8 +4,10 @@ import gg.archipelago.client.network.APPacket; import gg.archipelago.client.network.APPacketType; import gg.archipelago.client.parts.NetworkPlayer; +import gg.archipelago.client.parts.NetworkSlot; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; public class ConnectedPacket extends APPacket { @@ -20,6 +22,8 @@ public class ConnectedPacket extends APPacket { public HashSet missingLocations = new HashSet<>(); @SerializedName("checked_locations") public HashSet checkedLocations = new HashSet<>(); + @SerializedName("slot_info") + public HashMap slotInfo; public ConnectedPacket() { super(APPacketType.Connected); diff --git a/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java b/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java index 49020ba..0a7407f 100644 --- a/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java +++ b/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java @@ -5,6 +5,7 @@ import gg.archipelago.client.network.APPacketType; import gg.archipelago.client.network.RemainingMode; import gg.archipelago.client.parts.NetworkPlayer; +import gg.archipelago.client.parts.NetworkSlot; import gg.archipelago.client.parts.Version; import java.util.ArrayList; @@ -14,15 +15,14 @@ public class RoomInfoPacket extends APPacket { public Version version; + @SerializedName("generator_version") + public Version generatorVersion; + public String[] tags; public boolean password; - @SerializedName("forfeit_mode") - public RemainingMode.ForfeitMode forfeitMode; - - @SerializedName("remaining_mode") - public RemainingMode remainingMode; + public HashMap permissions; @SerializedName("hint_cost") public int hintCost; @@ -35,8 +35,9 @@ public class RoomInfoPacket extends APPacket { @SerializedName("games") public ArrayList games = new ArrayList<>(); - @SerializedName("datapackage_versions") - public HashMap datapackageVersions = new HashMap<>(); + + @SerializedName("datapackage_checksums") + public HashMap datapackageChecksums = new HashMap<>(); @SerializedName("seed_name") public String seedName; @@ -44,9 +45,6 @@ public class RoomInfoPacket extends APPacket { @SerializedName("time") public double time; - @SerializedName("permissions") - public HashMap permissions; - public RoomInfoPacket() { super(APPacketType.RoomInfo); } diff --git a/src/main/java/gg/archipelago/client/network/server/RoomUpdatePacket.java b/src/main/java/gg/archipelago/client/network/server/RoomUpdatePacket.java index 183a76c..b7a37e1 100644 --- a/src/main/java/gg/archipelago/client/network/server/RoomUpdatePacket.java +++ b/src/main/java/gg/archipelago/client/network/server/RoomUpdatePacket.java @@ -48,8 +48,8 @@ public class RoomUpdatePacket extends APPacket { @SerializedName("datapackage_version") public int datapackageVersion; - @SerializedName("datapackage_versions") - public HashMap datapackageVersions = new HashMap<>(); + @SerializedName("datapackage_checksums") + public HashMap datapackageChecksums = new HashMap<>(); public RoomUpdatePacket() { super(APPacketType.RoomUpdate); diff --git a/src/main/java/gg/archipelago/client/parts/DataPackage.java b/src/main/java/gg/archipelago/client/parts/DataPackage.java index 4f7da0b..765ed39 100644 --- a/src/main/java/gg/archipelago/client/parts/DataPackage.java +++ b/src/main/java/gg/archipelago/client/parts/DataPackage.java @@ -12,44 +12,36 @@ public class DataPackage implements Serializable { @SerializedName("games") HashMap games = new HashMap<>(); - @Expose - @SerializedName("version") - int version = -1; - HashMap itemIdToName = new HashMap<>(); HashMap locationIdToName = new HashMap<>(); public String uuid = UUID.randomUUID().toString(); - public String getItem(long itemID) { - for (Map.Entry game : games.entrySet()) { - for (Map.Entry item : game.getValue().itemNameToId.entrySet()) { - if(item.getValue() == itemID) - return item.getKey(); - } - } - return String.format("Unknown Item [%d]", itemID); + public String getItem(long itemID, String game) { + if (!games.containsKey(game)) + return String.format("Unknown Item [%d] for [%s]", itemID, game); + + if(!games.get(game).itemNameToId.containsValue(itemID)) + return String.format("Unknown Item [%d] for [%s]", itemID, game); + + return games.get(game).getItem(itemID); } - public String getLocation(long locationID) { - if(locationIdToName.containsKey(locationID)) - return locationIdToName.get(locationID); - for (Map.Entry game : games.entrySet()) { - for (Map.Entry location : game.getValue().locationNameToId.entrySet()) { - if(location.getValue() == locationID) { - locationIdToName.put(locationID, location.getKey()); - return location.getKey(); - } - } - } - return String.format("Unknown Location [%d]", locationID); + public String getLocation(long locationID, String game) { + if (!games.containsKey(game)) + return String.format("Unknown Location [%d] for [%s]", locationID, game); + + if (!games.get(game).locationNameToId.containsValue(locationID)) + return String.format("Unknown Location [%d] for [%s]", locationID, game); + + return games.get(game).getLocation(locationID); } - public Map getVersions() { - HashMap versions = new HashMap<>(); - games.forEach((key, value) -> versions.put(key, value.version)); - return versions; + public Map getChecksums() { + HashMap checksums = new HashMap<>(); + games.forEach((key, value) -> checksums.put(key, value.checksum)); + return checksums; } public HashMap getGames() { @@ -100,9 +92,6 @@ public HashMap getLocationsForGame(String game) { return ret; } - public int getVersion() { - return version; - } public String getUUID() { return uuid; @@ -110,6 +99,5 @@ public String getUUID() { public void update(DataPackage newData) { games.putAll(newData.getGames()); - version = newData.version; } } diff --git a/src/main/java/gg/archipelago/client/parts/Game.java b/src/main/java/gg/archipelago/client/parts/Game.java index 1c4a62c..437b414 100644 --- a/src/main/java/gg/archipelago/client/parts/Game.java +++ b/src/main/java/gg/archipelago/client/parts/Game.java @@ -1,21 +1,50 @@ package gg.archipelago.client.parts; +import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; +import java.beans.Transient; import java.io.Serializable; import java.util.HashMap; +import java.util.Map; public class Game implements Serializable { - @SerializedName("version") - public int version; - @SerializedName("hash") - public String hash; + + @SerializedName("checksum") + public String checksum; @SerializedName("item_name_to_id") public HashMap itemNameToId = new HashMap<>(); @SerializedName("location_name_to_id") public HashMap locationNameToId = new HashMap<>(); + + private final HashMap idToItem = new HashMap<>(); + private final HashMap idToLocation = new HashMap<>(); + + public String getItem(long itemID) { + if(idToItem.isEmpty()) { + for (Map.Entry entry : itemNameToId.entrySet()) { + idToItem.put(entry.getValue(), entry.getKey()); + } + } + if (!idToItem.containsKey(itemID)) + return String.format("Unknown Item [%d]", itemID); + + return idToItem.get(itemID); + } + + public String getLocation(long locationID) { + if(idToLocation.isEmpty()) { + for (Map.Entry entry : locationNameToId.entrySet()) { + idToLocation.put(entry.getValue(), entry.getKey()); + } + } + if (!idToLocation.containsKey(locationID)) + return String.format("Unknown Location [%d]", locationID); + + return idToLocation.get(locationID); + } } diff --git a/src/main/java/gg/archipelago/client/parts/NetworkSlot.java b/src/main/java/gg/archipelago/client/parts/NetworkSlot.java new file mode 100644 index 0000000..f95076b --- /dev/null +++ b/src/main/java/gg/archipelago/client/parts/NetworkSlot.java @@ -0,0 +1,41 @@ +package gg.archipelago.client.parts; + +import com.google.gson.annotations.SerializedName; + +public class NetworkSlot { + + @SerializedName("name") + public String name; + + @SerializedName("game") + public String game; + + @SerializedName("type") + public int type; + + + /** + * Flags that will tell you more about the slot type.
+ * {@link #SPECTATOR}, + * {@link #PLAYER}, + * {@link #GROUP} + */ + public static class flags { + + /** + * If set, indicates the slot is a spectator + */ + public final static int SPECTATOR = 0b001; + + /** + * If set, indicates the slot is a player + */ + public final static int PLAYER = 0b010; + + /** + * If set, indicates the slot is a group. + */ + public final static int GROUP = 0b100; + + } +} From ca3abef63f0208e22f312e28587527104f89bf99 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 20:32:29 -0700 Subject: [PATCH 02/17] Optimize imports. --- src/main/java/gg/archipelago/client/ArchipelagoClient.java | 3 --- src/main/java/gg/archipelago/client/EventManager.java | 2 +- src/main/java/gg/archipelago/client/LocationManager.java | 5 ++++- .../java/gg/archipelago/client/network/client/SetPacket.java | 1 - .../gg/archipelago/client/network/server/RoomInfoPacket.java | 2 -- src/main/java/gg/archipelago/client/parts/DataPackage.java | 4 +++- src/main/java/gg/archipelago/client/parts/Game.java | 2 -- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/gg/archipelago/client/ArchipelagoClient.java b/src/main/java/gg/archipelago/client/ArchipelagoClient.java index 7bf330f..b200e49 100644 --- a/src/main/java/gg/archipelago/client/ArchipelagoClient.java +++ b/src/main/java/gg/archipelago/client/ArchipelagoClient.java @@ -1,8 +1,6 @@ package gg.archipelago.client; -import com.google.gson.annotations.SerializedName; import gg.archipelago.client.Print.APPrint; -import gg.archipelago.client.helper.DeathLink; import gg.archipelago.client.network.client.*; import gg.archipelago.client.network.server.ConnectUpdatePacket; import gg.archipelago.client.network.server.RoomInfoPacket; @@ -11,7 +9,6 @@ import gg.archipelago.client.parts.NetworkSlot; import gg.archipelago.client.parts.Version; import org.apache.hc.core5.net.URIBuilder; -import org.slf4j.event.Level; import java.io.*; import java.net.URI; diff --git a/src/main/java/gg/archipelago/client/EventManager.java b/src/main/java/gg/archipelago/client/EventManager.java index b95d098..3f4bb9f 100644 --- a/src/main/java/gg/archipelago/client/EventManager.java +++ b/src/main/java/gg/archipelago/client/EventManager.java @@ -1,7 +1,7 @@ package gg.archipelago.client; -import gg.archipelago.client.events.Event; import gg.archipelago.client.events.ArchipelagoEventListener; +import gg.archipelago.client.events.Event; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/src/main/java/gg/archipelago/client/LocationManager.java b/src/main/java/gg/archipelago/client/LocationManager.java index 5080005..d3b4d5a 100644 --- a/src/main/java/gg/archipelago/client/LocationManager.java +++ b/src/main/java/gg/archipelago/client/LocationManager.java @@ -2,7 +2,10 @@ import gg.archipelago.client.network.client.LocationChecks; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; public class LocationManager { diff --git a/src/main/java/gg/archipelago/client/network/client/SetPacket.java b/src/main/java/gg/archipelago/client/network/client/SetPacket.java index 514c46a..36fc69a 100644 --- a/src/main/java/gg/archipelago/client/network/client/SetPacket.java +++ b/src/main/java/gg/archipelago/client/network/client/SetPacket.java @@ -1,6 +1,5 @@ package gg.archipelago.client.network.client; -import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import gg.archipelago.client.network.APPacket; import gg.archipelago.client.network.APPacketType; diff --git a/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java b/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java index 0a7407f..4491a59 100644 --- a/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java +++ b/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java @@ -3,9 +3,7 @@ import com.google.gson.annotations.SerializedName; import gg.archipelago.client.network.APPacket; import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.network.RemainingMode; import gg.archipelago.client.parts.NetworkPlayer; -import gg.archipelago.client.parts.NetworkSlot; import gg.archipelago.client.parts.Version; import java.util.ArrayList; diff --git a/src/main/java/gg/archipelago/client/parts/DataPackage.java b/src/main/java/gg/archipelago/client/parts/DataPackage.java index 765ed39..34fe268 100644 --- a/src/main/java/gg/archipelago/client/parts/DataPackage.java +++ b/src/main/java/gg/archipelago/client/parts/DataPackage.java @@ -4,7 +4,9 @@ import com.google.gson.annotations.SerializedName; import java.io.Serializable; -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; public class DataPackage implements Serializable { diff --git a/src/main/java/gg/archipelago/client/parts/Game.java b/src/main/java/gg/archipelago/client/parts/Game.java index 437b414..56fc24e 100644 --- a/src/main/java/gg/archipelago/client/parts/Game.java +++ b/src/main/java/gg/archipelago/client/parts/Game.java @@ -1,9 +1,7 @@ package gg.archipelago.client.parts; -import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import java.beans.Transient; import java.io.Serializable; import java.util.HashMap; import java.util.Map; From a65dadcfb298f8ae0be990ff413e6719c677f90f Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 20:59:53 -0700 Subject: [PATCH 03/17] convert to maven --- .github/workflows/gradle.yml | 29 ---- .gitignore | 44 +++++- LICENSE | 21 --- build.gradle | 36 ----- gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 5 - gradlew | 185 ----------------------- gradlew.bat | 89 ----------- pom.xml | 45 ++++++ settings.gradle | 5 - 10 files changed, 83 insertions(+), 376 deletions(-) delete mode 100644 .github/workflows/gradle.yml delete mode 100644 LICENSE delete mode 100644 build.gradle delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100644 gradlew delete mode 100644 gradlew.bat create mode 100644 pom.xml delete mode 100644 settings.gradle diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml deleted file mode 100644 index aea7251..0000000 --- a/.github/workflows/gradle.yml +++ /dev/null @@ -1,29 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle - -name: Java CI with Gradle - -on: - push: - branches: [ "master" ] - -jobs: - build-gradle-project: - runs-on: ubuntu-latest - steps: - - name: Checkout project sources - uses: actions/checkout@v3 - - name: Setup Gradle - uses: gradle/gradle-build-action@v2 - - name: Make gradlew executable - run: chmod +x ./gradlew - - name: Run build with Gradle Wrapper - run: ./gradlew shadowjar - - uses: actions/upload-artifact@v4 - with: - name: Archipelago.MultiClient.Java-SNAPSHOT - path: build/libs diff --git a/.gitignore b/.gitignore index dacb092..5ff6309 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,38 @@ -# Project exclude paths -/.gradle/ -/build/ -/build/classes/java/main/ -/.idea/ -gradle.properties \ No newline at end of file +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 92252ad..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 KonoTyran - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/build.gradle b/build.gradle deleted file mode 100644 index d779d50..0000000 --- a/build.gradle +++ /dev/null @@ -1,36 +0,0 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation - -plugins { - id 'com.github.johnrengelman.shadow' - id 'java-library' -} - -archivesBaseName = "Archipelago.MultiClient.Java" -group = 'gg.archipelago.APClient' -version = '1.13' - -java.toolchain.languageVersion = JavaLanguageVersion.of(8) - -logger.info('Java: {} JVM: {}({}}) Arch: {}',System.getProperty('java.version'),System.getProperty('java.vm.version'),System.getProperty('java.vendor'),System.getProperty('os.arch')) - -repositories { - mavenCentral() -} - - -dependencies { - implementation 'org.java-websocket:Java-WebSocket:1.5.2' - implementation 'com.google.code.gson:gson:2.8.9' - implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1' - implementation 'org.apache.httpcomponents.core5:httpcore5:5.2' - implementation 'org.slf4j:slf4j-nop:1.7.30' -} - -tasks.register('relocateShadowJar', ConfigureShadowRelocation) { - target = tasks.shadowJar - prefix = "archipelagoClient" // Default value is "shadow" -} -tasks.shadowJar.dependsOn tasks.relocateShadowJar - -shadowJar { -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59536 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 QuEJmfE|#`Dqx|px0L@K;Y5)KL diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 69a9715..0000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew deleted file mode 100644 index 744e882..0000000 --- a/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MSYS* | MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 107acd3..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ec53e53 --- /dev/null +++ b/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + gg.archipelago + multiclient.java + 1.0-SNAPSHOT + + + 8 + 8 + UTF-8 + + + + + org.java-websocket + Java-WebSocket + 1.5.2 + + + com.google.code.gson + gson + 2.8.9 + + + org.apache.httpcomponents.client5 + httpclient5 + 5.2.1 + + + org.apache.httpcomponents.core5 + httpcore5 + 5.2 + + + org.slf4j + slf4j-nop + 1.7.30 + + + + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index d8cc5a1..0000000 --- a/settings.gradle +++ /dev/null @@ -1,5 +0,0 @@ -pluginManagement { - plugins { - id 'com.github.johnrengelman.shadow' version '7.1.2' - } -} \ No newline at end of file From dcd695d7529a05bfdcaa5811b480ea22e1d012d4 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 21:01:20 -0700 Subject: [PATCH 04/17] update .gitignore --- .gitignore | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 5ff6309..b425f09 100644 --- a/.gitignore +++ b/.gitignore @@ -4,10 +4,7 @@ target/ !**/src/test/**/target/ ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +.idea/ *.iws *.iml *.ipr From c2fcbbba7e901236d67f2ccc00c6519828baf929 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 21:07:57 -0700 Subject: [PATCH 05/17] un-remove licence. --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..92252ad --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 KonoTyran + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 297359019afa345f949d0e24540a1f6495d9ba95 Mon Sep 17 00:00:00 2001 From: KonoTyran Date: Sat, 18 May 2024 21:15:13 -0700 Subject: [PATCH 06/17] Create maven.yml --- .github/workflows/maven.yml | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/maven.yml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..ee259fe --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,45 @@ +# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Java CI with Maven + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + - name: Build with Maven + run: mvn -B package --file pom.xml + + # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive + - name: Update dependency graph + uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 + + - uses: actions/upload-artifact@v4 + with: + # Name of the artifact to upload. + # Optional. Default is 'artifact' + name: Archipelago.MultiClient.Java-SNAPSHOT + + # A file, directory or wildcard pattern that describes what to upload + # Required. + path: target/*-SNAPSHOT.jar From f0443b2da48f0272d4b17a4c2bb2d08bcac6ca52 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 21:50:37 -0700 Subject: [PATCH 07/17] Attempt 1 at github packages. --- .github/workflows/maven-publish.yml | 20 ++++++++++++++++++++ pom.xml | 9 +++++++++ 2 files changed, 29 insertions(+) create mode 100644 .github/workflows/maven-publish.yml diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml new file mode 100644 index 0000000..f3a05ee --- /dev/null +++ b/.github/workflows/maven-publish.yml @@ -0,0 +1,20 @@ +name: Publish package to GitHub Packages +on: + release: + types: [created] +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + - name: Publish package + run: mvn --batch-mode deploy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pom.xml b/pom.xml index ec53e53..ed90f74 100644 --- a/pom.xml +++ b/pom.xml @@ -42,4 +42,13 @@ + + + github + GitHub konotyran Apache Maven Packages + https://maven.pkg.github.com/konotyran/Archipelago.MultiClient.Java + + + + \ No newline at end of file From ce63270d2a52ee0b84a8c8095b5a96a9ed1ae997 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 22:45:03 -0700 Subject: [PATCH 08/17] "start" readme "start" readme --- pom.xml | 17 +++++++++++++++-- readme.md | 0 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 readme.md diff --git a/pom.xml b/pom.xml index ed90f74..4f2251c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,11 @@ gg.archipelago multiclient.java - 1.0-SNAPSHOT + 0.1.0-SNAPSHOT + + + scm:git:https://github.com/KonoTyran/Archipelago.MultiClient.Java.git + 8 @@ -45,10 +49,19 @@ github - GitHub konotyran Apache Maven Packages + GitHub Packages https://maven.pkg.github.com/konotyran/Archipelago.MultiClient.Java + + + + org.apache.maven.plugins + maven-release-plugin + 3.0.1 + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e69de29 From 25b1fb7f16c81113154d140eaf08b9632a89f979 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 22:53:28 -0700 Subject: [PATCH 09/17] enable auto-publishing of snapshots via workflows --- .github/workflows/maven-publish.yml | 2 +- .github/workflows/maven.yml | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index f3a05ee..fdc03b3 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -15,6 +15,6 @@ jobs: java-version: '11' distribution: 'temurin' - name: Publish package - run: mvn --batch-mode deploy + run: mvn --batch-mode release:clean release:prepare deploy env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index ee259fe..44be510 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -34,12 +34,7 @@ jobs: - name: Update dependency graph uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 - - uses: actions/upload-artifact@v4 - with: - # Name of the artifact to upload. - # Optional. Default is 'artifact' - name: Archipelago.MultiClient.Java-SNAPSHOT - - # A file, directory or wildcard pattern that describes what to upload - # Required. - path: target/*-SNAPSHOT.jar + - name: Publish Snapshot + run: mvn --batch-mode deploy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From cdcdc4cdccc26a6cbc8a86e5328a69414357bb1f Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Sat, 18 May 2024 23:09:44 -0700 Subject: [PATCH 10/17] fix npe when encountering new game in datapackage checksum check. --- .../java/gg/archipelago/client/ArchipelagoWebSocket.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java b/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java index 618641d..b6c2f9d 100644 --- a/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java +++ b/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java @@ -226,8 +226,12 @@ private void checkDataPackage(HashMap versions, List gam for (Map.Entry game : versions.entrySet()) { if (!games.contains(game.getKey())) continue; - if (!checksums.containsKey(game.getKey())) + + if (!checksums.containsKey(game.getKey())) { gamesToUpdate.add(game.getKey()); + continue; + } + if (!checksums.get(game.getKey()).equals(game.getValue())) gamesToUpdate.add(game.getKey()); } From 630dd1e700e5def9d8c671097d3fc7d0979ec863 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Mon, 20 May 2024 18:04:56 -0700 Subject: [PATCH 11/17] move packages --- pom.xml | 52 ++++++ .../koifysh/archipelago/Client.java} | 159 ++++++++++++------ .../koifysh/archipelago}/ClientStatus.java | 4 +- .../koifysh/archipelago}/EventManager.java | 6 +- .../koifysh/archipelago}/ItemFlags.java | 2 +- .../koifysh/archipelago}/ItemManager.java | 36 ++-- .../koifysh/archipelago}/LocationManager.java | 16 +- .../koifysh/archipelago}/Print/APPrint.java | 4 +- .../archipelago}/Print/APPrintColor.java | 2 +- .../archipelago}/Print/APPrintPart.java | 2 +- .../archipelago}/Print/APPrintType.java | 2 +- .../koifysh/archipelago/WebSocket.java} | 145 ++++++++-------- .../events/ArchipelagoEventListener.java | 2 +- .../archipelago}/events/BouncedEvent.java | 2 +- .../events/CheckedLocationsEvent.java | 2 +- .../events/ConnectionAttemptEvent.java | 2 +- .../events/ConnectionResultEvent.java | 4 +- .../archipelago}/events/DeathLinkEvent.java | 2 +- .../dev/koifysh/archipelago/events/Event.java | 4 + .../events/InvalidPacketEvent.java | 2 +- .../events/LocationInfoEvent.java | 4 +- .../archipelago}/events/ReceiveItemEvent.java | 4 +- .../archipelago}/events/RetrievedEvent.java | 2 +- .../archipelago}/events/SetReplyEvent.java | 2 +- .../archipelago}/helper/DeathLink.java | 18 +- .../archipelago}/network/APPacket.java | 2 +- .../archipelago}/network/APPacketType.java | 2 +- .../network/ConnectionResult.java | 2 +- .../network/DataStorageOperation.java | 3 + .../archipelago}/network/Permission.java | 2 +- .../archipelago}/network/RemainingMode.java | 2 +- .../network/client/BouncePacket.java | 8 +- .../network/client/ConnectPacket.java | 8 +- .../network/client/GetDataPackagePacket.java | 6 +- .../network/client/GetPacket.java | 12 +- .../network/client/LocationChecks.java | 6 +- .../network/client/LocationScouts.java | 6 +- .../network/client/SayPacket.java | 6 +- .../network/client/SetNotifyPacket.java | 6 +- .../network/client/SetPacket.java | 11 +- .../network/client/StatusUpdatePacket.java | 8 +- .../network/client/SyncPacket.java | 12 ++ .../network/server/BouncedPacket.java | 6 +- .../network/server/ConnectUpdatePacket.java | 6 +- .../network/server/ConnectedPacket.java | 10 +- .../server/ConnectionRefusedPacket.java | 8 +- .../network/server/InvalidPacket.java | 6 +- .../network/server/JsonPrintPacket.java | 13 ++ .../network/server/LocationInfoPacket.java | 8 +- .../network/server/PrintPacket.java | 6 +- .../network/server/ReceivedItemsPacket.java | 8 +- .../network/server/RetrievedPacket.java | 6 +- .../network/server/RoomInfoPacket.java | 10 +- .../network/server/RoomUpdatePacket.java | 12 +- .../network/server/SetReplyPacket.java | 6 +- .../archipelago}/parts/DataPackage.java | 2 +- .../koifysh/archipelago}/parts/Game.java | 2 +- .../archipelago}/parts/NetworkItem.java | 2 +- .../archipelago}/parts/NetworkPlayer.java | 2 +- .../archipelago}/parts/NetworkSlot.java | 2 +- .../koifysh/archipelago}/parts/Version.java | 2 +- .../gg/archipelago/client/events/Event.java | 4 - .../client/network/DataStorageOperation.java | 3 - .../client/network/client/SyncPacket.java | 12 -- .../network/server/JsonPrintPacket.java | 13 -- 65 files changed, 424 insertions(+), 307 deletions(-) rename src/main/java/{gg/archipelago/client/ArchipelagoClient.java => dev/koifysh/archipelago/Client.java} (67%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/ClientStatus.java (86%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/EventManager.java (89%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/ItemFlags.java (91%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/ItemManager.java (54%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/LocationManager.java (83%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/Print/APPrint.java (87%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/Print/APPrintColor.java (94%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/Print/APPrintPart.java (84%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/Print/APPrintType.java (92%) rename src/main/java/{gg/archipelago/client/ArchipelagoWebSocket.java => dev/koifysh/archipelago/WebSocket.java} (60%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/ArchipelagoEventListener.java (80%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/BouncedEvent.java (96%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/CheckedLocationsEvent.java (86%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/ConnectionAttemptEvent.java (96%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/ConnectionResultEvent.java (92%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/DeathLinkEvent.java (87%) create mode 100644 src/main/java/dev/koifysh/archipelago/events/Event.java rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/InvalidPacketEvent.java (94%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/LocationInfoEvent.java (72%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/ReceiveItemEvent.java (89%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/RetrievedEvent.java (97%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/events/SetReplyEvent.java (96%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/helper/DeathLink.java (71%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/APPacket.java (88%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/APPacketType.java (96%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/ConnectionResult.java (73%) create mode 100644 src/main/java/dev/koifysh/archipelago/network/DataStorageOperation.java rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/Permission.java (84%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/RemainingMode.java (89%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/BouncePacket.java (79%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/ConnectPacket.java (75%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/GetDataPackagePacket.java (66%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/GetPacket.java (60%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/LocationChecks.java (67%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/LocationScouts.java (65%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/SayPacket.java (62%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/SetNotifyPacket.java (68%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/SetPacket.java (93%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/client/StatusUpdatePacket.java (52%) create mode 100644 src/main/java/dev/koifysh/archipelago/network/client/SyncPacket.java rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/BouncedPacket.java (79%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/ConnectUpdatePacket.java (64%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/ConnectedPacket.java (74%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/ConnectionRefusedPacket.java (56%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/InvalidPacket.java (70%) create mode 100644 src/main/java/dev/koifysh/archipelago/network/server/JsonPrintPacket.java rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/LocationInfoPacket.java (59%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/PrintPacket.java (64%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/ReceivedItemsPacket.java (63%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/RetrievedPacket.java (69%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/RoomInfoPacket.java (83%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/RoomUpdatePacket.java (81%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/network/server/SetReplyPacket.java (73%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/parts/DataPackage.java (98%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/parts/Game.java (97%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/parts/NetworkItem.java (96%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/parts/NetworkPlayer.java (88%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/parts/NetworkSlot.java (95%) rename src/main/java/{gg/archipelago/client => dev/koifysh/archipelago}/parts/Version.java (89%) delete mode 100644 src/main/java/gg/archipelago/client/events/Event.java delete mode 100644 src/main/java/gg/archipelago/client/network/DataStorageOperation.java delete mode 100644 src/main/java/gg/archipelago/client/network/client/SyncPacket.java delete mode 100644 src/main/java/gg/archipelago/client/network/server/JsonPrintPacket.java diff --git a/pom.xml b/pom.xml index 4f2251c..3912a60 100644 --- a/pom.xml +++ b/pom.xml @@ -8,6 +8,18 @@ multiclient.java 0.1.0-SNAPSHOT + Archipelago Java Library + The maven main core project description + http://maven.apache.org + + + + MIT License + https://github.com/ArchipelagoMW/Archipelago.MultiClient.Java/blob/master/LICENSE + repo + + + scm:git:https://github.com/KonoTyran/Archipelago.MultiClient.Java.git @@ -61,6 +73,46 @@ maven-release-plugin 3.0.1 + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + diff --git a/src/main/java/gg/archipelago/client/ArchipelagoClient.java b/src/main/java/dev/koifysh/archipelago/Client.java similarity index 67% rename from src/main/java/gg/archipelago/client/ArchipelagoClient.java rename to src/main/java/dev/koifysh/archipelago/Client.java index b200e49..86ab886 100644 --- a/src/main/java/gg/archipelago/client/ArchipelagoClient.java +++ b/src/main/java/dev/koifysh/archipelago/Client.java @@ -1,13 +1,14 @@ -package gg.archipelago.client; - -import gg.archipelago.client.Print.APPrint; -import gg.archipelago.client.network.client.*; -import gg.archipelago.client.network.server.ConnectUpdatePacket; -import gg.archipelago.client.network.server.RoomInfoPacket; -import gg.archipelago.client.parts.DataPackage; -import gg.archipelago.client.parts.NetworkItem; -import gg.archipelago.client.parts.NetworkSlot; -import gg.archipelago.client.parts.Version; +package dev.koifysh.archipelago; + +import dev.koifysh.archipelago.Print.APPrint; +import dev.koifysh.archipelago.events.RetrievedEvent; +import dev.koifysh.archipelago.network.server.ConnectUpdatePacket; +import dev.koifysh.archipelago.network.server.RoomInfoPacket; +import dev.koifysh.archipelago.parts.DataPackage; +import dev.koifysh.archipelago.parts.NetworkItem; +import dev.koifysh.archipelago.parts.NetworkSlot; +import dev.koifysh.archipelago.parts.Version; +import dev.koifysh.archipelago.network.client.*; import org.apache.hc.core5.net.URIBuilder; import java.io.*; @@ -16,15 +17,15 @@ import java.util.*; import java.util.logging.Logger; -public abstract class ArchipelagoClient { +public abstract class Client { - private final static Logger LOGGER = Logger.getLogger(ArchipelagoClient.class.getName()); + private final static Logger LOGGER = Logger.getLogger(Client.class.getName()); private final String dataPackageLocation = "./APData/DataPackage.ser"; private int hintPoints; - private ArchipelagoWebSocket archipelagoWebSocket; + private WebSocket webSocket; private String password; @@ -34,7 +35,7 @@ public abstract class ArchipelagoClient { private DataPackage dataPackage; - public static ArchipelagoClient archipelagoClient; + public static Client client; private final LocationManager locationManager; private final ItemManager itemManager; @@ -51,7 +52,7 @@ public abstract class ArchipelagoClient { private Set tags = new HashSet<>(); private int itemsHandlingFlags = 0b000; - public ArchipelagoClient() { + public Client() { loadDataPackage(); UUID = dataPackage.getUUID(); @@ -59,42 +60,59 @@ public ArchipelagoClient() { eventManager = new EventManager(); locationManager = new LocationManager(this); itemManager = new ItemManager(this); - archipelagoClient = this; + client = this; } + /** + * Sets the name of the game to send to Archipelago's servers + * @param game the name of your game. + */ public void setGame(String game) { this.game = game; } + /** + * overwrite, and set all tags sent to the Archipelago server. + * this will overwrite any previous tags that have been set. + * @param tags a Set of tags to send. + */ public void setTags(Set tags) { if (!this.tags.equals(tags)) { this.tags = tags; if (isConnected()) { ConnectUpdatePacket packet = new ConnectUpdatePacket(); packet.tags = this.tags; - archipelagoWebSocket.sendPacket(packet); + webSocket.sendPacket(packet); } } } + /** + * add a tag to your list, keeping all previous tags intact. + * @param tag String tag to be added. + */ public void addTag(String tag) { if (!this.tags.contains(tag)) { tags.add(tag); if (isConnected()) { ConnectUpdatePacket packet = new ConnectUpdatePacket(); packet.tags = this.tags; - archipelagoWebSocket.sendPacket(packet); + webSocket.sendPacket(packet); } } } + /** + * removes supplied tag, if it exists. + * @param tag String tag to be removed. + */ public void removeTag(String tag) { if (this.tags.contains(tag)) { tags.remove(tag); if (isConnected()) { ConnectUpdatePacket packet = new ConnectUpdatePacket(); packet.tags = this.tags; - archipelagoWebSocket.sendPacket(packet); + webSocket.sendPacket(packet); } } } @@ -142,15 +160,26 @@ void saveDataPackage() { } } + /** + * Returns true only if connected to an Archipelago server. + * @return true if connected, otherwise false + */ public boolean isConnected() { - return archipelagoWebSocket != null && archipelagoWebSocket.isOpen(); + return webSocket != null && webSocket.isOpen(); } + /** + * closes a connection to the Archipelago server if connected. + */ public void close() { - if (archipelagoWebSocket != null) - archipelagoWebSocket.close(); + if (webSocket != null) + webSocket.close(); } + /** + * sets a password to authenticate with to join a password protected room. + * @param password room password + */ public void setPassword(String password) { this.password = password; } @@ -159,6 +188,10 @@ void setHintPoints(int hintPoints) { this.hintPoints = hintPoints; } + /** + * sets the slot name to connect to an Archcipelago server with. + * @param name + */ public void setName(String name) { this.name = name; } @@ -183,14 +216,26 @@ void updateDataPackage(DataPackage newData) { dataPackage.update(newData); } + /** + * + * @return team ID + */ public int getTeam() { return team; } + /** + * + * @return Slot ID + */ public int getSlot() { return slot; } + /** + * fetches the + * @return Room info. + */ public RoomInfoPacket getRoomInfo() { return roomInfo; } @@ -203,9 +248,9 @@ public void connect(String address) throws URISyntaxException { builder.setPort(38281); } - if (archipelagoWebSocket != null && archipelagoWebSocket.isOpen()) { + if (webSocket != null && webSocket.isOpen()) { LOGGER.fine("previous WebSocket is open, closing."); - archipelagoWebSocket.close(); + webSocket.close(); } if (builder.getScheme() == null) { @@ -221,19 +266,35 @@ public void connect(URI address) { connect(address, false); } + /** + * Connects to an Archipelago server with previously provided info. + *
+ * supply the following info before calling this method + *
+ * game: {@link #setGame(String)}
+ * slot name: {@link #setName(String)}
+ *
+ * if no protocol wss:// or ws:// is given will attempt a ssl connection + * to the supplied address, if that fails it will then try a non-ssl connection, unless allowDowngrade is false.
+ *
+ * Do not prefix address with wss:// or ws://. let the user enter a protocol to use. + * by default ssl will be tried first, if that fails then non-ssl will be used. unless allowDowngrade is set to false. + * @param address address of the archipelago server. + * @param allowDowngrade if set to false will prevent auto downgrade of ssl connection. + */ public void connect(URI address, boolean allowDowngrade) { LOGGER.fine("attempting WebSocket connection to " + address.toString()); - archipelagoWebSocket = new ArchipelagoWebSocket(address, this); - locationManager.setAPWebSocket(archipelagoWebSocket); - itemManager.setAPWebSocket(archipelagoWebSocket); - archipelagoWebSocket.connect(allowDowngrade); + webSocket = new WebSocket(address, this); + locationManager.setAPWebSocket(webSocket); + itemManager.setAPWebSocket(webSocket); + webSocket.connect(allowDowngrade); } public void sendChat(String message) { - if (archipelagoWebSocket == null) + if (webSocket == null) return; - if (archipelagoWebSocket.isAuthenticated()) { - archipelagoWebSocket.sendChat(message); + if (webSocket.isAuthenticated()) { + webSocket.sendChat(message); } } @@ -248,7 +309,7 @@ public boolean checkLocations(Collection locationIDs) { public void scoutLocations(ArrayList locationIDs) { HashMap locations = dataPackage.getLocationsForGame(game); locationIDs.removeIf( location -> !locations.containsKey(location)); - archipelagoWebSocket.scoutLocation(locationIDs); + webSocket.scoutLocation(locationIDs); } public abstract void onPrint(String print); @@ -281,7 +342,7 @@ public String getGame() { public String getConnectedAddress() { if (isConnected()) - return archipelagoWebSocket.getRemoteSocketAddress().getHostName()+":"+archipelagoWebSocket.getRemoteSocketAddress().getPort(); + return webSocket.getRemoteSocketAddress().getHostName()+":"+ webSocket.getRemoteSocketAddress().getPort(); else return ""; } @@ -290,7 +351,7 @@ public String getConnectedAddress() { * this should not need to be called externally but is left public just in case. */ public void reconnect() { - archipelagoWebSocket.reconnect(); + webSocket.reconnect(); } public String getUUID() { @@ -314,25 +375,25 @@ public ItemManager getItemManager() { } public void setGameState(ClientStatus status) { - if (archipelagoWebSocket == null) + if (webSocket == null) return; - if (archipelagoWebSocket.isAuthenticated()) - archipelagoWebSocket.sendPacket(new StatusUpdatePacket(status)); + if (webSocket.isAuthenticated()) + webSocket.sendPacket(new StatusUpdatePacket(status)); } public void sync() { - archipelagoWebSocket.sendPacket(new SyncPacket()); + webSocket.sendPacket(new SyncPacket()); } public void sendBounce(BouncePacket bouncePacket) { - if (archipelagoWebSocket == null) + if (webSocket == null) return; - if (archipelagoWebSocket.isAuthenticated()) - archipelagoWebSocket.sendPacket(bouncePacket); + if (webSocket.isAuthenticated()) + webSocket.sendPacket(bouncePacket); } public void disconnect() { - archipelagoWebSocket.close(); + webSocket.close(); } public Set getTags() { @@ -357,10 +418,10 @@ public EventManager getEventManager() { * @param setPacket */ public int dataStorageSet(SetPacket setPacket) { - if (archipelagoWebSocket == null || !archipelagoWebSocket.isAuthenticated()) + if (webSocket == null || !webSocket.isAuthenticated()) return 0; - archipelagoWebSocket.sendPacket(setPacket); + webSocket.sendPacket(setPacket); return setPacket.getRequestID(); } @@ -370,14 +431,14 @@ public int dataStorageSet(SetPacket setPacket) { * @param keys List of Keys to be notified of. */ public void dataStorageSetNotify(Collection keys) { - if (archipelagoWebSocket == null || !archipelagoWebSocket.isAuthenticated()) + if (webSocket == null || !webSocket.isAuthenticated()) return; - archipelagoWebSocket.sendPacket(new SetNotifyPacket(keys)); + webSocket.sendPacket(new SetNotifyPacket(keys)); } /** * Uses DataStorage to reterieve a value from the server will get value back though a - * {@link gg.archipelago.client.events.RetrievedEvent RetrievedEvent}.
+ * {@link RetrievedEvent RetrievedEvent}.
* see following table for list of reserved keys. * * @@ -405,11 +466,11 @@ public void dataStorageSetNotify(Collection keys) { * @param keys a list of keys to retrieve values for */ public int dataStorageGet(Collection keys) { - if (archipelagoWebSocket == null || !archipelagoWebSocket.isAuthenticated()) + if (webSocket == null || !webSocket.isAuthenticated()) return 0; GetPacket getPacket = new GetPacket(keys); - archipelagoWebSocket.sendPacket(getPacket); + webSocket.sendPacket(getPacket); return getPacket.getRequestID(); } diff --git a/src/main/java/gg/archipelago/client/ClientStatus.java b/src/main/java/dev/koifysh/archipelago/ClientStatus.java similarity index 86% rename from src/main/java/gg/archipelago/client/ClientStatus.java rename to src/main/java/dev/koifysh/archipelago/ClientStatus.java index fafbfb9..c7f6d4a 100644 --- a/src/main/java/gg/archipelago/client/ClientStatus.java +++ b/src/main/java/dev/koifysh/archipelago/ClientStatus.java @@ -1,4 +1,4 @@ -package gg.archipelago.client; +package dev.koifysh.archipelago; import com.google.gson.annotations.SerializedName; @@ -13,7 +13,7 @@ public enum ClientStatus { @SerializedName("30") CLIENT_GOAL(30); - private int value; + private final int value; ClientStatus(int value) { this.value = value; } diff --git a/src/main/java/gg/archipelago/client/EventManager.java b/src/main/java/dev/koifysh/archipelago/EventManager.java similarity index 89% rename from src/main/java/gg/archipelago/client/EventManager.java rename to src/main/java/dev/koifysh/archipelago/EventManager.java index 3f4bb9f..e24afe3 100644 --- a/src/main/java/gg/archipelago/client/EventManager.java +++ b/src/main/java/dev/koifysh/archipelago/EventManager.java @@ -1,7 +1,7 @@ -package gg.archipelago.client; +package dev.koifysh.archipelago; -import gg.archipelago.client.events.ArchipelagoEventListener; -import gg.archipelago.client.events.Event; +import dev.koifysh.archipelago.events.ArchipelagoEventListener; +import dev.koifysh.archipelago.events.Event; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/src/main/java/gg/archipelago/client/ItemFlags.java b/src/main/java/dev/koifysh/archipelago/ItemFlags.java similarity index 91% rename from src/main/java/gg/archipelago/client/ItemFlags.java rename to src/main/java/dev/koifysh/archipelago/ItemFlags.java index c2d3e02..cfbc413 100644 --- a/src/main/java/gg/archipelago/client/ItemFlags.java +++ b/src/main/java/dev/koifysh/archipelago/ItemFlags.java @@ -1,4 +1,4 @@ -package gg.archipelago.client; +package dev.koifysh.archipelago; public class ItemFlags { diff --git a/src/main/java/gg/archipelago/client/ItemManager.java b/src/main/java/dev/koifysh/archipelago/ItemManager.java similarity index 54% rename from src/main/java/gg/archipelago/client/ItemManager.java rename to src/main/java/dev/koifysh/archipelago/ItemManager.java index 02a1d1e..2a7276e 100644 --- a/src/main/java/gg/archipelago/client/ItemManager.java +++ b/src/main/java/dev/koifysh/archipelago/ItemManager.java @@ -1,24 +1,24 @@ -package gg.archipelago.client; +package dev.koifysh.archipelago; -import gg.archipelago.client.events.ReceiveItemEvent; -import gg.archipelago.client.network.client.SyncPacket; -import gg.archipelago.client.parts.DataPackage; -import gg.archipelago.client.parts.NetworkItem; +import dev.koifysh.archipelago.events.ReceiveItemEvent; +import dev.koifysh.archipelago.network.client.SyncPacket; +import dev.koifysh.archipelago.parts.DataPackage; +import dev.koifysh.archipelago.parts.NetworkItem; import java.util.ArrayList; public class ItemManager { - ArchipelagoClient archipelagoClient; - ArchipelagoWebSocket webSocket; + Client client; + WebSocket webSocket; ArrayList receivedItems = new ArrayList<>(); int index; - public ItemManager(ArchipelagoClient archipelagoClient) { - this.archipelagoClient = archipelagoClient; + public ItemManager(Client client) { + this.client = client; } public void receiveItems(ArrayList ids, int index) { @@ -27,14 +27,14 @@ public void receiveItems(ArrayList ids, int index) { } if (receivedItems.size() == index) { receivedItems.addAll(ids); - DataPackage dp = archipelagoClient.getDataPackage(); - int myTeam = archipelagoClient.getTeam(); + DataPackage dp = client.getDataPackage(); + int myTeam = client.getTeam(); for (int i = this.index; i < receivedItems.size(); i++) { NetworkItem item = receivedItems.get(i); - item.itemName = dp.getItem(item.itemID, archipelagoClient.getGame()); - item.locationName = dp.getLocation(item.locationID, archipelagoClient.getSlotInfo().get(item.playerID).game); - item.playerName = archipelagoClient.getRoomInfo().getPlayer(myTeam,item.playerID).alias; - archipelagoClient.getEventManager().callEvent(new ReceiveItemEvent(item, 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)); } this.index = receivedItems.size(); @@ -42,7 +42,7 @@ public void receiveItems(ArrayList ids, int index) { else { if(webSocket != null) { webSocket.sendPacket(new SyncPacket()); - archipelagoClient.getLocationManager().resendAllCheckedLocations(); + client.getLocationManager().resendAllCheckedLocations(); } } } @@ -52,8 +52,8 @@ public void writeFromSave(ArrayList receivedItems, int index) { this.index = index; } - public void setAPWebSocket(ArchipelagoWebSocket archipelagoWebSocket) { - this.webSocket = archipelagoWebSocket; + public void setAPWebSocket(WebSocket webSocket) { + this.webSocket = webSocket; } public int getIndex() { diff --git a/src/main/java/gg/archipelago/client/LocationManager.java b/src/main/java/dev/koifysh/archipelago/LocationManager.java similarity index 83% rename from src/main/java/gg/archipelago/client/LocationManager.java rename to src/main/java/dev/koifysh/archipelago/LocationManager.java index d3b4d5a..10232c7 100644 --- a/src/main/java/gg/archipelago/client/LocationManager.java +++ b/src/main/java/dev/koifysh/archipelago/LocationManager.java @@ -1,6 +1,6 @@ -package gg.archipelago.client; +package dev.koifysh.archipelago; -import gg.archipelago.client.network.client.LocationChecks; +import dev.koifysh.archipelago.network.client.LocationChecks; import java.util.ArrayList; import java.util.Collection; @@ -9,15 +9,15 @@ public class LocationManager { - ArchipelagoClient archipelagoClient; - ArchipelagoWebSocket webSocket; + Client client; + WebSocket webSocket; Set checkedLocations = new HashSet<>(); Set missingLocations = new HashSet<>(); - public LocationManager(ArchipelagoClient archipelagoClient) { - this.archipelagoClient = archipelagoClient; + public LocationManager(Client client) { + this.client = client; } public boolean checkLocation(long id) { @@ -60,8 +60,8 @@ public void resendAllCheckedLocations() { webSocket.sendPacket(packet); } - protected void setAPWebSocket(ArchipelagoWebSocket archipelagoWebSocket) { - this.webSocket = archipelagoWebSocket; + protected void setAPWebSocket(WebSocket webSocket) { + this.webSocket = webSocket; } public Set getCheckedLocations() { diff --git a/src/main/java/gg/archipelago/client/Print/APPrint.java b/src/main/java/dev/koifysh/archipelago/Print/APPrint.java similarity index 87% rename from src/main/java/gg/archipelago/client/Print/APPrint.java rename to src/main/java/dev/koifysh/archipelago/Print/APPrint.java index 4f10c8d..822a508 100644 --- a/src/main/java/gg/archipelago/client/Print/APPrint.java +++ b/src/main/java/dev/koifysh/archipelago/Print/APPrint.java @@ -1,7 +1,7 @@ -package gg.archipelago.client.Print; +package dev.koifysh.archipelago.Print; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.parts.NetworkItem; +import dev.koifysh.archipelago.parts.NetworkItem; public class APPrint { diff --git a/src/main/java/gg/archipelago/client/Print/APPrintColor.java b/src/main/java/dev/koifysh/archipelago/Print/APPrintColor.java similarity index 94% rename from src/main/java/gg/archipelago/client/Print/APPrintColor.java rename to src/main/java/dev/koifysh/archipelago/Print/APPrintColor.java index a17bfb6..35b0e9b 100644 --- a/src/main/java/gg/archipelago/client/Print/APPrintColor.java +++ b/src/main/java/dev/koifysh/archipelago/Print/APPrintColor.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.Print; +package dev.koifysh.archipelago.Print; import java.awt.*; diff --git a/src/main/java/gg/archipelago/client/Print/APPrintPart.java b/src/main/java/dev/koifysh/archipelago/Print/APPrintPart.java similarity index 84% rename from src/main/java/gg/archipelago/client/Print/APPrintPart.java rename to src/main/java/dev/koifysh/archipelago/Print/APPrintPart.java index 2cbcbe1..a65dfef 100644 --- a/src/main/java/gg/archipelago/client/Print/APPrintPart.java +++ b/src/main/java/dev/koifysh/archipelago/Print/APPrintPart.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.Print; +package dev.koifysh.archipelago.Print; public class APPrintPart { public APPrintType type = APPrintType.text; diff --git a/src/main/java/gg/archipelago/client/Print/APPrintType.java b/src/main/java/dev/koifysh/archipelago/Print/APPrintType.java similarity index 92% rename from src/main/java/gg/archipelago/client/Print/APPrintType.java rename to src/main/java/dev/koifysh/archipelago/Print/APPrintType.java index 93ce2e5..0a1f680 100644 --- a/src/main/java/gg/archipelago/client/Print/APPrintType.java +++ b/src/main/java/dev/koifysh/archipelago/Print/APPrintType.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.Print; +package dev.koifysh.archipelago.Print; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java b/src/main/java/dev/koifysh/archipelago/WebSocket.java similarity index 60% rename from src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java rename to src/main/java/dev/koifysh/archipelago/WebSocket.java index b6c2f9d..57ca340 100644 --- a/src/main/java/gg/archipelago/client/ArchipelagoWebSocket.java +++ b/src/main/java/dev/koifysh/archipelago/WebSocket.java @@ -1,23 +1,24 @@ -package gg.archipelago.client; +package dev.koifysh.archipelago; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -import gg.archipelago.client.Print.APPrint; -import gg.archipelago.client.Print.APPrintType; -import gg.archipelago.client.events.*; -import gg.archipelago.client.helper.DeathLink; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.ConnectionResult; -import gg.archipelago.client.network.client.ConnectPacket; -import gg.archipelago.client.network.client.GetDataPackagePacket; -import gg.archipelago.client.network.client.LocationScouts; -import gg.archipelago.client.network.client.SayPacket; -import gg.archipelago.client.network.server.*; -import gg.archipelago.client.parts.DataPackage; -import gg.archipelago.client.parts.NetworkItem; -import gg.archipelago.client.parts.NetworkPlayer; +import dev.koifysh.archipelago.Print.APPrint; +import dev.koifysh.archipelago.Print.APPrintType; +import dev.koifysh.archipelago.helper.DeathLink; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.ConnectionResult; +import dev.koifysh.archipelago.network.client.ConnectPacket; +import dev.koifysh.archipelago.network.client.GetDataPackagePacket; +import dev.koifysh.archipelago.network.client.LocationScouts; +import dev.koifysh.archipelago.network.client.SayPacket; +import dev.koifysh.archipelago.parts.DataPackage; +import dev.koifysh.archipelago.parts.NetworkItem; +import dev.koifysh.archipelago.parts.NetworkPlayer; +import dev.koifysh.archipelago.events.*; +import dev.koifysh.archipelago.network.server.*; + import org.apache.hc.core5.net.URIBuilder; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; @@ -28,11 +29,11 @@ import java.util.*; import java.util.logging.Level; -public class ArchipelagoWebSocket extends WebSocketClient { +public class WebSocket extends WebSocketClient { - private final static java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger(ArchipelagoWebSocket.class.getName()); + private final static java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger(WebSocket.class.getName()); - private final ArchipelagoClient archipelagoClient; + private final Client client; private final Gson gson = new Gson(); @@ -44,9 +45,9 @@ public class ArchipelagoWebSocket extends WebSocketClient { private static Timer reconnectTimer; private boolean downgrade = false; - public ArchipelagoWebSocket(URI serverUri, ArchipelagoClient archipelagoClient) { + public WebSocket(URI serverUri, Client client) { super(serverUri); - this.archipelagoClient = archipelagoClient; + this.client = client; if (reconnectTimer != null) { reconnectTimer.cancel(); } @@ -77,50 +78,50 @@ public void onMessage(String message) { RoomInfoPacket roomInfo = gson.fromJson(packet, RoomInfoPacket.class); //save room info - archipelagoClient.setRoomInfo(roomInfo); + client.setRoomInfo(roomInfo); checkDataPackage(roomInfo.datapackageChecksums, roomInfo.games); seedName = roomInfo.seedName; ConnectPacket connectPacket = new ConnectPacket(); - connectPacket.version = ArchipelagoClient.protocolVersion; - connectPacket.name = archipelagoClient.getMyName(); - connectPacket.password = (archipelagoClient.getPassword() == null) ? "" : archipelagoClient.getPassword(); - connectPacket.uuid = archipelagoClient.getUUID(); - connectPacket.game = archipelagoClient.getGame(); - connectPacket.tags = archipelagoClient.getTags(); - connectPacket.itemsHandling = archipelagoClient.getItemsHandlingFlags(); + connectPacket.version = Client.protocolVersion; + connectPacket.name = client.getMyName(); + connectPacket.password = (client.getPassword() == null) ? "" : client.getPassword(); + connectPacket.uuid = client.getUUID(); + connectPacket.game = client.getGame(); + connectPacket.tags = client.getTags(); + connectPacket.itemsHandling = client.getItemsHandlingFlags(); //send reply sendPacket(connectPacket); - archipelagoClient.setRoomInfo(roomInfo); + client.setRoomInfo(roomInfo); break; case Connected: ConnectedPacket connectedPacket = gson.fromJson(packet, ConnectedPacket.class); - archipelagoClient.setTeam(connectedPacket.team); - archipelagoClient.setSlot(connectedPacket.slot); - archipelagoClient.setSlotInfo(connectedPacket.slotInfo); + client.setTeam(connectedPacket.team); + client.setSlot(connectedPacket.slot); + client.setSlotInfo(connectedPacket.slotInfo); - archipelagoClient.getRoomInfo().networkPlayers.addAll(connectedPacket.players); - archipelagoClient.getRoomInfo().networkPlayers.add(new NetworkPlayer(connectedPacket.team, 0, "Archipelago")); - archipelagoClient.setAlias(archipelagoClient.getRoomInfo().getPlayer(connectedPacket.team, connectedPacket.slot).alias); + client.getRoomInfo().networkPlayers.addAll(connectedPacket.players); + client.getRoomInfo().networkPlayers.add(new NetworkPlayer(connectedPacket.team, 0, "Archipelago")); + client.setAlias(client.getRoomInfo().getPlayer(connectedPacket.team, connectedPacket.slot).alias); JsonElement slotData = packet.getAsJsonObject().get("slot_data"); ConnectionAttemptEvent attemptConnectionEvent = new ConnectionAttemptEvent(connectedPacket.team, connectedPacket.slot, seedName, slotData); - archipelagoClient.getEventManager().callEvent(attemptConnectionEvent); + client.getEventManager().callEvent(attemptConnectionEvent); if (!attemptConnectionEvent.isCanceled()) { authenticated = true; //only send locations if the connection is not canceled. - archipelagoClient.getLocationManager().addCheckedLocations(connectedPacket.checkedLocations); - archipelagoClient.getLocationManager().setMissingLocations(connectedPacket.missingLocations); - archipelagoClient.getLocationManager().sendIfChecked(connectedPacket.missingLocations); + client.getLocationManager().addCheckedLocations(connectedPacket.checkedLocations); + client.getLocationManager().setMissingLocations(connectedPacket.missingLocations); + client.getLocationManager().sendIfChecked(connectedPacket.missingLocations); ConnectionResultEvent connectionResultEvent = new ConnectionResultEvent(ConnectionResult.Success, connectedPacket.team, connectedPacket.slot, seedName, slotData); - archipelagoClient.getEventManager().callEvent(connectionResultEvent); + client.getEventManager().callEvent(connectionResultEvent); } else { this.close(); //close out of this loop because we are no longer interested in further commands from the server. @@ -129,17 +130,17 @@ public void onMessage(String message) { break; case ConnectionRefused: ConnectionRefusedPacket error = gson.fromJson(cmdList.get(i), ConnectionRefusedPacket.class); - archipelagoClient.getEventManager().callEvent(new ConnectionResultEvent(error.errors[0])); + client.getEventManager().callEvent(new ConnectionResultEvent(error.errors[0])); break; case Print: - archipelagoClient.onPrint(gson.fromJson(packet, PrintPacket.class).getText()); + client.onPrint(gson.fromJson(packet, PrintPacket.class).getText()); break; case DataPackage: JsonElement data = packet.getAsJsonObject().get("data"); DataPackage dataPackage = gson.fromJson(data, DataPackage.class); - dataPackage.uuid = archipelagoClient.getUUID(); - archipelagoClient.updateDataPackage(dataPackage); - archipelagoClient.saveDataPackage(); + dataPackage.uuid = client.getUUID(); + client.updateDataPackage(dataPackage); + client.saveDataPackage(); break; case PrintJSON: LOGGER.finest("PrintJSON packet"); @@ -148,18 +149,18 @@ public void onMessage(String message) { 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 = archipelagoClient.getRoomInfo().getPlayer(archipelagoClient.getTeam(), playerID); + NetworkPlayer player = client.getRoomInfo().getPlayer(client.getTeam(), playerID); 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 = archipelagoClient.getDataPackage().getItem(itemID,archipelagoClient.getSlotInfo().get(print.parts[i].player).game); + 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 = archipelagoClient.getDataPackage().getLocation(locationID,archipelagoClient.getSlotInfo().get(print.parts[i].player).game); + print.parts[p].text = client.getDataPackage().getLocation(locationID, client.getSlotInfo().get(print.parts[i].player).game); } } - archipelagoClient.onPrintJson(print, print.type, print.receiving, print.item); + client.onPrintJson(print, print.type, print.receiving, print.item); break; case RoomUpdate: RoomUpdatePacket updatePacket = gson.fromJson(packet, RoomUpdatePacket.class); @@ -167,7 +168,7 @@ public void onMessage(String message) { break; case ReceivedItems: ReceivedItemsPacket items = gson.fromJson(packet, ReceivedItemsPacket.class); - ItemManager itemManager = archipelagoClient.getItemManager(); + ItemManager itemManager = client.getItemManager(); itemManager.receiveItems(items.items, items.index); break; case Bounced: @@ -175,28 +176,28 @@ public void onMessage(String message) { if (DeathLink.isDeathLink(bounced)) DeathLink.receiveDeathLink(bounced); else - archipelagoClient.getEventManager().callEvent(new BouncedEvent(bounced.games, bounced.tags, bounced.slots, bounced.data)); + client.getEventManager().callEvent(new BouncedEvent(bounced.games, bounced.tags, bounced.slots, bounced.data)); break; case LocationInfo: LocationInfoPacket locations = gson.fromJson(packet, LocationInfoPacket.class); for (NetworkItem item : locations.locations) { - item.itemName = archipelagoClient.getDataPackage().getItem(item.itemID, archipelagoClient.getSlotInfo().get(item.playerID).game); - item.locationName = archipelagoClient.getDataPackage().getLocation(item.locationID, archipelagoClient.getSlotInfo().get(archipelagoClient.getSlot()).game); - item.playerName = archipelagoClient.getRoomInfo().getPlayer(archipelagoClient.getTeam(), item.playerID).alias; + item.itemName = client.getDataPackage().getItem(item.itemID, client.getSlotInfo().get(item.playerID).game); + item.locationName = client.getDataPackage().getLocation(item.locationID, client.getSlotInfo().get(client.getSlot()).game); + item.playerName = client.getRoomInfo().getPlayer(client.getTeam(), item.playerID).alias; } - archipelagoClient.getEventManager().callEvent(new LocationInfoEvent(locations.locations)); + client.getEventManager().callEvent(new LocationInfoEvent(locations.locations)); break; case Retrieved: RetrievedPacket retrievedPacket = gson.fromJson(packet, RetrievedPacket.class); - archipelagoClient.getEventManager().callEvent(new RetrievedEvent(retrievedPacket.keys, packet.getAsJsonObject().get("keys").getAsJsonObject(), retrievedPacket.requestID)); + client.getEventManager().callEvent(new RetrievedEvent(retrievedPacket.keys, packet.getAsJsonObject().get("keys").getAsJsonObject(), retrievedPacket.requestID)); break; case SetReply: SetReplyPacket setReplyPacket = gson.fromJson(packet, SetReplyPacket.class); - archipelagoClient.getEventManager().callEvent(new SetReplyEvent(setReplyPacket.key, setReplyPacket.value, setReplyPacket.original_Value, packet.getAsJsonObject().get("value"), setReplyPacket.requestID)); + client.getEventManager().callEvent(new SetReplyEvent(setReplyPacket.key, setReplyPacket.value, setReplyPacket.original_Value, packet.getAsJsonObject().get("value"), setReplyPacket.requestID)); break; case InvalidPacket: InvalidPacket invalidPacket = gson.fromJson(packet, InvalidPacket.class); - archipelagoClient.getEventManager().callEvent(new InvalidPacketEvent(invalidPacket.type, invalidPacket.Original_cmd, invalidPacket.text)); + client.getEventManager().callEvent(new InvalidPacketEvent(invalidPacket.type, invalidPacket.Original_cmd, invalidPacket.text)); default: } @@ -209,20 +210,20 @@ public void onMessage(String message) { private void updateRoom(RoomUpdatePacket updateRoomPacket) { if (!updateRoomPacket.networkPlayers.isEmpty()) { - archipelagoClient.getRoomInfo().networkPlayers = updateRoomPacket.networkPlayers; - archipelagoClient.getRoomInfo().networkPlayers.add(new NetworkPlayer(archipelagoClient.getTeam(), 0, "Archipelago")); + client.getRoomInfo().networkPlayers = updateRoomPacket.networkPlayers; + client.getRoomInfo().networkPlayers.add(new NetworkPlayer(client.getTeam(), 0, "Archipelago")); } - archipelagoClient.setHintPoints(updateRoomPacket.hintPoints); - archipelagoClient.setAlias(archipelagoClient.getRoomInfo().getPlayer(archipelagoClient.getTeam(), archipelagoClient.getSlot()).alias); + client.setHintPoints(updateRoomPacket.hintPoints); + client.setAlias(client.getRoomInfo().getPlayer(client.getTeam(), client.getSlot()).alias); - archipelagoClient.getEventManager().callEvent(new CheckedLocationsEvent(updateRoomPacket.checkedLocations)); + client.getEventManager().callEvent(new CheckedLocationsEvent(updateRoomPacket.checkedLocations)); } private void checkDataPackage(HashMap versions, List games) { Set gamesToUpdate = new HashSet<>(); - Map checksums = archipelagoClient.getDataPackage().getChecksums(); + Map checksums = client.getDataPackage().getChecksums(); for (Map.Entry game : versions.entrySet()) { if (!games.contains(game.getKey())) continue; @@ -268,18 +269,18 @@ public void onClose(int code, String wsReason, boolean remote) { // attempt to reconnect using non-secure web socket if we are failing to connect with a secure socket. if (uri.getScheme().equalsIgnoreCase("wss") && downgrade) { try { - archipelagoClient.connect(new URIBuilder(uri).setScheme("ws").build()); + client.connect(new URIBuilder(uri).setScheme("ws").build()); } catch (URISyntaxException ignored) { - archipelagoClient.onClose("(AP-275) " + reason, 0); + client.onClose("(AP-275) " + reason, 0); } return; } - archipelagoClient.onClose("(AP-279) " + reason, 0); + client.onClose("(AP-279) " + reason, 0); return; } if (code == 1000) { reconnectTimer.cancel(); - archipelagoClient.onClose("(AP-284) Disconnected.", 0); + client.onClose("(AP-284) Disconnected.", 0); } if (code == 1006) { @@ -290,20 +291,20 @@ public void onClose(int code, String wsReason, boolean remote) { TimerTask reconnectTask = new TimerTask() { @Override public void run() { - archipelagoClient.reconnect(); + client.reconnect(); } }; reconnectTimer.cancel(); reconnectTimer = new Timer(); reconnectTimer.schedule(reconnectTask, reconnectDelay); - archipelagoClient.onClose("(AP-302) " + reason, reconnectDelay / 1000); + client.onClose("(AP-302) " + reason, reconnectDelay / 1000); return; } } reconnectTimer.cancel(); - archipelagoClient.onClose("(AP-308) "+reason, 0); + client.onClose("(AP-308) "+reason, 0); } @Override @@ -312,7 +313,7 @@ public void onError(Exception ex) { LOGGER.info(String.format("SSL Error: %s", ex.getMessage())); return; } - archipelagoClient.onError(ex); + client.onError(ex); LOGGER.log(Level.WARNING, "Error in websocket connection"); ex.printStackTrace(); } diff --git a/src/main/java/gg/archipelago/client/events/ArchipelagoEventListener.java b/src/main/java/dev/koifysh/archipelago/events/ArchipelagoEventListener.java similarity index 80% rename from src/main/java/gg/archipelago/client/events/ArchipelagoEventListener.java rename to src/main/java/dev/koifysh/archipelago/events/ArchipelagoEventListener.java index 3451931..aa8ffd3 100644 --- a/src/main/java/gg/archipelago/client/events/ArchipelagoEventListener.java +++ b/src/main/java/dev/koifysh/archipelago/events/ArchipelagoEventListener.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/src/main/java/gg/archipelago/client/events/BouncedEvent.java b/src/main/java/dev/koifysh/archipelago/events/BouncedEvent.java similarity index 96% rename from src/main/java/gg/archipelago/client/events/BouncedEvent.java rename to src/main/java/dev/koifysh/archipelago/events/BouncedEvent.java index 235ef71..82754bf 100644 --- a/src/main/java/gg/archipelago/client/events/BouncedEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/BouncedEvent.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/events/CheckedLocationsEvent.java b/src/main/java/dev/koifysh/archipelago/events/CheckedLocationsEvent.java similarity index 86% rename from src/main/java/gg/archipelago/client/events/CheckedLocationsEvent.java rename to src/main/java/dev/koifysh/archipelago/events/CheckedLocationsEvent.java index 57559a2..1a657d3 100644 --- a/src/main/java/gg/archipelago/client/events/CheckedLocationsEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/CheckedLocationsEvent.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; import java.util.ArrayList; diff --git a/src/main/java/gg/archipelago/client/events/ConnectionAttemptEvent.java b/src/main/java/dev/koifysh/archipelago/events/ConnectionAttemptEvent.java similarity index 96% rename from src/main/java/gg/archipelago/client/events/ConnectionAttemptEvent.java rename to src/main/java/dev/koifysh/archipelago/events/ConnectionAttemptEvent.java index 0f28139..30d750e 100644 --- a/src/main/java/gg/archipelago/client/events/ConnectionAttemptEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/ConnectionAttemptEvent.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; import com.google.gson.Gson; import com.google.gson.JsonElement; diff --git a/src/main/java/gg/archipelago/client/events/ConnectionResultEvent.java b/src/main/java/dev/koifysh/archipelago/events/ConnectionResultEvent.java similarity index 92% rename from src/main/java/gg/archipelago/client/events/ConnectionResultEvent.java rename to src/main/java/dev/koifysh/archipelago/events/ConnectionResultEvent.java index 40a16ff..429b3e4 100644 --- a/src/main/java/gg/archipelago/client/events/ConnectionResultEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/ConnectionResultEvent.java @@ -1,9 +1,9 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.internal.Primitives; -import gg.archipelago.client.network.ConnectionResult; +import dev.koifysh.archipelago.network.ConnectionResult; public class ConnectionResultEvent implements Event { diff --git a/src/main/java/gg/archipelago/client/events/DeathLinkEvent.java b/src/main/java/dev/koifysh/archipelago/events/DeathLinkEvent.java similarity index 87% rename from src/main/java/gg/archipelago/client/events/DeathLinkEvent.java rename to src/main/java/dev/koifysh/archipelago/events/DeathLinkEvent.java index 5cd5727..7c5bd9a 100644 --- a/src/main/java/gg/archipelago/client/events/DeathLinkEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/DeathLinkEvent.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; public class DeathLinkEvent implements Event { diff --git a/src/main/java/dev/koifysh/archipelago/events/Event.java b/src/main/java/dev/koifysh/archipelago/events/Event.java new file mode 100644 index 0000000..51ed3a4 --- /dev/null +++ b/src/main/java/dev/koifysh/archipelago/events/Event.java @@ -0,0 +1,4 @@ +package dev.koifysh.archipelago.events; + +public interface Event { +} diff --git a/src/main/java/gg/archipelago/client/events/InvalidPacketEvent.java b/src/main/java/dev/koifysh/archipelago/events/InvalidPacketEvent.java similarity index 94% rename from src/main/java/gg/archipelago/client/events/InvalidPacketEvent.java rename to src/main/java/dev/koifysh/archipelago/events/InvalidPacketEvent.java index 014b653..fd6ba61 100644 --- a/src/main/java/gg/archipelago/client/events/InvalidPacketEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/InvalidPacketEvent.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; public class InvalidPacketEvent implements Event { diff --git a/src/main/java/gg/archipelago/client/events/LocationInfoEvent.java b/src/main/java/dev/koifysh/archipelago/events/LocationInfoEvent.java similarity index 72% rename from src/main/java/gg/archipelago/client/events/LocationInfoEvent.java rename to src/main/java/dev/koifysh/archipelago/events/LocationInfoEvent.java index 272a194..95a314d 100644 --- a/src/main/java/gg/archipelago/client/events/LocationInfoEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/LocationInfoEvent.java @@ -1,6 +1,6 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; -import gg.archipelago.client.parts.NetworkItem; +import dev.koifysh.archipelago.parts.NetworkItem; import java.util.ArrayList; diff --git a/src/main/java/gg/archipelago/client/events/ReceiveItemEvent.java b/src/main/java/dev/koifysh/archipelago/events/ReceiveItemEvent.java similarity index 89% rename from src/main/java/gg/archipelago/client/events/ReceiveItemEvent.java rename to src/main/java/dev/koifysh/archipelago/events/ReceiveItemEvent.java index fa72596..a3edf71 100644 --- a/src/main/java/gg/archipelago/client/events/ReceiveItemEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/ReceiveItemEvent.java @@ -1,6 +1,6 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; -import gg.archipelago.client.parts.NetworkItem; +import dev.koifysh.archipelago.parts.NetworkItem; public class ReceiveItemEvent implements Event { diff --git a/src/main/java/gg/archipelago/client/events/RetrievedEvent.java b/src/main/java/dev/koifysh/archipelago/events/RetrievedEvent.java similarity index 97% rename from src/main/java/gg/archipelago/client/events/RetrievedEvent.java rename to src/main/java/dev/koifysh/archipelago/events/RetrievedEvent.java index 24f201c..93b29ad 100644 --- a/src/main/java/gg/archipelago/client/events/RetrievedEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/RetrievedEvent.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; import com.google.gson.Gson; import com.google.gson.JsonObject; diff --git a/src/main/java/gg/archipelago/client/events/SetReplyEvent.java b/src/main/java/dev/koifysh/archipelago/events/SetReplyEvent.java similarity index 96% rename from src/main/java/gg/archipelago/client/events/SetReplyEvent.java rename to src/main/java/dev/koifysh/archipelago/events/SetReplyEvent.java index c5fc1b5..ff23305 100644 --- a/src/main/java/gg/archipelago/client/events/SetReplyEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/SetReplyEvent.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.events; +package dev.koifysh.archipelago.events; import com.google.gson.Gson; import com.google.gson.JsonElement; diff --git a/src/main/java/gg/archipelago/client/helper/DeathLink.java b/src/main/java/dev/koifysh/archipelago/helper/DeathLink.java similarity index 71% rename from src/main/java/gg/archipelago/client/helper/DeathLink.java rename to src/main/java/dev/koifysh/archipelago/helper/DeathLink.java index 9311b8f..70003b5 100644 --- a/src/main/java/gg/archipelago/client/helper/DeathLink.java +++ b/src/main/java/dev/koifysh/archipelago/helper/DeathLink.java @@ -1,12 +1,12 @@ -package gg.archipelago.client.helper; +package dev.koifysh.archipelago.helper; -import gg.archipelago.client.events.DeathLinkEvent; -import gg.archipelago.client.network.client.BouncePacket; -import gg.archipelago.client.network.server.BouncedPacket; +import dev.koifysh.archipelago.network.client.BouncePacket; +import dev.koifysh.archipelago.network.server.BouncedPacket; +import dev.koifysh.archipelago.events.DeathLinkEvent; import java.util.HashMap; -import static gg.archipelago.client.ArchipelagoClient.archipelagoClient; +import static dev.koifysh.archipelago.Client.client; public class DeathLink { @@ -23,7 +23,7 @@ public static void receiveDeathLink(BouncedPacket bounced) { return; DeathLinkEvent dl = new DeathLinkEvent((String)bounced.data.get("source"), (String)bounced.data.get("cause"), (Double)bounced.data.get("time")); - archipelagoClient.getEventManager().callEvent(dl); + client.getEventManager().callEvent(dl); } catch (ClassCastException ex) { System.out.println("Error Receiving DeathLink, possible malformed bounce packet"); } @@ -39,13 +39,13 @@ public static void SendDeathLink(String source, String cause) { put("time", lastDeath); put("source",source); }}); - archipelagoClient.sendBounce(deathLinkPacket); + client.sendBounce(deathLinkPacket); } public static void setDeathLinkEnabled(boolean enabled) { if(enabled) - archipelagoClient.addTag("DeathLink"); + client.addTag("DeathLink"); else - archipelagoClient.removeTag("DeathLink"); + client.removeTag("DeathLink"); } } diff --git a/src/main/java/gg/archipelago/client/network/APPacket.java b/src/main/java/dev/koifysh/archipelago/network/APPacket.java similarity index 88% rename from src/main/java/gg/archipelago/client/network/APPacket.java rename to src/main/java/dev/koifysh/archipelago/network/APPacket.java index 641a11b..89d40f6 100644 --- a/src/main/java/gg/archipelago/client/network/APPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/APPacket.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.network; +package dev.koifysh.archipelago.network; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/network/APPacketType.java b/src/main/java/dev/koifysh/archipelago/network/APPacketType.java similarity index 96% rename from src/main/java/gg/archipelago/client/network/APPacketType.java rename to src/main/java/dev/koifysh/archipelago/network/APPacketType.java index 3f00654..0d0c14d 100644 --- a/src/main/java/gg/archipelago/client/network/APPacketType.java +++ b/src/main/java/dev/koifysh/archipelago/network/APPacketType.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.network; +package dev.koifysh.archipelago.network; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/network/ConnectionResult.java b/src/main/java/dev/koifysh/archipelago/network/ConnectionResult.java similarity index 73% rename from src/main/java/gg/archipelago/client/network/ConnectionResult.java rename to src/main/java/dev/koifysh/archipelago/network/ConnectionResult.java index a681c87..e0f709b 100644 --- a/src/main/java/gg/archipelago/client/network/ConnectionResult.java +++ b/src/main/java/dev/koifysh/archipelago/network/ConnectionResult.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.network; +package dev.koifysh.archipelago.network; public enum ConnectionResult { Success,InvalidSlot, SlotAlreadyTaken, IncompatibleVersion, InvalidPassword diff --git a/src/main/java/dev/koifysh/archipelago/network/DataStorageOperation.java b/src/main/java/dev/koifysh/archipelago/network/DataStorageOperation.java new file mode 100644 index 0000000..2346540 --- /dev/null +++ b/src/main/java/dev/koifysh/archipelago/network/DataStorageOperation.java @@ -0,0 +1,3 @@ +package dev.koifysh.archipelago.network; + + diff --git a/src/main/java/gg/archipelago/client/network/Permission.java b/src/main/java/dev/koifysh/archipelago/network/Permission.java similarity index 84% rename from src/main/java/gg/archipelago/client/network/Permission.java rename to src/main/java/dev/koifysh/archipelago/network/Permission.java index e705083..b8c7c07 100644 --- a/src/main/java/gg/archipelago/client/network/Permission.java +++ b/src/main/java/dev/koifysh/archipelago/network/Permission.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.network; +package dev.koifysh.archipelago.network; public enum Permission { disabled(0b000), diff --git a/src/main/java/gg/archipelago/client/network/RemainingMode.java b/src/main/java/dev/koifysh/archipelago/network/RemainingMode.java similarity index 89% rename from src/main/java/gg/archipelago/client/network/RemainingMode.java rename to src/main/java/dev/koifysh/archipelago/network/RemainingMode.java index ada9cc6..c1fb5df 100644 --- a/src/main/java/gg/archipelago/client/network/RemainingMode.java +++ b/src/main/java/dev/koifysh/archipelago/network/RemainingMode.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.network; +package dev.koifysh.archipelago.network; public enum RemainingMode { enabled, diff --git a/src/main/java/gg/archipelago/client/network/client/BouncePacket.java b/src/main/java/dev/koifysh/archipelago/network/client/BouncePacket.java similarity index 79% rename from src/main/java/gg/archipelago/client/network/client/BouncePacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/BouncePacket.java index 7419fb3..6d822ff 100644 --- a/src/main/java/gg/archipelago/client/network/client/BouncePacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/BouncePacket.java @@ -1,10 +1,10 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.events.Event; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.events.Event; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.HashMap; diff --git a/src/main/java/gg/archipelago/client/network/client/ConnectPacket.java b/src/main/java/dev/koifysh/archipelago/network/client/ConnectPacket.java similarity index 75% rename from src/main/java/gg/archipelago/client/network/client/ConnectPacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/ConnectPacket.java index c312307..99d4b13 100644 --- a/src/main/java/gg/archipelago/client/network/client/ConnectPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/ConnectPacket.java @@ -1,9 +1,9 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.parts.Version; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; +import dev.koifysh.archipelago.parts.Version; import java.util.Set; diff --git a/src/main/java/gg/archipelago/client/network/client/GetDataPackagePacket.java b/src/main/java/dev/koifysh/archipelago/network/client/GetDataPackagePacket.java similarity index 66% rename from src/main/java/gg/archipelago/client/network/client/GetDataPackagePacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/GetDataPackagePacket.java index 92c6053..267a06d 100644 --- a/src/main/java/gg/archipelago/client/network/client/GetDataPackagePacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/GetDataPackagePacket.java @@ -1,7 +1,7 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.Set; diff --git a/src/main/java/gg/archipelago/client/network/client/GetPacket.java b/src/main/java/dev/koifysh/archipelago/network/client/GetPacket.java similarity index 60% rename from src/main/java/gg/archipelago/client/network/client/GetPacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/GetPacket.java index 3db6fa9..fa10ce1 100644 --- a/src/main/java/gg/archipelago/client/network/client/GetPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/GetPacket.java @@ -1,16 +1,18 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.Client; +import dev.koifysh.archipelago.events.RetrievedEvent; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.Collection; import java.util.Random; /** * Used to request a single or multiple values from the server's data storage, see the - * {@link gg.archipelago.client.ArchipelagoClient#dataStorageSet(SetPacket) ArchipelagoClient.dataStorageSet()} for how to write values to the data storage. - * A Get package will be answered with a {@link gg.archipelago.client.events.RetrievedEvent RetreivedEvent}. + * {@link Client#dataStorageSet(SetPacket) ArchipelagoClient.dataStorageSet()} for how to write values to the data storage. + * A Get package will be answered with a {@link RetrievedEvent RetreivedEvent}. */ public class GetPacket extends APPacket { diff --git a/src/main/java/gg/archipelago/client/network/client/LocationChecks.java b/src/main/java/dev/koifysh/archipelago/network/client/LocationChecks.java similarity index 67% rename from src/main/java/gg/archipelago/client/network/client/LocationChecks.java rename to src/main/java/dev/koifysh/archipelago/network/client/LocationChecks.java index b4a46db..e6bf674 100644 --- a/src/main/java/gg/archipelago/client/network/client/LocationChecks.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/LocationChecks.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/gg/archipelago/client/network/client/LocationScouts.java b/src/main/java/dev/koifysh/archipelago/network/client/LocationScouts.java similarity index 65% rename from src/main/java/gg/archipelago/client/network/client/LocationScouts.java rename to src/main/java/dev/koifysh/archipelago/network/client/LocationScouts.java index 37a9f4b..e099785 100644 --- a/src/main/java/gg/archipelago/client/network/client/LocationScouts.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/LocationScouts.java @@ -1,7 +1,7 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.ArrayList; diff --git a/src/main/java/gg/archipelago/client/network/client/SayPacket.java b/src/main/java/dev/koifysh/archipelago/network/client/SayPacket.java similarity index 62% rename from src/main/java/gg/archipelago/client/network/client/SayPacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/SayPacket.java index 33d5cd4..1d53ec8 100644 --- a/src/main/java/gg/archipelago/client/network/client/SayPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/SayPacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; public class SayPacket extends APPacket { diff --git a/src/main/java/gg/archipelago/client/network/client/SetNotifyPacket.java b/src/main/java/dev/koifysh/archipelago/network/client/SetNotifyPacket.java similarity index 68% rename from src/main/java/gg/archipelago/client/network/client/SetNotifyPacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/SetNotifyPacket.java index 868bf75..aa7ca67 100644 --- a/src/main/java/gg/archipelago/client/network/client/SetNotifyPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/SetNotifyPacket.java @@ -1,7 +1,7 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.Collection; diff --git a/src/main/java/gg/archipelago/client/network/client/SetPacket.java b/src/main/java/dev/koifysh/archipelago/network/client/SetPacket.java similarity index 93% rename from src/main/java/gg/archipelago/client/network/client/SetPacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/SetPacket.java index 36fc69a..d4264c6 100644 --- a/src/main/java/gg/archipelago/client/network/client/SetPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/SetPacket.java @@ -1,8 +1,9 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.events.SetReplyEvent; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.ArrayList; import java.util.Random; @@ -22,7 +23,7 @@ public class SetPacket extends APPacket { public Object defaultValue; /** - * If true, the server will send a {@link gg.archipelago.client.events.SetReplyEvent SetReplyEvent} response back to the client. + * If true, the server will send a {@link SetReplyEvent SetReplyEvent} response back to the client. */ @SerializedName("want_reply") public boolean want_reply = false; @@ -95,7 +96,7 @@ private static class DataStorageOperation { */ public enum Operation { /** - * Sets the current value of the key on the server to the value given in {@link gg.archipelago.client.network.client.SetPacket#addDataStorageOperation addDataStorageOperation(Operation, Value)}. + * Sets the current value of the key on the server to the value given in {@link SetPacket#addDataStorageOperation addDataStorageOperation(Operation, Value)}. */ @SerializedName("replace") REPLACE, diff --git a/src/main/java/gg/archipelago/client/network/client/StatusUpdatePacket.java b/src/main/java/dev/koifysh/archipelago/network/client/StatusUpdatePacket.java similarity index 52% rename from src/main/java/gg/archipelago/client/network/client/StatusUpdatePacket.java rename to src/main/java/dev/koifysh/archipelago/network/client/StatusUpdatePacket.java index 7a99390..32320d8 100644 --- a/src/main/java/gg/archipelago/client/network/client/StatusUpdatePacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/client/StatusUpdatePacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.client; +package dev.koifysh.archipelago.network.client; -import gg.archipelago.client.ClientStatus; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.ClientStatus; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; public class StatusUpdatePacket extends APPacket { diff --git a/src/main/java/dev/koifysh/archipelago/network/client/SyncPacket.java b/src/main/java/dev/koifysh/archipelago/network/client/SyncPacket.java new file mode 100644 index 0000000..940b259 --- /dev/null +++ b/src/main/java/dev/koifysh/archipelago/network/client/SyncPacket.java @@ -0,0 +1,12 @@ +package dev.koifysh.archipelago.network.client; + +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; + +public class SyncPacket extends APPacket { + + + public SyncPacket() { + super(APPacketType.Sync); + } +} diff --git a/src/main/java/gg/archipelago/client/network/server/BouncedPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/BouncedPacket.java similarity index 79% rename from src/main/java/gg/archipelago/client/network/server/BouncedPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/BouncedPacket.java index dcaef8f..6c744ba 100644 --- a/src/main/java/gg/archipelago/client/network/server/BouncedPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/BouncedPacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.HashMap; import java.util.HashSet; diff --git a/src/main/java/gg/archipelago/client/network/server/ConnectUpdatePacket.java b/src/main/java/dev/koifysh/archipelago/network/server/ConnectUpdatePacket.java similarity index 64% rename from src/main/java/gg/archipelago/client/network/server/ConnectUpdatePacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/ConnectUpdatePacket.java index 7b05468..2871d70 100644 --- a/src/main/java/gg/archipelago/client/network/server/ConnectUpdatePacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/ConnectUpdatePacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.Set; diff --git a/src/main/java/gg/archipelago/client/network/server/ConnectedPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/ConnectedPacket.java similarity index 74% rename from src/main/java/gg/archipelago/client/network/server/ConnectedPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/ConnectedPacket.java index 91215c2..9049c49 100644 --- a/src/main/java/gg/archipelago/client/network/server/ConnectedPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/ConnectedPacket.java @@ -1,10 +1,10 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.parts.NetworkPlayer; -import gg.archipelago.client.parts.NetworkSlot; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; +import dev.koifysh.archipelago.parts.NetworkPlayer; +import dev.koifysh.archipelago.parts.NetworkSlot; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/gg/archipelago/client/network/server/ConnectionRefusedPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/ConnectionRefusedPacket.java similarity index 56% rename from src/main/java/gg/archipelago/client/network/server/ConnectionRefusedPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/ConnectionRefusedPacket.java index ff60fef..0e91e4f 100644 --- a/src/main/java/gg/archipelago/client/network/server/ConnectionRefusedPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/ConnectionRefusedPacket.java @@ -1,9 +1,9 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.network.ConnectionResult; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; +import dev.koifysh.archipelago.network.ConnectionResult; public class ConnectionRefusedPacket extends APPacket { diff --git a/src/main/java/gg/archipelago/client/network/server/InvalidPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/InvalidPacket.java similarity index 70% rename from src/main/java/gg/archipelago/client/network/server/InvalidPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/InvalidPacket.java index 7179ba6..f5a855e 100644 --- a/src/main/java/gg/archipelago/client/network/server/InvalidPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/InvalidPacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; public class InvalidPacket extends APPacket { diff --git a/src/main/java/dev/koifysh/archipelago/network/server/JsonPrintPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/JsonPrintPacket.java new file mode 100644 index 0000000..6c7b874 --- /dev/null +++ b/src/main/java/dev/koifysh/archipelago/network/server/JsonPrintPacket.java @@ -0,0 +1,13 @@ +package dev.koifysh.archipelago.network.server; + +import dev.koifysh.archipelago.Print.APPrintPart; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; + +public class JsonPrintPacket extends APPacket { + APPrintPart[] parts; + + public JsonPrintPacket() { + super(APPacketType.PrintJSON); + } +} diff --git a/src/main/java/gg/archipelago/client/network/server/LocationInfoPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/LocationInfoPacket.java similarity index 59% rename from src/main/java/gg/archipelago/client/network/server/LocationInfoPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/LocationInfoPacket.java index efbd2e7..309ca7b 100644 --- a/src/main/java/gg/archipelago/client/network/server/LocationInfoPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/LocationInfoPacket.java @@ -1,9 +1,9 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.parts.NetworkItem; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; +import dev.koifysh.archipelago.parts.NetworkItem; import java.util.ArrayList; diff --git a/src/main/java/gg/archipelago/client/network/server/PrintPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/PrintPacket.java similarity index 64% rename from src/main/java/gg/archipelago/client/network/server/PrintPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/PrintPacket.java index 45a5a86..8c7a9ed 100644 --- a/src/main/java/gg/archipelago/client/network/server/PrintPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/PrintPacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; public class PrintPacket extends APPacket { diff --git a/src/main/java/gg/archipelago/client/network/server/ReceivedItemsPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/ReceivedItemsPacket.java similarity index 63% rename from src/main/java/gg/archipelago/client/network/server/ReceivedItemsPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/ReceivedItemsPacket.java index 08071ca..a8925e3 100644 --- a/src/main/java/gg/archipelago/client/network/server/ReceivedItemsPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/ReceivedItemsPacket.java @@ -1,9 +1,9 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.parts.NetworkItem; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; +import dev.koifysh.archipelago.parts.NetworkItem; import java.util.ArrayList; diff --git a/src/main/java/gg/archipelago/client/network/server/RetrievedPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/RetrievedPacket.java similarity index 69% rename from src/main/java/gg/archipelago/client/network/server/RetrievedPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/RetrievedPacket.java index 34ecbbe..7033406 100644 --- a/src/main/java/gg/archipelago/client/network/server/RetrievedPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/RetrievedPacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; import java.util.HashMap; diff --git a/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/RoomInfoPacket.java similarity index 83% rename from src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/RoomInfoPacket.java index 4491a59..46f2b88 100644 --- a/src/main/java/gg/archipelago/client/network/server/RoomInfoPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/RoomInfoPacket.java @@ -1,10 +1,10 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.parts.NetworkPlayer; -import gg.archipelago.client.parts.Version; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; +import dev.koifysh.archipelago.parts.NetworkPlayer; +import dev.koifysh.archipelago.parts.Version; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/gg/archipelago/client/network/server/RoomUpdatePacket.java b/src/main/java/dev/koifysh/archipelago/network/server/RoomUpdatePacket.java similarity index 81% rename from src/main/java/gg/archipelago/client/network/server/RoomUpdatePacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/RoomUpdatePacket.java index b7a37e1..10b677f 100644 --- a/src/main/java/gg/archipelago/client/network/server/RoomUpdatePacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/RoomUpdatePacket.java @@ -1,11 +1,11 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; -import gg.archipelago.client.network.RemainingMode; -import gg.archipelago.client.parts.NetworkPlayer; -import gg.archipelago.client.parts.Version; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; +import dev.koifysh.archipelago.network.RemainingMode; +import dev.koifysh.archipelago.parts.NetworkPlayer; +import dev.koifysh.archipelago.parts.Version; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/gg/archipelago/client/network/server/SetReplyPacket.java b/src/main/java/dev/koifysh/archipelago/network/server/SetReplyPacket.java similarity index 73% rename from src/main/java/gg/archipelago/client/network/server/SetReplyPacket.java rename to src/main/java/dev/koifysh/archipelago/network/server/SetReplyPacket.java index 3dc9efd..dde6829 100644 --- a/src/main/java/gg/archipelago/client/network/server/SetReplyPacket.java +++ b/src/main/java/dev/koifysh/archipelago/network/server/SetReplyPacket.java @@ -1,8 +1,8 @@ -package gg.archipelago.client.network.server; +package dev.koifysh.archipelago.network.server; import com.google.gson.annotations.SerializedName; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; +import dev.koifysh.archipelago.network.APPacket; +import dev.koifysh.archipelago.network.APPacketType; public class SetReplyPacket extends APPacket { @SerializedName("key") diff --git a/src/main/java/gg/archipelago/client/parts/DataPackage.java b/src/main/java/dev/koifysh/archipelago/parts/DataPackage.java similarity index 98% rename from src/main/java/gg/archipelago/client/parts/DataPackage.java rename to src/main/java/dev/koifysh/archipelago/parts/DataPackage.java index 34fe268..87fa9a9 100644 --- a/src/main/java/gg/archipelago/client/parts/DataPackage.java +++ b/src/main/java/dev/koifysh/archipelago/parts/DataPackage.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.parts; +package dev.koifysh.archipelago.parts; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/parts/Game.java b/src/main/java/dev/koifysh/archipelago/parts/Game.java similarity index 97% rename from src/main/java/gg/archipelago/client/parts/Game.java rename to src/main/java/dev/koifysh/archipelago/parts/Game.java index 56fc24e..0d52bc4 100644 --- a/src/main/java/gg/archipelago/client/parts/Game.java +++ b/src/main/java/dev/koifysh/archipelago/parts/Game.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.parts; +package dev.koifysh.archipelago.parts; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/parts/NetworkItem.java b/src/main/java/dev/koifysh/archipelago/parts/NetworkItem.java similarity index 96% rename from src/main/java/gg/archipelago/client/parts/NetworkItem.java rename to src/main/java/dev/koifysh/archipelago/parts/NetworkItem.java index 36a3876..cdbcffe 100644 --- a/src/main/java/gg/archipelago/client/parts/NetworkItem.java +++ b/src/main/java/dev/koifysh/archipelago/parts/NetworkItem.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.parts; +package dev.koifysh.archipelago.parts; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/parts/NetworkPlayer.java b/src/main/java/dev/koifysh/archipelago/parts/NetworkPlayer.java similarity index 88% rename from src/main/java/gg/archipelago/client/parts/NetworkPlayer.java rename to src/main/java/dev/koifysh/archipelago/parts/NetworkPlayer.java index 6af4d80..bd5e511 100644 --- a/src/main/java/gg/archipelago/client/parts/NetworkPlayer.java +++ b/src/main/java/dev/koifysh/archipelago/parts/NetworkPlayer.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.parts; +package dev.koifysh.archipelago.parts; public class NetworkPlayer { public int team; diff --git a/src/main/java/gg/archipelago/client/parts/NetworkSlot.java b/src/main/java/dev/koifysh/archipelago/parts/NetworkSlot.java similarity index 95% rename from src/main/java/gg/archipelago/client/parts/NetworkSlot.java rename to src/main/java/dev/koifysh/archipelago/parts/NetworkSlot.java index f95076b..bd494f4 100644 --- a/src/main/java/gg/archipelago/client/parts/NetworkSlot.java +++ b/src/main/java/dev/koifysh/archipelago/parts/NetworkSlot.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.parts; +package dev.koifysh.archipelago.parts; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/parts/Version.java b/src/main/java/dev/koifysh/archipelago/parts/Version.java similarity index 89% rename from src/main/java/gg/archipelago/client/parts/Version.java rename to src/main/java/dev/koifysh/archipelago/parts/Version.java index 59d27ba..eed4df7 100644 --- a/src/main/java/gg/archipelago/client/parts/Version.java +++ b/src/main/java/dev/koifysh/archipelago/parts/Version.java @@ -1,4 +1,4 @@ -package gg.archipelago.client.parts; +package dev.koifysh.archipelago.parts; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/gg/archipelago/client/events/Event.java b/src/main/java/gg/archipelago/client/events/Event.java deleted file mode 100644 index 0f1c503..0000000 --- a/src/main/java/gg/archipelago/client/events/Event.java +++ /dev/null @@ -1,4 +0,0 @@ -package gg.archipelago.client.events; - -public interface Event { -} diff --git a/src/main/java/gg/archipelago/client/network/DataStorageOperation.java b/src/main/java/gg/archipelago/client/network/DataStorageOperation.java deleted file mode 100644 index d8251b0..0000000 --- a/src/main/java/gg/archipelago/client/network/DataStorageOperation.java +++ /dev/null @@ -1,3 +0,0 @@ -package gg.archipelago.client.network; - - diff --git a/src/main/java/gg/archipelago/client/network/client/SyncPacket.java b/src/main/java/gg/archipelago/client/network/client/SyncPacket.java deleted file mode 100644 index 378c985..0000000 --- a/src/main/java/gg/archipelago/client/network/client/SyncPacket.java +++ /dev/null @@ -1,12 +0,0 @@ -package gg.archipelago.client.network.client; - -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; - -public class SyncPacket extends APPacket { - - - public SyncPacket() { - super(APPacketType.Sync); - } -} diff --git a/src/main/java/gg/archipelago/client/network/server/JsonPrintPacket.java b/src/main/java/gg/archipelago/client/network/server/JsonPrintPacket.java deleted file mode 100644 index 123c891..0000000 --- a/src/main/java/gg/archipelago/client/network/server/JsonPrintPacket.java +++ /dev/null @@ -1,13 +0,0 @@ -package gg.archipelago.client.network.server; - -import gg.archipelago.client.Print.APPrintPart; -import gg.archipelago.client.network.APPacket; -import gg.archipelago.client.network.APPacketType; - -public class JsonPrintPacket extends APPacket { - APPrintPart[] parts; - - public JsonPrintPacket() { - super(APPacketType.PrintJSON); - } -} From 312e9aac05824807b19502a4035ea1184a7a7d8b Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Mon, 20 May 2024 20:01:37 -0700 Subject: [PATCH 12/17] prepare for maven central repo --- .github/workflows/maven-publish.yml | 20 ---------- .github/workflows/maven.yml | 5 --- pom.xml | 37 +++++++++++-------- readme.md | 2 + .../dev/koifysh/archipelago/WebSocket.java | 2 +- 5 files changed, 24 insertions(+), 42 deletions(-) delete mode 100644 .github/workflows/maven-publish.yml diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml deleted file mode 100644 index fdc03b3..0000000 --- a/.github/workflows/maven-publish.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Publish package to GitHub Packages -on: - release: - types: [created] -jobs: - publish: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - java-version: '11' - distribution: 'temurin' - - name: Publish package - run: mvn --batch-mode release:clean release:prepare deploy - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 44be510..9558e40 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -33,8 +33,3 @@ jobs: # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive - name: Update dependency graph uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 - - - name: Publish Snapshot - run: mvn --batch-mode deploy - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pom.xml b/pom.xml index 3912a60..c0b63d0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,24 +4,24 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - gg.archipelago - multiclient.java - 0.1.0-SNAPSHOT + dev.koifysh + archipelago-client + 0.1.0 Archipelago Java Library - The maven main core project description - http://maven.apache.org + Library to connect to an Archipelago Server + https://github.com/KonoTyran/archipelago-client MIT License - https://github.com/ArchipelagoMW/Archipelago.MultiClient.Java/blob/master/LICENSE + https://github.com/KonoTyran/archipelago-client/blob/main/LICENSE repo - scm:git:https://github.com/KonoTyran/Archipelago.MultiClient.Java.git + https://github.com/KonoTyran/archipelago-client @@ -58,14 +58,6 @@ - - - github - GitHub Packages - https://maven.pkg.github.com/konotyran/Archipelago.MultiClient.Java - - - @@ -89,7 +81,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9.1 + 3.6.3 attach-javadocs @@ -98,6 +90,9 @@ + + none + org.apache.maven.plugins @@ -113,6 +108,16 @@ + + org.sonatype.central + central-publishing-maven-plugin + 0.4.0 + true + + central + true + + diff --git a/readme.md b/readme.md index e69de29..4d42016 100644 --- a/readme.md +++ b/readme.md @@ -0,0 +1,2 @@ +## Archipelago Java Client +A java client to connect to an [Archipelago](http://giithub.com/ArchipelagoMW/Archipelago) Server. diff --git a/src/main/java/dev/koifysh/archipelago/WebSocket.java b/src/main/java/dev/koifysh/archipelago/WebSocket.java index 57ca340..92befa4 100644 --- a/src/main/java/dev/koifysh/archipelago/WebSocket.java +++ b/src/main/java/dev/koifysh/archipelago/WebSocket.java @@ -29,7 +29,7 @@ import java.util.*; import java.util.logging.Level; -public class WebSocket extends WebSocketClient { +class WebSocket extends WebSocketClient { private final static java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger(WebSocket.class.getName()); From 66468edc8a28cd5da5047c01aea381f47c5d7371 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Mon, 20 May 2024 20:02:35 -0700 Subject: [PATCH 13/17] fix typo in readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 4d42016..17b5d34 100644 --- a/readme.md +++ b/readme.md @@ -1,2 +1,2 @@ ## Archipelago Java Client -A java client to connect to an [Archipelago](http://giithub.com/ArchipelagoMW/Archipelago) Server. +A java client to connect to an [Archipelago](http://github.com/ArchipelagoMW/Archipelago) Server. From 779ea8162c01d8c79c0ee0ac8a2bf814c73a9f7b Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Mon, 20 May 2024 20:10:36 -0700 Subject: [PATCH 14/17] add missing info to pom.xml --- pom.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pom.xml b/pom.xml index c0b63d0..d4f0c57 100644 --- a/pom.xml +++ b/pom.xml @@ -21,9 +21,18 @@ + scm:git:git://github.com/KonoTyran/archipelago-client.git + scm:git:https://github.com/KonoTyran/archipelago-client.git https://github.com/KonoTyran/archipelago-client + + + Kono Tyran + Kono.Tyran@gmail.com + + + 8 8 From e2b4f30bdae5a1afe6670596e0786731b2d283fe Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Tue, 21 May 2024 20:34:29 -0700 Subject: [PATCH 15/17] Documentation. Lots and Lots of Documentation. and it's still not enough... --- pom.xml | 4 +- .../java/dev/koifysh/archipelago/Client.java | 80 ++++++++++++++++++- .../dev/koifysh/archipelago/ClientStatus.java | 7 ++ .../dev/koifysh/archipelago/EventManager.java | 10 +++ .../dev/koifysh/archipelago/ItemFlags.java | 18 ++++- .../dev/koifysh/archipelago/WebSocket.java | 10 ++- .../events/ArchipelagoEventListener.java | 3 + .../archipelago/events/DeathLinkEvent.java | 3 + .../archipelago/events/PrintJSONEvent.java | 28 +++++++ .../koifysh/archipelago/helper/DeathLink.java | 19 +++-- 10 files changed, 164 insertions(+), 18 deletions(-) create mode 100644 src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java diff --git a/pom.xml b/pom.xml index d4f0c57..1e812fb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.koifysh archipelago-client - 0.1.0 + 0.1.13 Archipelago Java Library Library to connect to an Archipelago Server @@ -21,7 +21,7 @@ - scm:git:git://github.com/KonoTyran/archipelago-client.git + scm:git:git://github.com/KonoTyran/archipelago-client scm:git:https://github.com/KonoTyran/archipelago-client.git https://github.com/KonoTyran/archipelago-client diff --git a/src/main/java/dev/koifysh/archipelago/Client.java b/src/main/java/dev/koifysh/archipelago/Client.java index 86ab886..5f1ee95 100644 --- a/src/main/java/dev/koifysh/archipelago/Client.java +++ b/src/main/java/dev/koifysh/archipelago/Client.java @@ -242,6 +242,11 @@ public RoomInfoPacket getRoomInfo() { public HashMap getSlotInfo() {return slotInfo;} + /** + * Works exactly like {@link #connect(URI, boolean)} with allowDowngrade set to true; + * @param address + * @throws URISyntaxException on malformed address + */ public void connect(String address) throws URISyntaxException { URIBuilder builder = new URIBuilder((!address.contains("//")) ? "//" + address : address); if (builder.getPort() == -1) { //set default port if not included @@ -262,6 +267,10 @@ public void connect(String address) throws URISyntaxException { connect(builder.build()); } + /** + * Works exactly like {@link #connect(URI, boolean)} but allowDowngrade is False + * @param address Address to connect to + */ public void connect(URI address) { connect(address, false); } @@ -290,6 +299,10 @@ public void connect(URI address, boolean allowDowngrade) { webSocket.connect(allowDowngrade); } + /** + * Sends a Chat message to all other connected Clients. + * @param message Message to send. + */ public void sendChat(String message) { if (webSocket == null) return; @@ -298,23 +311,46 @@ public void sendChat(String message) { } } + /** + * inform the Archipelago server that a location ID has been checked. + * @param locationID id of a location. + * @return true if packet was successfully sent. False if not connected or otherwise failed to send. + */ public boolean checkLocation(long locationID) { return locationManager.checkLocation(locationID); } + /** + * inform the Archipelago server that a collection of location ID has been checked. + * @param locationIDs a collection of a locations. + * @return true if packet was successfully sent. False if not connected or otherwise failed to send. + */ public boolean checkLocations(Collection locationIDs) { return locationManager.checkLocations(locationIDs); } + /** + * Ask the server for information about what is in locations. you will get a response in the {@link dev.koifysh.archipelago.events.LocationInfoEvent} event. + * @param locationIDs List of location ID's to request info on. + */ public void scoutLocations(ArrayList locationIDs) { HashMap locations = dataPackage.getLocationsForGame(game); locationIDs.removeIf( location -> !locations.containsKey(location)); webSocket.scoutLocation(locationIDs); } - public abstract void onPrint(String print); - - public abstract void onPrintJson(APPrint apPrint, String type, int sending, NetworkItem receiving); + /** + * 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); @@ -354,14 +390,26 @@ public void reconnect() { webSocket.reconnect(); } + /** + * Gets the UUID of this client. + * @return UUID of the client, this should theoretically never change. + */ public String getUUID() { return UUID; } + /** + * gets the alias of this slot. + * @return Alias of the slot connected to. + */ public String getAlias() { return alias; } + /** + * sets an Alias for this slot on the Archipelago server. + * @param alias Name to set the alias to. + */ void setAlias(String alias) { this.alias = alias; } @@ -374,6 +422,12 @@ public ItemManager getItemManager() { return itemManager; } + /** + * Update the current game status. + * @see ClientStatus + * + * @param status a {@link ClientStatus} to send to the server. + */ public void setGameState(ClientStatus status) { if (webSocket == null) return; @@ -381,6 +435,9 @@ public void setGameState(ClientStatus status) { webSocket.sendPacket(new StatusUpdatePacket(status)); } + /** + * manually trigger a resync to the Archipelago server. this should be done automatically if the library detects a desync. + */ public void sync() { webSocket.sendPacket(new SyncPacket()); } @@ -392,22 +449,38 @@ public void sendBounce(BouncePacket bouncePacket) { webSocket.sendPacket(bouncePacket); } + /** + * disconnects from a connected Archipelago server. + */ public void disconnect() { webSocket.close(); } + /** + * @return set of tags currently in use. + */ public Set getTags() { return tags; } + /** + * fetch the itemflags that have been set, bitwise Or against {@link ItemFlags} to read. + * @return items handling int. + */ public int getItemsHandlingFlags() { return itemsHandlingFlags; } + /** + * fetch the itemflags that have been set, bitwise Or against {@link ItemFlags} to read. + */ public void setItemsHandlingFlags(int itemsHandlingFlags) { this.itemsHandlingFlags = itemsHandlingFlags; } + /** + * @return the event manager. + */ public EventManager getEventManager() { return eventManager; } @@ -415,7 +488,6 @@ public EventManager getEventManager() { /** * Uses DataStorage to save a value on the AP server. * - * @param setPacket */ public int dataStorageSet(SetPacket setPacket) { if (webSocket == null || !webSocket.isAuthenticated()) diff --git a/src/main/java/dev/koifysh/archipelago/ClientStatus.java b/src/main/java/dev/koifysh/archipelago/ClientStatus.java index c7f6d4a..1dcc8d6 100644 --- a/src/main/java/dev/koifysh/archipelago/ClientStatus.java +++ b/src/main/java/dev/koifysh/archipelago/ClientStatus.java @@ -2,6 +2,13 @@ import com.google.gson.annotations.SerializedName; +/** + * A Status to send to the server.
+ * {@link #CLIENT_UNKNOWN} - default, no status.
+ * {@link #CLIENT_READY} - Ready to start.
+ * {@link #CLIENT_PLAYING} - Player has started playing.
+ * {@link #CLIENT_GOAL} - Player has finished their game. This will trigger an auto-release depending on server settings. + */ public enum ClientStatus { @SerializedName("0") diff --git a/src/main/java/dev/koifysh/archipelago/EventManager.java b/src/main/java/dev/koifysh/archipelago/EventManager.java index e24afe3..3f6d1da 100644 --- a/src/main/java/dev/koifysh/archipelago/EventManager.java +++ b/src/main/java/dev/koifysh/archipelago/EventManager.java @@ -8,10 +8,20 @@ import java.util.HashMap; import java.util.Map; +/** + * Manages registering and calling events + * @see #registerListener(Object) + */ public class EventManager { private final Map registeredListeners = new HashMap<>(); + /** + * Use to register 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 registerListener(Object listener) { for (Method method : listener.getClass().getMethods()) { if (!method.isAnnotationPresent(ArchipelagoEventListener.class)) diff --git a/src/main/java/dev/koifysh/archipelago/ItemFlags.java b/src/main/java/dev/koifysh/archipelago/ItemFlags.java index cfbc413..2c8260e 100644 --- a/src/main/java/dev/koifysh/archipelago/ItemFlags.java +++ b/src/main/java/dev/koifysh/archipelago/ItemFlags.java @@ -1,14 +1,26 @@ package dev.koifysh.archipelago; +/** + * Item Flag variables to read {@link Client#getItemsHandlingFlags()} and set {@link Client#setItemsHandlingFlags(int)} + *
+ * Current item flags: {@link #SEND_ITEMS} {@link #SEND_OWN_ITEMS} {@link #SEND_STARTING_INVENTORY} + */ public class ItemFlags { - //Indicates you get items sent from other worlds. + /** + * Tells the server to send you items from other worlds. + */ public static final int SEND_ITEMS = 0b001; - //send your own items to you (remote items game) + /** + * Tells the server to send your own items to you (remote items game) + */ public static final int SEND_OWN_ITEMS = 0b010; - //send starting inventory upon connect + /** + * Tells the server to send you any items that You should start with. + * don't set this if you handle starting items by some kind of data file. + */ public static final int SEND_STARTING_INVENTORY = 0b100; } diff --git a/src/main/java/dev/koifysh/archipelago/WebSocket.java b/src/main/java/dev/koifysh/archipelago/WebSocket.java index 92befa4..cdd814b 100644 --- a/src/main/java/dev/koifysh/archipelago/WebSocket.java +++ b/src/main/java/dev/koifysh/archipelago/WebSocket.java @@ -132,9 +132,6 @@ public void onMessage(String message) { ConnectionRefusedPacket error = gson.fromJson(cmdList.get(i), ConnectionRefusedPacket.class); client.getEventManager().callEvent(new ConnectionResultEvent(error.errors[0])); break; - case Print: - client.onPrint(gson.fromJson(packet, PrintPacket.class).getText()); - break; case DataPackage: JsonElement data = packet.getAsJsonObject().get("data"); DataPackage dataPackage = gson.fromJson(data, DataPackage.class); @@ -160,7 +157,12 @@ public void onMessage(String message) { print.parts[p].text = client.getDataPackage().getLocation(locationID, client.getSlotInfo().get(print.parts[i].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); @@ -173,7 +175,7 @@ public void onMessage(String message) { break; case Bounced: BouncedPacket bounced = gson.fromJson(packet, BouncedPacket.class); - if (DeathLink.isDeathLink(bounced)) + if (bounced.tags.contains("DeathLink")) DeathLink.receiveDeathLink(bounced); else client.getEventManager().callEvent(new BouncedEvent(bounced.games, bounced.tags, bounced.slots, bounced.data)); diff --git a/src/main/java/dev/koifysh/archipelago/events/ArchipelagoEventListener.java b/src/main/java/dev/koifysh/archipelago/events/ArchipelagoEventListener.java index aa8ffd3..ae75a40 100644 --- a/src/main/java/dev/koifysh/archipelago/events/ArchipelagoEventListener.java +++ b/src/main/java/dev/koifysh/archipelago/events/ArchipelagoEventListener.java @@ -3,6 +3,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * tag a method with this who's only parameter is a class that extends {@link Event} + */ @Retention(RetentionPolicy.RUNTIME) public @interface ArchipelagoEventListener { } diff --git a/src/main/java/dev/koifysh/archipelago/events/DeathLinkEvent.java b/src/main/java/dev/koifysh/archipelago/events/DeathLinkEvent.java index 7c5bd9a..367f736 100644 --- a/src/main/java/dev/koifysh/archipelago/events/DeathLinkEvent.java +++ b/src/main/java/dev/koifysh/archipelago/events/DeathLinkEvent.java @@ -1,5 +1,8 @@ package dev.koifysh.archipelago.events; +/** + * event that is fired whenever you receive a death link from another player. must first enable death links via {@link dev.koifysh.archipelago.helper.DeathLink} + */ public class DeathLinkEvent implements Event { public double time; diff --git a/src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java b/src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java new file mode 100644 index 0000000..01f639d --- /dev/null +++ b/src/main/java/dev/koifysh/archipelago/events/PrintJSONEvent.java @@ -0,0 +1,28 @@ +package dev.koifysh.archipelago.events; + +import dev.koifysh.archipelago.Print.APPrint; +import dev.koifysh.archipelago.parts.NetworkItem; + +/** + * event that is fired when the server wishes to send a message to the user. + */ +public class PrintJSONEvent implements Event { + + public APPrint apPrint; + public String type; + public int player; + public NetworkItem item; + + /** + * @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. + */ + public PrintJSONEvent(APPrint apPrint, String type, int player, NetworkItem item) { + this.apPrint = apPrint; + this.type = type; + this.player = player; + this.item = item; + } +} diff --git a/src/main/java/dev/koifysh/archipelago/helper/DeathLink.java b/src/main/java/dev/koifysh/archipelago/helper/DeathLink.java index 70003b5..4946adc 100644 --- a/src/main/java/dev/koifysh/archipelago/helper/DeathLink.java +++ b/src/main/java/dev/koifysh/archipelago/helper/DeathLink.java @@ -8,15 +8,15 @@ import static dev.koifysh.archipelago.Client.client; - +/** + * a helper-class for sending and receiving death links. + *
+ * enable death links by calling {@link #setDeathLinkEnabled(boolean)} + */ public class DeathLink { static private double lastDeath = 0; - public static boolean isDeathLink(BouncedPacket bounced) { - return bounced.tags.contains("DeathLink"); - } - public static void receiveDeathLink(BouncedPacket bounced) { try { if ((Double) bounced.data.getOrDefault("time", 0d) == lastDeath) @@ -29,6 +29,11 @@ public static void receiveDeathLink(BouncedPacket bounced) { } } + /** + * helper for sending a death link bounce packet. you can send these without enabling death link first, but it is frowned upon. + * @param source A String that is the name of the player sending the death link (does not have to be slot name) + * @param cause A String that is the cause of this death. may be empty. + */ public static void SendDeathLink(String source, String cause) { lastDeath = (double)System.currentTimeMillis() / 1000D; @@ -42,6 +47,10 @@ public static void SendDeathLink(String source, String cause) { client.sendBounce(deathLinkPacket); } + /** + * Enable or Disable receiving death links. + * @param enabled set to TRUE to enable death links, FALSE to disable. + */ public static void setDeathLinkEnabled(boolean enabled) { if(enabled) client.addTag("DeathLink"); From 33c67a291f3cded015ffa5f770a6616ef39ac050 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Tue, 21 May 2024 20:46:14 -0700 Subject: [PATCH 16/17] clean up datapackage --- .../java/dev/koifysh/archipelago/Client.java | 3 +- .../archipelago/parts/DataPackage.java | 48 +------------------ 2 files changed, 3 insertions(+), 48 deletions(-) diff --git a/src/main/java/dev/koifysh/archipelago/Client.java b/src/main/java/dev/koifysh/archipelago/Client.java index 5f1ee95..312fe58 100644 --- a/src/main/java/dev/koifysh/archipelago/Client.java +++ b/src/main/java/dev/koifysh/archipelago/Client.java @@ -334,8 +334,7 @@ public boolean checkLocations(Collection locationIDs) { * @param locationIDs List of location ID's to request info on. */ public void scoutLocations(ArrayList locationIDs) { - HashMap locations = dataPackage.getLocationsForGame(game); - locationIDs.removeIf( location -> !locations.containsKey(location)); + locationIDs.removeIf( location -> !dataPackage.getGame(game).locationNameToId.containsValue(location)); webSocket.scoutLocation(locationIDs); } diff --git a/src/main/java/dev/koifysh/archipelago/parts/DataPackage.java b/src/main/java/dev/koifysh/archipelago/parts/DataPackage.java index 87fa9a9..85a3573 100644 --- a/src/main/java/dev/koifysh/archipelago/parts/DataPackage.java +++ b/src/main/java/dev/koifysh/archipelago/parts/DataPackage.java @@ -14,10 +14,6 @@ public class DataPackage implements Serializable { @SerializedName("games") HashMap games = new HashMap<>(); - HashMap itemIdToName = new HashMap<>(); - - HashMap locationIdToName = new HashMap<>(); - public String uuid = UUID.randomUUID().toString(); public String getItem(long itemID, String game) { @@ -50,48 +46,8 @@ public HashMap getGames() { return games; } - public HashMap getItems() { - if(itemIdToName.isEmpty()) { - for (Map.Entry gameEntry : games.entrySet()) { - for (Map.Entry items : gameEntry.getValue().itemNameToId.entrySet()) { - itemIdToName.put(items.getValue(), items.getKey()); - } - } - } - return itemIdToName; - } - - public HashMap getItemsForGame(String game) { - HashMap ret = new HashMap<>(); - for (Map.Entry gameEntry : games.entrySet()) { - if(!gameEntry.getKey().equals(game)) continue; - for (Map.Entry items : gameEntry.getValue().itemNameToId.entrySet()) { - ret.put(items.getValue(), items.getKey()); - } - } - return ret; - } - - public HashMap getLocations() { - if(locationIdToName.isEmpty()) { - for (Map.Entry gameEntry : games.entrySet()) { - for (Map.Entry locations : gameEntry.getValue().locationNameToId.entrySet()) { - itemIdToName.put(locations.getValue(), locations.getKey()); - } - } - } - return itemIdToName; - } - - public HashMap getLocationsForGame(String game) { - HashMap ret = new HashMap<>(); - for (Map.Entry gameEntry : games.entrySet()) { - if(!gameEntry.getKey().equals(game)) continue; - for (Map.Entry locations : gameEntry.getValue().locationNameToId.entrySet()) { - ret.put(locations.getValue(), locations.getKey()); - } - } - return ret; + public Game getGame(String game) { + return games.get(game); } From 8ddc6eee2d328ba4cdff1a5a9261addcdaa43b01 Mon Sep 17 00:00:00 2001 From: Kono Tyran Date: Wed, 22 May 2024 11:29:15 -0700 Subject: [PATCH 17/17] update readme.md --- readme.md | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 17b5d34..bd40d54 100644 --- a/readme.md +++ b/readme.md @@ -1,2 +1,29 @@ -## Archipelago Java Client -A java client to connect to an [Archipelago](http://github.com/ArchipelagoMW/Archipelago) Server. +Archipelago Java Client +======================= +![Maven Central Version](https://img.shields.io/maven-central/v/dev.koifysh/archipelago-client) + +A java client Library to connect to an [Archipelago](http://github.com/ArchipelagoMW/Archipelago) Server. + + +## Getting Started +Use the following Code snippits to add this library to your project using the following. + +### Maven +To use maven add this dependency to your `pom.xml`: +```xml + + dev.koifysh + archipelago-client + 0.1.13 + +``` + +### Gradle +To use Gradle add the maven central repository to your repositories list: +```gradle +mavenCentral() +``` +then add this to your `dependancy` section +```gradle +implementation 'dev.koifysh:archipelago-client:0.1.13' +``` \ No newline at end of file