diff --git a/build.gradle.kts b/build.gradle.kts index 6112fe7..882aa55 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ plugins { java `maven-publish` idea - id("dev.plex.module") version "1.0" + id("dev.plex.module") version "1.1" } group = "dev.plex" @@ -20,21 +20,26 @@ repositories { url = uri("https://nexus.telesphoreo.me/repository/plex/") } - maven { url = uri("https://maven.enginehub.org/repo/") } + maven { + url = uri("https://maven.enginehub.org/repo/") + } - maven { url = uri("https://repo.codemc.io/repository/maven-public/") } + maven { + url = uri("https://repo.codemc.io/repository/maven-public/") + } } dependencies { implementation("org.projectlombok:lombok:1.18.46") annotationProcessor("org.projectlombok:lombok:1.18.46") compileOnly("io.papermc.paper:paper-api:26.1.2.build.+") - implementation("dev.plex:server:2.0-SNAPSHOT") + implementation("dev.plex:api:2.0-SNAPSHOT") implementation("org.json:json:20251224") implementation("org.reflections:reflections:0.10.2") plexLibrary("org.eclipse.jetty:jetty-server:12.1.9") plexLibrary("org.eclipse.jetty.ee10:jetty-ee10-servlet:12.1.9") plexLibrary("org.eclipse.jetty:jetty-proxy:12.1.9") + plexLibrary("de.tr7zw:item-nbt-api:2.15.7") implementation(platform("com.intellectualsites.bom:bom-newest:1.56")) // Ref: https://github.com/IntellectualSites/bom compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core") implementation("commons-io:commons-io:2.22.0") diff --git a/src/main/java/dev/plex/HTTPDModule.java b/src/main/java/dev/plex/HTTPDModule.java index c4a6952..463452d 100644 --- a/src/main/java/dev/plex/HTTPDModule.java +++ b/src/main/java/dev/plex/HTTPDModule.java @@ -3,6 +3,7 @@ package dev.plex; import dev.plex.assets.MinecraftAssetsManager; import dev.plex.authentication.AuthenticationManager; import dev.plex.cache.FileCache; +import dev.plex.api.PlexApi; import dev.plex.config.ModuleConfig; import dev.plex.logging.Log; import dev.plex.module.PlexModule; @@ -15,7 +16,6 @@ import dev.plex.request.SchematicUploadServlet; import dev.plex.request.StaffPlayersStreamServlet; import dev.plex.request.StatsStreamServlet; import dev.plex.request.impl.*; -import dev.plex.util.PlexLog; import jakarta.servlet.DispatcherType; import jakarta.servlet.MultipartConfigElement; import lombok.Getter; @@ -38,6 +38,12 @@ public class HTTPDModule extends PlexModule private AtomicReference atomicServer = new AtomicReference<>(); public static ModuleConfig moduleConfig; + private static PlexApi plexApi; + + public static PlexApi plexApi() + { + return plexApi; + } public static final FileCache fileCache = new FileCache(); @@ -55,6 +61,7 @@ public class HTTPDModule extends PlexModule @Override public void load() { + plexApi = api(); // Move it from /httpd/config.yml to /plugins/Plex/modules/Plex-HTTPD/config.yml moduleConfig = new ModuleConfig(this, "httpd/config.yml", "config.yml"); } @@ -63,7 +70,7 @@ public class HTTPDModule extends PlexModule public void enable() { moduleConfig.load(); - PlexLog.debug("HTTPD Module Port: {0}", moduleConfig.getInt("server.port")); + HTTPDModule.plexApi().logging().debug("HTTPD Module Port: {0}", moduleConfig.getInt("server.port")); accessLogFile = new File(getDataFolder(), moduleConfig.getString("server.logging.file-path", "httpd.log")); @@ -73,7 +80,7 @@ public class HTTPDModule extends PlexModule authenticationManager = new AuthenticationManager(); if (authenticationManager.provider() == null) { - PlexLog.debug("Authentication is disabled or misconfigured"); + HTTPDModule.plexApi().logging().debug("Authentication is disabled or misconfigured"); } @@ -153,13 +160,13 @@ public class HTTPDModule extends PlexModule } }, "Jetty-Server"); serverThread.start(); - PlexLog.log("Starting Jetty server on port " + moduleConfig.getInt("server.port")); + HTTPDModule.plexApi().logging().info("Starting Jetty server on port " + moduleConfig.getInt("server.port")); } @Override public void disable() { - PlexLog.debug("Stopping Jetty server"); + HTTPDModule.plexApi().logging().debug("Stopping Jetty server"); try { StatsBroadcaster.get().shutdown(); diff --git a/src/main/java/dev/plex/assets/MinecraftAssetsManager.java b/src/main/java/dev/plex/assets/MinecraftAssetsManager.java index afbeca3..07b25f0 100644 --- a/src/main/java/dev/plex/assets/MinecraftAssetsManager.java +++ b/src/main/java/dev/plex/assets/MinecraftAssetsManager.java @@ -1,6 +1,6 @@ package dev.plex.assets; -import dev.plex.util.PlexLog; +import dev.plex.HTTPDModule; import org.bukkit.Bukkit; import org.json.JSONArray; import org.json.JSONObject; @@ -63,7 +63,7 @@ public class MinecraftAssetsManager } catch (Exception e) { - PlexLog.log("Unable to download Minecraft assets for HTTPD inventory view: " + e.getMessage()); + HTTPDModule.plexApi().logging().info("Unable to download Minecraft assets for HTTPD inventory view: " + e.getMessage()); e.printStackTrace(); } }); @@ -90,13 +90,13 @@ public class MinecraftAssetsManager String cachedVersion = Files.exists(versionFile) ? Files.readString(versionFile).trim() : ""; if (minecraftVersion.equals(cachedVersion) && hasAssets()) { - PlexLog.debug("HTTPD Minecraft assets are already cached for {0}", minecraftVersion); + HTTPDModule.plexApi().logging().debug("HTTPD Minecraft assets are already cached for {0}", minecraftVersion); return; } if (!cachedVersion.isEmpty() && !minecraftVersion.equals(cachedVersion)) { - PlexLog.log("Minecraft version changed from " + cachedVersion + " to " + minecraftVersion + "; recreating HTTPD asset cache"); + HTTPDModule.plexApi().logging().info("Minecraft version changed from " + cachedVersion + " to " + minecraftVersion + "; recreating HTTPD asset cache"); } recreateCache(); } @@ -114,7 +114,7 @@ public class MinecraftAssetsManager deleteDirectory(root); Files.createDirectories(root); - PlexLog.log("Downloading Minecraft " + minecraftVersion + " client assets for HTTPD inventory view"); + HTTPDModule.plexApi().logging().info("Downloading Minecraft " + minecraftVersion + " client assets for HTTPD inventory view"); JSONObject version = findVersionJson(); String clientUrl = version.getJSONObject("downloads").getJSONObject("client").getString("url"); @@ -142,7 +142,7 @@ public class MinecraftAssetsManager } Files.writeString(versionFile, minecraftVersion + System.lineSeparator()); - PlexLog.log("HTTPD Minecraft assets cached for " + minecraftVersion); + HTTPDModule.plexApi().logging().info("HTTPD Minecraft assets cached for " + minecraftVersion); } private JSONObject findVersionJson() throws IOException, InterruptedException diff --git a/src/main/java/dev/plex/authentication/AuthenticationManager.java b/src/main/java/dev/plex/authentication/AuthenticationManager.java index cff7507..82a5224 100644 --- a/src/main/java/dev/plex/authentication/AuthenticationManager.java +++ b/src/main/java/dev/plex/authentication/AuthenticationManager.java @@ -2,7 +2,6 @@ package dev.plex.authentication; import dev.plex.HTTPDModule; import dev.plex.authentication.impl.XenForoOAuth2Provider; -import dev.plex.util.PlexLog; public class AuthenticationManager { @@ -17,7 +16,7 @@ public class AuthenticationManager return; } - PlexLog.log("[HTTPD] XenForo OAuth2 authentication is enabled"); + HTTPDModule.plexApi().logging().info("[HTTPD] XenForo OAuth2 authentication is enabled"); provider = new XenForoOAuth2Provider(); } diff --git a/src/main/java/dev/plex/authentication/impl/XenForoOAuth2Provider.java b/src/main/java/dev/plex/authentication/impl/XenForoOAuth2Provider.java index 3f278a0..8ab0bc6 100644 --- a/src/main/java/dev/plex/authentication/impl/XenForoOAuth2Provider.java +++ b/src/main/java/dev/plex/authentication/impl/XenForoOAuth2Provider.java @@ -5,7 +5,6 @@ import dev.plex.authentication.AuthenticatedUser; import dev.plex.authentication.AuthenticationException; import dev.plex.authentication.OAuth2Provider; import dev.plex.authentication.UserType; -import dev.plex.util.PlexLog; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -62,7 +61,7 @@ public class XenForoOAuth2Provider implements OAuth2Provider if (domain.isEmpty() || clientId.isEmpty() || clientSecret.isEmpty() || redirectUri.isEmpty()) { - PlexLog.error("XenForo OAuth2 misconfigured: domain, clientId, clientSecret, redirectUri are all required."); + HTTPDModule.plexApi().logging().error("XenForo OAuth2 misconfigured: domain, clientId, clientSecret, redirectUri are all required."); } String base = "https://" + domain.replaceFirst("^https?://", "").replaceAll("/+$", ""); @@ -286,7 +285,7 @@ public class XenForoOAuth2Provider implements OAuth2Provider } catch (Exception e) { - PlexLog.debug("Failed to revoke XenForo token: {0}", e.getMessage()); + HTTPDModule.plexApi().logging().debug("Failed to revoke XenForo token: {0}", e.getMessage()); } } diff --git a/src/main/java/dev/plex/request/AbstractServlet.java b/src/main/java/dev/plex/request/AbstractServlet.java index abdaea3..51d899b 100644 --- a/src/main/java/dev/plex/request/AbstractServlet.java +++ b/src/main/java/dev/plex/request/AbstractServlet.java @@ -66,7 +66,7 @@ public class AbstractServlet extends HttpServlet /*Enumeration headerz = req.getHeaderNames(); while (headerz.hasMoreElements()) { String header = headerz.nextElement(); - PlexLog.debug("Header: {0} Value {1}", header, req.getHeader(header)); + HTTPDModule.plexApi().logging().debug("Header: {0} Value {1}", header, req.getHeader(header)); }*/ GET_MAPPINGS.stream().filter(mapping -> endpointMatchesRequest(mapping.getMapping().endpoint(), requestPath)).forEach(mapping -> { diff --git a/src/main/java/dev/plex/request/PlayerActionServlet.java b/src/main/java/dev/plex/request/PlayerActionServlet.java index 3894e82..f2bf6a5 100644 --- a/src/main/java/dev/plex/request/PlayerActionServlet.java +++ b/src/main/java/dev/plex/request/PlayerActionServlet.java @@ -1,14 +1,11 @@ package dev.plex.request; -import dev.plex.Plex; +import dev.plex.HTTPDModule; +import dev.plex.api.player.PlexPlayerView; +import dev.plex.api.punishment.PunishmentRequest; +import dev.plex.api.punishment.PunishmentType; import dev.plex.authentication.AuthenticatedUser; -import dev.plex.cache.DataUtils; import dev.plex.logging.Log; -import dev.plex.player.PlexPlayer; -import dev.plex.punishment.Punishment; -import dev.plex.punishment.PunishmentType; -import dev.plex.util.BungeeUtil; -import dev.plex.util.TimeUtils; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; @@ -16,6 +13,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.inventory.PlayerInventory; +import net.kyori.adventure.text.Component; import java.io.IOException; import java.time.ZoneId; @@ -73,7 +71,7 @@ public class PlayerActionServlet extends HttpServlet return; } - PlexPlayer target = DataUtils.getPlayer(uuid); + PlexPlayerView target = HTTPDModule.plexApi().players().byUuid(uuid).orElse(null); if (target == null) { response.setStatus(HttpServletResponse.SC_NOT_FOUND); @@ -91,21 +89,25 @@ public class PlayerActionServlet extends HttpServlet if (safeReason.length() > 500) safeReason = safeReason.substring(0, 500); PunishmentType type = mapType(action); - ZonedDateTime now = ZonedDateTime.now(ZoneId.of(TimeUtils.TIMEZONE)); + ZonedDateTime now = ZonedDateTime.now(ZoneId.systemDefault()); ZonedDateTime endDate = TEMP_ACTIONS.contains(action) ? now.plusSeconds(parseDurationSeconds(durationStr)) : now.plusDays(FAR_FUTURE_DAYS); - Punishment punishment = new Punishment(uuid, null); - punishment.setType(type); - punishment.setReason(safeReason); - punishment.setPunishedUsername(target.getName()); - punishment.setPunisherName("xf:" + staff.username()); - punishment.setEndDate(endDate); - punishment.setCustomTime(TEMP_ACTIONS.contains(action)); - punishment.setActive(true); - List ips = target.getIps(); - if (ips != null && !ips.isEmpty()) punishment.setIp(ips.getLast()); + List ips = target.ips(); + String ip = ips == null || ips.isEmpty() ? "" : ips.getLast(); + PunishmentRequest punishment = new PunishmentRequest( + uuid, + null, + "xf:" + staff.username(), + ip, + target.name(), + type, + safeReason, + TEMP_ACTIONS.contains(action), + true, + endDate + ); String ipAddress = request.getRemoteAddr(); if ("127.0.0.1".equals(ipAddress)) @@ -113,15 +115,15 @@ public class PlayerActionServlet extends HttpServlet String forwarded = request.getHeader("X-FORWARDED-FOR"); if (forwarded != null) ipAddress = forwarded; } - Log.log(ipAddress + " (xf:" + staff.username() + ") issued " + action + " on " + target.getName() + " (" + uuid + ")"); + Log.log(ipAddress + " (xf:" + staff.username() + ") issued " + action + " on " + target.name() + " (" + uuid + ")"); final boolean kick = action.equals("ban") || action.equals("tempban"); - final Punishment toApply = punishment; - Bukkit.getScheduler().runTask(Plex.get(), () -> + final PunishmentRequest toApply = punishment; + HTTPDModule.plexApi().scheduler().runSync(() -> { try { - Plex.get().getPunishmentManager().punish(target, toApply); + HTTPDModule.plexApi().punishments().punish(target, toApply); } catch (Throwable t) { @@ -133,7 +135,7 @@ public class PlayerActionServlet extends HttpServlet Player online = Bukkit.getPlayer(uuid); if (online != null) { - try { BungeeUtil.kickPlayer(online, Punishment.generateBanMessage(toApply)); } + try { online.kick(Component.text("You have been banned: " + toApply.reason())); } catch (Throwable t) { t.printStackTrace(); } } } @@ -142,7 +144,7 @@ public class PlayerActionServlet extends HttpServlet response.sendRedirect("/player/" + uuid); } - private static void handleInventoryAction(HttpServletRequest request, HttpServletResponse response, AuthenticatedUser staff, UUID uuid, PlexPlayer target, String action, String slot) + private static void handleInventoryAction(HttpServletRequest request, HttpServletResponse response, AuthenticatedUser staff, UUID uuid, PlexPlayerView target, String action, String slot) throws IOException { String ipAddress = request.getRemoteAddr(); @@ -152,9 +154,9 @@ public class PlayerActionServlet extends HttpServlet if (forwarded != null) ipAddress = forwarded; } - Log.log(ipAddress + " (xf:" + staff.username() + ") issued " + action + " on " + target.getName() + " (" + uuid + ")" + (slot == null || slot.isBlank() ? "" : " slot " + slot)); + Log.log(ipAddress + " (xf:" + staff.username() + ") issued " + action + " on " + target.name() + " (" + uuid + ")" + (slot == null || slot.isBlank() ? "" : " slot " + slot)); - Bukkit.getScheduler().runTask(Plex.get(), () -> + HTTPDModule.plexApi().scheduler().runSync(() -> { Player online = Bukkit.getPlayer(uuid); if (online == null) return; diff --git a/src/main/java/dev/plex/request/SchematicUploadServlet.java b/src/main/java/dev/plex/request/SchematicUploadServlet.java index 71ab021..22fb978 100644 --- a/src/main/java/dev/plex/request/SchematicUploadServlet.java +++ b/src/main/java/dev/plex/request/SchematicUploadServlet.java @@ -5,7 +5,6 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import dev.plex.HTTPDModule; import dev.plex.authentication.AuthenticatedUser; import dev.plex.logging.Log; -import dev.plex.util.PlexLog; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; @@ -68,7 +67,7 @@ public class SchematicUploadServlet extends HttpServlet ClipboardFormat schematicFormat = ClipboardFormats.findByFile(schematicFile); if (schematicFormat == null) { - PlexLog.log(user.username() + " FAILED to upload schematic with filename: " + filename); + HTTPDModule.plexApi().logging().info(user.username() + " FAILED to upload schematic with filename: " + filename); Log.log("{0} (xf:{1}) FAILED to upload schematic {2}", user.username(), user.userId(), filename); response.getWriter().println(schematicUploadBadHTML("Schematic is not a valid format.")); FileUtils.deleteQuietly(schematicFile); @@ -80,7 +79,7 @@ public class SchematicUploadServlet extends HttpServlet } catch (IOException e) { - PlexLog.log(user.username() + " FAILED to upload schematic with filename: " + filename); + HTTPDModule.plexApi().logging().info(user.username() + " FAILED to upload schematic with filename: " + filename); Log.log("{0} (xf:{1}) FAILED to upload schematic {2}", user.username(), user.userId(), filename); response.getWriter().println(schematicUploadBadHTML("Schematic is not a valid format.")); FileUtils.deleteQuietly(schematicFile); @@ -88,7 +87,7 @@ public class SchematicUploadServlet extends HttpServlet } inputStream.close(); response.getWriter().println(schematicUploadGoodHTML("Successfully uploaded " + filename + ".")); - PlexLog.log(user.username() + " uploaded schematic with filename: " + filename); + HTTPDModule.plexApi().logging().info(user.username() + " uploaded schematic with filename: " + filename); Log.log("{0} (xf:{1}) uploaded schematic {2}", user.username(), user.userId(), filename); } diff --git a/src/main/java/dev/plex/request/impl/AuthenticationEndpoint.java b/src/main/java/dev/plex/request/impl/AuthenticationEndpoint.java index 495efd8..7a093a3 100644 --- a/src/main/java/dev/plex/request/impl/AuthenticationEndpoint.java +++ b/src/main/java/dev/plex/request/impl/AuthenticationEndpoint.java @@ -7,7 +7,6 @@ import dev.plex.authentication.OAuth2Provider; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; import dev.plex.request.MappingHeaders; -import dev.plex.util.PlexLog; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -64,7 +63,7 @@ public class AuthenticationEndpoint extends AbstractServlet } catch (AuthenticationException e) { - PlexLog.error("OAuth2 callback failed: " + e.getMessage()); + HTTPDModule.plexApi().logging().error("OAuth2 callback failed: " + e.getMessage()); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("text/html; charset=UTF-8"); return "Sign-in failed" diff --git a/src/main/java/dev/plex/request/impl/IndefBansEndpoint.java b/src/main/java/dev/plex/request/impl/IndefBansEndpoint.java index 15e62a0..63478a2 100644 --- a/src/main/java/dev/plex/request/impl/IndefBansEndpoint.java +++ b/src/main/java/dev/plex/request/impl/IndefBansEndpoint.java @@ -1,7 +1,7 @@ package dev.plex.request.impl; import com.google.gson.GsonBuilder; -import dev.plex.Plex; +import dev.plex.HTTPDModule; import dev.plex.authentication.AuthenticatedUser; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; @@ -20,7 +20,7 @@ public class IndefBansEndpoint extends AbstractServlet } response.setHeader("content-type", "application/json"); - return new GsonBuilder().setPrettyPrinting().create().toJson(Plex.get().getPunishmentManager().getIndefiniteBans().stream().toList()); + return new GsonBuilder().setPrettyPrinting().create().toJson(HTTPDModule.plexApi().punishments().indefiniteBans()); } private String indefbansHTML(String message) diff --git a/src/main/java/dev/plex/request/impl/IndefBansUIEndpoint.java b/src/main/java/dev/plex/request/impl/IndefBansUIEndpoint.java index 3e56a5b..5869e5e 100644 --- a/src/main/java/dev/plex/request/impl/IndefBansUIEndpoint.java +++ b/src/main/java/dev/plex/request/impl/IndefBansUIEndpoint.java @@ -1,8 +1,8 @@ package dev.plex.request.impl; -import dev.plex.Plex; +import dev.plex.HTTPDModule; import dev.plex.authentication.AuthenticatedUser; -import dev.plex.punishment.PunishmentManager.IndefiniteBan; +import dev.plex.api.punishment.IndefiniteBanView; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; import jakarta.servlet.http.HttpServletRequest; @@ -22,19 +22,19 @@ public class IndefBansUIEndpoint extends AbstractServlet return errorHTML(signInPrompt(request, "to view this page")); } - List bans = Plex.get().getPunishmentManager().getIndefiniteBans(); + List bans = HTTPDModule.plexApi().punishments().indefiniteBans(); return listHTML(bans); } - private String listHTML(List bans) + private String listHTML(List bans) { StringBuilder cards = new StringBuilder(); int totalUsers = 0, totalUuids = 0, totalIps = 0; - for (IndefiniteBan ban : bans) + for (IndefiniteBanView ban : bans) { - totalUsers += ban.getUsernames().size(); - totalUuids += ban.getUuids().size(); - totalIps += ban.getIps().size(); + totalUsers += ban.usernames().size(); + totalUuids += ban.uuids().size(); + totalIps += ban.ips().size(); cards.append(renderCard(ban)); } if (cards.length() == 0) @@ -55,26 +55,26 @@ public class IndefBansUIEndpoint extends AbstractServlet return file; } - private static String renderCard(IndefiniteBan ban) + private static String renderCard(IndefiniteBanView ban) { - String reason = (ban.getReason() == null || ban.getReason().isBlank()) + String reason = (ban.reason() == null || ban.reason().isBlank()) ? "No reason provided" - : escapeHtml(ban.getReason()); + : escapeHtml(ban.reason()); - int total = ban.getUsernames().size() + ban.getUuids().size() + ban.getIps().size(); + int total = ban.usernames().size() + ban.uuids().size() + ban.ips().size(); StringBuilder rows = new StringBuilder(); - if (!ban.getUsernames().isEmpty()) + if (!ban.usernames().isEmpty()) { - rows.append(renderRow("Users", "text-foreground/90 break-all", ban.getUsernames().stream().map(IndefBansUIEndpoint::escapeHtml).toList())); + rows.append(renderRow("Users", "text-foreground/90 break-all", ban.usernames().stream().map(IndefBansUIEndpoint::escapeHtml).toList())); } - if (!ban.getUuids().isEmpty()) + if (!ban.uuids().isEmpty()) { - rows.append(renderRow("UUIDs", "font-mono text-foreground/55 break-all", ban.getUuids().stream().map(UUID::toString).toList())); + rows.append(renderRow("UUIDs", "font-mono text-foreground/55 break-all", ban.uuids().stream().map(UUID::toString).toList())); } - if (!ban.getIps().isEmpty()) + if (!ban.ips().isEmpty()) { - rows.append(renderRow("IPs", "font-mono text-warning break-all", ban.getIps().stream().map(IndefBansUIEndpoint::escapeHtml).toList())); + rows.append(renderRow("IPs", "font-mono text-warning break-all", ban.ips().stream().map(IndefBansUIEndpoint::escapeHtml).toList())); } return """ diff --git a/src/main/java/dev/plex/request/impl/PlayerAdminEndpoint.java b/src/main/java/dev/plex/request/impl/PlayerAdminEndpoint.java index 3275bb6..5827816 100644 --- a/src/main/java/dev/plex/request/impl/PlayerAdminEndpoint.java +++ b/src/main/java/dev/plex/request/impl/PlayerAdminEndpoint.java @@ -1,8 +1,8 @@ package dev.plex.request.impl; +import dev.plex.HTTPDModule; +import dev.plex.api.player.PlexPlayerView; import dev.plex.authentication.AuthenticatedUser; -import dev.plex.cache.DataUtils; -import dev.plex.player.PlexPlayer; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; import jakarta.servlet.http.HttpServletRequest; @@ -39,36 +39,36 @@ public class PlayerAdminEndpoint extends AbstractServlet return errorPage("No player specified."); } - PlexPlayer player = lookupPlayer(query); + PlexPlayerView player = lookupPlayer(query); if (player == null) { return errorPage("No player found matching " + escapeHtml(query) + "."); } String file = readFile(this.getClass().getResourceAsStream("/httpd/player.html")); - file = file.replace("${player_uuid}", player.getUuid().toString()); - file = file.replace("${player_name}", escapeHtml(player.getName())); + file = file.replace("${player_uuid}", player.uuid().toString()); + file = file.replace("${player_name}", escapeHtml(player.name())); file = file.replace("${player_ip}", lastIp(player)); - file = file.replace("${player_first_played}", firstPlayed(player.getUuid())); - file = file.replace("${player_namemc}", "https://namemc.com/profile/" + player.getUuid()); + file = file.replace("${player_first_played}", firstPlayed(player.uuid())); + file = file.replace("${player_namemc}", "https://namemc.com/profile/" + player.uuid()); return file; } - private static PlexPlayer lookupPlayer(String query) + private static PlexPlayerView lookupPlayer(String query) { try { - return DataUtils.getPlayer(UUID.fromString(query)); + return HTTPDModule.plexApi().players().byUuid(UUID.fromString(query)).orElse(null); } catch (IllegalArgumentException ignored) { - return DataUtils.getPlayer(query); + return HTTPDModule.plexApi().players().byName(query).orElse(null); } } - private static String lastIp(PlexPlayer player) + private static String lastIp(PlexPlayerView player) { - List ips = player.getIps(); + List ips = player.ips(); if (ips == null || ips.isEmpty()) return ""; return escapeHtml(ips.getLast()); } diff --git a/src/main/java/dev/plex/request/impl/PlayerInventoryBroadcaster.java b/src/main/java/dev/plex/request/impl/PlayerInventoryBroadcaster.java index bf6532f..fed07e1 100644 --- a/src/main/java/dev/plex/request/impl/PlayerInventoryBroadcaster.java +++ b/src/main/java/dev/plex/request/impl/PlayerInventoryBroadcaster.java @@ -2,8 +2,6 @@ package dev.plex.request.impl; import com.google.gson.GsonBuilder; import dev.plex.HTTPDModule; -import dev.plex.Plex; -import dev.plex.util.PlexLog; import jakarta.servlet.AsyncContext; import org.bukkit.Bukkit; import org.bukkit.enchantments.Enchantment; @@ -29,7 +27,6 @@ import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; -import org.bukkit.plugin.Plugin; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.KeybindComponent; import net.kyori.adventure.text.ScoreComponent; @@ -87,12 +84,11 @@ public final class PlayerInventoryBroadcaster try { - refreshTask = Bukkit.getScheduler().runTaskTimer( - Plex.get(), this::tick, 0L, REFRESH_TICKS); + refreshTask = (BukkitTask)HTTPDModule.plexApi().scheduler().runTimer(this::tick, 0L, REFRESH_TICKS); } catch (Throwable t) { - PlexLog.debug("PlayerInventoryBroadcaster: could not register refresh task: " + t.getMessage()); + HTTPDModule.plexApi().logging().debug("PlayerInventoryBroadcaster: could not register refresh task: " + t.getMessage()); } try @@ -101,7 +97,7 @@ public final class PlayerInventoryBroadcaster } catch (Throwable t) { - PlexLog.debug("PlayerInventoryBroadcaster: NBT-API preload failed: " + t.getMessage()); + HTTPDModule.plexApi().logging().debug("PlayerInventoryBroadcaster: NBT-API preload failed: " + t.getMessage()); } } @@ -468,12 +464,7 @@ public final class PlayerInventoryBroadcaster private static Class nbtClass() throws ClassNotFoundException { - Plugin plugin = Bukkit.getPluginManager().getPlugin("NBTAPI"); - if (plugin == null || !plugin.isEnabled()) - { - throw new ClassNotFoundException("NBTAPI plugin is not enabled"); - } - return Class.forName("de.tr7zw.changeme.nbtapi.NBT", true, plugin.getClass().getClassLoader()); + return Class.forName("de.tr7zw.changeme.nbtapi.NBT", true, PlayerInventoryBroadcaster.class.getClassLoader()); } } diff --git a/src/main/java/dev/plex/request/impl/PlayersBroadcaster.java b/src/main/java/dev/plex/request/impl/PlayersBroadcaster.java index b692ccd..efacde0 100644 --- a/src/main/java/dev/plex/request/impl/PlayersBroadcaster.java +++ b/src/main/java/dev/plex/request/impl/PlayersBroadcaster.java @@ -2,8 +2,6 @@ package dev.plex.request.impl; import com.google.gson.GsonBuilder; import dev.plex.HTTPDModule; -import dev.plex.Plex; -import dev.plex.util.PlexLog; import jakarta.servlet.AsyncContext; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -76,21 +74,20 @@ public final class PlayersBroadcaster listener = new PlayersListener(); try { - Bukkit.getPluginManager().registerEvents(listener, Plex.get()); + HTTPDModule.plexApi().listeners().register(listener); } catch (Throwable t) { - PlexLog.debug("PlayersBroadcaster: could not register Bukkit listener: " + t.getMessage()); + HTTPDModule.plexApi().logging().debug("PlayersBroadcaster: could not register Bukkit listener: " + t.getMessage()); } try { - refreshTask = Bukkit.getScheduler().runTaskTimer( - Plex.get(), this::refreshAndBroadcast, 0L, REFRESH_TICKS); + refreshTask = (BukkitTask)HTTPDModule.plexApi().scheduler().runTimer(this::refreshAndBroadcast, 0L, REFRESH_TICKS); } catch (Throwable t) { - PlexLog.debug("PlayersBroadcaster: could not register refresh task: " + t.getMessage()); + HTTPDModule.plexApi().logging().debug("PlayersBroadcaster: could not register refresh task: " + t.getMessage()); } } @@ -216,7 +213,7 @@ public final class PlayersBroadcaster if (!refreshScheduled.compareAndSet(false, true)) return; try { - Bukkit.getScheduler().runTaskLater(Plex.get(), () -> + HTTPDModule.plexApi().scheduler().runLater(() -> { refreshScheduled.set(false); refreshAndBroadcast(); diff --git a/src/main/java/dev/plex/request/impl/PunishmentsEndpoint.java b/src/main/java/dev/plex/request/impl/PunishmentsEndpoint.java index 59a1d53..e5a0d63 100644 --- a/src/main/java/dev/plex/request/impl/PunishmentsEndpoint.java +++ b/src/main/java/dev/plex/request/impl/PunishmentsEndpoint.java @@ -1,9 +1,10 @@ package dev.plex.request.impl; import com.google.gson.GsonBuilder; +import dev.plex.HTTPDModule; +import dev.plex.api.player.PlexPlayerView; +import dev.plex.api.punishment.PunishmentView; import dev.plex.authentication.AuthenticatedUser; -import dev.plex.cache.DataUtils; -import dev.plex.player.PlexPlayer; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; import dev.plex.util.adapter.ZonedDateTimeAdapter; @@ -23,22 +24,22 @@ public class PunishmentsEndpoint extends AbstractServlet return readFile(this.getClass().getResourceAsStream("/httpd/punishments.html")); } - PlexPlayer punishedPlayer; + PlexPlayerView punishedPlayer; try { UUID pathUUID = UUID.fromString(request.getPathInfo().replace("/", "")); - punishedPlayer = DataUtils.getPlayer(pathUUID); + punishedPlayer = HTTPDModule.plexApi().players().byUuid(pathUUID).orElse(null); } catch (IllegalArgumentException ignored) { - punishedPlayer = DataUtils.getPlayer(request.getPathInfo().replace("/", "")); + punishedPlayer = HTTPDModule.plexApi().players().byName(request.getPathInfo().replace("/", "")).orElse(null); } if (punishedPlayer == null) { return punishmentsHTML("This player has never joined the server before."); } - if (punishedPlayer.getPunishments().isEmpty()) + if (punishedPlayer.punishments().isEmpty()) { return punishmentsGoodHTML("This player has been a good boy. They have no punishments!"); } @@ -47,9 +48,27 @@ public class PunishmentsEndpoint extends AbstractServlet response.setHeader("content-type", "application/json"); if (viewer == null) { - return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().peek(punishment -> punishment.setIp("")).toList()); + return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create().toJson(punishedPlayer.punishments().stream().map(PunishmentsEndpoint::hideIp).toList()); } - return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create().toJson(punishedPlayer.getPunishments().stream().toList()); + return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter()).setPrettyPrinting().create().toJson(punishedPlayer.punishments().stream().toList()); + } + + private static Object hideIp(PunishmentView punishment) + { + return new Object() + { + public final UUID punished = punishment.punished(); + public final UUID punisher = punishment.punisher(); + public final String punisherName = punishment.punisherName(); + public final String ip = ""; + public final String punishedUsername = punishment.punishedUsername(); + public final Object type = punishment.type(); + public final String reason = punishment.reason(); + public final boolean customTime = punishment.customTime(); + public final boolean active = punishment.active(); + public final ZonedDateTime issueDate = punishment.issueDate(); + public final ZonedDateTime endDate = punishment.endDate(); + }; } private String punishmentsHTML(String message) diff --git a/src/main/java/dev/plex/request/impl/PunishmentsUIEndpoint.java b/src/main/java/dev/plex/request/impl/PunishmentsUIEndpoint.java index f489a5f..0077bc3 100644 --- a/src/main/java/dev/plex/request/impl/PunishmentsUIEndpoint.java +++ b/src/main/java/dev/plex/request/impl/PunishmentsUIEndpoint.java @@ -1,9 +1,9 @@ package dev.plex.request.impl; -import dev.plex.cache.DataUtils; -import dev.plex.player.PlexPlayer; -import dev.plex.punishment.Punishment; -import dev.plex.punishment.PunishmentType; +import dev.plex.HTTPDModule; +import dev.plex.api.player.PlexPlayerView; +import dev.plex.api.punishment.PunishmentType; +import dev.plex.api.punishment.PunishmentView; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; import jakarta.servlet.http.HttpServletRequest; @@ -33,67 +33,67 @@ public class PunishmentsUIEndpoint extends AbstractServlet return readFile(this.getClass().getResourceAsStream("/httpd/punishments.html")); } - PlexPlayer punished = lookupPlayer(query); + PlexPlayerView punished = lookupPlayer(query); if (punished == null) { return errorHTML("No player found matching " + escapeHtml(query) + "."); } - List punishments = punished.getPunishments(); + List punishments = punished.punishments(); if (punishments == null || punishments.isEmpty()) { - return goodHTML(escapeHtml(punished.getName()) + " has no punishments on record."); + return goodHTML(escapeHtml(punished.name()) + " has no punishments on record."); } boolean showIps = currentStaff(request) != null; return resultsHTML(punished, punishments, showIps); } - private static PlexPlayer lookupPlayer(String query) + private static PlexPlayerView lookupPlayer(String query) { try { - return DataUtils.getPlayer(UUID.fromString(query)); + return HTTPDModule.plexApi().players().byUuid(UUID.fromString(query)).orElse(null); } catch (IllegalArgumentException ignored) { - return DataUtils.getPlayer(query); + return HTTPDModule.plexApi().players().byName(query).orElse(null); } } - private String resultsHTML(PlexPlayer player, List punishments, boolean showIps) + private String resultsHTML(PlexPlayerView player, List punishments, boolean showIps) { StringBuilder cards = new StringBuilder(); - for (Punishment p : punishments) + for (PunishmentView p : punishments) { cards.append(renderCard(p, showIps)); } String file = readFile(this.getClass().getResourceAsStream("/httpd/punishments_results.html")); - file = file.replace("${player_name}", escapeHtml(player.getName())); - file = file.replace("${player_uuid}", player.getUuid().toString()); + file = file.replace("${player_name}", escapeHtml(player.name())); + file = file.replace("${player_uuid}", player.uuid().toString()); file = file.replace("${punishment_count}", String.valueOf(punishments.size())); file = file.replace("${punishment_label}", punishments.size() == 1 ? "punishment" : "punishments"); file = file.replace("${punishments}", cards.toString()); return file; } - private static String renderCard(Punishment p, boolean showIps) + private static String renderCard(PunishmentView p, boolean showIps) { - PunishmentType type = p.getType(); + PunishmentType type = p.type(); String typeName = type == null ? "UNKNOWN" : type.name(); String accent = accentFor(type); - String rawReason = (p.getReason() == null || p.getReason().isBlank()) ? "" : p.getReason(); + String rawReason = (p.reason() == null || p.reason().isBlank()) ? "" : p.reason(); String reason = rawReason.isEmpty() ? "No reason provided" : escapeHtml(rawReason); String punisher = resolvePunisher(p); - String endDate = p.getEndDate() == null ? "permanent" : escapeHtml(formatDate(p.getEndDate())); + String endDate = p.endDate() == null ? "permanent" : escapeHtml(formatDate(p.endDate())); boolean isBan = type == PunishmentType.BAN || type == PunishmentType.TEMPBAN; String status = ""; String statusChip = ""; if (isBan) { - if (p.isActive()) + if (p.active()) { status = "active"; statusChip = "Active"; @@ -107,13 +107,13 @@ public class PunishmentsUIEndpoint extends AbstractServlet String ipRow = ""; String ipBlob = ""; - if (showIps && p.getIp() != null && !p.getIp().isBlank()) + if (showIps && p.ip() != null && !p.ip().isBlank()) { - ipBlob = p.getIp(); + ipBlob = p.ip(); ipRow = """
IP
%s
- """.formatted(escapeHtml(p.getIp())); + """.formatted(escapeHtml(p.ip())); } String searchBlob = escapeHtml((typeName + " " + rawReason + " " + punisher + " " + status + " " + ipBlob).toLowerCase()); @@ -148,17 +148,10 @@ public class PunishmentsUIEndpoint extends AbstractServlet }; } - private static String resolvePunisher(Punishment p) + private static String resolvePunisher(PunishmentView p) { - try - { - String name = Punishment.punisherDisplayName(p); - if (name != null && !name.isBlank()) return name; - } - catch (Throwable ignored) - { - } - UUID uuid = p.getPunisher(); + if (p.punisherName() != null && !p.punisherName().isBlank()) return p.punisherName(); + UUID uuid = p.punisher(); return uuid == null ? "CONSOLE" : uuid.toString(); } diff --git a/src/main/java/dev/plex/request/impl/SchematicDownloadEndpoint.java b/src/main/java/dev/plex/request/impl/SchematicDownloadEndpoint.java index 78b7281..006d126 100644 --- a/src/main/java/dev/plex/request/impl/SchematicDownloadEndpoint.java +++ b/src/main/java/dev/plex/request/impl/SchematicDownloadEndpoint.java @@ -5,7 +5,6 @@ import dev.plex.authentication.AuthenticatedUser; import dev.plex.logging.Log; import dev.plex.request.AbstractServlet; import dev.plex.request.GetMapping; -import dev.plex.util.PlexLog; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -76,7 +75,7 @@ public class SchematicDownloadEndpoint extends AbstractServlet { AuthenticatedUser user = currentUser(request); String who = user != null ? user.username() + " (xf:" + user.userId() + ")" : request.getRemoteAddr(); - PlexLog.log("{0} downloaded schematic {1}", who, schemFile.getName()); + HTTPDModule.plexApi().logging().info("{0} downloaded schematic {1}", who, schemFile.getName()); Log.log("{0} downloaded schematic {1}", who, schemFile.getName()); } @@ -119,7 +118,7 @@ public class SchematicDownloadEndpoint extends AbstractServlet { if (fileEntry.isDirectory()) { - PlexLog.debug("Found directory"); + HTTPDModule.plexApi().logging().debug("Found directory"); listFilesForFolder(fileEntry); } else diff --git a/src/main/java/dev/plex/request/impl/StatsBroadcaster.java b/src/main/java/dev/plex/request/impl/StatsBroadcaster.java index 03ba9ac..d3c265e 100644 --- a/src/main/java/dev/plex/request/impl/StatsBroadcaster.java +++ b/src/main/java/dev/plex/request/impl/StatsBroadcaster.java @@ -2,8 +2,6 @@ package dev.plex.request.impl; import com.google.gson.GsonBuilder; import dev.plex.HTTPDModule; -import dev.plex.Plex; -import dev.plex.util.PlexLog; import jakarta.servlet.AsyncContext; import org.bukkit.Bukkit; import org.bukkit.World; @@ -79,11 +77,11 @@ public final class StatsBroadcaster try { - bukkitTask = Bukkit.getScheduler().runTaskTimer(Plex.get(), this::sampleBukkit, 0L, 40L); + bukkitTask = (BukkitTask)HTTPDModule.plexApi().scheduler().runTimer(this::sampleBukkit, 0L, 40L); } catch (Throwable t) { - PlexLog.debug("StatsBroadcaster: could not register Bukkit sampling task: " + t.getMessage()); + HTTPDModule.plexApi().logging().debug("StatsBroadcaster: could not register Bukkit sampling task: " + t.getMessage()); } broadcastTask = executor.scheduleAtFixedRate(