diff --git a/pom.xml b/pom.xml index 4796725..7624fee 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xyz.etztech ServerAPI - 0.0.1 + 0.0.2 jar diff --git a/src/main/java/xyz/etztech/serverapi/ServerAPI.java b/src/main/java/xyz/etztech/serverapi/ServerAPI.java index 4d871e2..aa0ee19 100644 --- a/src/main/java/xyz/etztech/serverapi/ServerAPI.java +++ b/src/main/java/xyz/etztech/serverapi/ServerAPI.java @@ -3,9 +3,9 @@ package xyz.etztech.serverapi; import org.bukkit.BanEntry; import org.bukkit.BanList; -import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import xyz.etztech.serverapi.commands.MainCommand; import xyz.etztech.serverapi.tps.TPS; @@ -13,10 +13,7 @@ import xyz.etztech.serverapi.web.IProvider; import xyz.etztech.serverapi.web.Web; import xyz.etztech.serverapi.web.api.*; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.logging.Logger; public class ServerAPI extends JavaPlugin implements IProvider { @@ -111,8 +108,17 @@ public class ServerAPI extends JavaPlugin implements IProvider { } @Override - public QueryAPI query() { - return QueryAPI.fromMinecraft(getServer()); + public PingAPI ping() { + return PingAPI.fromMinecraft(getServer()); + } + + @Override + public List plugins() { + List plugins = new ArrayList<>(); + for (Plugin plugin : getServer().getPluginManager().getPlugins()) { + plugins.add(PluginAPI.fromMinecraft(plugin)); + } + return plugins; } } diff --git a/src/main/java/xyz/etztech/serverapi/web/GraphQL.java b/src/main/java/xyz/etztech/serverapi/web/GraphQL.java index 42f5ca7..fb01bd8 100644 --- a/src/main/java/xyz/etztech/serverapi/web/GraphQL.java +++ b/src/main/java/xyz/etztech/serverapi/web/GraphQL.java @@ -21,9 +21,14 @@ public class GraphQL implements QueryGraphql { return provider.players().toArray(new PlayerAPI[0]); } - @GraphQLName("query") - public QueryAPI getQuery() { - return provider.query(); + @GraphQLName("ping") + public PingAPI getPing() { + return provider.ping(); + } + + @GraphQLName("plugins") + public PluginAPI[] getPlugins() { + return provider.plugins().toArray(new PluginAPI[0]); } @GraphQLName("world") diff --git a/src/main/java/xyz/etztech/serverapi/web/IProvider.java b/src/main/java/xyz/etztech/serverapi/web/IProvider.java index cc353d1..2362f42 100644 --- a/src/main/java/xyz/etztech/serverapi/web/IProvider.java +++ b/src/main/java/xyz/etztech/serverapi/web/IProvider.java @@ -8,10 +8,11 @@ import java.util.Set; public interface IProvider { Set bans(); Set players(); - QueryAPI query(); + PingAPI ping(); TPSAPI TPS(); List worlds(); WorldAPI world(String name); + List plugins(); void log(String message); } diff --git a/src/main/java/xyz/etztech/serverapi/web/README.md b/src/main/java/xyz/etztech/serverapi/web/README.md new file mode 100644 index 0000000..13fc2f2 --- /dev/null +++ b/src/main/java/xyz/etztech/serverapi/web/README.md @@ -0,0 +1,22 @@ +# Adding a new endpoint + +1. Create a new `API` class in [api](api). + * Make sure to correctly add the appropriate JSON and GraphQL annotations. + Look at other classes for examples. + * **NOTE:** If anything returned could be null, make sure to instead provide an appropriate zero-value property, + otherwise GraphQL will choke. + See [PluginAPI::new](api/PluginAPI.java) for an example. +2. Add a method to return the needed data to [IProvider](IProvider.java). +3. Add a new REST endpoint to the [Web::start](Web.java) method. +4. Add a new GraphQL method to [GraphQL](GraphQL.java) + * Make sure to correctly add the appropriate GraphQL annotation. +5. Modify both [ServerAPI](../ServerAPI.java) +and [MockProvider](../../../../../../test/java/xyz/etztech/serverapi/MockProvider.java) +to fulfill the [IProvider](IProvider.java) interface. + +# Testing + +[ServerRunner](../../../../../../test/java/xyz/etztech/serverapi/ServerRunner.java) should start up the API using +[MockProvider](../../../../../../test/java/xyz/etztech/serverapi/MockProvider.java). + +If possible, a real test on a running Minecraft server would ideal! \ No newline at end of file diff --git a/src/main/java/xyz/etztech/serverapi/web/Web.java b/src/main/java/xyz/etztech/serverapi/web/Web.java index a1d8cc4..defd106 100644 --- a/src/main/java/xyz/etztech/serverapi/web/Web.java +++ b/src/main/java/xyz/etztech/serverapi/web/Web.java @@ -36,9 +36,12 @@ public class Web { app.before(this::access); } + // REST Endpoints + // For GraphQL endpoints, see GraphQL.java app.get("/bans", this::bans); app.get("/players", this::players); - app.get("/query", this::query); + app.get("/plugins", this::plugins); + app.get("/ping", this::ping); app.get("/tps", this::tps); app.get("/worlds", this::worlds); app.get("/worlds/:name", this::world); @@ -107,11 +110,15 @@ public class Web { ctx.json(provider.players()); } + public void plugins(Context ctx) { + ctx.json(provider.plugins()); + } + public void bans(Context ctx) { ctx.json(provider.bans()); } - public void query(Context ctx) { - ctx.json(provider.query()); + public void ping(Context ctx) { + ctx.json(provider.ping()); } } diff --git a/src/main/java/xyz/etztech/serverapi/web/api/BanAPI.java b/src/main/java/xyz/etztech/serverapi/web/api/BanAPI.java index c1736c3..7994f81 100644 --- a/src/main/java/xyz/etztech/serverapi/web/api/BanAPI.java +++ b/src/main/java/xyz/etztech/serverapi/web/api/BanAPI.java @@ -1,12 +1,9 @@ package xyz.etztech.serverapi.web.api; import com.expediagroup.graphql.annotations.GraphQLDescription; -import com.expediagroup.graphql.annotations.GraphQLDirective; import com.expediagroup.graphql.annotations.GraphQLName; import org.bukkit.BanEntry; -import java.util.Date; - @GraphQLName("Ban") @GraphQLDescription("Ban GraphQL") public class BanAPI { diff --git a/src/main/java/xyz/etztech/serverapi/web/api/QueryAPI.java b/src/main/java/xyz/etztech/serverapi/web/api/PingAPI.java similarity index 83% rename from src/main/java/xyz/etztech/serverapi/web/api/QueryAPI.java rename to src/main/java/xyz/etztech/serverapi/web/api/PingAPI.java index c9247d2..4b0aeee 100644 --- a/src/main/java/xyz/etztech/serverapi/web/api/QueryAPI.java +++ b/src/main/java/xyz/etztech/serverapi/web/api/PingAPI.java @@ -5,9 +5,9 @@ import com.expediagroup.graphql.annotations.GraphQLName; import com.fasterxml.jackson.annotation.JsonProperty; import org.bukkit.Server; -@GraphQLName("MCQuery") -@GraphQLDescription("MCQuery GraphQL") -public class QueryAPI { +@GraphQLName("Ping") +@GraphQLDescription("Ping GraphQL") +public class PingAPI { private final String type; private final String version; private final String motd; @@ -16,7 +16,7 @@ public class QueryAPI { @JsonProperty("max_players") private final int maxPlayers; - public QueryAPI(String type, String version, String motd, int currentPlayers, int maxPlayers) { + public PingAPI(String type, String version, String motd, int currentPlayers, int maxPlayers) { this.type = type; this.version = version; this.motd = motd; @@ -49,8 +49,8 @@ public class QueryAPI { return maxPlayers; } - public static QueryAPI fromMinecraft(Server server) { - return new QueryAPI( + public static PingAPI fromMinecraft(Server server) { + return new PingAPI( server.getName(), server.getBukkitVersion().split("-")[0], // 1.x.x-R0.1-SNAPSHOT server.getMotd(), diff --git a/src/main/java/xyz/etztech/serverapi/web/api/PluginAPI.java b/src/main/java/xyz/etztech/serverapi/web/api/PluginAPI.java new file mode 100644 index 0000000..f185700 --- /dev/null +++ b/src/main/java/xyz/etztech/serverapi/web/api/PluginAPI.java @@ -0,0 +1,54 @@ +package xyz.etztech.serverapi.web.api; + +import com.expediagroup.graphql.annotations.GraphQLDescription; +import com.expediagroup.graphql.annotations.GraphQLName; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; + +@GraphQLName("Plugin") +@GraphQLDescription("Plugin GraphQL") +public class PluginAPI { + private final String name; + private final String version; + private final List authors; + private final String website; + + + public PluginAPI(String name, String version, List authors, String website) { + this.name = name; + this.version = version; + this.authors = authors != null ? authors : new ArrayList<>(); + this.website = website != null ? website : ""; + } + + @GraphQLName("name") + public String getName() { + return name; + } + + @GraphQLName("version") + public String getVersion() { + return version; + } + + @GraphQLName("authors") + public List getAuthors() { + return authors; + } + + @GraphQLName("website") + public String getWebsite() { + return website; + } + + public static PluginAPI fromMinecraft(Plugin plugin) { + return new PluginAPI( + plugin.getName(), + plugin.getDescription().getVersion(), + plugin.getDescription().getAuthors(), + plugin.getDescription().getWebsite() + ); + } +} diff --git a/src/main/java/xyz/etztech/serverapi/web/api/WorldAPI.java b/src/main/java/xyz/etztech/serverapi/web/api/WorldAPI.java index 813315c..098d7d5 100644 --- a/src/main/java/xyz/etztech/serverapi/web/api/WorldAPI.java +++ b/src/main/java/xyz/etztech/serverapi/web/api/WorldAPI.java @@ -3,7 +3,6 @@ package xyz.etztech.serverapi.web.api; import com.expediagroup.graphql.annotations.GraphQLDescription; import com.expediagroup.graphql.annotations.GraphQLName; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonNaming; import org.bukkit.World; @GraphQLName("World") diff --git a/src/test/java/xyz/etztech/serverapi/MockProvider.java b/src/test/java/xyz/etztech/serverapi/MockProvider.java index 5051acc..2a7ca06 100644 --- a/src/test/java/xyz/etztech/serverapi/MockProvider.java +++ b/src/test/java/xyz/etztech/serverapi/MockProvider.java @@ -56,8 +56,17 @@ public class MockProvider implements IProvider { } @Override - public QueryAPI query() { - return new QueryAPI("Mock", "0.0.1", "Hello, world!", 0, 100); + public PingAPI ping() { + return new PingAPI("Mock", "0.0.1", "Hello, world!", 0, 100); + } + + @Override + public List plugins() { + return Arrays.asList( + new PluginAPI("ServerAPI", "0.0.1", Collections.singletonList("Etzelia"), "https://git.etztech.xyz"), + new PluginAPI("dynmap", "0.1.0", null, "https://www.spigotmc.org/resources/dynmap.274/"), + new PluginAPI("CoreProtect", "1.0.0", Collections.singletonList("Intelli"), null) + ); } @Override diff --git a/src/test/java/xyz/etztech/serverapi/ServerRunner.java b/src/test/java/xyz/etztech/serverapi/ServerRunner.java index e34587f..cc64fe3 100644 --- a/src/test/java/xyz/etztech/serverapi/ServerRunner.java +++ b/src/test/java/xyz/etztech/serverapi/ServerRunner.java @@ -6,7 +6,6 @@ public class ServerRunner { public static void main(String[] args) { Web web = new Web(new MockProvider()); - web.start(8080, ""); } }