minecraft-server: package major versions
This commit is contained in:
parent
ae02cde6df
commit
867b8e2188
|
@ -1,40 +1,17 @@
|
|||
{ lib, stdenv, fetchurl, nixosTests, jre_headless }:
|
||||
stdenv.mkDerivation {
|
||||
pname = "minecraft-server";
|
||||
version = "1.18.1";
|
||||
{ callPackage, lib }:
|
||||
# if you add more versions make sure to add to all-packages.nix
|
||||
let
|
||||
versions = lib.importJSON ./versions.json;
|
||||
latestVersion = lib.last (builtins.sort lib.versionOlder (builtins.attrNames versions));
|
||||
escapeVersion = builtins.replaceStrings [ "." ] [ "_" ];
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://launcher.mojang.com/v1/objects/125e5adf40c659fd3bce3e66e67a16bb49ecc1b9/server.jar";
|
||||
# sha1 because that comes from mojang via api
|
||||
sha1 = "125e5adf40c659fd3bce3e66e67a16bb49ecc1b9";
|
||||
};
|
||||
|
||||
preferLocalBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin $out/lib/minecraft
|
||||
cp -v $src $out/lib/minecraft/server.jar
|
||||
|
||||
cat > $out/bin/minecraft-server << EOF
|
||||
#!/bin/sh
|
||||
exec ${jre_headless}/bin/java \$@ -jar $out/lib/minecraft/server.jar nogui
|
||||
EOF
|
||||
|
||||
chmod +x $out/bin/minecraft-server
|
||||
'';
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
passthru = {
|
||||
tests = { inherit (nixosTests) minecraft-server; };
|
||||
updateScript = ./update.sh;
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "Minecraft Server";
|
||||
homepage = "https://minecraft.net";
|
||||
license = licenses.unfreeRedistributable;
|
||||
platforms = platforms.unix;
|
||||
maintainers = with maintainers; [ thoughtpolice tomberek costrouc ];
|
||||
};
|
||||
packages = lib.mapAttrs'
|
||||
(version: value: {
|
||||
name = "minecraft-server_${escapeVersion version}";
|
||||
value = callPackage ./derivation.nix { inherit (value) version url sha1; };
|
||||
})
|
||||
versions;
|
||||
in
|
||||
packages // {
|
||||
minecraft-server = builtins.getAttr "minecraft-server_${escapeVersion latestVersion}" packages;
|
||||
}
|
||||
|
|
36
pkgs/games/minecraft-server/derivation.nix
Normal file
36
pkgs/games/minecraft-server/derivation.nix
Normal file
|
@ -0,0 +1,36 @@
|
|||
{ lib, stdenv, fetchurl, nixosTests, jre_headless, version, url, sha1 }:
|
||||
stdenv.mkDerivation {
|
||||
pname = "minecraft-server";
|
||||
inherit version;
|
||||
|
||||
src = fetchurl { inherit url sha1; };
|
||||
|
||||
preferLocalBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin $out/lib/minecraft
|
||||
cp -v $src $out/lib/minecraft/server.jar
|
||||
|
||||
cat > $out/bin/minecraft-server << EOF
|
||||
#!/bin/sh
|
||||
exec ${jre_headless}/bin/java \$@ -jar $out/lib/minecraft/server.jar nogui
|
||||
EOF
|
||||
|
||||
chmod +x $out/bin/minecraft-server
|
||||
'';
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
passthru = {
|
||||
tests = { inherit (nixosTests) minecraft-server; };
|
||||
updateScript = ./update.py;
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "Minecraft Server";
|
||||
homepage = "https://minecraft.net";
|
||||
license = licenses.unfreeRedistributable;
|
||||
platforms = platforms.unix;
|
||||
maintainers = with maintainers; [ thoughtpolice tomberek costrouc ];
|
||||
};
|
||||
}
|
147
pkgs/games/minecraft-server/update.py
Executable file
147
pkgs/games/minecraft-server/update.py
Executable file
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p python3Packages.requests python3Packages.dataclasses-json
|
||||
|
||||
import json
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import requests
|
||||
from dataclasses_json import DataClassJsonMixin, LetterCase, config
|
||||
from marshmallow import fields
|
||||
|
||||
|
||||
@dataclass
|
||||
class Download(DataClassJsonMixin):
|
||||
sha1: str
|
||||
size: int
|
||||
url: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Version(DataClassJsonMixin):
|
||||
id: str
|
||||
type: str
|
||||
url: str
|
||||
time: datetime = field(
|
||||
metadata=config(
|
||||
encoder=datetime.isoformat,
|
||||
decoder=datetime.fromisoformat,
|
||||
mm_field=fields.DateTime(format="iso"),
|
||||
)
|
||||
)
|
||||
release_time: datetime = field(
|
||||
metadata=config(
|
||||
encoder=datetime.isoformat,
|
||||
decoder=datetime.fromisoformat,
|
||||
mm_field=fields.DateTime(format="iso"),
|
||||
letter_case=LetterCase.CAMEL,
|
||||
)
|
||||
)
|
||||
|
||||
def get_manifest(self) -> Any:
|
||||
"""Return the version's manifest."""
|
||||
response = requests.get(self.url)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
def get_downloads(self) -> Dict[str, Download]:
|
||||
"""
|
||||
Return all downloadable files from the version's manifest, in Download
|
||||
objects.
|
||||
"""
|
||||
return {
|
||||
download_name: Download.from_dict(download_info)
|
||||
for download_name, download_info in self.get_manifest()["downloads"].items()
|
||||
}
|
||||
|
||||
def get_server(self) -> Optional[Download]:
|
||||
"""
|
||||
If the version has a server download available, return the Download
|
||||
object for the server download. If the version does not have a server
|
||||
download avilable, return None.
|
||||
"""
|
||||
downloads = self.get_downloads()
|
||||
if "server" in downloads:
|
||||
return downloads["server"]
|
||||
return None
|
||||
|
||||
|
||||
def get_versions() -> List[Version]:
|
||||
"""Return a list of Version objects for all available versions."""
|
||||
response = requests.get(
|
||||
"https://launchermeta.mojang.com/mc/game/version_manifest.json"
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return [Version.from_dict(version) for version in data["versions"]]
|
||||
|
||||
|
||||
def get_major_release(version_id: str) -> str:
|
||||
"""
|
||||
Return the major release for a version. The major release for 1.17 and
|
||||
1.17.1 is 1.17.
|
||||
"""
|
||||
if not len(version_id.split(".")) >= 2:
|
||||
raise ValueError(f"version not in expected format: '{version_id}'")
|
||||
return ".".join(version_id.split(".")[:2])
|
||||
|
||||
|
||||
def group_major_releases(releases: List[Version]) -> Dict[str, List[Version]]:
|
||||
"""
|
||||
Return a dictionary containing each version grouped by each major release.
|
||||
The key "1.17" contains a list with two Version objects, one for "1.17"
|
||||
and another for "1.17.1".
|
||||
"""
|
||||
groups: Dict[str, List[Version]] = {}
|
||||
for release in releases:
|
||||
major_release = get_major_release(release.id)
|
||||
if major_release not in groups:
|
||||
groups[major_release] = []
|
||||
groups[major_release].append(release)
|
||||
return groups
|
||||
|
||||
|
||||
def get_latest_major_releases(releases: List[Version]) -> Dict[str, Version]:
|
||||
"""
|
||||
Return a dictionary containing the latest version for each major release.
|
||||
The latest major release for 1.16 is 1.16.5, so the key "1.16" contains a
|
||||
Version object for 1.16.5.
|
||||
"""
|
||||
return {
|
||||
major_release: sorted(releases, key=lambda x: x.id, reverse=True)[0]
|
||||
for major_release, releases in group_major_releases(releases).items()
|
||||
}
|
||||
|
||||
|
||||
def generate() -> Dict[str, Dict[str, str]]:
|
||||
"""
|
||||
Return a dictionary containing the latest url, sha1 and version for each major
|
||||
release.
|
||||
"""
|
||||
versions = get_versions()
|
||||
releases = list(
|
||||
filter(lambda version: version.type == "release", versions)
|
||||
) # remove snapshots and betas
|
||||
latest_major_releases = get_latest_major_releases(releases)
|
||||
|
||||
servers = {
|
||||
version: Download.schema().dump(download_info) # Download -> dict
|
||||
for version, download_info in {
|
||||
version: value.get_server()
|
||||
for version, value in latest_major_releases.items()
|
||||
}.items()
|
||||
if download_info is not None # versions < 1.2 do not have a server
|
||||
}
|
||||
for server in servers.values():
|
||||
del server["size"] # don't need it
|
||||
|
||||
for version, server in servers.items():
|
||||
server["version"] = latest_major_releases[version].id
|
||||
return servers
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open("versions.json", "w") as file:
|
||||
json.dump(generate(), file, indent=2)
|
||||
file.write("\n")
|
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl jq common-updater-scripts
|
||||
|
||||
BASEDIR="$(dirname "$0")"
|
||||
|
||||
# get current release version
|
||||
versions=$(curl -s 'https://launchermeta.mojang.com/mc/game/version_manifest.json')
|
||||
version=$(echo $versions | jq .latest.release)
|
||||
url=$(echo $versions | jq -r ".versions[] | select(.id == $version) | .url")
|
||||
|
||||
# get current server.jar
|
||||
versions=$(curl -s $url | jq .downloads.server)
|
||||
sha1=$(echo $versions | jq .sha1)
|
||||
url=$(echo $versions | jq .url)
|
||||
|
||||
echo $version: $url:$sha1
|
||||
|
||||
# change default.nix
|
||||
sed -i "s/version = \"[0-9.]*\";/version = ${version};/g" "$BASEDIR/default.nix"
|
||||
sed -i "s+url = \"[a-zA-Z0-9/:.]*/server.jar\";+url = $url;+g" "$BASEDIR/default.nix"
|
||||
sed -i "s/sha1 = \"[a-zA-Z0-9]*\";/sha1 = ${sha1};/g" "$BASEDIR/default.nix"
|
87
pkgs/games/minecraft-server/versions.json
Normal file
87
pkgs/games/minecraft-server/versions.json
Normal file
|
@ -0,0 +1,87 @@
|
|||
{
|
||||
"1.18": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/125e5adf40c659fd3bce3e66e67a16bb49ecc1b9/server.jar",
|
||||
"sha1": "125e5adf40c659fd3bce3e66e67a16bb49ecc1b9",
|
||||
"version": "1.18.1"
|
||||
},
|
||||
"1.17": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/a16d67e5807f57fc4e550299cf20226194497dc2/server.jar",
|
||||
"sha1": "a16d67e5807f57fc4e550299cf20226194497dc2",
|
||||
"version": "1.17.1"
|
||||
},
|
||||
"1.16": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/1b557e7b033b583cd9f66746b7a9ab1ec1673ced/server.jar",
|
||||
"sha1": "1b557e7b033b583cd9f66746b7a9ab1ec1673ced",
|
||||
"version": "1.16.5"
|
||||
},
|
||||
"1.15": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/bb2b6b1aefcd70dfd1892149ac3a215f6c636b07/server.jar",
|
||||
"sha1": "bb2b6b1aefcd70dfd1892149ac3a215f6c636b07",
|
||||
"version": "1.15.2"
|
||||
},
|
||||
"1.14": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/3dc3d84a581f14691199cf6831b71ed1296a9fdf/server.jar",
|
||||
"sha1": "3dc3d84a581f14691199cf6831b71ed1296a9fdf",
|
||||
"version": "1.14.4"
|
||||
},
|
||||
"1.13": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/3737db93722a9e39eeada7c27e7aca28b144ffa7/server.jar",
|
||||
"sha1": "3737db93722a9e39eeada7c27e7aca28b144ffa7",
|
||||
"version": "1.13.2"
|
||||
},
|
||||
"1.12": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/886945bfb2b978778c3a0288fd7fab09d315b25f/server.jar",
|
||||
"sha1": "886945bfb2b978778c3a0288fd7fab09d315b25f",
|
||||
"version": "1.12.2"
|
||||
},
|
||||
"1.11": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/f00c294a1576e03fddcac777c3cf4c7d404c4ba4/server.jar",
|
||||
"sha1": "f00c294a1576e03fddcac777c3cf4c7d404c4ba4",
|
||||
"version": "1.11.2"
|
||||
},
|
||||
"1.10": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/3d501b23df53c548254f5e3f66492d178a48db63/server.jar",
|
||||
"sha1": "3d501b23df53c548254f5e3f66492d178a48db63",
|
||||
"version": "1.10.2"
|
||||
},
|
||||
"1.9": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/edbb7b1758af33d365bf835eb9d13de005b1e274/server.jar",
|
||||
"sha1": "edbb7b1758af33d365bf835eb9d13de005b1e274",
|
||||
"version": "1.9.4"
|
||||
},
|
||||
"1.8": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/b58b2ceb36e01bcd8dbf49c8fb66c55a9f0676cd/server.jar",
|
||||
"sha1": "b58b2ceb36e01bcd8dbf49c8fb66c55a9f0676cd",
|
||||
"version": "1.8.9"
|
||||
},
|
||||
"1.7": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/4cec86a928ec171fdc0c6b40de2de102f21601b5/server.jar",
|
||||
"sha1": "4cec86a928ec171fdc0c6b40de2de102f21601b5",
|
||||
"version": "1.7.9"
|
||||
},
|
||||
"1.6": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/050f93c1f3fe9e2052398f7bd6aca10c63d64a87/server.jar",
|
||||
"sha1": "050f93c1f3fe9e2052398f7bd6aca10c63d64a87",
|
||||
"version": "1.6.4"
|
||||
},
|
||||
"1.5": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/f9ae3f651319151ce99a0bfad6b34fa16eb6775f/server.jar",
|
||||
"sha1": "f9ae3f651319151ce99a0bfad6b34fa16eb6775f",
|
||||
"version": "1.5.2"
|
||||
},
|
||||
"1.4": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/2f0ec8efddd2f2c674c77be9ddb370b727dec676/server.jar",
|
||||
"sha1": "2f0ec8efddd2f2c674c77be9ddb370b727dec676",
|
||||
"version": "1.4.7"
|
||||
},
|
||||
"1.3": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/3de2ae6c488135596e073a9589842800c9f53bfe/server.jar",
|
||||
"sha1": "3de2ae6c488135596e073a9589842800c9f53bfe",
|
||||
"version": "1.3.2"
|
||||
},
|
||||
"1.2": {
|
||||
"url": "https://launcher.mojang.com/v1/objects/d8321edc9470e56b8ad5c67bbd16beba25843336/server.jar",
|
||||
"sha1": "d8321edc9470e56b8ad5c67bbd16beba25843336",
|
||||
"version": "1.2.5"
|
||||
}
|
||||
}
|
|
@ -30810,7 +30810,25 @@ with pkgs;
|
|||
|
||||
minecraft = callPackage ../games/minecraft { };
|
||||
|
||||
minecraft-server = callPackage ../games/minecraft-server { };
|
||||
inherit (import ../games/minecraft-server { inherit callPackage lib; })
|
||||
minecraft-server_1_2
|
||||
minecraft-server_1_3
|
||||
minecraft-server_1_4
|
||||
minecraft-server_1_5
|
||||
minecraft-server_1_6
|
||||
minecraft-server_1_7
|
||||
minecraft-server_1_8
|
||||
minecraft-server_1_9
|
||||
minecraft-server_1_10
|
||||
minecraft-server_1_11
|
||||
minecraft-server_1_12
|
||||
minecraft-server_1_13
|
||||
minecraft-server_1_14
|
||||
minecraft-server_1_15
|
||||
minecraft-server_1_16
|
||||
minecraft-server_1_17
|
||||
minecraft-server_1_18
|
||||
minecraft-server;
|
||||
|
||||
moon-buggy = callPackage ../games/moon-buggy {};
|
||||
|
||||
|
|
Loading…
Reference in a new issue