diff --git a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/RootCommand.java b/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/RootCommand.java index a63fc93..4698b12 100644 --- a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/RootCommand.java +++ b/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/RootCommand.java @@ -1,7 +1,6 @@ package io.github.silentdevelopment.headdb.paper.command; import io.github.silentdevelopment.headdb.paper.HeadDBPlugin; -import io.github.silentdevelopment.headdb.paper.command.format.RootFormatter; import io.github.silentdevelopment.headdb.paper.command.subcommand.CategoriesCommand; import io.github.silentdevelopment.headdb.paper.command.subcommand.CollectionsCommand; import io.github.silentdevelopment.headdb.paper.command.subcommand.PlayerCommand; @@ -28,7 +27,6 @@ import io.github.silentdevelopment.relay.core.command.builder.CommandBuilder; import io.github.silentdevelopment.relay.paper.command.AbstractPaperCommandGroup; import io.github.silentdevelopment.relay.paper.command.context.PaperCommandContext; -import net.kyori.adventure.text.Component; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -85,11 +83,7 @@ protected void handle(@NotNull PaperCommandContext context) { return; } - CommandSender sender = context.source(); - - for (Component line : RootFormatter.format(plugin, context.sender())) { - plugin.messages().send(sender, line); - } + VersionCommand.send(plugin, context.sender()); } @Override diff --git a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/format/RootFormatter.java b/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/format/RootFormatter.java deleted file mode 100644 index 7c34f0e..0000000 --- a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/format/RootFormatter.java +++ /dev/null @@ -1,183 +0,0 @@ -package io.github.silentdevelopment.headdb.paper.command.format; - -import io.github.silentdevelopment.headdb.paper.HeadDBPlugin; -import io.github.silentdevelopment.headdb.paper.permission.Permissions; -import io.github.silentdevelopment.headdb.paper.runtime.BuildInfo; -import io.papermc.paper.plugin.configuration.PluginMeta; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public final class RootFormatter { - - private static final String HEADDB_URL = "https://github.com/SilentDevelopment/HeadDB"; - private static final String SILENT_DEVELOPMENT_URL = "https://github.com/SilentDevelopment"; - private static final String THE_SILENT_PRO_URL = "https://github.com/TheSilentPro"; - - private RootFormatter() { - } - - public static @NotNull List format(@NotNull HeadDBPlugin plugin, @NotNull CommandSender sender) { - Objects.requireNonNull(plugin, "plugin"); - Objects.requireNonNull(sender, "sender"); - - PluginMeta description = plugin.getPluginMeta(); - BuildInfo buildInfo = BuildInfo.read(plugin); - - List lines = new ArrayList<>(); - - lines.add(Component.empty()); - lines.add(runningLine(description, buildInfo)); - lines.add(Component.empty()); - lines.add(helpLine()); - - if (sender.hasPermission(Permissions.ADMIN)) { - lines.add(Component.empty()); - lines.add(section("Build")); - lines.add(field("Version", buildInfo.version())); - lines.add(field("Build", buildInfo.displayBuild())); - lines.add(field("Channel", buildInfo.channel())); - lines.add(field("Run ID", valueOrUnavailable(buildInfo.runId()))); - lines.add(field("Commit", valueOrUnavailable(buildInfo.commit()))); - lines.add(field("Full commit", valueOrUnavailable(buildInfo.fullCommit()))); - lines.add(field("Branch", valueOrUnavailable(buildInfo.branch()))); - lines.add(field("Timestamp", valueOrUnavailable(buildInfo.buildTime()))); - } - - Component buttons = actionButtons(sender); - if (!buttons.equals(Component.empty())) { - lines.add(Component.empty()); - lines.add(buttons); - } - - lines.add(Component.empty()); - - return List.copyOf(lines); - } - - private static @NotNull Component runningLine( - @NotNull PluginMeta meta, - @NotNull BuildInfo buildInfo - ) { - return Component.text("Running ", NamedTextColor.GRAY) - .append(link( - meta.getName() + " " + buildInfo.version(), - HEADDB_URL, - "Open on GitHub", - NamedTextColor.GOLD - )) - .append(Component.text(" by ", NamedTextColor.GRAY)) - .append(link( - "SilentDevelopment", - SILENT_DEVELOPMENT_URL, - "Open on GitHub", - NamedTextColor.GOLD - )) - .append(Component.text(" / ", NamedTextColor.DARK_GRAY)) - .append(link( - "TheSilentPro", - THE_SILENT_PRO_URL, - "Open on GitHub", - NamedTextColor.GOLD - )); - } - - private static @NotNull Component section(@NotNull String title) { - return Component.text(" > ", NamedTextColor.DARK_GRAY) - .append(Component.text(title, NamedTextColor.GOLD)); - } - - private static @NotNull Component field(@NotNull String key, @NotNull String value) { - return Component.text(" ") - .append(Component.text(key + ": ", NamedTextColor.GRAY)) - .append(Component.text(value, NamedTextColor.GOLD)); - } - - private static @NotNull Component helpLine() { - return Component.text(" > ", NamedTextColor.DARK_GRAY) - .append(Component.text("Run ", NamedTextColor.GRAY)) - .append(Component.text("/hdb help", NamedTextColor.GOLD) - .clickEvent(ClickEvent.suggestCommand("/hdb help")) - .hoverEvent(HoverEvent.showText(Component.text("Click to suggest /hdb help", NamedTextColor.GRAY)))) - .append(Component.text(" for command information.", NamedTextColor.GRAY)); - } - - private static @NotNull Component actionButtons(@NotNull CommandSender sender) { - List buttons = new ArrayList<>(); - - if (Permissions.has(sender, Permissions.RELOAD)) { - buttons.add(button("RELOAD", "/hdb reload", "Reload config, messages, and runtime.")); - } - - if (Permissions.has(sender, Permissions.VERIFY)) { - buttons.add(button("VERIFY", "/hdb verify", "Verify the remote database without replacing the active database.")); - } - - if (Permissions.has(sender, Permissions.REFRESH)) { - buttons.add(button("REFRESH", "/hdb refresh", "Fetch the latest remote head database.")); - } - - if (Permissions.has(sender, Permissions.STATUS)) { - buttons.add(button("STATUS", "/hdb status", "Show database and refresh status.")); - } - - if (Permissions.has(sender, Permissions.DEBUG)) { - buttons.add(button("DEBUG", "/hdb debug", "Show detailed runtime diagnostics.")); - } - - if (buttons.isEmpty()) { - return Component.empty(); - } - - Component result = buttons.getFirst(); - - for (int index = 1; index < buttons.size(); index++) { - result = result.append(divider()) - .append(buttons.get(index)); - } - - return result; - } - - private static @NotNull Component button( - @NotNull String label, - @NotNull String command, - @NotNull String hover - ) { - return Component.text("[ ", NamedTextColor.DARK_GRAY) - .append(Component.text(label, NamedTextColor.GOLD) - .clickEvent(ClickEvent.runCommand(command)) - .hoverEvent(HoverEvent.showText(Component.text(hover, NamedTextColor.GRAY)))) - .append(Component.text(" ]", NamedTextColor.DARK_GRAY)); - } - - private static @NotNull Component divider() { - return Component.text(" · ", NamedTextColor.DARK_GRAY); - } - - private static @NotNull Component link( - @NotNull String text, - @NotNull String url, - @NotNull String hover, - @NotNull NamedTextColor color - ) { - return Component.text(text, color) - .clickEvent(ClickEvent.openUrl(url)) - .hoverEvent(HoverEvent.showText(Component.text(hover, NamedTextColor.GRAY))); - } - - private static @NotNull String valueOrUnavailable(String value) { - if (value == null || value.isBlank()) { - return "unavailable"; - } - - return value; - } -} diff --git a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/format/VersionFormatter.java b/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/format/VersionFormatter.java index 2f39a63..3fbfebe 100644 --- a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/format/VersionFormatter.java +++ b/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/format/VersionFormatter.java @@ -1,13 +1,15 @@ package io.github.silentdevelopment.headdb.paper.command.format; import io.github.silentdevelopment.headdb.paper.HeadDBPlugin; +import io.github.silentdevelopment.headdb.paper.permission.Permissions; import io.github.silentdevelopment.headdb.paper.runtime.BuildInfo; -import io.github.silentdevelopment.headdb.paper.updater.GitHubRelease; import io.github.silentdevelopment.headdb.paper.updater.UpdateCheckResult; +import io.papermc.paper.plugin.configuration.PluginMeta; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,6 +19,11 @@ public final class VersionFormatter { + private static final String HEADDB_URL = "https://github.com/SilentDevelopment/HeadDB"; + private static final String SILENT_DEVELOPMENT_URL = "https://github.com/SilentDevelopment"; + private static final String THE_SILENT_PRO_URL = "https://github.com/TheSilentPro"; + private static final String SUPPORT_URL = "https://support.headsdb.com"; + private VersionFormatter() { throw new UnsupportedOperationException("This class cannot be instantiated."); } @@ -34,9 +41,10 @@ private VersionFormatter() { lines.add(Component.empty()); lines.add(Component.empty()); - lines.add(runningLine(plugin)); + lines.add(startupRunningLine(plugin)); lines.add(Component.empty()); lines.add(versionLine(buildInfo.version(), updateResult)); + lines.add(supportLine()); if (plugin.config().isDebug()) { lines.add(field("Build", buildInfo.displayBuild())); @@ -51,33 +59,43 @@ private VersionFormatter() { return joinLines(lines); } - public static @NotNull List command(@NotNull HeadDBPlugin plugin) { + public static @NotNull List command(@NotNull HeadDBPlugin plugin, @NotNull CommandSender sender) { Objects.requireNonNull(plugin, "plugin"); + Objects.requireNonNull(sender, "sender"); + PluginMeta meta = plugin.getPluginMeta(); BuildInfo buildInfo = BuildInfo.read(plugin); - UpdateCheckResult updateResult = plugin.updater().lastResult(); List lines = new ArrayList<>(); lines.add(Component.empty()); - lines.add(runningLine(plugin)); - lines.add(versionLine(buildInfo.version(), updateResult)); - lines.add(field("Build", buildInfo.displayBuild())); - lines.add(field("Branch", value(buildInfo.branch()))); - lines.add(field("Commit", value(buildInfo.commit()))); - lines.add(field("Timestamp", value(buildInfo.buildTime()))); + lines.add(commandRunningLine(meta, buildInfo)); + lines.add(Component.empty()); + lines.add(helpLine()); - Component actions = updateActions(updateResult); + if (sender.hasPermission(Permissions.ADMIN)) { + lines.add(Component.empty()); + lines.add(section("Build")); + lines.add(indentedField("Version", buildInfo.version())); + lines.add(indentedField("Build", buildInfo.displayBuild())); + lines.add(indentedField("Channel", buildInfo.channel())); + lines.add(indentedField("Run ID", valueOrUnavailable(buildInfo.runId()))); + lines.add(indentedField("Commit", valueOrUnavailable(buildInfo.commit()))); + lines.add(indentedField("Full commit", valueOrUnavailable(buildInfo.fullCommit()))); + lines.add(indentedField("Branch", valueOrUnavailable(buildInfo.branch()))); + lines.add(indentedField("Timestamp", valueOrUnavailable(buildInfo.buildTime()))); + } - if (actions != null) { + Component buttons = actionButtons(sender); + if (!buttons.equals(Component.empty())) { lines.add(Component.empty()); - lines.add(actions); + lines.add(buttons); } lines.add(Component.empty()); return List.copyOf(lines); } - private static @NotNull Component runningLine(@NotNull HeadDBPlugin plugin) { + private static @NotNull Component startupRunningLine(@NotNull HeadDBPlugin plugin) { List authors = plugin.getPluginMeta().getAuthors(); String authorText = authors.isEmpty() ? "Unknown" : String.join(", ", authors); @@ -87,6 +105,30 @@ private VersionFormatter() { .append(Component.text(authorText, NamedTextColor.GOLD)); } + private static @NotNull Component commandRunningLine(@NotNull PluginMeta meta, @NotNull BuildInfo buildInfo) { + return Component.text("Running ", NamedTextColor.GRAY) + .append(link( + meta.getName() + " " + buildInfo.version(), + HEADDB_URL, + "Open on GitHub", + NamedTextColor.GOLD + )) + .append(Component.text(" by ", NamedTextColor.GRAY)) + .append(link( + "SilentDevelopment", + SILENT_DEVELOPMENT_URL, + "Open on GitHub", + NamedTextColor.GOLD + )) + .append(Component.text(" / ", NamedTextColor.DARK_GRAY)) + .append(link( + "TheSilentPro", + THE_SILENT_PRO_URL, + "Open on GitHub", + NamedTextColor.GOLD + )); + } + private static @NotNull Component versionLine( @NotNull String version, @Nullable UpdateCheckResult updateResult @@ -114,32 +156,99 @@ private VersionFormatter() { return Component.text("Latest", NamedTextColor.GOLD); } + private static @NotNull Component supportLine() { + return Component.text("Donate: ", NamedTextColor.GRAY) + .append(Component.text("support.headsdb.com", NamedTextColor.GOLD) + .clickEvent(ClickEvent.openUrl(SUPPORT_URL)) + .hoverEvent(HoverEvent.showText(Component.text("Support HeadDB", NamedTextColor.GRAY)))); + } + + private static @NotNull Component section(@NotNull String title) { + return Component.text(" > ", NamedTextColor.DARK_GRAY) + .append(Component.text(title, NamedTextColor.GOLD)); + } + private static @NotNull Component field(@NotNull String key, @NotNull String value) { - return Component.text(key + ": ", NamedTextColor.GRAY).append(Component.text(value, NamedTextColor.GOLD)); + return Component.text(key + ": ", NamedTextColor.GRAY) + .append(Component.text(value, NamedTextColor.GOLD)); + } + + private static @NotNull Component indentedField(@NotNull String key, @NotNull String value) { + return Component.text(" ") + .append(Component.text(key + ": ", NamedTextColor.GRAY)) + .append(Component.text(value, NamedTextColor.GOLD)); + } + + private static @NotNull Component helpLine() { + return Component.text(" > ", NamedTextColor.DARK_GRAY) + .append(Component.text("Run ", NamedTextColor.GRAY)) + .append(Component.text("/hdb help", NamedTextColor.GOLD) + .clickEvent(ClickEvent.suggestCommand("/hdb help")) + .hoverEvent(HoverEvent.showText(Component.text("Click to suggest /hdb help", NamedTextColor.GRAY)))) + .append(Component.text(" for command information.", NamedTextColor.GRAY)); } - private static @Nullable Component updateActions(@Nullable UpdateCheckResult updateResult) { - if (updateResult == null || !updateResult.updateAvailable()) { - return null; + private static @NotNull Component actionButtons(@NotNull CommandSender sender) { + List buttons = new ArrayList<>(); + + if (Permissions.has(sender, Permissions.RELOAD)) { + buttons.add(button("RELOAD", "/hdb reload", "Reload config, messages, and runtime.")); + } + + if (Permissions.has(sender, Permissions.VERIFY)) { + buttons.add(button("VERIFY", "/hdb verify", "Verify the remote database without replacing the active database.")); + } + + if (Permissions.has(sender, Permissions.REFRESH)) { + buttons.add(button("REFRESH", "/hdb refresh", "Fetch the latest remote head database.")); + } + + if (Permissions.has(sender, Permissions.STATUS)) { + buttons.add(button("STATUS", "/hdb status", "Show database and refresh status.")); } - GitHubRelease release = updateResult.release(); + if (Permissions.has(sender, Permissions.DEBUG)) { + buttons.add(button("DEBUG", "/hdb debug", "Show detailed runtime diagnostics.")); + } - if (release == null) { - return null; + if (buttons.isEmpty()) { + return Component.empty(); } - Component open = Component.text("[OPEN]", NamedTextColor.GOLD) - .clickEvent(ClickEvent.openUrl(release.htmlUrl())) - .hoverEvent(HoverEvent.showText(Component.text("Open the release page.", NamedTextColor.GRAY))); + Component result = buttons.getFirst(); - Component update = Component.text("[UPDATE]", NamedTextColor.GOLD) - .clickEvent(ClickEvent.runCommand("/hdb update")) - .hoverEvent(HoverEvent.showText(Component.text("Download and install this update.", NamedTextColor.GRAY))); + for (int index = 1; index < buttons.size(); index++) { + result = result.append(divider()).append(buttons.get(index)); + } - return open - .append(Component.text(" -=- ", NamedTextColor.GRAY)) - .append(update); + return result; + } + + private static @NotNull Component button( + @NotNull String label, + @NotNull String command, + @NotNull String hover + ) { + return Component.text("[ ", NamedTextColor.DARK_GRAY) + .append(Component.text(label, NamedTextColor.GOLD) + .clickEvent(ClickEvent.runCommand(command)) + .hoverEvent(HoverEvent.showText(Component.text(hover, NamedTextColor.GRAY)))) + .append(Component.text(" ]", NamedTextColor.DARK_GRAY)); + } + + private static @NotNull Component divider() { + return Component.text(" · ", NamedTextColor.DARK_GRAY); + } + + private static @NotNull Component link( + @NotNull String text, + @NotNull String url, + @NotNull String hover, + @NotNull NamedTextColor color + ) { + return Component.text(text, color) + .clickEvent(ClickEvent.openUrl(url)) + .hoverEvent(HoverEvent.showText(Component.text(hover, NamedTextColor.GRAY))); } private static @NotNull Component joinLines(@NotNull List lines) { @@ -163,4 +272,12 @@ private VersionFormatter() { return value; } + + private static @NotNull String valueOrUnavailable(@Nullable String value) { + if (value == null || value.isBlank()) { + return "unavailable"; + } + + return value; + } } diff --git a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/subcommand/VersionCommand.java b/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/subcommand/VersionCommand.java index 0d4efb0..70f922f 100644 --- a/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/subcommand/VersionCommand.java +++ b/headdb-platforms/headdb-paper/src/main/java/io/github/silentdevelopment/headdb/paper/command/subcommand/VersionCommand.java @@ -9,6 +9,7 @@ import io.github.silentdevelopment.relay.paper.command.PaperCommands; import io.github.silentdevelopment.relay.paper.command.context.PaperCommandContext; import net.kyori.adventure.text.Component; +import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.util.Objects; @@ -23,8 +24,15 @@ public VersionCommand(@NotNull HeadDBPlugin plugin) { @Override protected void handle(@NotNull PaperCommandContext context) { - for (Component line : VersionFormatter.command(plugin)) { - plugin.messages().send(context.sender(), line); + send(plugin, context.sender()); + } + + public static void send(@NotNull HeadDBPlugin plugin, @NotNull CommandSender sender) { + Objects.requireNonNull(plugin, "plugin"); + Objects.requireNonNull(sender, "sender"); + + for (Component line : VersionFormatter.command(plugin, sender)) { + plugin.messages().send(sender, line); } }