From 21d0bb49071758c64562b0e229d042171ada5362 Mon Sep 17 00:00:00 2001 From: quiquelhappy Date: Wed, 10 Mar 2021 12:33:12 +0100 Subject: [PATCH] versioning --- .idea/compiler.xml | 3 +- pom.xml | 1 + src/io/purecore/api/Core.java | 89 +++++++++++++++-- src/io/purecore/api/call/Call.java | 1 + src/io/purecore/api/call/Param.java | 34 ++++++- src/io/purecore/api/event/Handler.java | 8 ++ .../api/execution/ExecutionContext.java | 4 +- .../api/execution/ExecutionSuccess.java | 49 ++++++++++ src/io/purecore/api/instance/Instance.java | 40 ++++---- src/io/purecore/api/versioning/Game.java | 21 ++++ .../purecore/api/versioning/GameSoftware.java | 20 ++++ .../InvalidVersionFormatException.java | 7 ++ src/io/purecore/api/versioning/Version.java | 98 +++++++++++++++++++ .../api/versioning/VersionCompatibility.java | 66 +++++++++++++ .../api/versioning/VersionStability.java | 18 ++++ 15 files changed, 425 insertions(+), 34 deletions(-) create mode 100644 src/io/purecore/api/execution/ExecutionSuccess.java create mode 100644 src/io/purecore/api/versioning/Game.java create mode 100644 src/io/purecore/api/versioning/GameSoftware.java create mode 100644 src/io/purecore/api/versioning/InvalidVersionFormatException.java create mode 100644 src/io/purecore/api/versioning/Version.java create mode 100644 src/io/purecore/api/versioning/VersionCompatibility.java create mode 100644 src/io/purecore/api/versioning/VersionStability.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 2b565cd..d9144e6 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -9,9 +9,8 @@ - + - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8e40487..1dcd508 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,7 @@ okhttp 4.9.0 + diff --git a/src/io/purecore/api/Core.java b/src/io/purecore/api/Core.java index e5e4733..f32db28 100644 --- a/src/io/purecore/api/Core.java +++ b/src/io/purecore/api/Core.java @@ -2,16 +2,25 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import io.purecore.api.call.ApiException; import io.purecore.api.call.Call; +import io.purecore.api.call.Param; import io.purecore.api.event.Handler; import io.purecore.api.instance.Instance; import io.purecore.api.key.Key; +import io.purecore.api.versioning.Game; +import io.purecore.api.versioning.GameSoftware; +import io.purecore.api.versioning.Version; import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; import okhttp3.OkHttpClient; +import org.json.JSONException; import org.json.JSONObject; +import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; @@ -22,9 +31,18 @@ public class Core { protected static OkHttpClient client = new OkHttpClient(); protected static Socket socket; + protected static String clientVersion; protected static boolean connected = false; protected static ArrayList handlers = new ArrayList<>(); + public static String getClientVersion(){ + return Core.clientVersion; + } + + public static void setClientVersion(String version){ + Core.clientVersion=version; + } + public Core(String key){ Core.key = new Key(key); if(Core.client==null){ @@ -57,24 +75,40 @@ public static boolean isConnected(){ public static void emit(String key, String string){ Core.socket.emit(key,string); } - public static void emit(String key, JsonElement data){ - Core.socket.emit(key,new JSONObject(data)); + public static void emit(String key, JsonElement data) throws JSONException { + Core.socket.emit(key,new JSONObject(new Gson().toJson(data))); } - public static void emit(String key, HashMap data){ - Core.emit(key, new Gson().toJson(data)); + public static void emit(String key, HashMap data) throws JSONException { + Core.emit(key, new Gson().toJsonTree(data)); } public Instance getInstance(){ return new Instance(); } + public Version getVersionCandidate(Game game, GameSoftware gameSoftware, String gameVersion) throws IOException, ApiException { + JsonElement element = Core.call("/version/get/candidate/") + .addParam(Param.GameVersion,gameVersion) + .addParam(Param.Game, String.valueOf(game)) + .addParam(Param.GameSoftware, String.valueOf(gameSoftware)) + .commit(); + return new Version(element.getAsJsonObject()); + } + private static void connect(){ - URI uri = URI.create("https://socket.purecore.io/instances/"); - Core.socket = IO.socket(uri); + + URI uri = URI.create("https://socket.purecore.io:443/"); + IO.Options options = new IO.Options(); + options.path="/instances/"; + + Core.socket = IO.socket(uri,options); Core.socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { @Override public void call(Object... objects) { - Core.socket.emit("handshake",Core.key.getHash()); + for (Handler handler:Core.handlers){ + handler.onAuthenticating(); + } + Core.emit("handshake",Core.key.getHash()); } }).on("connected", new Emitter.Listener() { @Override @@ -100,7 +134,48 @@ public void call(Object... objects) { handler.onNewExecutions(); } } + }).on("checkVersion", new Emitter.Listener() { + @Override + public void call(Object... objects) { + JsonElement body = new Gson().fromJson(String.valueOf(objects[0]), JsonElement.class); + Version version = new Version(body.getAsJsonObject()); + for (Handler handler:Core.handlers){ + handler.onNewVersion(version); + } + } + }).on(Socket.EVENT_CONNECTING, new Emitter.Listener() { + @Override + public void call(Object... objects) { + for (Handler handler:Core.handlers){ + handler.onConnecting(); + } + } + }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() { + @Override + public void call(Object... objects) { + for (Handler handler:Core.handlers){ + handler.onConnectError(); + } + } + }).on(Socket.EVENT_RECONNECTING, new Emitter.Listener() { + @Override + public void call(Object... objects) { + for (Handler handler:Core.handlers){ + handler.onReconnecting(); + } + } + }).on(Socket.EVENT_RECONNECT, new Emitter.Listener() { + @Override + public void call(Object... objects) { + for (Handler handler:Core.handlers){ + handler.onAuthenticating(); + } + Core.socket.emit("handshake",Core.key.getHash()); + } }); + for (Handler handler:Core.handlers){ + handler.onSocketCreated(); + } Core.socket.connect(); } diff --git a/src/io/purecore/api/call/Call.java b/src/io/purecore/api/call/Call.java index dabc296..7b20f28 100644 --- a/src/io/purecore/api/call/Call.java +++ b/src/io/purecore/api/call/Call.java @@ -26,6 +26,7 @@ public Call(String path, Key key, OkHttpClient client){ this.endpoint=path; this.hash=key.getHash(); this.client=client; + this.params=new HashMap<>(); } public Call addParam(Param param, String value){ diff --git a/src/io/purecore/api/call/Param.java b/src/io/purecore/api/call/Param.java index 7642b47..5c8bdce 100644 --- a/src/io/purecore/api/call/Param.java +++ b/src/io/purecore/api/call/Param.java @@ -1,12 +1,25 @@ package io.purecore.api.call; public enum Param { + Version("v"), + GameVersion("gv"), + Token("tok"), + SinceVersion("sv"), + UntilVersion("uv"), + Repo("rep"), + Tag("ta"), + FileName("f"), + Notify("noti"), + Stability("st"), + GameSoftwares("gss"), + GameSoftware("gs"), Year("ye"), Month("mo"), Week("we"), Day("da"), Hour("ho"), Epoch("ep"), + Page("pa"), Address("ad"), PaymentMethod("pm"), Key("k"), @@ -21,11 +34,13 @@ public enum Param { Cname("cnm"), Game("gme"), PlatformId("plid"), + SubjectPlatformId("splid"), PlatformName("plnm"), Quantity("qty"), Value("val"), Ip("ip"), DeviceFingerprint("dv"), + Url("u"), ForumCategory("fc"), ForumEmote("fe"), ForumObject("fo"), @@ -73,12 +88,25 @@ public enum Param { Price("pr"), Amount("am"), ExecutionType("et"), + PunishmentSystem("ps"), Punishment("pn"), Appeal("a"), Report("r"), - Offence("o"), - Offences("os"), - PunishmentAction("pa"), + PunishmentType("pt"), + Reason("re"), + Until("ut"), + Trigger("trg"), + LocalId("lid"), + BanCmd("bcmd"), + TempbanCmd("tbcmd"), + UnbanCmd("ubcmd"), + MuteCmd("mcmd"), + TempmuteCmd("tmcmd"), + UnmuteCmd("umcmd"), + WarnCmd("wcmd"), + UnwarnCmd("uwcmd"), + TempwarnCmd("twcmd"), + KickCmd("kcmd"), VotingSite("vs"), Ticket("t"), TicketCategory("tc"), diff --git a/src/io/purecore/api/event/Handler.java b/src/io/purecore/api/event/Handler.java index 1eb88d0..c0a2c24 100644 --- a/src/io/purecore/api/event/Handler.java +++ b/src/io/purecore/api/event/Handler.java @@ -1,9 +1,17 @@ package io.purecore.api.event; +import io.purecore.api.versioning.Version; + public interface Handler { void onConnected(); + void onConnecting(); + void onAuthenticating(); + void onReconnecting(); + void onConnectError(); + void onSocketCreated(); void onDisconnected(); void onNewExecutions(); + void onNewVersion(Version version); } diff --git a/src/io/purecore/api/execution/ExecutionContext.java b/src/io/purecore/api/execution/ExecutionContext.java index d0457a7..80d1f79 100644 --- a/src/io/purecore/api/execution/ExecutionContext.java +++ b/src/io/purecore/api/execution/ExecutionContext.java @@ -14,10 +14,10 @@ public ExecutionContext(JsonObject object){ this.username=object.get("username").getAsString(); this.id=object.get("id").getAsString(); this.packageName=object.get("packageName").getAsString(); - if(object.get("quantity").isJsonNull()){ + if(!object.get("quantity").isJsonNull()){ this.quantity=object.get("quantity").getAsFloat(); } - if(object.get("quantityDifference").isJsonNull()){ + if(!object.get("quantityDifference").isJsonNull()){ this.quantityDifference=object.get("quantityDifference").getAsFloat(); } } diff --git a/src/io/purecore/api/execution/ExecutionSuccess.java b/src/io/purecore/api/execution/ExecutionSuccess.java new file mode 100644 index 0000000..e0f178d --- /dev/null +++ b/src/io/purecore/api/execution/ExecutionSuccess.java @@ -0,0 +1,49 @@ +package io.purecore.api.execution; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.purecore.api.Core; +import io.purecore.api.call.ApiException; +import io.purecore.api.call.Param; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ExecutionSuccess { + + public List success; + public List fail; + + public ExecutionSuccess(JsonObject object){ + this.success=new ArrayList<>(); + for (JsonElement element: object.get("success").getAsJsonArray()){ + this.success.add(new SimplifiedExecution(element.getAsJsonObject())); + } + + this.fail=new ArrayList<>(); + for (JsonElement element: object.get("fail").getAsJsonArray()){ + this.fail.add(new SimplifiedExecution(element.getAsJsonObject())); + } + } + + public ExecutionSuccess(List executions) throws IOException, ApiException { + List ids = new ArrayList<>(); + for (SimplifiedExecution execution:executions){ + ids.add(execution.getId()); + } + String jsonIds = new Gson().toJson(ids); + JsonObject response = Core.call("/execution/batch/mark/").addParam(Param.SimplifiedCommandExecutions,jsonIds).commit().getAsJsonObject(); + this.success=new ArrayList<>(); + for (JsonElement element: response.get("success").getAsJsonArray()){ + this.success.add(new SimplifiedExecution(element.getAsJsonObject())); + } + + this.fail=new ArrayList<>(); + for (JsonElement element: response.get("fail").getAsJsonArray()){ + this.fail.add(new SimplifiedExecution(element.getAsJsonObject())); + } + } + +} diff --git a/src/io/purecore/api/instance/Instance.java b/src/io/purecore/api/instance/Instance.java index 9dcc8e0..ae38cf7 100644 --- a/src/io/purecore/api/instance/Instance.java +++ b/src/io/purecore/api/instance/Instance.java @@ -7,6 +7,7 @@ import io.purecore.api.call.ApiException; import io.purecore.api.call.Param; import io.purecore.api.execution.SimplifiedExecution; +import org.json.JSONException; import java.io.IOException; import java.util.ArrayList; @@ -17,33 +18,23 @@ public class Instance { public String name; public String id; public boolean online; - public Type type; + public int type; public Instance(){ this.name=null; this.id=null; this.online=false; - this.type=Type.Unknown; + this.type=-1; } public Instance(JsonObject object){ this.name=object.get("name").getAsString(); this.id=object.get("id").getAsString(); this.online=object.get("online").getAsBoolean(); - this.type=Type.Unknown; - switch (object.get("type").getAsInt()){ - case 0: { - this.type=Type.Network; - break; - } - case 1: { - this.type=Type.Server; - break; - } - } + this.type=object.get("type").getAsInt(); } - public void connect(String platformId, String platformUsername, String ip) throws IOException, ApiException { + public void connect(String platformId, String platformUsername, String ip) throws IOException, ApiException, JSONException { if(Core.isConnected()){ HashMap data = new HashMap<>(); data.put(Param.PlatformId.getParam(),platformId); @@ -51,7 +42,7 @@ public void connect(String platformId, String platformUsername, String ip) throw data.put(Param.Ip.getParam(), ip); Core.emit("playerLogin", data); } else { - Core.call("connections/open/") + Core.call("/connections/open/") .addParam(Param.PlatformId,platformId) .addParam(Param.PlatformName,platformUsername) .addParam(Param.Ip,ip) @@ -59,19 +50,19 @@ public void connect(String platformId, String platformUsername, String ip) throw } } - public void disconnect(String platformId) throws IOException, ApiException { + public void disconnect(String platformId) throws IOException, ApiException, JSONException { if(Core.isConnected()){ HashMap data = new HashMap<>(); data.put(Param.PlatformId.getParam(),platformId); - Core.emit("playerLogin", data); + Core.emit("playerLogout", data); } else { - Core.call("connections/open/") + Core.call("/connections/open/") .addParam(Param.PlatformId,platformId).commit(); } } public ArrayList getPendingExecutions() throws IOException, ApiException { - JsonArray data = Core.call("instance/get/executions/simplified/").commit().getAsJsonArray(); + JsonArray data = Core.call("/instance/get/executions/simplified/").commit().getAsJsonArray(); ArrayList executions = new ArrayList<>(); for (JsonElement execution:data) { executions.add(new SimplifiedExecution(execution.getAsJsonObject())); @@ -80,7 +71,7 @@ public ArrayList getPendingExecutions() throws IOException, } public ArrayList getPendingExecutions(SimplifiedExecution since) throws IOException, ApiException { - JsonArray data = Core.call("instance/get/executions/simplified/").addParam(Param.CommandExecution,since.getId()).commit().getAsJsonArray(); + JsonArray data = Core.call("/instance/get/executions/simplified/").addParam(Param.CommandExecution,since.getId()).commit().getAsJsonArray(); ArrayList executions = new ArrayList<>(); for (JsonElement execution:data) { executions.add(new SimplifiedExecution(execution.getAsJsonObject())); @@ -88,4 +79,13 @@ public ArrayList getPendingExecutions(SimplifiedExecution s return executions; } + public Instance update() throws IOException, ApiException { + Instance instance = new Instance(Core.call("/instance/get/").commit().getAsJsonObject()); + this.id=instance.id; + this.type=instance.type; + this.online=instance.online; + this.name=instance.name; + return instance; + } + } diff --git a/src/io/purecore/api/versioning/Game.java b/src/io/purecore/api/versioning/Game.java new file mode 100644 index 0000000..9e4d393 --- /dev/null +++ b/src/io/purecore/api/versioning/Game.java @@ -0,0 +1,21 @@ +package io.purecore.api.versioning; + +public enum Game { + + Unknown(-1), + Minecraft(0), + MinecraftBedrock(1), + SpaceEngineers(2); + + private int val; + + Game(int val) + { + this.val = val; + } + + public int getParam(){ + return this.val; + } + +} diff --git a/src/io/purecore/api/versioning/GameSoftware.java b/src/io/purecore/api/versioning/GameSoftware.java new file mode 100644 index 0000000..9c6ec86 --- /dev/null +++ b/src/io/purecore/api/versioning/GameSoftware.java @@ -0,0 +1,20 @@ +package io.purecore.api.versioning; + +public enum GameSoftware { + + Unknown(-1), + Spigot(0), + BungeeCord(1); + + private int val; + + GameSoftware(int val) + { + this.val = val; + } + + public int getParam(){ + return this.val; + } + +} diff --git a/src/io/purecore/api/versioning/InvalidVersionFormatException.java b/src/io/purecore/api/versioning/InvalidVersionFormatException.java new file mode 100644 index 0000000..9e5c463 --- /dev/null +++ b/src/io/purecore/api/versioning/InvalidVersionFormatException.java @@ -0,0 +1,7 @@ +package io.purecore.api.versioning; + +public class InvalidVersionFormatException extends Exception { + InvalidVersionFormatException(String s){ + super(s); + } +} diff --git a/src/io/purecore/api/versioning/Version.java b/src/io/purecore/api/versioning/Version.java new file mode 100644 index 0000000..86ad269 --- /dev/null +++ b/src/io/purecore/api/versioning/Version.java @@ -0,0 +1,98 @@ +package io.purecore.api.versioning; + +import com.google.gson.JsonObject; + +public class Version { + + public String id; + public String repo; + public long releaseDate; + public VersionCompatibility compatibility; + public String tag; + public String fileName; + public VersionStability stability; + + public Version(JsonObject object){ + this.id=object.get("id").getAsString(); + this.repo=object.get("repo").getAsString(); + this.releaseDate=object.get("releaseDate").getAsLong(); + this.compatibility=new VersionCompatibility(object.get("compatibility").getAsJsonObject()); + this.tag=object.get("tag").getAsString(); + this.fileName=object.get("fileName").getAsString(); + int stability = object.get("stability").getAsInt(); + switch (stability){ + case 0: + this.stability=VersionStability.Release; + break; + case 1: + this.stability=VersionStability.Prerelease; + break; + default: + this.stability=VersionStability.Unknown; + } + } + + public static float getRepresentativePart(String version) throws InvalidVersionFormatException { + String[] split = version.split("\\."); + if(split.length<=1) throw new InvalidVersionFormatException("Missing subversion"); + int valid = split[0].length(); + String versionNoDot = version.replaceAll("\\.",""); + int inv = versionNoDot.length() - valid; + if(inv <= 0) throw new InvalidVersionFormatException("Impossible to get representative version"); + return (float) Integer.parseInt(versionNoDot) / (inv ^ 10); + } + + public boolean isCompatible(Game game, GameSoftware gameSoftware, String gameVersion) throws InvalidVersionFormatException { + if(game==this.compatibility.getGame() && this.compatibility.getSoftwares().contains(gameSoftware)){ + if(Version.getRepresentativePart(this.compatibility.getSinceVersion())<=Version.getRepresentativePart(gameVersion)){ + if(this.compatibility.getUntilVersion()==null){ + return true; + } else return this.compatibility.getUntilVersion() != null && Version.getRepresentativePart(this.compatibility.getUntilVersion()) >= Version.getRepresentativePart(gameVersion); + } else { + return false; + } + } else { + return false; + } + } + + public boolean isCompatible(Game game, GameSoftware gameSoftware) throws InvalidVersionFormatException { + if(game==this.compatibility.getGame() && this.compatibility.getSoftwares().contains(gameSoftware)){ + return true; + } else { + return false; + } + } + + public String getDownloadURL(){ + return "https://github.com/purecoreio/" + this.getTag() + "/releases/download/" + this.getTag() + "/" + this.getFileName(); + } + + public long getReleaseDate() { + return releaseDate; + } + + public String getId() { + return id; + } + + public String getRepo() { + return repo; + } + + public String getFileName() { + return fileName; + } + + public String getTag() { + return tag; + } + + public VersionCompatibility getCompatibility() { + return compatibility; + } + + public VersionStability getStability() { + return stability; + } +} diff --git a/src/io/purecore/api/versioning/VersionCompatibility.java b/src/io/purecore/api/versioning/VersionCompatibility.java new file mode 100644 index 0000000..33d29f7 --- /dev/null +++ b/src/io/purecore/api/versioning/VersionCompatibility.java @@ -0,0 +1,66 @@ +package io.purecore.api.versioning; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.util.ArrayList; + +public class VersionCompatibility { + + public Game game; + public ArrayList softwares; + public String sinceVersion; + public String untilVersion; + + public VersionCompatibility(JsonObject object){ + int game = object.get("game").getAsInt(); + switch (game){ + case 0: + this.game=Game.Minecraft; + break; + case 1: + this.game=Game.MinecraftBedrock; + break; + case 2: + this.game=Game.SpaceEngineers; + break; + default: + this.game=Game.Unknown; + } + this.softwares=new ArrayList<>(); + for (JsonElement software : object.get("softwares").getAsJsonArray()) { + switch (software.getAsInt()){ + case 0: + this.softwares.add(GameSoftware.Spigot); + break; + case 1: + this.softwares.add(GameSoftware.BungeeCord); + break; + default: + this.softwares.add(GameSoftware.Unknown); + } + } + this.sinceVersion=object.get("sinceVersion").getAsString(); + if(object.get("untilVersion").isJsonNull()){ + this.untilVersion=null; + } else { + this.untilVersion=object.get("untilVersion").getAsString(); + } + } + + public Game getGame() { + return game; + } + + public String getSinceVersion() { + return sinceVersion; + } + + public String getUntilVersion() { + return untilVersion; + } + + public ArrayList getSoftwares() { + return softwares; + } +} diff --git a/src/io/purecore/api/versioning/VersionStability.java b/src/io/purecore/api/versioning/VersionStability.java new file mode 100644 index 0000000..6bc23e8 --- /dev/null +++ b/src/io/purecore/api/versioning/VersionStability.java @@ -0,0 +1,18 @@ +package io.purecore.api.versioning; + +public enum VersionStability { + Unknown(-1), + Release(0), + Prerelease(1); + + private int val; + + VersionStability(int val) + { + this.val = val; + } + + public int getParam(){ + return this.val; + } +}