From f1924ad2474e39a1c31fd9eaa73d8cf68747ae18 Mon Sep 17 00:00:00 2001 From: Kyle Wood Date: Thu, 1 Mar 2018 19:57:22 -0600 Subject: [PATCH] Track previous version and report in command It is often difficult to diagnose new issues server admins get when upgrading to a new server version because the only information they are able to tell us regarding the server version they are running is "latest". This commit attempts to mitigate this by keeping track of the previous version of Paper they were running, which is then reported by the `/version` or `/paper version` command. This gives us a better idea of the commits included in the upgrade, which may help diagnose new issues easier. --- ...d-version-history-to-version-command.patch | 199 ++++++++++++++++++ ...Load-version-history-at-server-start.patch | 19 ++ 2 files changed, 218 insertions(+) create mode 100644 Spigot-API-Patches/Add-version-history-to-version-command.patch create mode 100644 Spigot-Server-Patches/Load-version-history-at-server-start.patch diff --git a/Spigot-API-Patches/Add-version-history-to-version-command.patch b/Spigot-API-Patches/Add-version-history-to-version-command.patch new file mode 100644 index 0000000000..4895de410a --- /dev/null +++ b/Spigot-API-Patches/Add-version-history-to-version-command.patch @@ -0,0 +1,199 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kyle Wood +Date: Thu, 1 Mar 2018 19:37:52 -0600 +Subject: [PATCH] Add version history to version command + + +diff --git a/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java b/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java +new file mode 100644 +index 00000000..1daaca2f +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/VersionHistoryManager.java +@@ -0,0 +0,0 @@ ++package com.destroystokyo.paper; ++ ++import com.google.common.base.MoreObjects; ++import com.google.gson.Gson; ++import com.google.gson.JsonSyntaxException; ++import java.io.BufferedReader; ++import java.io.BufferedWriter; ++import java.io.IOException; ++import java.nio.charset.StandardCharsets; ++import java.nio.file.Files; ++import java.nio.file.Path; ++import java.nio.file.Paths; ++import java.nio.file.StandardOpenOption; ++import java.util.Objects; ++import java.util.logging.Level; ++import java.util.logging.Logger; ++import javax.annotation.Nullable; ++import org.bukkit.Bukkit; ++ ++public enum VersionHistoryManager { ++ INSTANCE; ++ ++ private final Gson gson = new Gson(); ++ ++ private final Logger logger = Bukkit.getLogger(); ++ ++ private VersionData currentData = null; ++ ++ VersionHistoryManager() { ++ final Path path = Paths.get("version_history.json"); ++ ++ if (Files.exists(path)) { ++ // Basic file santiy checks ++ if (!Files.isRegularFile(path)) { ++ if (Files.isDirectory(path)) { ++ logger.severe(path + " is a directory, cannot be used for version history"); ++ } else { ++ logger.severe(path + " is not a regular file, cannot be used for version history"); ++ } ++ // We can't continue ++ return; ++ } ++ ++ try (final BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { ++ currentData = gson.fromJson(reader, VersionData.class); ++ } catch (final IOException e) { ++ logger.log(Level.SEVERE, "Failed to read version history file '" + path + "'", e); ++ return; ++ } catch (final JsonSyntaxException e) { ++ logger.log(Level.SEVERE, "Invalid json syntax for file '" + path + "'", e); ++ return; ++ } ++ ++ final String version = Bukkit.getVersion(); ++ if (version == null) { ++ logger.severe("Failed to retrieve current version"); ++ return; ++ } ++ ++ if (!version.equals(currentData.getCurrentVersion())) { ++ // The version appears to have changed ++ currentData.setOldVersion(currentData.getCurrentVersion()); ++ currentData.setCurrentVersion(version); ++ writeFile(path); ++ } ++ } else { ++ // File doesn't exist, start fresh ++ currentData = new VersionData(); ++ // oldVersion is null ++ currentData.setCurrentVersion(Bukkit.getVersion()); ++ writeFile(path); ++ } ++ } ++ ++ private void writeFile(final Path path) { ++ try (final BufferedWriter writer = Files.newBufferedWriter( ++ path, ++ StandardCharsets.UTF_8, ++ StandardOpenOption.WRITE, ++ StandardOpenOption.CREATE, ++ StandardOpenOption.TRUNCATE_EXISTING ++ )) { ++ gson.toJson(currentData, writer); ++ } catch (final IOException e) { ++ logger.log(Level.SEVERE, "Failed to write to version history file", e); ++ } ++ } ++ ++ @Nullable ++ public VersionData getVersionData() { ++ return currentData; ++ } ++ ++ public class VersionData { ++ private String oldVersion; ++ ++ private String currentVersion; ++ ++ @Nullable ++ public String getOldVersion() { ++ return oldVersion; ++ } ++ ++ public void setOldVersion(@Nullable String oldVersion) { ++ this.oldVersion = oldVersion; ++ } ++ ++ @Nullable ++ public String getCurrentVersion() { ++ return currentVersion; ++ } ++ ++ public void setCurrentVersion(@Nullable String currentVersion) { ++ this.currentVersion = currentVersion; ++ } ++ ++ @Override ++ public String toString() { ++ return MoreObjects.toStringHelper(this) ++ .add("oldVersion", oldVersion) ++ .add("currentVersion", currentVersion) ++ .toString(); ++ } ++ ++ @Override ++ public boolean equals(Object o) { ++ if (this == o) { ++ return true; ++ } ++ if (o == null || getClass() != o.getClass()) { ++ return false; ++ } ++ final VersionData versionData = (VersionData) o; ++ return Objects.equals(oldVersion, versionData.oldVersion) && ++ Objects.equals(currentVersion, versionData.currentVersion); ++ } ++ ++ @Override ++ public int hashCode() { ++ return Objects.hash(oldVersion, currentVersion); ++ } ++ } ++} +diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java +index 044361af..c45faf4c 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 @@ import org.json.simple.parser.ParseException; + // Paper start + import java.io.InputStreamReader; + import java.net.HttpURLConnection; ++import com.destroystokyo.paper.VersionHistoryManager; + // Paper end + + public class VersionCommand extends BukkitCommand { +@@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand { + + if (args.length == 0) { + sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")"); ++ tellHistory(sender); // Paper + sendVersion(sender); + } else { + StringBuilder name = new StringBuilder(); +@@ -0,0 +0,0 @@ public class VersionCommand extends BukkitCommand { + return true; + } + ++ // Paper start - show version history ++ private void tellHistory(final CommandSender sender) { ++ final VersionHistoryManager.VersionData data = VersionHistoryManager.INSTANCE.getVersionData(); ++ if (data == null) { ++ return; ++ } ++ ++ final String oldVersion = data.getOldVersion(); ++ if (oldVersion == null) { ++ return; ++ } ++ ++ sender.sendMessage("Previous version: " + oldVersion); ++ } ++ // Paper end ++ + private void describeToSender(Plugin plugin, CommandSender sender) { + PluginDescriptionFile desc = plugin.getDescription(); + sender.sendMessage(ChatColor.GREEN + desc.getName() + ChatColor.WHITE + " version " + ChatColor.GREEN + desc.getVersion()); +-- \ No newline at end of file diff --git a/Spigot-Server-Patches/Load-version-history-at-server-start.patch b/Spigot-Server-Patches/Load-version-history-at-server-start.patch new file mode 100644 index 0000000000..b85701b72a --- /dev/null +++ b/Spigot-Server-Patches/Load-version-history-at-server-start.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kyle Wood +Date: Thu, 1 Mar 2018 19:38:14 -0600 +Subject: [PATCH] Load version history at server start + + +diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java +index 85445571..39a3d46f 100644 +--- a/src/main/java/net/minecraft/server/DedicatedServer.java ++++ b/src/main/java/net/minecraft/server/DedicatedServer.java +@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + // Paper start + com.destroystokyo.paper.PaperConfig.init((File) options.valueOf("paper-settings")); + com.destroystokyo.paper.PaperConfig.registerCommands(); ++ com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now + // Paper end + + DedicatedServer.LOGGER.info("Generating keypair"); +-- \ No newline at end of file