Skip to content

Commit cfe649b

Browse files
authored
Merge pull request ArchipelagoMW#27 from mattman107/main
Update Java-Client to current network protocol
2 parents cfe08f6 + 25a71dc commit cfe649b

File tree

8 files changed

+205
-45
lines changed

8 files changed

+205
-45
lines changed

pom.xml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
<name>Kono Tyran</name>
3131
<email>[email protected]</email>
3232
</developer>
33+
<developer>
34+
<name>mattman107</name>
35+
</developer>
3336
</developers>
3437

3538
<properties>
@@ -42,22 +45,22 @@
4245
<dependency>
4346
<groupId>org.java-websocket</groupId>
4447
<artifactId>Java-WebSocket</artifactId>
45-
<version>1.5.7</version>
48+
<version>1.6.0</version>
4649
</dependency>
4750
<dependency>
4851
<groupId>com.google.code.gson</groupId>
4952
<artifactId>gson</artifactId>
50-
<version>2.11.0</version>
53+
<version>2.13.1</version>
5154
</dependency>
5255
<dependency>
5356
<groupId>org.apache.httpcomponents.client5</groupId>
5457
<artifactId>httpclient5</artifactId>
55-
<version>5.2.1</version>
58+
<version>5.4.4</version>
5659
</dependency>
5760
<dependency>
5861
<groupId>org.apache.httpcomponents.core5</groupId>
5962
<artifactId>httpcore5</artifactId>
60-
<version>5.2.5</version>
63+
<version>5.3.4</version>
6164
</dependency>
6265
</dependencies>
6366

src/main/java/dev/koifysh/archipelago/Client.java

Lines changed: 132 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,48 @@
1010
import dev.koifysh.archipelago.network.client.*;
1111
import org.apache.hc.core5.net.URIBuilder;
1212

13+
import com.google.gson.Gson;
14+
1315
import java.io.*;
1416
import java.net.URI;
1517
import java.net.URISyntaxException;
18+
import java.nio.file.Path;
19+
import java.nio.file.Paths;
1620
import java.util.*;
1721
import java.util.logging.Logger;
1822

1923
public abstract class Client {
2024

2125
private final static Logger LOGGER = Logger.getLogger(Client.class.getName());
2226

23-
private final String dataPackageLocation = "./APData/DataPackage.ser";
27+
private static String OS = System.getProperty("os.name").toLowerCase();
28+
29+
private static final Path windowsDataPackageCache;
30+
31+
private static final Path otherDataPackageCache;
32+
33+
static
34+
{
35+
String appData = System.getenv("LOCALAPPDATA");
36+
String winHome = System.getenv("USERPROFILE");
37+
String userHome = System.getProperty("user.home");
38+
39+
if(appData == null || appData.isEmpty()) {
40+
windowsDataPackageCache = Paths.get(winHome, "appdata","local","Archipelago","cache","datapackage");
41+
} else {
42+
windowsDataPackageCache = Paths.get(appData, "Archipelago", "cache", "datapackage");
43+
}
44+
45+
otherDataPackageCache = Paths.get(userHome, ".cache", "Archipelago", "datapackage");
46+
}
47+
48+
private static Path dataPackageLocation;
49+
50+
protected Map<String,String> versions;
51+
52+
protected ArrayList<String> games;
53+
54+
private final static Gson gson = new Gson();
2455

2556
private int hintPoints;
2657

@@ -40,7 +71,7 @@ public abstract class Client {
4071
private final ItemManager itemManager;
4172
private final EventManager eventManager;
4273

43-
public static final Version protocolVersion = new Version(0, 4, 7);
74+
public static final Version protocolVersion = new Version(0, 6, 1);
4475

4576
private int team;
4677
private int slot;
@@ -52,7 +83,16 @@ public abstract class Client {
5283
private int itemsHandlingFlags = 0b000;
5384

5485
public Client() {
55-
loadDataPackage();
86+
//Determine what platform we are on
87+
if(OS.startsWith("windows")){
88+
dataPackageLocation = windowsDataPackageCache;
89+
} else{
90+
dataPackageLocation = otherDataPackageCache;
91+
}
92+
93+
if(dataPackage == null){
94+
dataPackage = new DataPackage();
95+
}
5696

5797
UUID = dataPackage.getUUID();
5898

@@ -117,45 +157,84 @@ public void removeTag(String tag) {
117157
}
118158

119159

120-
private void loadDataPackage() {
121-
try {
122-
FileInputStream fileInput = new FileInputStream(dataPackageLocation);
123-
ObjectInputStream objectInput = new ObjectInputStream(fileInput);
124-
125-
dataPackage = (DataPackage) objectInput.readObject();
126-
fileInput.close();
127-
objectInput.close();
128-
129-
} catch (IOException e) {
130-
LOGGER.info("no dataPackage found creating a new one.");
131-
dataPackage = new DataPackage();
132-
saveDataPackage();
133-
} catch (ClassNotFoundException e) {
134-
LOGGER.info("Failed to Read Previous datapackage. Creating new one.");
135-
dataPackage = new DataPackage();
160+
protected void loadDataPackage() {
161+
synchronized (Client.class){
162+
File directoryPath = dataPackageLocation.toFile();
163+
164+
//ensure the path to the cache exists
165+
if(directoryPath.exists() && directoryPath.isDirectory()){
166+
//loop through all Archipelago cache folders to find valid data package files
167+
Map<String,File> localGamesList = new HashMap<String,File>();
168+
169+
for(File gameDir : directoryPath.listFiles()){
170+
if(gameDir.isDirectory()){
171+
localGamesList.put(gameDir.getName(), gameDir);
172+
}
173+
}
174+
175+
if(localGamesList.isEmpty()){
176+
//cache doesn't exist. Create the filepath
177+
boolean success = directoryPath.mkdirs();
178+
if(success){
179+
LOGGER.info("DataPackage directory didn't exist. Starting from a new one.");
180+
} else{
181+
LOGGER.severe("Failed to make directories for datapackage cache.");
182+
}
183+
return;
184+
}
185+
186+
for(String gameName : games) {
187+
File dir = localGamesList.get(gameName);
188+
189+
if(null == dir){
190+
continue;
191+
}
192+
193+
//check all checksums
194+
for(File version : dir.listFiles()){
195+
String versionStr = versions.get(gameName);
196+
if(versionStr != null && versionStr.equals(version.getName())) {
197+
try(FileReader reader = new FileReader(version)){
198+
updateDataPackage(gson.fromJson(reader, DataPackage.class));
199+
LOGGER.info("Read datapackage for Game: ".concat(gameName).concat(" Checksum: ").concat(version.getName()));
200+
} catch (IOException e){
201+
LOGGER.info("Failed to read a datapackage. Starting with a new one.");
202+
}
203+
}
204+
}
205+
}
206+
}
136207
}
137208
}
138209

139-
void saveDataPackage() {
140-
try {
141-
File dataPackageFile = new File(dataPackageLocation);
142-
143-
//noinspection ResultOfMethodCallIgnored
144-
dataPackageFile.getParentFile().mkdirs();
145-
//noinspection ResultOfMethodCallIgnored
146-
dataPackageFile.createNewFile();
147-
148-
FileOutputStream fileOut = new FileOutputStream(dataPackageFile);
149-
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
150-
151-
objectOut.writeObject(dataPackage);
210+
public void saveDataPackage() {
211+
synchronized (Client.class){
212+
//Loop through games to ensure we have folders for each of them in the cache
213+
for(String gameName : games){
214+
File gameFolder = dataPackageLocation.resolve(gameName).toFile();
215+
if(!gameFolder.exists()){
216+
//game folder not found. Make it
217+
gameFolder.mkdirs();
218+
}
219+
220+
//save the datapackage
221+
String gameVersion = versions.get(gameName);
222+
if(gameVersion == null) {
223+
continue;
224+
}
225+
226+
//if key is for this game
227+
File filePath = dataPackageLocation.resolve(gameName).resolve(gameVersion).toFile();
228+
229+
try (Writer writer = new FileWriter(filePath)){
230+
//if game is in list of games, save it
231+
gson.toJson(dataPackage.getGame(gameName), writer);
232+
LOGGER.info("Saving datapackage for Game: ".concat(gameName).concat(" Checksum: ").concat(gameVersion));
233+
} catch (IOException e) {
234+
LOGGER.warning("unable to save DataPackage.");
235+
}
152236

153-
154-
fileOut.close();
155-
objectOut.close();
156-
157-
} catch (IOException e) {
158-
LOGGER.warning("unable to save DataPackage.");
237+
}
159238
}
160239
}
161240

@@ -518,6 +597,21 @@ public void dataStorageSetNotify(Collection<String> keys) {
518597
* <td> dict[str, list[str]] </td>
519598
* <td> item_name_groups belonging to the requested game. </td>
520599
* </tr>
600+
* <tr>
601+
* <td> location_name_groups_{game_name} </td>
602+
* <td> dict[str, list[str]] </td>
603+
* <td> location_name_groups belonging to the requested game. </td>
604+
* </tr>
605+
* <tr>
606+
* <td> client_status_{team}_{slot} </td>
607+
* <td> ClientStatus </td>
608+
* <td> The current game status of the requested player. </td>
609+
* </tr>
610+
* <tr>
611+
* <td> race_mode </td>
612+
* <td> int </td>
613+
* <td> 0 if race mode is disabled, and 1 if it's enabled. </td>
614+
* </tr>
521615
* </table>
522616
*
523617
* @param keys a list of keys to retrieve values for

src/main/java/dev/koifysh/archipelago/WebSocket.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import dev.koifysh.archipelago.parts.NetworkSlot;
2525
import org.apache.hc.core5.net.URIBuilder;
2626
import org.java_websocket.client.WebSocketClient;
27+
import org.java_websocket.drafts.Draft;
28+
import org.java_websocket.drafts.Draft_6455;
29+
import org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension;
2730
import org.java_websocket.handshake.ServerHandshake;
2831

2932
import javax.net.ssl.SSLException;
@@ -48,8 +51,10 @@ class WebSocket extends WebSocketClient {
4851
private static Timer reconnectTimer;
4952
private boolean downgrade = false;
5053

54+
private static final Draft perMessageDeflateDraft = new Draft_6455(new PerMessageDeflateExtension());
55+
5156
public WebSocket(URI serverUri, Client client) {
52-
super(serverUri);
57+
super(serverUri, perMessageDeflateDraft);
5358
this.client = client;
5459
if (reconnectTimer != null) {
5560
reconnectTimer.cancel();
@@ -83,6 +88,11 @@ public void onMessage(String message) {
8388
//save room info
8489
client.setRoomInfo(roomInfo);
8590

91+
client.versions = roomInfo.datapackageChecksums;
92+
client.games = roomInfo.games;
93+
94+
client.loadDataPackage();
95+
8696
checkDataPackage(roomInfo.datapackageChecksums, roomInfo.games);
8797

8898
seedName = roomInfo.seedName;

src/main/java/dev/koifysh/archipelago/network/APPacketType.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@ public enum APPacketType {
5252
@SerializedName("SetReply")
5353
SetReply,
5454
@SerializedName("InvalidPacket")
55-
InvalidPacket
55+
InvalidPacket,
56+
@SerializedName("UpdateHint")
57+
UpdateHint
5658
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package dev.koifysh.archipelago.network.client;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
public enum HintStatus {
6+
@SerializedName("HINT_UNSPECIFIED")
7+
HINT_UNSPECIFIED(0),
8+
@SerializedName("HINT_NO_PRIORITY")
9+
HINT_NO_PRIORITY(10),
10+
@SerializedName("HINT_AVOID")
11+
HINT_AVOID(20),
12+
@SerializedName("HINT_PRIORITY")
13+
HINT_PRIORITY(30),
14+
@SerializedName("HINT_FOUND")
15+
HINT_FOUND(40);
16+
17+
public final int value;
18+
HintStatus(int value) {
19+
this.value=value;
20+
}
21+
}

src/main/java/dev/koifysh/archipelago/network/client/SetPacket.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ private static class DataStorageOperation {
9292
* {@link #OR},
9393
* {@link #XOR},
9494
* {@link #LEFT_SHIFT},
95-
* {@link #RIGHT_SHIFT}
95+
* {@link #RIGHT_SHIFT},
96+
* {@link #REMOVE},
97+
* {@link #POP},
98+
* {@link #UPDATE}
9699
*/
97100
public enum Operation {
98101
/**
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dev.koifysh.archipelago.network.client;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
import dev.koifysh.archipelago.network.APPacket;
6+
import dev.koifysh.archipelago.network.APPacketType;
7+
8+
public class UpdateHintPacket extends APPacket{
9+
/*
10+
* NEED TO IMPLEMENT STUFF FOR UPDATEHINTPACKET?
11+
*/
12+
13+
@SerializedName("player")
14+
int player;
15+
16+
@SerializedName("location")
17+
int location;
18+
19+
@SerializedName("status")
20+
HintStatus status;
21+
22+
public UpdateHintPacket(){
23+
super(APPacketType.UpdateHint);
24+
}
25+
}

src/main/java/dev/koifysh/archipelago/network/server/SetReplyPacket.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public class SetReplyPacket extends APPacket {
1111
public Object value;
1212
@SerializedName("original_value")
1313
public Object original_Value;
14+
@SerializedName("slot")
15+
public int slot;
1416
@SerializedName("request_id")
1517
public int requestID;
1618

0 commit comments

Comments
 (0)