From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Professor Bloodstone Date: Sun, 20 Jun 2021 01:48:31 +0200 Subject: [PATCH] Add Git information to version command/on startup diff --git a/src/main/java/io/papermc/paper/util/JarManifests.java b/src/main/java/io/papermc/paper/util/JarManifests.java new file mode 100644 index 0000000000000000000000000000000000000000..02ad04c41b9c3ec68b1dcdc22c538340d8d3455b --- /dev/null +++ b/src/main/java/io/papermc/paper/util/JarManifests.java @@ -0,0 +1,93 @@ +/* +Copyright (c) 2012-2017, jcabi.com +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: 1) Redistributions of source code must retain the above +copyright notice, this list of conditions and the following +disclaimer. 2) Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided +with the distribution. 3) Neither the name of the jcabi.com nor +the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +package io.papermc.paper.util; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.*; +import java.util.jar.Manifest; +import org.jetbrains.annotations.NotNull; + +/** + * Modified version of jcabi-manifests + * + */ +public final class JarManifests { + + public static final JarManifests JAR_MANIFESTS = new JarManifests(); + public static final Map MANIFEST_MAP; + + static { + try { + MANIFEST_MAP = Collections.unmodifiableMap(JAR_MANIFESTS.getManifestMap()); + } catch (final IOException ex) { + throw new RuntimeException(ex); + } + } + + private JarManifests() {} + + // Based on: + // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/ClasspathMfs.java#L49-L58 + + /** + * Get collection containing all META-INF/MANIFEST.MF streams + * + * @throws IOException if unable to get resources from classloader + */ + public @NotNull Collection<@NotNull InputStream> getManifestStreams() throws IOException { + final Enumeration resources = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); + final Collection streams = new ArrayList<>(1); + while (resources.hasMoreElements()) { + streams.add(resources.nextElement().openStream()); + } + return streams; + } + + // Based on: + // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/Manifests.java#L209-L225 + // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/Manifests.java#L381-L388 + + /** + * Get map containing entries from all manifests + * + * @throws IOException if unable to get manifest streams + */ + public @NotNull Map<@NotNull String, @NotNull String> getManifestMap() throws IOException { + final HashMap attribs = new HashMap<>(); + for (final InputStream stream : getManifestStreams()) { + for (final Map.Entry attr: new Manifest(stream).getMainAttributes().entrySet()) { + attribs.put(attr.getKey().toString(), attr.getValue().toString()); + } + } + return attribs; + } +} diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java index 0521781a48d326c0a4a01b920188e9ce00b51ef0..ca64f6c0b3f89231a7d8a2bb08d732270831bd2d 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java @@ -51,6 +51,7 @@ import org.bukkit.util.CachedServerIcon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import io.papermc.paper.util.JarManifests; // Paper /** * Represents the Bukkit core, for version and Server singleton handling @@ -100,7 +101,25 @@ public final class Bukkit { } Bukkit.server = server; - server.getLogger().info("This server is running " + getName() + " version " + getVersion() + " (Implementing API version " + getBukkitVersion() + ")"); + // Paper start - add git information + server.getLogger().info(getVersionMessage()); + } + /** + * Gets message describing the version server is running. + * + * @return message describing the version server is running + */ + @NotNull + public static String getVersionMessage() { + Map attributes = JarManifests.MANIFEST_MAP; + @NotNull String gitBranch = attributes.get("Git-Branch"); + @NotNull String gitCommit = attributes.get("Git-Commit"); + @NotNull String branchMsg = " on " + gitBranch; + if ("master".equals(gitBranch) || "main".equals(gitBranch)) { + branchMsg = ""; // Don't show branch on main/master + } + return "This server is running " + getName() + " version " + getVersion() + " (Implementing API version " + getBukkitVersion() + ") (Git: " + gitCommit + branchMsg + ")"; + // 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 4c2ddc722a9dc4011906ad9530b13fa9be1d3ff9..57a21495843f3a144cd73473cdc8781d6129b7ca 100644 --- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java +++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java @@ -241,7 +241,7 @@ public class VersionCommand extends BukkitCommand { private void setVersionMessage(final @NotNull Component msg) { lastCheck = System.currentTimeMillis(); final Component message = net.kyori.adventure.text.TextComponent.ofChildren( - Component.text("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")", net.kyori.adventure.text.format.NamedTextColor.WHITE), + Component.text(Bukkit.getVersionMessage(), net.kyori.adventure.text.format.NamedTextColor.WHITE), Component.newline(), msg );