diff --git a/pom.xml b/pom.xml
index 7189b12..14ddddb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,11 @@
vertx-redis-client
3.2.0
+
+ com.google.guava
+ guava
+ 19.0
+
org.projectlombok
lombok
diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java
index d2d6596..048ae3c 100644
--- a/src/main/java/net/frozenorb/apiv3/APIv3.java
+++ b/src/main/java/net/frozenorb/apiv3/APIv3.java
@@ -1,15 +1,15 @@
package net.frozenorb.apiv3;
+import com.google.common.collect.ImmutableList;
import io.vertx.core.AbstractVerticle;
-import io.vertx.core.Vertx;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.mongo.MongoClient;
import io.vertx.ext.web.Router;
-import io.vertx.ext.web.impl.RouterImpl;
import lombok.Getter;
-
-import java.util.List;
+import net.frozenorb.apiv3.types.Server;
+import net.frozenorb.apiv3.types.ServerGroup;
+import net.frozenorb.apiv3.utils.ErrorUtils;
public class APIv3 extends AbstractVerticle {
@@ -31,11 +31,40 @@ public class APIv3 extends AbstractVerticle {
ctx.next();
});
- coreHttpRouter.get("/servers").handler(ctx -> {
-
+ Server.findServersByGroup("MineHG", res -> {
+ res.result().forEach(Server::update);
});
- vertx.createHttpServer().requestHandler(coreHttpRouter::accept).listen(80);
+ coreHttpRouter.get("/servers").handler(ctx -> {
+ Server.findServersByGroup("MineHG", res -> {
+ if (res.succeeded()) {
+ JsonArray response = new JsonArray();
+
+ res.result().forEach(server -> {
+ response.add(server.toLiteJson());
+ });
+
+ ctx.response().end(response.encode());
+ } else {
+ JsonObject error = ErrorUtils.toJson(res.cause());
+ ctx.response().end(error.encode());
+ }
+ });
+ });
+
+ coreHttpRouter.get("/server/:server").handler(ctx -> {
+ Server.findServerById(ctx.request().getParam("server"), res -> {
+ if (res.succeeded()) {
+ JsonObject json = res.result().toFullJson();
+ ctx.response().end(json.encode());
+ } else {
+ JsonObject error = ErrorUtils.toJson(res.cause());
+ ctx.response().end(error.encode());
+ }
+ });
+ });
+
+ vertx.createHttpServer().requestHandler(coreHttpRouter::accept).listen(8080);
}
}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/types/Rank.java b/src/main/java/net/frozenorb/apiv3/types/Rank.java
new file mode 100644
index 0000000..cd92d59
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/types/Rank.java
@@ -0,0 +1,7 @@
+package net.frozenorb.apiv3.types;
+
+public class Rank {
+
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/types/Server.java b/src/main/java/net/frozenorb/apiv3/types/Server.java
index c0b1643..8b0b7e8 100644
--- a/src/main/java/net/frozenorb/apiv3/types/Server.java
+++ b/src/main/java/net/frozenorb/apiv3/types/Server.java
@@ -1,33 +1,83 @@
package net.frozenorb.apiv3.types;
-import com.fasterxml.jackson.databind.util.JSONPObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import io.vertx.core.AsyncResult;
-import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import lombok.Getter;
+import lombok.ToString;
import net.frozenorb.apiv3.APIv3;
+import net.frozenorb.apiv3.utils.MongoUtils;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.time.Instant;
+import java.util.*;
-public class Server {
+@ToString(exclude={ "secret" })
+public final class Server {
+
+ public static final String COLLECTION_NAME = "server";
@Getter private String id;
+ @Getter private String bungeeId;
+ @Getter private String displayName;
+ @Getter private String secret;
+ @Getter private String group;
+ @Getter private String internalIp;
+ @Getter private Instant lastUpdate;
+ @Getter private double lastTps;
+ @Getter private List players;
- private static void findServers(JSONPObject query, Handler>> callback) {
- APIv3.getMongoClient().find("servers", query, result -> {
- if (result.succeeded()) {
- List servers = result.result();
- ctx.response().end(new JsonArray(servers).encode());
+ public static void findServerById(String id, Handler> callback) {
+ MongoUtils.findOneAndTransform(COLLECTION_NAME, new JsonObject().put("_id", id), Server::new, callback);
+ }
- servers.
- } else {
- callback.handle(Future.failedFuture());
- }
- });
+ public static void findServersByGroup(String groupId, Handler>> callback) {
+ MongoUtils.findManyAndTransform(COLLECTION_NAME, new JsonObject().put("group", groupId), Server::new, callback);
+ }
+
+ private Server(JsonObject json) {
+ this.id = json.getString("_id");
+ this.bungeeId = json.getString("bungeeId");
+ this.displayName = json.getString("displayName");
+ this.secret = json.getString("secret");
+ this.group = json.getString("group");
+ this.internalIp = json.getString("internalIp");
+ this.lastUpdate = json.getInstant("lastUpdate");
+ this.lastTps = json.getDouble("lastTps");
+ this.players = new ArrayList<>();
+
+ for (Object uuidString : json.getJsonArray("players")) {
+ players.add(UUID.fromString((String) uuidString));
+ }
+ }
+
+ public void update() {
+ this.lastUpdate = Instant.now();
+ APIv3.getMongoClient().update(COLLECTION_NAME, new JsonObject().put("_id", id), MongoUtils.set(new JsonObject().put("lastUpdate", lastUpdate)), res -> {});
+ }
+
+ public JsonObject toLiteJson() {
+ JsonObject json = new JsonObject();
+
+ json.put("_id", id);
+ json.put("bungeeId", bungeeId);
+ json.put("displayName", displayName);
+ json.put("group", group);
+ json.put("internalIp", internalIp);
+
+ return json;
+ }
+
+ public JsonObject toFullJson() {
+ JsonObject json = toLiteJson();
+
+ json.put("lastUpdate", lastUpdate);
+ json.put("lastTps", lastTps);
+ json.put("players", new JsonArray(players));
+
+ return json;
}
}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/types/ServerGroup.java b/src/main/java/net/frozenorb/apiv3/types/ServerGroup.java
new file mode 100644
index 0000000..0f75519
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/types/ServerGroup.java
@@ -0,0 +1,11 @@
+package net.frozenorb.apiv3.types;
+
+import lombok.Getter;
+
+public class ServerGroup {
+
+ @Getter private String id;
+ @Getter private ServerGroup[] inheritsFrom;
+ //@Getter private Map<>
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java
new file mode 100644
index 0000000..bdd3c96
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java
@@ -0,0 +1,22 @@
+package net.frozenorb.apiv3.utils;
+
+import io.vertx.core.json.JsonObject;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class ErrorUtils {
+
+ public static JsonObject toJson(Throwable throwable) {
+ return toJson(throwable.getClass().getSimpleName());
+ }
+
+ public static JsonObject toJson(String reason) {
+ JsonObject json = new JsonObject();
+
+ json.put("failed", true);
+ json.put("reason", reason);
+
+ return json;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java b/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java
new file mode 100644
index 0000000..258a2a6
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java
@@ -0,0 +1,37 @@
+package net.frozenorb.apiv3.utils;
+
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class IPUtils {
+
+ public static String machineToHuman(long machine) {
+ StringBuilder builder = new StringBuilder(15); // All IPv4 addresses are 15 characters
+
+ for (int i = 0; i < 4; i++) {
+ builder.insert(0, Long.toString(machine & 0xFF));
+
+ if (i < 3) {
+ builder.insert(0, '.');
+ }
+
+ machine >>= 8;
+ }
+
+ return builder.toString();
+ }
+
+ public static long humanToMachine(String human) {
+ long result = 0;
+ String[] octets = human.split("\\.");
+
+ for (int i = 3; i >= 0; i--) {
+ long ip = Long.parseLong(octets[3 - i]);
+
+ result |= ip << (i * 8);
+ }
+
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/utils/MongoUtils.java b/src/main/java/net/frozenorb/apiv3/utils/MongoUtils.java
new file mode 100644
index 0000000..ec6d72e
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/utils/MongoUtils.java
@@ -0,0 +1,54 @@
+package net.frozenorb.apiv3.utils;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import io.vertx.core.AsyncResult;
+import io.vertx.core.Future;
+import io.vertx.core.Handler;
+import io.vertx.core.json.JsonObject;
+import io.vertx.ext.mongo.FindOptions;
+import lombok.experimental.UtilityClass;
+import net.frozenorb.apiv3.APIv3;
+
+import java.util.Collection;
+import java.util.List;
+
+@UtilityClass
+public class MongoUtils {
+
+ private static final FindOptions limitOne = new FindOptions().setLimit(1);
+
+ public static void findOneAndTransform(String collection, JsonObject query, Function transformation, Handler> callback) {
+ APIv3.getMongoClient().findWithOptions(collection, query, limitOne, res -> {
+ if (res.succeeded()) {
+ if (!res.result().isEmpty()) {
+ JsonObject json = res.result().get(0);
+ T transformed = transformation.apply(json);
+
+ callback.handle(Future.succeededFuture(transformed));
+ } else {
+ callback.handle(Future.succeededFuture(null));
+ }
+ } else {
+ callback.handle(Future.failedFuture(res.cause()));
+ }
+ });
+ }
+
+ public static void findManyAndTransform(String collection, JsonObject query, Function transformation, Handler>> callback) {
+ APIv3.getMongoClient().find(collection, query, res -> {
+ if (res.succeeded()) {
+ Collection servers = Collections2.transform(res.result(), transformation);
+ callback.handle(Future.succeededFuture(ImmutableList.copyOf(servers)));
+ } else {
+ callback.handle(Future.failedFuture(res.cause()));
+ }
+ });
+ }
+
+ public static JsonObject set(JsonObject json) {
+ return new JsonObject().put("$set", json);
+ }
+
+}
\ No newline at end of file