From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Zach Brown <1254957+zachbr@users.noreply.github.com> Date: Mon, 27 May 2019 01:10:06 -0500 Subject: [PATCH] Version Command 2.0 diff --git a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java @@ -0,0 +0,0 @@ +package com.destroystokyo.paper.util; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; + +public interface VersionFetcher { + /** + * Amount of time to cache results for in milliseconds + *

+ * Negative values will never cache. + * + * @return cache time + */ + long getCacheTime(); + + /** + * Gets the version message to cache and show to command senders. + * + *

NOTE: This is run in a new thread separate from that of the command processing thread

+ * + * @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()}) + * @return the message to show when requesting a version + */ + @NotNull + Component getVersionMessage(@NotNull String serverVersion); + + class DummyVersionFetcher implements VersionFetcher { + + @Override + public long getCacheTime() { + return -1; + } + + @NotNull + @Override + public Component getVersionMessage(@NotNull String serverVersion) { + Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!"); + Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()"); + new Throwable().printStackTrace(); + return Component.text("Unable to check for updates. No version provider set.", NamedTextColor.RED); + } + } +} diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/UnsafeValues.java +++ b/src/main/java/org/bukkit/UnsafeValues.java @@ -0,0 +0,0 @@ public interface UnsafeValues { * @return name */ String getTimingsServerName(); + + /** + * Called once by the version command on first use, then cached. + */ + default com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { + return new com.destroystokyo.paper.util.VersionFetcher.DummyVersionFetcher(); + } // Paper end } diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java +++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java @@ -0,0 +0,0 @@ package org.bukkit.command.defaults; +import com.destroystokyo.paper.util.VersionFetcher; // Paper - version supplier import com.google.common.base.Charsets; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -0,0 +0,0 @@ import org.bukkit.util.StringUtil; import org.jetbrains.annotations.NotNull; public class VersionCommand extends BukkitCommand { + private VersionFetcher versionFetcher; + private VersionFetcher getVersionFetcher() { // lazy load because unsafe isn't available at command registration + if (versionFetcher == null) { + versionFetcher = Bukkit.getUnsafe().getVersionFetcher(); + } + + return versionFetcher; + } + public VersionCommand(@NotNull String name) { super(name); @@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand { if (!testPermission(sender)) return true; if (args.length == 0) { - sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")"); + //sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")"); // Paper - moved to setVersionMessage sendVersion(sender); } else { StringBuilder name = new StringBuilder(); @@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand { private final ReentrantLock versionLock = new ReentrantLock(); private boolean hasVersion = false; - private String versionMessage = null; + private net.kyori.adventure.text.Component versionMessage = null; // Paper private final Set versionWaiters = new HashSet(); private boolean versionTaskStarted = false; private long lastCheck = 0; private void sendVersion(@NotNull CommandSender sender) { if (hasVersion) { - if (System.currentTimeMillis() - lastCheck > 21600000) { + if (System.currentTimeMillis() - lastCheck > getVersionFetcher().getCacheTime()) { // Paper - use version supplier lastCheck = System.currentTimeMillis(); hasVersion = false; } else { @@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand { return; } versionWaiters.add(sender); - sender.sendMessage("Checking version, please wait..."); + sender.sendMessage(net.kyori.adventure.text.Component.text("Checking version, please wait...", net.kyori.adventure.text.format.NamedTextColor.WHITE, net.kyori.adventure.text.format.TextDecoration.ITALIC)); // Paper if (!versionTaskStarted) { versionTaskStarted = true; new Thread(new Runnable() { @@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand { private void obtainVersion() { String version = Bukkit.getVersion(); + // Paper start + if (version.startsWith("null")) { // running from ide? + setVersionMessage(net.kyori.adventure.text.Component.text("Unknown version, custom build?", net.kyori.adventure.text.format.NamedTextColor.YELLOW)); + return; + } + setVersionMessage(getVersionFetcher().getVersionMessage(version)); + /* if (version == null) version = "Custom"; String[] parts = version.substring(0, version.indexOf(' ')).split("-"); if (parts.length == 4) { @@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand { } else { setVersionMessage("Unknown version, custom build?"); } + */ + // Paper end } - private void setVersionMessage(@NotNull String msg) { + // Paper start + private void setVersionMessage(final @NotNull net.kyori.adventure.text.Component msg) { lastCheck = System.currentTimeMillis(); - versionMessage = msg; + final net.kyori.adventure.text.Component message = net.kyori.adventure.text.TextComponent.ofChildren( + net.kyori.adventure.text.Component.text("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")", net.kyori.adventure.text.format.NamedTextColor.WHITE), + net.kyori.adventure.text.Component.newline(), + msg + ); + this.versionMessage = net.kyori.adventure.text.Component.text() + .append(message) + .hoverEvent(net.kyori.adventure.text.Component.text("Click to copy to clipboard", net.kyori.adventure.text.format.NamedTextColor.WHITE)) + .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard(net.kyori.adventure.text.serializer.plain.PlainComponentSerializer.plain().serialize(message))) + .build(); + // Paper end versionLock.lock(); try { hasVersion = true;