papermc: provide multiple versions
This commit is contained in:
parent
51c9129bcf
commit
ef321a0ed6
5 changed files with 262 additions and 50 deletions
|
@ -1,50 +1,15 @@
|
|||
{
|
||||
lib,
|
||||
stdenvNoCC,
|
||||
fetchurl,
|
||||
jre,
|
||||
makeBinaryWrapper,
|
||||
}:
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "papermc";
|
||||
version = "1.20.4.435";
|
||||
|
||||
src =
|
||||
let
|
||||
mcVersion = lib.versions.pad 3 finalAttrs.version;
|
||||
buildNum = builtins.elemAt (lib.splitVersion finalAttrs.version) 3;
|
||||
in
|
||||
fetchurl {
|
||||
url = "https://papermc.io/api/v2/projects/paper/versions/${mcVersion}/builds/${buildNum}/downloads/paper-${mcVersion}-${buildNum}.jar";
|
||||
hash = "sha256-NrIsYLoAAWORw/S26NDFjYBVwpNITJxuWGZow3696wM=";
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
install -D $src $out/share/papermc/papermc.jar
|
||||
|
||||
makeWrapper ${lib.getExe jre} "$out/bin/minecraft-server" \
|
||||
--append-flags "-jar $out/share/papermc/papermc.jar nogui"
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [
|
||||
makeBinaryWrapper
|
||||
];
|
||||
|
||||
dontUnpack = true;
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
|
||||
meta = {
|
||||
description = "High-performance Minecraft Server";
|
||||
homepage = "https://papermc.io/";
|
||||
sourceProvenance = with lib.sourceTypes; [ binaryBytecode ];
|
||||
license = lib.licenses.gpl3Only;
|
||||
platforms = lib.platforms.unix;
|
||||
maintainers = with lib.maintainers; [ aaronjanse neonfuz ];
|
||||
mainProgram = "minecraft-server";
|
||||
};
|
||||
{ callPackage, lib, ... }:
|
||||
let
|
||||
versions = lib.importJSON ./versions.json;
|
||||
latestVersion = lib.last (builtins.sort lib.versionOlder (builtins.attrNames versions));
|
||||
escapeVersion = builtins.replaceStrings [ "." ] [ "_" ];
|
||||
packages = lib.mapAttrs'
|
||||
(version: value: {
|
||||
name = "papermc-${escapeVersion version}";
|
||||
value = callPackage ./derivation.nix { inherit (value) version hash; };
|
||||
})
|
||||
versions;
|
||||
in
|
||||
lib.recurseIntoAttrs (packages // {
|
||||
papermc = builtins.getAttr "papermc-${escapeVersion latestVersion}" packages;
|
||||
})
|
||||
|
|
50
pkgs/games/papermc/derivation.nix
Normal file
50
pkgs/games/papermc/derivation.nix
Normal file
|
@ -0,0 +1,50 @@
|
|||
{ lib, stdenvNoCC, fetchurl, makeBinaryWrapper, jre, version, hash }:
|
||||
|
||||
stdenvNoCC.mkDerivation {
|
||||
pname = "papermc";
|
||||
inherit version;
|
||||
|
||||
src =
|
||||
let
|
||||
version-split = lib.strings.splitString "-" version;
|
||||
mcVersion = builtins.elemAt version-split 0;
|
||||
buildNum = builtins.elemAt version-split 1;
|
||||
in
|
||||
fetchurl {
|
||||
url = "https://papermc.io/api/v2/projects/paper/versions/${mcVersion}/builds/${buildNum}/downloads/paper-${version}.jar";
|
||||
inherit hash;
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
install -D $src $out/share/papermc/papermc.jar
|
||||
|
||||
makeWrapper ${lib.getExe jre} "$out/bin/minecraft-server" \
|
||||
--append-flags "-jar $out/share/papermc/papermc.jar nogui"
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [
|
||||
makeBinaryWrapper
|
||||
];
|
||||
|
||||
dontUnpack = true;
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
|
||||
passthru = {
|
||||
updateScript = ./update.py;
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "High-performance Minecraft Server";
|
||||
homepage = "https://papermc.io/";
|
||||
sourceProvenance = with lib.sourceTypes; [ binaryBytecode ];
|
||||
license = lib.licenses.gpl3Only;
|
||||
platforms = lib.platforms.unix;
|
||||
maintainers = with lib.maintainers; [ aaronjanse neonfuz MayNiklas ];
|
||||
mainProgram = "minecraft-server";
|
||||
};
|
||||
}
|
145
pkgs/games/papermc/update.py
Executable file
145
pkgs/games/papermc/update.py
Executable file
|
@ -0,0 +1,145 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#! nix-shell -i python -p "python3.withPackages (ps: with ps; [ps.requests ])"
|
||||
|
||||
import hashlib
|
||||
import base64
|
||||
import json
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class Version:
|
||||
def __init__(self, name: str):
|
||||
self.name: str = name
|
||||
self.hash: str | None = None
|
||||
self.build_number: int | None = None
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
v_name = f"{self.name}-{self.build_number}"
|
||||
|
||||
# this will probably never happen because the download of a build with NoneType in URL would fail
|
||||
if not self.name or not self.build_number:
|
||||
print(f"Warning: version '{v_name}' contains NoneType!")
|
||||
|
||||
return v_name
|
||||
|
||||
|
||||
class VersionManager:
|
||||
def __init__(self, base_url: str = "https://api.papermc.io/v2/projects/paper"):
|
||||
self.versions: list[Version] = []
|
||||
self.base_url: str = base_url
|
||||
|
||||
def fetch_versions(self, not_before_minor_version: int = 18):
|
||||
"""
|
||||
Fetch all versions after given minor release
|
||||
"""
|
||||
|
||||
response = requests.get(self.base_url)
|
||||
|
||||
try:
|
||||
response.raise_for_status()
|
||||
|
||||
except requests.exceptions.HTTPError as e:
|
||||
print(e)
|
||||
return
|
||||
|
||||
# we only want versions that are no pre-releases
|
||||
release_versions = filter(
|
||||
lambda v_name: 'pre' not in v_name, response.json()["versions"])
|
||||
|
||||
for version_name in release_versions:
|
||||
|
||||
# split version string, convert to list ot int
|
||||
version_split = version_name.split(".")
|
||||
version_split = list(map(int, version_split))
|
||||
|
||||
# check if version is higher than 1.<not_before_sub_version>
|
||||
if (version_split[0] > 1) or (version_split[0] == 1 and version_split[1] >= not_before_minor_version):
|
||||
self.versions.append(Version(version_name))
|
||||
|
||||
def fetch_latest_version_builds(self):
|
||||
"""
|
||||
Set latest build number to each version
|
||||
"""
|
||||
|
||||
for version in self.versions:
|
||||
url = f"{self.base_url}/versions/{version.name}"
|
||||
response = requests.get(url)
|
||||
|
||||
# check that we've got a good response
|
||||
try:
|
||||
response.raise_for_status()
|
||||
|
||||
except requests.exceptions.HTTPError as e:
|
||||
print(e)
|
||||
return
|
||||
|
||||
# the highest build in response.json()['builds']:
|
||||
latest_build = response.json()['builds'][-1]
|
||||
version.build_number = latest_build
|
||||
|
||||
def generate_version_hashes(self):
|
||||
"""
|
||||
Generate and set the hashes for all registered versions (versions will are downloaded to memory)
|
||||
"""
|
||||
|
||||
for version in self.versions:
|
||||
url = f"{self.base_url}/versions/{version.name}/builds/{version.build_number}/downloads/paper-{version.full_name}.jar"
|
||||
version.hash = self.download_and_generate_sha256_hash(url)
|
||||
|
||||
def versions_to_json(self):
|
||||
return json.dumps(
|
||||
{version.name: {'hash': version.hash, 'version': version.full_name}
|
||||
for version in self.versions},
|
||||
indent=4
|
||||
)
|
||||
|
||||
def write_versions(self, file_name: str):
|
||||
""" write all processed versions to json """
|
||||
# save json to versions.json
|
||||
with open(file_name, 'w') as f:
|
||||
f.write(self.versions_to_json() + "\n")
|
||||
|
||||
@staticmethod
|
||||
def download_and_generate_sha256_hash(url: str) -> str | None:
|
||||
"""
|
||||
Fetch the tarball from the given URL.
|
||||
Then generate a sha256 hash of the tarball.
|
||||
"""
|
||||
|
||||
try:
|
||||
# Download the file from the URL
|
||||
response = requests.get(url)
|
||||
response.raise_for_status()
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error: {e}")
|
||||
return None
|
||||
|
||||
# Create a new SHA-256 hash object
|
||||
sha256_hash = hashlib.sha256()
|
||||
|
||||
# Update the hash object with chunks of the downloaded content
|
||||
for byte_block in response.iter_content(4096):
|
||||
sha256_hash.update(byte_block)
|
||||
|
||||
# Get the hexadecimal representation of the hash
|
||||
hash_value = sha256_hash.digest()
|
||||
|
||||
# Encode the hash value in base64
|
||||
base64_hash = base64.b64encode(hash_value).decode('utf-8')
|
||||
|
||||
# Format it as "sha256-{base64_hash}"
|
||||
sri_representation = f"sha256-{base64_hash}"
|
||||
|
||||
return sri_representation
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
version_manager = VersionManager()
|
||||
|
||||
version_manager.fetch_versions()
|
||||
version_manager.fetch_latest_version_builds()
|
||||
version_manager.generate_version_hashes()
|
||||
version_manager.write_versions(file_name="versions.json")
|
50
pkgs/games/papermc/versions.json
Normal file
50
pkgs/games/papermc/versions.json
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"1.18": {
|
||||
"hash": "sha256-PJlfINrk5OIdVVT6yVegqKXIW9W/NJFfrEtPFuDvEBs=",
|
||||
"version": "1.18-66"
|
||||
},
|
||||
"1.18.1": {
|
||||
"hash": "sha256-qUkXpEcsLLyZB6FcZmu7eE+V7Ne1PHe8CP5xED5Uh/U=",
|
||||
"version": "1.18.1-216"
|
||||
},
|
||||
"1.18.2": {
|
||||
"hash": "sha256-BXjxj01jK0lLRo7FaztBS1tW/qCH7n05z23N9MnQHwU=",
|
||||
"version": "1.18.2-388"
|
||||
},
|
||||
"1.19": {
|
||||
"hash": "sha256-DTnKzFGneysHHhzoYvy/C0pL1mjMfosxNZjYT6Cfq6w=",
|
||||
"version": "1.19-81"
|
||||
},
|
||||
"1.19.1": {
|
||||
"hash": "sha256-Wv4jofreksVHEk+odLx9kI+mdvSfCYefqHYiS2Lp1Rs=",
|
||||
"version": "1.19.1-111"
|
||||
},
|
||||
"1.19.2": {
|
||||
"hash": "sha256-LrXHRZ7JS83Fl+1xHVSaOrSw/aE+QSoHkqGgabWQOGQ=",
|
||||
"version": "1.19.2-307"
|
||||
},
|
||||
"1.19.3": {
|
||||
"hash": "sha256-MAfyxjjV8E7TK2raozBT/jY0zPp0NFyD0+pJgtONtdw=",
|
||||
"version": "1.19.3-448"
|
||||
},
|
||||
"1.19.4": {
|
||||
"hash": "sha256-5YfXjLo+me+MS8JM8gzDvbvonjOwtXIHBEavTra+XM8=",
|
||||
"version": "1.19.4-550"
|
||||
},
|
||||
"1.20": {
|
||||
"hash": "sha256-HkzPwFmfSR7m/uRFXTciMyrF14WE/M1Vy7O1HhFQRQU=",
|
||||
"version": "1.20-17"
|
||||
},
|
||||
"1.20.1": {
|
||||
"hash": "sha256-I0qbMgmBAMb8EWZk1k42zNtYtbZJrw+AvMywiwJV6uo=",
|
||||
"version": "1.20.1-196"
|
||||
},
|
||||
"1.20.2": {
|
||||
"hash": "sha256-ujQKg1rEC4Vjqn7aHNZHmhGnYjQJyJosNc2ddJDtF6c=",
|
||||
"version": "1.20.2-318"
|
||||
},
|
||||
"1.20.4": {
|
||||
"hash": "sha256-NrIsYLoAAWORw/S26NDFjYBVwpNITJxuWGZow3696wM=",
|
||||
"version": "1.20.4-435"
|
||||
}
|
||||
}
|
|
@ -37850,7 +37850,9 @@ with pkgs;
|
|||
|
||||
pacvim = callPackage ../games/pacvim { };
|
||||
|
||||
papermc = callPackage ../games/papermc { };
|
||||
papermcServers = callPackages ../games/papermc { };
|
||||
|
||||
papermc = papermcServers.papermc;
|
||||
|
||||
path-of-building = qt6Packages.callPackage ../games/path-of-building {};
|
||||
|
||||
|
|
Loading…
Reference in a new issue