Skip to content

Commit

Permalink
Add config endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianVennen committed Nov 30, 2023
1 parent 16510d1 commit ad3316f
Show file tree
Hide file tree
Showing 26 changed files with 791 additions and 35 deletions.
4 changes: 1 addition & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
- Add option to use own credits to Server.start()
- Use JSON body instead of form data
- Update dependencies
- Add endpoints for the server config
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,42 @@ file.delete();
file.createAsDirectory();
```

### Websocket API
### Configs
Some files are special because they are parsed, validated and understood by the exaroton backend.
These files are called configs and can be managed like this:
```java
ExarotonClient client = new ExarotonClient("example-api-token");

Server server = client.getServer("tgkm731xO7GiHt76");
ServerFile file = server.getFile("/server.properties");
ServerConfig config = file.getConfig();

Map<String, ServerConfigOption> options = config.getOptions();
for (ServerConfigOption option: options) {
System.out.println(option.getName() + ": " + option.getValue());
}

ConfigOption option = config.getOption("level-seed");
```

There are several types of options which extend the ServerConfigOption class:
```java
for (ServerConfigOption option: options) {
if (option.getType() == OptionType.BOOLEAN) {
BooleanConfigOption booleanOption = (BooleanConfigOption) option;
System.out.println(booleanOption.getName() + ": " + booleanOption.getValue());
}
}
```

To save changes to a config, use the save() method:
```java
config.getOption("level-seed").setValue("example");
config.save();
```


## Websocket API
The websocket API allows a constant connection to our websocket service to receive events in real time without polling
(e.g. trying to get the server status every few seconds).

Expand Down
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies {
implementation 'org.java-websocket:Java-WebSocket:1.5.3'
implementation 'org.slf4j:slf4j-api:2.0.7'
implementation 'org.slf4j:slf4j-jdk14:2.0.7'
implementation 'org.jetbrains:annotations:24.1.0'
}

test {
Expand All @@ -31,6 +32,10 @@ test {
java {
withJavadocJar()
withSourcesJar()

toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}

ext.isReleaseVersion = !version.endsWith("SNAPSHOT")
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/exaroton/api/APIRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public InputStream requestRaw() throws APIException {
Object body = this.getBody();
InputStream inputStream = this.getInputStream();
if (body != null) {
inputStream = new ByteArrayInputStream((new Gson()).toJson(body).getBytes(StandardCharsets.UTF_8));
inputStream = new ByteArrayInputStream(client.getGson().toJson(body).getBytes(StandardCharsets.UTF_8));
connection.setRequestProperty("Content-Type", "application/json");
}

Expand Down Expand Up @@ -101,7 +101,7 @@ public String requestString() throws APIException {

public APIResponse<Datatype> request() throws APIException {
String json = this.requestString();
APIResponse<Datatype> response = (new Gson()).fromJson(json, this.getType());
APIResponse<Datatype> response = client.getGson().fromJson(json, this.getType());
if (!response.isSuccess()) throw new APIException(response.getError());

return response;
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/exaroton/api/ExarotonClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import com.exaroton.api.request.account.GetAccountRequest;
import com.exaroton.api.request.server.GetServersRequest;
import com.exaroton.api.server.Server;
import com.exaroton.api.server.config.ConfigOption;
import com.exaroton.api.server.config.ConfigOptionTypeAdapter;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.BufferedReader;
import java.io.IOException;
Expand All @@ -16,6 +20,10 @@
import java.util.stream.Collectors;

public class ExarotonClient {
/**
* Gson instance used for (de-)serialization
*/
private final Gson gson;

/**
* Request protocol
Expand Down Expand Up @@ -47,6 +55,13 @@ public class ExarotonClient {
*/
public ExarotonClient(String apiToken) {
this.apiToken = apiToken;
this.gson = new GsonBuilder()
.registerTypeAdapter(ConfigOption.class, new ConfigOptionTypeAdapter())
.create();
}

public Gson getGson() {
return this.gson;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,9 @@
import java.lang.reflect.Type;
import java.util.HashMap;

public class FileDataRequest extends APIRequest<Object> {
protected final String serverId;
protected final String path;

public class FileDataRequest extends FileRequest<Object> {
public FileDataRequest(ExarotonClient client, String serverId, String path) {
super(client);
this.serverId = serverId;
this.path = path;
super(client, serverId, path);
}

@Override
Expand All @@ -27,12 +22,4 @@ protected String getEndpoint() {
protected Type getType() {
return new TypeToken<APIResponse<Object>>(){}.getType();
}

@Override
protected HashMap<String, String> getData() {
HashMap<String, String> map = super.getData();
map.put("server", this.serverId);
map.put("path", this.path);
return map;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.exaroton.api.request.server.files;

import com.exaroton.api.APIRequest;
import com.exaroton.api.ExarotonClient;

import java.util.HashMap;

public abstract class FileRequest<T> extends APIRequest<T> {
protected final String serverId;
protected final String path;

public FileRequest(ExarotonClient client, String serverId, String path) {
super(client);
this.serverId = serverId;
this.path = path;
}

@Override
protected HashMap<String, String> getData() {
HashMap<String, String> map = super.getData();
map.put("server", this.serverId);
map.put("path", this.path);
return map;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.exaroton.api.request.server.files;

import com.exaroton.api.APIResponse;
import com.exaroton.api.ExarotonClient;
import com.exaroton.api.server.config.ConfigOption;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;

public class GetConfigOptionsRequest extends FileRequest<ConfigOption[]> {

public GetConfigOptionsRequest(ExarotonClient client, String serverId, String path) {
super(client, serverId, path);
}


@Override
protected String getEndpoint() {
return "servers/{server}/files/config/{path}";
}

@Override
protected Type getType() {
return new TypeToken<APIResponse<ConfigOption[]>>(){}.getType();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.exaroton.api.request.server.files;

import com.exaroton.api.APIResponse;
import com.exaroton.api.ExarotonClient;
import com.exaroton.api.server.config.ConfigOption;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

public class UpdateConfigOptionsRequest extends FileRequest<ConfigOption[]> {
private final Map<String, Object> options;

public UpdateConfigOptionsRequest(ExarotonClient client, String serverId, String path, Map<String, Object> options) {
super(client, serverId, path);
this.options = options;
}

@Override
protected String getEndpoint() {
return "servers/{server}/files/config/{path}";
}

@Override
protected Type getType() {
return new TypeToken<APIResponse<ConfigOption[]>>(){}.getType();
}

@Override
protected String getMethod() {
return "POST";
}

@Override
protected Object getBody() {
return client.getGson().toJson(this.options);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/exaroton/api/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ public void setClient(ExarotonClient client) {
public void subscribe() {
String protocol = this.client.getProtocol().equals("https") ? "wss" : "ws";
String uri = protocol + "://" + this.client.getHost() + this.client.getBasePath() + "servers/" + this.id + "/websocket";
this.webSocket = new WebSocketManager(uri, this.client.getApiToken(), this);
this.webSocket = new WebSocketManager(client, uri, this.client.getApiToken(), this);
}

/**
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/com/exaroton/api/server/ServerFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.exaroton.api.APIException;
import com.exaroton.api.ExarotonClient;
import com.exaroton.api.request.server.files.*;
import com.exaroton.api.server.config.ServerConfig;

import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -140,6 +141,14 @@ public void createAsDirectory() throws APIException {
new CreateDirectoryRequest(this.client, this.server.getId(), this.path).request();
}

/**
* get a ServerConfig object for this file
* @return server config object
*/
public ServerConfig getConfig() {
return new ServerConfig(this.client, this.server, this.path);
}

public String getPath() {
return path;
}
Expand Down Expand Up @@ -188,7 +197,6 @@ public void setPath(String path) {
this.path = path.replaceAll("^/+", "");
}


/**
* update properties from fetched object
* @param file file fetched from the API
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/com/exaroton/api/server/config/ConfigOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.exaroton.api.server.config;

import org.jetbrains.annotations.Nullable;

public abstract class ConfigOption {
private final String key;
private final String label;
private final OptionType type;
private final String[] options;

protected ConfigOption(String key, String label, OptionType type, String[] options) {
this.key = key;
this.label = label;
this.type = type;
this.options = options;
}

public String getKey() {
return key;
}

public String getLabel() {
return label;
}

public @Nullable String[] getOptions() {
return options;
}

abstract public @Nullable Object getValue();

public OptionType getType() {
return type;
}
}
Loading

0 comments on commit ad3316f

Please sign in to comment.