diff --git a/build.gradle b/build.gradle
index 7b1f7967..6435d368 100644
--- a/build.gradle
+++ b/build.gradle
@@ -99,6 +99,8 @@ dependencies {
exclude module: 'opus-java'
}
+ implementation "com.sparkjava:spark-core:2.9.3"
+
implementation project(":CommonCore")
}
diff --git a/src/de/steamwar/bungeecore/api/EndPoint.java b/src/de/steamwar/bungeecore/api/EndPoint.java
new file mode 100644
index 00000000..02304f82
--- /dev/null
+++ b/src/de/steamwar/bungeecore/api/EndPoint.java
@@ -0,0 +1,24 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.api;
+
+public interface EndPoint {
+ void ignite();
+}
diff --git a/src/de/steamwar/bungeecore/api/Token.java b/src/de/steamwar/bungeecore/api/Token.java
new file mode 100644
index 00000000..5acb2326
--- /dev/null
+++ b/src/de/steamwar/bungeecore/api/Token.java
@@ -0,0 +1,162 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.api;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.stream.JsonWriter;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+
+import javax.crypto.Cipher;
+import java.io.*;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.*;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.util.Base64;
+import java.util.UUID;
+
+public class Token {
+
+ private static KeyPair pair;
+
+ private static KeyPair getKeyPair() {
+ if (pair != null) return pair;
+
+ File publicKeyFile = new File("~/token_dsa.pub");
+ File privateKeyFile = new File("~/token_dsa");
+
+ if (publicKeyFile.exists() && privateKeyFile.exists()) {
+ PublicKey publicKey = null;
+ try {
+ JsonObject jsonObject = JsonParser.parseReader(new BufferedReader(new InputStreamReader(new FileInputStream(publicKeyFile)))).getAsJsonObject();
+ BigInteger y = jsonObject.get("y").getAsBigInteger();
+ BigInteger p = jsonObject.get("p").getAsBigInteger();
+ BigInteger q = jsonObject.get("q").getAsBigInteger();
+ BigInteger g = jsonObject.get("g").getAsBigInteger();
+ KeyFactory keyFactory = KeyFactory.getInstance("DSA");
+ publicKey = keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g));
+ } catch (Exception e) {
+ // Ignore
+ }
+ PrivateKey privateKey = null;
+ try {
+ JsonObject jsonObject = JsonParser.parseReader(new BufferedReader(new InputStreamReader(new FileInputStream(privateKeyFile)))).getAsJsonObject();
+ BigInteger x = jsonObject.get("x").getAsBigInteger();
+ BigInteger p = jsonObject.get("p").getAsBigInteger();
+ BigInteger q = jsonObject.get("q").getAsBigInteger();
+ BigInteger g = jsonObject.get("g").getAsBigInteger();
+ KeyFactory keyFactory = KeyFactory.getInstance("DSA");
+ privateKey = keyFactory.generatePrivate(new DSAPrivateKeySpec(x, p, q, g));
+ } catch (Exception e) {
+ // Ignore
+ }
+ pair = new KeyPair(publicKey, privateKey);
+ return pair;
+ }
+ try {
+ KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
+ keyPairGen.initialize(2048);
+ pair = keyPairGen.generateKeyPair();
+ saveKeyPair();
+ return pair;
+ } catch (Exception e) {
+ throw new SecurityException(e.getMessage(), e);
+ }
+ }
+
+ private static void saveKeyPair() {
+ File publicKeyFile = new File("~/token_dsa.pub");
+ File privateKeyFile = new File("~/token_dsa");
+
+ try {
+ publicKeyFile.createNewFile();
+ KeyFactory keyFactory = KeyFactory.getInstance(pair.getPrivate().getAlgorithm());
+ DSAPublicKeySpec dsaPublicKeySpec = keyFactory.getKeySpec(pair.getPublic(), DSAPublicKeySpec.class);
+
+ JsonObject privateKey = new JsonObject();
+ privateKey.addProperty("y", dsaPublicKeySpec.getY());
+ privateKey.addProperty("p", dsaPublicKeySpec.getP());
+ privateKey.addProperty("q", dsaPublicKeySpec.getQ());
+ privateKey.addProperty("g", dsaPublicKeySpec.getG());
+ new JsonWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(publicKeyFile)))).close();
+ } catch (Exception e) {
+
+ }
+
+ try {
+ privateKeyFile.createNewFile();
+ KeyFactory keyFactory = KeyFactory.getInstance(pair.getPrivate().getAlgorithm());
+ DSAPrivateKeySpec dsaPrivateKeySpec = keyFactory.getKeySpec(pair.getPrivate(), DSAPrivateKeySpec.class);
+
+ JsonObject privateKey = new JsonObject();
+ privateKey.addProperty("x", dsaPrivateKeySpec.getX());
+ privateKey.addProperty("p", dsaPrivateKeySpec.getP());
+ privateKey.addProperty("q", dsaPrivateKeySpec.getQ());
+ privateKey.addProperty("g", dsaPrivateKeySpec.getG());
+ new JsonWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(privateKeyFile)))).close();
+ } catch (Exception e) {
+
+ }
+ }
+
+ private UUID uuid;
+ private long creationDate;
+
+ public Token(SteamwarUser steamwarUser) {
+ uuid = steamwarUser.getUuid();
+ creationDate = System.currentTimeMillis();
+ }
+
+ public Token(JsonObject jsonObject) {
+ uuid = UUID.fromString(jsonObject.get("uuid").getAsString());
+ creationDate = jsonObject.get("creationDate").getAsLong();
+ }
+
+ public JsonObject toJSON() {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("uuid", uuid.toString());
+ jsonObject.addProperty("creationDate", creationDate);
+ return jsonObject;
+ }
+
+ public String encrypt() {
+ try {
+ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, getKeyPair().getPublic());
+ return Base64.getEncoder().encodeToString(cipher.doFinal(toJSON().toString().getBytes(StandardCharsets.UTF_8)));
+ } catch (Exception e) {
+ throw new SecurityException(e.getMessage(), e);
+ }
+ }
+
+ public static Token decrypt(String s) {
+ try {
+ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
+ cipher.init(Cipher.DECRYPT_MODE, getKeyPair().getPrivate());
+ byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(s));
+ JsonObject jsonObject = JsonParser.parseReader(new InputStreamReader(new ByteArrayInputStream(bytes))).getAsJsonObject();
+ return new Token(jsonObject);
+ } catch (Exception e) {
+ throw new SecurityException(e.getMessage(), e);
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/api/WebAPI.java b/src/de/steamwar/bungeecore/api/WebAPI.java
new file mode 100644
index 00000000..830bb1f7
--- /dev/null
+++ b/src/de/steamwar/bungeecore/api/WebAPI.java
@@ -0,0 +1,35 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.api;
+
+import de.steamwar.bungeecore.api.v1.ServerStatusEndPoint;
+import de.steamwar.bungeecore.api.v1.ServerTeamEndPoint;
+
+import static spark.Spark.port;
+
+public class WebAPI {
+
+ public static void start() {
+ port(1024);
+
+ new ServerStatusEndPoint().ignite();
+ new ServerTeamEndPoint().ignite();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/api/v1/ServerStatusEndPoint.java b/src/de/steamwar/bungeecore/api/v1/ServerStatusEndPoint.java
new file mode 100644
index 00000000..b21d70e4
--- /dev/null
+++ b/src/de/steamwar/bungeecore/api/v1/ServerStatusEndPoint.java
@@ -0,0 +1,42 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.api.v1;
+
+import com.google.gson.JsonObject;
+import de.steamwar.bungeecore.api.EndPoint;
+import net.md_5.bungee.BungeeCord;
+
+import static spark.Spark.post;
+
+public class ServerStatusEndPoint implements EndPoint {
+
+ @Override
+ public void ignite() {
+ post("/v1/serverstatus", (request, response) -> {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("players", BungeeCord.getInstance().getPlayers().size());
+ jsonObject.addProperty("maxPlayers", BungeeCord.getInstance().getConfig().getPlayerLimit());
+
+ response.type("application/json");
+ response.status(200);
+ return jsonObject.toString();
+ });
+ }
+}
diff --git a/src/de/steamwar/bungeecore/api/v1/ServerTeamEndPoint.java b/src/de/steamwar/bungeecore/api/v1/ServerTeamEndPoint.java
new file mode 100644
index 00000000..a0599e8f
--- /dev/null
+++ b/src/de/steamwar/bungeecore/api/v1/ServerTeamEndPoint.java
@@ -0,0 +1,49 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.api.v1;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import de.steamwar.bungeecore.api.EndPoint;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+
+import static spark.Spark.post;
+
+public class ServerTeamEndPoint implements EndPoint {
+
+ @Override
+ public void ignite() {
+ post("/v1/serverteam", (request, response) -> {
+ JsonObject jsonObject = new JsonObject();
+ JsonArray jsonArray = new JsonArray();
+ SteamwarUser.getServerTeam().forEach(steamwarUser -> {
+ JsonObject user = new JsonObject();
+ user.addProperty("name", steamwarUser.getUserName());
+ user.addProperty("rank", steamwarUser.getUserGroup().name());
+ jsonArray.add(user);
+ });
+ jsonObject.add("", jsonArray);
+
+ response.type("application/json");
+ response.status(200);
+ return jsonObject.toString();
+ });
+ }
+}
diff --git a/src/de/steamwar/bungeecore/sql/SteamwarUser.java b/src/de/steamwar/bungeecore/sql/SteamwarUser.java
index 901c2197..772f9d72 100644
--- a/src/de/steamwar/bungeecore/sql/SteamwarUser.java
+++ b/src/de/steamwar/bungeecore/sql/SteamwarUser.java
@@ -59,6 +59,8 @@ public class SteamwarUser {
private static final Statement getPlaytime = new Statement("SELECT SUM(UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime)) as Playtime FROM Session WHERE UserID = ?");
private static final Statement getFirstjoin = new Statement("SELECT MIN(StartTime) AS FirstJoin FROM Session WHERE UserID = ?");
+ private static final Statement getServerTeam = new Statement("SELECT * FROM UserData WHERE UserGroup != 'Member' AND UserGroup != 'YouTuber'");
+
private static final Map usersByName = new HashMap<>();
private static final Map usersByUUID = new HashMap<>();
private static final Map usersById = new HashMap<>();
@@ -390,4 +392,13 @@ public class SteamwarUser {
updateLocale.update(locale.toLanguageTag(), manualLocale, id);
new LocaleInvalidationPacket(id).send(getPlayer());
}
+
+ public static List getServerTeam() {
+ return getServerTeam.select(rs -> {
+ List users = new ArrayList<>();
+ while(rs.next())
+ users.add(new SteamwarUser(rs));
+ return users;
+ });
+ }
}