Although this is an older question, it seems to still be relevant, as I just implemented a solution to this problem myself. I wrote a small bash script that, when passed a path to a minecraft server jar, extracts the MinecraftServer.class
file to a temporary location, then extracts the String constants table using the javap
tool (requires the JDK to be installed, rather than/in addition to the Java runtime), then filters the table down by looking for the expected Major.Minor.Rev
version pattern. This solution works pretty reliably for now, with a couple of caveats:
- Version number must be in
Maj.Min.Rev
format. Versioning tends to be pretty consistent once applied to a software application, but any changes will break the script.
- Assumes no new additional string constants that match the expected format are present. A future change could very well introduce a "conflicting" string which would likely break the script.
To use the script, simply pass it the path to the minecraft server jar as the only argument. On success, the script returns 0 and outputs the version string to stdout. On failure, the script returns a non zero value.
#!/bin/bash
# Simple bash script that attempts to extract the version number from the
# minecraft server jar file.
#
# This script makes use of the Java dissassembler tool, provided with the
# Java JDK. You may need to explicitly install the JDK, since most server
# installs likely rely solely on the Java runtime (which does not include
# the development tools)
# Temporary file to extract the relevant class file into
TMP_CLASS=$(mktemp /tmp/mc-server-class.XXXXXXXXXXXXXXXX.class)
if [ -z "$1" ]; then
>&2 echo "ERROR: You must specify a minecraft server jar file"
exit 1
fi
# Ensure expected external dependencies are present
which unzip >/dev/null
if [ $? -ne 0 ]; then
>&2 echo "ERROR: This utility requires 'unzip' to be installed"
exit 2
fi
which javap >/dev/null
if [ $? -ne 0 ]; then
>&2 echo "ERROR: This utility requires 'javap' to be installed"
exit 2
fi
# Extract the main server class into the temporary file (we do this since
# javap apparently does not like to slurp from stdout)
unzip -p "$1" net/minecraft/server/MinecraftServer.class >$TMP_CLASS
# Use the java dissassembler tool to extract the constants table. We pipe the
# constants table into grep, and seperate out the Utf8 lines (all the String
# constact values). Next, we pipe the string constants to another grep, looking
# for the expected major.minor.revision number format. Finally, pipe the line
# for the version constant string into sed, to pare it down to a jsut the
# version string itself.
javap -c -verbose $TMP_CLASS | grep 'Utf8' | grep '[0-9]\{1,\}\.[0-9]\{1,\}\(\.[0-9]\{1,\}\)\{0,1\}' | sed -n 's/.*[^0-9.]\([0-9]\{1,\}\.[0-9]\{1,\}\(\.[0-9]\{1,\}\)\{0,1\}\).*/\1/p'
rm $TMP_CLASS
if [ $? -ne 0 ]; then
>&2 echo "ERROR: Failed to remove temporary class file '${TMP_CLASS}'"
fi