diff --git a/src/main/java/xyz/etztech/serverapi/ServerAPI.java b/src/main/java/xyz/etztech/serverapi/ServerAPI.java index 8b5df44..d026ba5 100644 --- a/src/main/java/xyz/etztech/serverapi/ServerAPI.java +++ b/src/main/java/xyz/etztech/serverapi/ServerAPI.java @@ -9,6 +9,7 @@ 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.listeners.AsyncPlayerChatListener; import xyz.etztech.serverapi.token.TokenList; import xyz.etztech.serverapi.tps.TPS; import xyz.etztech.serverapi.web.IProvider; @@ -25,6 +26,8 @@ public class ServerAPI extends JavaPlugin implements IProvider { private Web web = new Web(this); private final Logger log = Logger.getLogger( "Minecraft" ); + private static final List chat = new ArrayList<>(); + @Override public void onEnable() { instance = this; @@ -33,6 +36,7 @@ public class ServerAPI extends JavaPlugin implements IProvider { reloadConfig(); if (isEnabled()) { + new AsyncPlayerChatListener(this); new MainCommand(this); tps = new TPS(); @@ -68,6 +72,10 @@ public class ServerAPI extends JavaPlugin implements IProvider { return tps; } + public static List getChat() { + return chat; + } + @Override public TPSAPI TPS() { return new TPSAPI(tps.getHistory()); @@ -110,6 +118,11 @@ public class ServerAPI extends JavaPlugin implements IProvider { return bans; } + @Override + public List chat() { + return chat; + } + @Override public void kick(BanAPI kick) { Player player = Bukkit.getPlayerExact(kick.getTarget()); diff --git a/src/main/java/xyz/etztech/serverapi/listeners/AsyncPlayerChatListener.java b/src/main/java/xyz/etztech/serverapi/listeners/AsyncPlayerChatListener.java new file mode 100644 index 0000000..6206e2e --- /dev/null +++ b/src/main/java/xyz/etztech/serverapi/listeners/AsyncPlayerChatListener.java @@ -0,0 +1,31 @@ +package xyz.etztech.serverapi.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import xyz.etztech.serverapi.ServerAPI; +import xyz.etztech.serverapi.web.api.ChatAPI; + +import java.util.Date; + +public class AsyncPlayerChatListener implements Listener { + private final ServerAPI plugin; + + public AsyncPlayerChatListener(ServerAPI plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + + @EventHandler(priority= EventPriority.MONITOR, ignoreCancelled=true) + public void onChat(AsyncPlayerChatEvent event) { + int chatLimit = plugin.getConfig().getInt("chat", 100); + if (ServerAPI.getChat().size() >= chatLimit) { + ServerAPI.getChat().remove(0); + } + ServerAPI.getChat().add(new ChatAPI( + String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()), + new Date().getTime() + )); + } +} diff --git a/src/main/java/xyz/etztech/serverapi/web/GraphQL.java b/src/main/java/xyz/etztech/serverapi/web/GraphQL.java index fb01bd8..81f62be 100644 --- a/src/main/java/xyz/etztech/serverapi/web/GraphQL.java +++ b/src/main/java/xyz/etztech/serverapi/web/GraphQL.java @@ -45,4 +45,9 @@ public class GraphQL implements QueryGraphql { public TPSAPI getTps() { return provider.TPS(); } + + @GraphQLName("chat") + public ChatAPI[] getChat() { + return provider.chat().toArray(new ChatAPI[0]); + } } diff --git a/src/main/java/xyz/etztech/serverapi/web/IProvider.java b/src/main/java/xyz/etztech/serverapi/web/IProvider.java index 85feea6..17a4636 100644 --- a/src/main/java/xyz/etztech/serverapi/web/IProvider.java +++ b/src/main/java/xyz/etztech/serverapi/web/IProvider.java @@ -15,6 +15,7 @@ public interface IProvider { List worlds(); WorldAPI world(String name); List plugins(); + List chat(); // POST void kick(BanAPI kick); diff --git a/src/main/java/xyz/etztech/serverapi/web/Web.java b/src/main/java/xyz/etztech/serverapi/web/Web.java index f988a30..395f4fd 100644 --- a/src/main/java/xyz/etztech/serverapi/web/Web.java +++ b/src/main/java/xyz/etztech/serverapi/web/Web.java @@ -59,6 +59,7 @@ public class Web { app.get("/tps", this::tps); app.get("/worlds", this::worlds); app.get("/worlds/:name", this::world); + app.get("/chat", this::chat); app.post("/kick", this::kick); app.post("/ban", this::ban); @@ -135,6 +136,10 @@ public class Web { ctx.json(provider.world(ctx.pathParam("name"))); } + public void chat(Context ctx) { + ctx.json(provider.chat()); + } + public void players(Context ctx) { ctx.json(provider.players()); } diff --git a/src/main/java/xyz/etztech/serverapi/web/api/ChatAPI.java b/src/main/java/xyz/etztech/serverapi/web/api/ChatAPI.java new file mode 100644 index 0000000..9cb1623 --- /dev/null +++ b/src/main/java/xyz/etztech/serverapi/web/api/ChatAPI.java @@ -0,0 +1,26 @@ +package xyz.etztech.serverapi.web.api; + +import com.expediagroup.graphql.annotations.GraphQLDescription; +import com.expediagroup.graphql.annotations.GraphQLName; + +@GraphQLName("Chat") +@GraphQLDescription("Chat GraphQL") +public class ChatAPI { + private final String message; + private final long timestamp; + + public ChatAPI(String message, long timestamp) { + this.message = message; + this.timestamp = timestamp; + } + + @GraphQLName("message") + public String getMessage() { + return message; + } + + @GraphQLName("timestamp") + public long getTimestamp() { + return timestamp; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 311f57d..9cd5c8c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,9 @@ # The port to run on port: 8080 +# Number of chat logs to retain +chat: 100 + # Authentication auth: # Protect GET routes. If false, GET routes are public. diff --git a/src/test/java/xyz/etztech/serverapi/MockProvider.java b/src/test/java/xyz/etztech/serverapi/MockProvider.java index 1603777..c733e85 100644 --- a/src/test/java/xyz/etztech/serverapi/MockProvider.java +++ b/src/test/java/xyz/etztech/serverapi/MockProvider.java @@ -84,6 +84,16 @@ public class MockProvider implements IProvider { ); } + @Override + public List chat() { + long now = new Date().getTime(); + return Arrays.asList( + new ChatAPI("message 1", now-2), + new ChatAPI("message 2", now-1), + new ChatAPI("message 3", now) + ); + } + @Override public void log(String message) { System.out.println(message); diff --git a/src/test/java/xyz/etztech/serverapi/ServerRunner.java b/src/test/java/xyz/etztech/serverapi/ServerRunner.java index ccd67ef..821723b 100644 --- a/src/test/java/xyz/etztech/serverapi/ServerRunner.java +++ b/src/test/java/xyz/etztech/serverapi/ServerRunner.java @@ -5,7 +5,6 @@ import xyz.etztech.serverapi.token.TokenList; import xyz.etztech.serverapi.token.TokenScope; import xyz.etztech.serverapi.web.Web; -import java.util.ArrayList; import java.util.Arrays; import java.util.List;