Is there a way to get the latest server jar through a URL that doesn't change?

Solution 1:

Full Instructions

I recently decompiled the launcher for this very reason, to manage automatic updates for my server wrapper with their new naming convention.

I found the file they use to work out what the current version is and the URL to it:

https://launchermeta.mojang.com/mc/game/version_manifest.json

This file includes the following (as of this answer):

"latest": {
    "snapshot": "1.9-pre3",
    "release": "1.8.9"
},
"versions": [
    {
        "id": "1.13.1",
        "type": "release",
        "url": "https://launchermeta.mojang.com/v1/packages/c0f1e6239a16681ffbfa68fc469038643304d5a9/1.13.1.json",
        "time": "2018-08-30T09:49:34+00:00",
        "releaseTime": "2018-08-22T14:03:42+00:00"
    },
    ...
]

That file also has a "versions" array. Loop through this to find the version you are looking for in the id field. It is also usually the first entry in this array, so you could address it versions[0]. Grab the url value and fetch that file which contains the following useful key:

"downloads": {
    "client": {
        "sha1": "8de235e5ec3a7fce168056ea395d21cbdec18d7c",
        "size": 16088559,
        "url": "https://launcher.mojang.com/v1/objects/8de235e5ec3a7fce168056ea395d21cbdec18d7c/client.jar"
    },
    "server": {
        "sha1": "fe123682e9cb30031eae351764f653500b7396c9",
        "size": 33832589,
        "url": "https://launcher.mojang.com/v1/objects/fe123682e9cb30031eae351764f653500b7396c9/server.jar"
    }
},

Therefore, the URL you need is contained in downloads.server.url.

Summary

  • GET https://launchermeta.mojang.com/mc/game/version_manifest.json
  • GET versions[0].url
  • GET downloads.server.url

Outdated instructions - for posterity only

Which you can then use to extrapolate the latest version for release and snapshots using this scheme:

https://s3.amazonaws.com/Minecraft.Download/versions/" + Ver + "/minecraft_server." + Ver + ".jar

Using this method you don't need to download the jar/exe file every time, just the json file and then if it's changed, you can grab the appropriate jar.

Solution 2:

You can use jsawk to pull the latest jar version number from the Minecraft version JSON:

#!/bin/bash
VER=`curl -s https://launchermeta.mojang.com/mc/game/version_manifest.json | jsawk -n 'out(this.latest.release)'`
wget https://s3.amazonaws.com/Minecraft.Download/versions/$VER/minecraft_server.$VER.jar

Requires:

  • jsawk
  • SpiderMonkey

Solution 3:

I'll even throw my hat into the ring! Very similar to up above, with a few extras.

#!/bin/bash

tmpfile=/tmp/minecrafttempfile.tmp
downloadurl="https://minecraft.net/download"
serverurl=""
loc=$([[ -n $1 ]] && echo $1 || echo "/tmp/minecraft_server.jar")

if [[ -a $loc ]]; then
        echo "$loc exists -- moving to ${loc}.old"
        mv $loc ${loc}.old
fi

echo "Grabbing minecraft download page..."

curl $downloadurl > $tmpfile

echo "Getting download URL for minecraft server..."

serverurl=`egrep -io 'https.*versions\/(.*)\/minecraft_server.\1.jar' $tmpfile`

echo "URL = "$serverurl

echo "Downloading server jar..."

wget -q -O $loc $serverurl

https://github.com/cptskyhawk/LinuxMinecraftTools

Solution 4:

I have a server setup which updates every night with a webget.exe command earlier on. The change got me to make a program that scrapes the download page after a *server.exe and downloads it as minecraft_server.exe.

I have modified it to take in a param "jar" so it gets *server.jar instead and downloads it as minecraft_server.jar.

The zipped exe is here: http://halsvik.net/downloads/GetLatestMinecraftServer.zip

If you download the program, run it without any params: GetLatestMinecraftServer.exe

If you want the jar server file instead use: GetLatestMinecraftServer.exe jar

Source code is this:

 static void Main(string[] args)
    {
        try
        {
            var ext = ".exe";
            if (args.Length > 0)
            {
                ext = "." + args[0];
            }

            var wc = new System.Net.WebClient();
            var url = "http://minecraft.net/download";
            var data = wc.DownloadData(url);
            var page = Encoding.UTF8.GetString(data);
            var links = Misc.GetStringsBetween(page, "<a href=\"", "\""); //Custom method to get matches

            bool match = false;
            foreach (var item in links)
            {
                if (item.ToLower().Contains("server") && item.ToLower().Contains(ext))
                {
                    var filename = "minecraft_server" +ext;
                    var fn = Path.GetFullPath(filename);
                    while (File.Exists(filename + ".old")) File.Delete(filename + ".old");
                    if (File.Exists(fn)) File.Move(fn, fn + ".old");

                    try
                    {
                        var comp = false;
                        wc.DownloadProgressChanged += (o, e) =>
                        {
                            Console.Write("#"); //Indicate something is downloading
                        };
                        wc.DownloadFileCompleted += (o, e) =>
                        {
                            comp = true;
                        };
                        wc.DownloadFileAsync(new Uri(item), filename);

                        //Wait for download to complete
                        while (!comp)
                        {
                            Console.Write("."); //Indicate time is going
                            Thread.Sleep(1000);
                        }

                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Download of " + item + " failed. " +ex.Message);
                        return;
                    }
                    Console.WriteLine("Download OK");
                    match = true;
                    break;
                }
            }

            if (!match)
            {
                Console.WriteLine("Could not find minecraft server on http://minecraft.net/download");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Something failed. " + ex.ToString());

        }
    }

Solution 5:

here's my horrible sed version.

less correct than Jason's version, above. but fewer dependencies.

#!/bin/bash

wget -qN  https://launchermeta.mojang.com/mc/game/version_manifest.json
MCVER=`sed -n -e '/\"latest\"/,/}/ s/.*\"snapshot\": \"\([^\"]*\)\".*/\1/p' < version_manifest.json`

wget -N https://s3.amazonaws.com/Minecraft.Download/versions/$MCVER/minecraft_server.$MCVER.jar