aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/api/0014-Version-Command-2.0.patch
blob: d0f58fe0ab6df58031171ef76cb2955896bfd8f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach@zachbr.io>
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..a736d7bcdc5861a01b66ba36158db1c716339346
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
@@ -0,0 +1,45 @@
+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
+     * <p>
+     * Negative values will never cache.
+     *
+     * @return cache time
+     */
+    long getCacheTime();
+
+    /**
+     * Gets the version message to cache and show to command senders.
+     *
+     * <p>NOTE: This is run in a new thread separate from that of the command processing thread</p>
+     *
+     * @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 f68ef89f37057cf677a767026ab395f7a839a2f9..a6aa33b9574d0278e10927007a62290e1d102e73 100644
--- a/src/main/java/org/bukkit/UnsafeValues.java
+++ b/src/main/java/org/bukkit/UnsafeValues.java
@@ -119,5 +119,12 @@ 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 04b4fb6859df0221f8f9f92c5a7ac2dda1073355..b50f614806f4634960d383e8a33f094c2f46935f 100644
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
@@ -1,5 +1,6 @@
 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;
@@ -26,6 +27,15 @@ 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);
 
@@ -40,7 +50,7 @@ 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();
@@ -146,14 +156,14 @@ 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<CommandSender> versionWaiters = new HashSet<CommandSender>();
     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 {
@@ -168,7 +178,7 @@ 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() {
@@ -186,6 +196,13 @@ 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) {
@@ -215,11 +232,24 @@ 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;