diff --git a/src/main/java/dev/plex/HTTPDModule.java b/src/main/java/dev/plex/HTTPDModule.java index 4517e8e..1fd3e70 100644 --- a/src/main/java/dev/plex/HTTPDModule.java +++ b/src/main/java/dev/plex/HTTPDModule.java @@ -2,7 +2,10 @@ package dev.plex; import dev.plex.config.ModuleConfig; import dev.plex.module.PlexModule; -import dev.plex.request.impl.GetEndpoints; +import dev.plex.request.impl.AdminsEndpoint; +import dev.plex.request.impl.IndefBansEndpoint; +import dev.plex.request.impl.ListEndpoint; +import dev.plex.request.impl.PunishmentsEndpoint; import dev.plex.util.PlexLog; import java.util.concurrent.atomic.AtomicReference; import lombok.Getter; @@ -27,12 +30,11 @@ public class HTTPDModule extends PlexModule @Getter private static Permission permissions = null; - private ModuleConfig moduleConfig; + public static ModuleConfig moduleConfig; @Override public void load() { - moduleConfig = new ModuleConfig(this, "settings.yml"); } @@ -58,13 +60,15 @@ public class HTTPDModule extends PlexModule connector.setHost(moduleConfig.getString("server.bind-address")); connector.setPort(moduleConfig.getInt("server.port")); - new GetEndpoints(); + new AdminsEndpoint(); + new IndefBansEndpoint(); + new ListEndpoint(); + new PunishmentsEndpoint(); server.setConnectors(new Connector[]{connector}); server.setHandler(context); atomicServer.set(server); - PlexLog.debug("Set atomicServer value? {0}", atomicServer.get() != null); try { server.start(); @@ -76,6 +80,7 @@ public class HTTPDModule extends PlexModule } }, "Jetty-Server"); serverThread.start(); + PlexLog.log("Starting Jetty server on port " + moduleConfig.getInt("server.port")); } @Override diff --git a/src/main/java/dev/plex/logging/Log.java b/src/main/java/dev/plex/logging/Log.java new file mode 100644 index 0000000..99d5360 --- /dev/null +++ b/src/main/java/dev/plex/logging/Log.java @@ -0,0 +1,25 @@ +package dev.plex.logging; + +import dev.plex.HTTPDModule; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + + +public class Log +{ + public static void log(String message, Object... strings) + { + for (int i = 0; i < strings.length; i++) + { + if (message.contains("{" + i + "}")) + { + message = message.replace("{" + i + "}", strings[i].toString()); + } + } + + if (HTTPDModule.moduleConfig.getBoolean("server.logging")) + { + Bukkit.getConsoleSender().sendMessage(String.format(ChatColor.DARK_AQUA + "[Plex HTTPD] " + ChatColor.GRAY + "%s", message)); + } + } +} diff --git a/src/main/java/dev/plex/request/AbstractServlet.java b/src/main/java/dev/plex/request/AbstractServlet.java index 4db509e..3362b5b 100644 --- a/src/main/java/dev/plex/request/AbstractServlet.java +++ b/src/main/java/dev/plex/request/AbstractServlet.java @@ -2,7 +2,7 @@ package dev.plex.request; import com.google.common.collect.Lists; import dev.plex.HTTPDModule; -import dev.plex.util.PlexLog; +import dev.plex.logging.Log; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; @@ -16,7 +16,6 @@ import org.eclipse.jetty.servlet.ServletHolder; public class AbstractServlet extends HttpServlet { - private final List GET_MAPPINGS = Lists.newArrayList(); public AbstractServlet() @@ -42,16 +41,13 @@ public class AbstractServlet extends HttpServlet @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - PlexLog.debug("Context Path: " + req.getHttpServletMapping().getMatchValue()); - - String ipAddress = req.getHeader("X-FORWARDED-FOR"); + String ipAddress = req.getRemoteAddr(); if (ipAddress == null) { - ipAddress = req.getRemoteAddr(); + ipAddress = req.getHeader("X-FORWARDED-FOR"); } - PlexLog.debug("HTTP Remote IP: " + ipAddress); - PlexLog.debug("HTTP Local IP: " + req.getLocalAddr()); + + Log.log(ipAddress + " visited endpoint " + req.getHttpServletMapping().getMatchValue()); /*Enumeration headerz = req.getHeaderNames(); while (headerz.hasMoreElements()) { @@ -59,7 +55,6 @@ public class AbstractServlet extends HttpServlet PlexLog.debug("Header: {0} Value {1}", header, req.getHeader(header)); }*/ - PlexLog.debug("-------------------------"); GET_MAPPINGS.stream().filter(mapping -> mapping.getMapping().endpoint().substring(1, mapping.getMapping().endpoint().length() - 1).equalsIgnoreCase(req.getHttpServletMapping().getMatchValue())).forEach(mapping -> { if (mapping.headers != null) @@ -84,9 +79,8 @@ public class AbstractServlet extends HttpServlet }); } - @Data - public class Mapping + public static class Mapping { private final Method method; private final GetMapping mapping; diff --git a/src/main/java/dev/plex/request/impl/AdminsEndpoint.java b/src/main/java/dev/plex/request/impl/AdminsEndpoint.java new file mode 100644 index 0000000..f39fe00 --- /dev/null +++ b/src/main/java/dev/plex/request/impl/AdminsEndpoint.java @@ -0,0 +1,56 @@ +package dev.plex.request.impl; + +import com.google.common.collect.Lists; +import com.google.gson.GsonBuilder; +import dev.plex.HTTPDModule; +import dev.plex.Plex; +import dev.plex.cache.DataUtils; +import dev.plex.player.PlexPlayer; +import dev.plex.rank.enums.Rank; +import dev.plex.request.AbstractServlet; +import dev.plex.request.GetMapping; +import dev.plex.util.PlexLog; +import jakarta.servlet.http.HttpServletRequest; +import java.util.UUID; +import java.util.stream.Collectors; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; + +public class AdminsEndpoint extends AbstractServlet +{ + @GetMapping(endpoint = "/api/admins/") + public String getAdmins(HttpServletRequest request) + { + String ipAddress = request.getRemoteAddr(); + if (ipAddress == null) + { + return "An IP address could not be detected. Please ensure you are connecting using IPv4."; + } + final PlexPlayer player = DataUtils.getPlayerByIP(ipAddress); + if (player == null) + { + // This likely means they've never joined the server before. That's okay. We can just not return IPs. + return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).collect(Collectors.toList())); + } + if (Plex.get().getSystem().equalsIgnoreCase("ranks")) + { + PlexLog.debug("Plex-HTTPD using ranks check"); + if (!player.getRankFromString().isAtLeast(Rank.ADMIN)) + { + // Don't return IPs either if the person is not an Admin or above. + return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).collect(Collectors.toList())); + } + } + else if (Plex.get().getSystem().equalsIgnoreCase("permissions")) + { + PlexLog.debug("Plex-HTTPD using permissions check"); + final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(player.getUuid())); + if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.admins.access")) + { + // If the person doesn't have permission, don't return IPs + return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).collect(Collectors.toList())); + } + } + return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers()); + } +} diff --git a/src/main/java/dev/plex/request/impl/GetEndpoints.java b/src/main/java/dev/plex/request/impl/GetEndpoints.java deleted file mode 100644 index 41b9d67..0000000 --- a/src/main/java/dev/plex/request/impl/GetEndpoints.java +++ /dev/null @@ -1,90 +0,0 @@ -package dev.plex.request.impl; - -import com.google.common.collect.Lists; -import com.google.gson.GsonBuilder; -import dev.plex.HTTPDModule; -import dev.plex.Plex; -import dev.plex.cache.DataUtils; -import dev.plex.player.PlexPlayer; -import dev.plex.rank.enums.Rank; -import dev.plex.request.AbstractServlet; -import dev.plex.request.GetMapping; -import dev.plex.util.PlexLog; -import dev.plex.util.adapter.LocalDateTimeSerializer; -import jakarta.servlet.http.HttpServletRequest; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.UUID; -import java.util.stream.Collectors; - -//@RestController -//@RequestMapping("/api/admins") -public class GetEndpoints extends AbstractServlet -{ - @GetMapping(endpoint = "/api/admins/") - public String getAdmins(HttpServletRequest request) - { - String ipAddress = request.getHeader("X-FORWARDED-FOR"); - if (ipAddress == null) - { - ipAddress = request.getRemoteAddr(); - } - final PlexPlayer player = DataUtils.getPlayerByIP(ipAddress); - if (player == null) - { - return "Couldn't load your IP Address: " + ipAddress + ". Check if your SSL settings are setup correctly."; - } - if (Plex.get().getSystem().equalsIgnoreCase("ranks")) - { - PlexLog.debug("Plex-HTTPD using ranks check"); - if (!player.getRankFromString().isAtLeast(Rank.ADMIN)) - { - return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).peek(plexPlayer -> plexPlayer.setPunishments(Lists.newArrayList())).collect(Collectors.toList())); - } - } else if (Plex.get().getSystem().equalsIgnoreCase("permissions")) - { - PlexLog.debug("Plex-HTTPD using permissions check"); - final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(player.getUuid())); - if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.admins.access")) - { - return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).setPrettyPrinting().create().toJson(Plex.get().getAdminList().getAllAdminPlayers().stream().peek(plexPlayer -> plexPlayer.setIps(Lists.newArrayList())).peek(plexPlayer -> plexPlayer.setPunishments(Lists.newArrayList())).collect(Collectors.toList())); - } - } - return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).setPrettyPrinting().create().toJson(new ArrayList<>(Plex.get().getAdminList().getAllAdminPlayers())); - } - - @GetMapping(endpoint = "/api/indefbans/") - public String getBans(HttpServletRequest request) - { - String ipAddress = request.getHeader("X-FORWARDED-FOR"); - if (ipAddress == null) - { - ipAddress = request.getRemoteAddr(); - } - final PlexPlayer player = DataUtils.getPlayerByIP(ipAddress); - if (player == null) - { - return "Couldn't load your IP Address: " + ipAddress + ". Check if your SSL settings are setup correctly."; - } - if (Plex.get().getSystem().equalsIgnoreCase("ranks")) - { - PlexLog.debug("Plex-HTTPD using ranks check"); - if (!player.getRankFromString().isAtLeast(Rank.ADMIN)) - { - return "Not a high enough rank to view this page."; - } - } else if (Plex.get().getSystem().equalsIgnoreCase("permissions")) - { - PlexLog.debug("Plex-HTTPD using permissions check"); - final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(player.getUuid())); - if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.indefbans.access")) - { - return "Not enough permissions to view this page."; - } - } - return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getPunishmentManager().getIndefiniteBans().stream().toList()); - } -} diff --git a/src/main/java/dev/plex/request/impl/IndefBansEndpoint.java b/src/main/java/dev/plex/request/impl/IndefBansEndpoint.java new file mode 100644 index 0000000..20f5932 --- /dev/null +++ b/src/main/java/dev/plex/request/impl/IndefBansEndpoint.java @@ -0,0 +1,51 @@ +package dev.plex.request.impl; + +import com.google.gson.GsonBuilder; +import dev.plex.HTTPDModule; +import dev.plex.Plex; +import dev.plex.cache.DataUtils; +import dev.plex.player.PlexPlayer; +import dev.plex.rank.enums.Rank; +import dev.plex.request.AbstractServlet; +import dev.plex.request.GetMapping; +import dev.plex.util.PlexLog; +import jakarta.servlet.http.HttpServletRequest; +import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; + +public class IndefBansEndpoint extends AbstractServlet +{ + @GetMapping(endpoint = "/api/indefbans/") + public String getBans(HttpServletRequest request) + { + String ipAddress = request.getRemoteAddr(); + if (ipAddress == null) + { + return "An IP address could not be detected. Please ensure you are connecting using IPv4."; + } + final PlexPlayer player = DataUtils.getPlayerByIP(ipAddress); + if (player == null) + { + return "Couldn't load your IP Address: " + ipAddress + ". Have you joined the server before?"; + } + if (Plex.get().getSystem().equalsIgnoreCase("ranks")) + { + PlexLog.debug("Plex-HTTPD using ranks check"); + if (!player.getRankFromString().isAtLeast(Rank.ADMIN)) + { + return "Not a high enough rank to view this page."; + } + } + else if (Plex.get().getSystem().equalsIgnoreCase("permissions")) + { + PlexLog.debug("Plex-HTTPD using permissions check"); + final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(player.getUuid())); + if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.indefbans.access")) + { + return "Not enough permissions to view this page."; + } + } + return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getPunishmentManager().getIndefiniteBans().stream().toList()); + } +} diff --git a/src/main/java/dev/plex/request/impl/ListEndpoint.java b/src/main/java/dev/plex/request/impl/ListEndpoint.java new file mode 100644 index 0000000..8b6fcf5 --- /dev/null +++ b/src/main/java/dev/plex/request/impl/ListEndpoint.java @@ -0,0 +1,25 @@ +package dev.plex.request.impl; + +import com.google.gson.GsonBuilder; +import dev.plex.request.AbstractServlet; +import dev.plex.request.GetMapping; +import jakarta.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class ListEndpoint extends AbstractServlet +{ + List players = new ArrayList<>(); + + @GetMapping(endpoint = "/api/list/") + public String getOnlinePlayers(HttpServletRequest request) + { + for (Player player : Bukkit.getOnlinePlayers()) + { + players.add(player.getName()); + } + return new GsonBuilder().setPrettyPrinting().create().toJson(players.stream().toList()); + } +} diff --git a/src/main/java/dev/plex/request/impl/PunishmentsEndpoint.java b/src/main/java/dev/plex/request/impl/PunishmentsEndpoint.java new file mode 100644 index 0000000..6e821d7 --- /dev/null +++ b/src/main/java/dev/plex/request/impl/PunishmentsEndpoint.java @@ -0,0 +1,99 @@ +package dev.plex.request.impl; + +import com.google.gson.GsonBuilder; +import dev.plex.HTTPDModule; +import dev.plex.Plex; +import dev.plex.cache.DataUtils; +import dev.plex.player.PlexPlayer; +import dev.plex.player.PunishedPlayer; +import dev.plex.rank.enums.Rank; +import dev.plex.request.AbstractServlet; +import dev.plex.request.GetMapping; +import dev.plex.util.PlexLog; +import dev.plex.util.adapter.LocalDateTimeSerializer; +import jakarta.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; + +public class PunishmentsEndpoint extends AbstractServlet +{ + @GetMapping(endpoint = "/api/punishments/") + public String getPunishments(HttpServletRequest request) + { + String ipAddress = request.getRemoteAddr(); + if (ipAddress == null) + { + return "An IP address could not be detected. Please ensure you are connecting using IPv4."; + } + if (request.getPathInfo() == null) + { + return "Please specify the UUID of the player you would like to check.\nExample: /api/punishments/"; + } + try + { + UUID uuid = UUID.fromString(request.getPathInfo().replace("/", "")); + final PunishedPlayer punishedPlayer = new PunishedPlayer(uuid); + final PlexPlayer player = DataUtils.getPlayerByIP(ipAddress); + if (punishedPlayer.getPunishments().isEmpty()) + { + return "This player has been a good boy. They have no punishments! Or they've never been on the server before. Take your pick."; + } + if (player == null) + { + // If the player is null, give it to them without the IPs + return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList()); + } + if (Plex.get().getSystem().equalsIgnoreCase("ranks")) + { + PlexLog.debug("Plex-HTTPD using ranks check"); + if (!player.getRankFromString().isAtLeast(Rank.ADMIN)) + { + // Don't return IPs either if the person is not an Admin or above. + return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList()); + } + } + else if (Plex.get().getSystem().equalsIgnoreCase("permissions")) + { + PlexLog.debug("Plex-HTTPD using permissions check"); + final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(player.getUuid())); + if (!HTTPDModule.getPermissions().playerHas(null, offlinePlayer, "plex.httpd.punishments.access")) + { + // If the person doesn't have permission, don't return IPs + return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList()); + } + } + return new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().toList()); + } + catch (java.lang.IllegalArgumentException ignored) + { + return "Invalid UUID"; + } + } + + public File getPunishmentsFile(UUID uuid) + { + File folder = new File(Plex.get().getDataFolder() + File.separator + "punishments"); + if (!folder.exists()) + { + folder.mkdir(); + } + + File file = new File(folder, "" + uuid.toString() + ".json"); + if (!file.exists()) + { + try + { + file.createNewFile(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + return file; + } +} diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index 51742e3..3dae029 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -1,3 +1,4 @@ server: bind-address: 0.0.0.0 - port: 27192 \ No newline at end of file + port: 27192 + logging: false \ No newline at end of file