From b474f7e97c6bedb00ec33a6c785d14d5b6cfe5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Thu, 22 Apr 2021 22:32:54 +0100 Subject: [PATCH] Add forge minecraft service --- configuration/default.nix | 1 + .../minecraft/voor-kia/server.properties | 52 ++++++++++ configuration/services/minecraft.nix | 94 +++++++++++++++++++ flake.nix | 24 +++-- pkgs/default.nix | 6 ++ pkgs/minecraft/forge-server.nix | 64 +++++++++++++ 6 files changed, 231 insertions(+), 10 deletions(-) create mode 100644 configuration/services/configs/minecraft/voor-kia/server.properties create mode 100644 configuration/services/minecraft.nix create mode 100644 pkgs/default.nix create mode 100644 pkgs/minecraft/forge-server.nix diff --git a/configuration/default.nix b/configuration/default.nix index 1bbb6bb..fbf55b8 100644 --- a/configuration/default.nix +++ b/configuration/default.nix @@ -3,6 +3,7 @@ { imports = [ ./services/gitea.nix + ./services/minecraft.nix ./services/nextcloud.nix ./services/webserver.nix ./ids.nix diff --git a/configuration/services/configs/minecraft/voor-kia/server.properties b/configuration/services/configs/minecraft/voor-kia/server.properties new file mode 100644 index 0000000..1c5787e --- /dev/null +++ b/configuration/services/configs/minecraft/voor-kia/server.properties @@ -0,0 +1,52 @@ +#Minecraft server properties +#Thu Apr 08 21:07:16 BST 2021 +allow-flight=true +allow-nether=true +broadcast-console-to-ops=true +broadcast-rcon-to-ops=true +difficulty=normal +enable-command-block=false +enable-jmx-monitoring=false +enable-query=false +enable-rcon=false +enable-status=true +enforce-whitelist=true +entity-broadcast-range-percentage=100 +force-gamemode=false +function-permission-level=2 +gamemode=survival +generate-structures=true +generator-settings= +hardcore=false +level-name=world +level-seed= +level-type=default +max-build-height=256 +max-players=5 +max-tick-time=-1 +max-world-size=29999984 +motd=Minecraft met Kia en die broers +network-compression-threshold=256 +online-mode=true +op-permission-level=4 +player-idle-timeout=0 +prevent-proxy-connections=false +pvp=false +query.port=25565 +rate-limit=0 +rcon.password= +rcon.port=25575 +resource-pack= +resource-pack-sha1= +server-ip= +server-port=25565 +snooper-enabled=true +spawn-animals=true +spawn-monsters=true +spawn-npcs=true +spawn-protection=1 +sync-chunk-writes=true +text-filtering-config= +use-native-transport=true +view-distance=10 +white-list=true diff --git a/configuration/services/minecraft.nix b/configuration/services/minecraft.nix new file mode 100644 index 0000000..fc5ecae --- /dev/null +++ b/configuration/services/minecraft.nix @@ -0,0 +1,94 @@ +{ config, pkgs, ... }: + +let + minecraft-server-args = [ + "-Xms2G" + "-Xmx2G" + "-Dsun.rmi.dgc.server.gcInterval=2157583646" + "-XX:+UseG1GC" + "-XX:+ParallelRefProcEnabled" + "-XX:MaxGCPauseMillis=200" + "-XX:+UnlockExperimentalVMOptions" + "-XX:+DisableExplicitGC" + "-XX:+AlwaysPreTouch" + "-XX:G1NewSizePercent=30" + "-XX:G1MaxNewSizePercent=40" + "-XX:G1HeapRegionSize=8M" + "-XX:G1ReservePercent=20" + "-XX:G1HeapWastePercent=5" + "-XX:G1MixedGCCountTarget=4" + "-XX:InitiatingHeapOccupancyPercent=15" + "-XX:G1MixedGCLiveThresholdPercent=90" + "-XX:G1RSetUpdatingPauseTimePercent=5" + "-XX:SurvivorRatio=32" + "-XX:+PerfDisableSharedMem" + "-XX:MaxTenuringThreshold=1" + ]; + ops = pkgs.writeText "ops.json" (builtins.toJSON [{ + uuid = "140d177a-966f-41b8-a4c0-e305babd291b"; + name = "TLATER"; + level = 4; + bypassesPlayerLimit = true; + }]); + whitelist = pkgs.writeText "whitelist.json" (builtins.toJSON [ + { + uuid = "59cd1648-14a4-4bcf-8f5a-2e1bde678f2c"; + name = "romino25"; + } + { + uuid = "0ab6e3d1-544a-47e7-8538-2e6c248e49a4"; + name = "lasi25"; + } + { + uuid = "01c9e737-fc9d-4d55-b8c2-610ca80eb4be"; + name = "Nampeyo25"; + } + { + uuid = "140d177a-966f-41b8-a4c0-e305babd291b"; + name = "tlater"; + } + ]); + eula = pkgs.writeText "eula.txt" "eula=true"; + +in { + nixpkgs.config.allowUnfreePredicate = pkg: + builtins.elem (pkgs.lib.getName pkg) [ "forge-server" ]; + + virtualisation.oci-containers.containers.minecraft-voor-kia = + let properties = ./configs/minecraft/voor-kia/server.properties; + in { + image = "tlaternet/minecraft-voor-kia"; + + imageFile = pkgs.dockerTools.buildImage { + name = "tlaternet/minecraft-voor-kia"; + tag = "latest"; + contents = [ + (pkgs.local.forge-server.override { + jre_headless = pkgs.jdk11_headless; + }) + ]; + + config = let + # Use the upstream minecraft uid + uid = toString config.ids.uids.minecraft; + gid = toString config.users.groups.nogroup.gid; + in { + Cmd = [ "forge-server" ] ++ minecraft-server-args; + WorkingDir = "/var/lib/minecraft"; + Volumes = { "/var/lib/minecraft" = { }; }; + ExposedPorts = { "25565" = { }; }; + User = "${uid}:${gid}"; + }; + }; + + autoStart = false; + ports = [ "25565:25565" ]; + volumes = [ + "minecraft:/var/lib/minecraft" + "${properties}:/var/lib/minecraft/server.properties:ro" + "${ops}:/var/lib/minecraft/ops.json:ro" + "${whitelist}:/var/lib/minecraft/whitelist.json:ro" + "${eula}:/var/lib/minecraft/eula.txt:ro" + ]; + }; +} diff --git a/flake.nix b/flake.nix index cc23dbb..17cf407 100644 --- a/flake.nix +++ b/flake.nix @@ -76,14 +76,18 @@ ]; }; }; - } // flake-utils.lib.eachDefaultSystem (system: { - devShell = with nixpkgs.legacyPackages.${system}; - mkShell { - buildInputs = [ nixfmt git-lfs ]; - shellHook = '' - export QEMU_OPTS="-m 3941 -smp 2 -curses" - export QEMU_NET_OPTS="hostfwd=::3022-:2222,hostfwd=::3080-:80,hostfwd=::3443-:443,hostfwd=::3021-:2221,hostfwd=::25565-:25565" - ''; - }; - }); + } // flake-utils.lib.eachDefaultSystem (system: + let pkgs = import nixpkgs { inherit system overlays; }; + in { + devShell = with pkgs; + mkShell { + buildInputs = [ nixfmt git-lfs ]; + shellHook = '' + export QEMU_OPTS="-m 3941 -smp 2 -curses" + export QEMU_NET_OPTS="hostfwd=::3022-:2222,hostfwd=::3080-:80,hostfwd=::3443-:443,hostfwd=::3021-:2221,hostfwd=::25565-:25565" + ''; + }; + + packages = import ./pkgs { inherit pkgs; }; + }); } diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 0000000..1089cbd --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: + +{ + # Forge + forge-server = pkgs.callPackage ./minecraft/forge-server.nix { }; +} diff --git a/pkgs/minecraft/forge-server.nix b/pkgs/minecraft/forge-server.nix new file mode 100644 index 0000000..047a04a --- /dev/null +++ b/pkgs/minecraft/forge-server.nix @@ -0,0 +1,64 @@ +{ lib, stdenv, fetchurl, jre_headless, runtimeShell }: + +let + name = "forge-server"; + version = "1.16.5-36.1.1"; + mirror = "https://files.minecraftforge.net/maven/net/minecraftforge/forge"; + src = fetchurl { + url = "${mirror}/${version}/forge-${version}-installer.jar"; + # Forge doesn't seem to like newer shas + sha1 = "78e5bd0b19f05136bb25bf3c5be9b64a1d0e850e"; + }; + + unpackCmd = "mkdir -p src; cp $curSrc src/forge-${version}-installer.jar"; + + # Somewhat evil pre-install step to run through the network + # dependency resolution forge needs. This is also common for gradle + # projects, so I think this is ok-ish here, though ideally I'd + # identify all the dependencies and package them as well. + deps = stdenv.mkDerivation { + name = "${name}-deps"; + inherit src unpackCmd; + + nativeBuildInputs = [ jre_headless ]; + buildPhase = '' + java -jar forge-${version}-installer.jar --installServer installation + ''; + installPhase = '' + mkdir -p $out + cp -r installation/forge-${version}.jar installation/libraries $out + ''; + + outputHashAlgo = "sha256"; + outputHashMode = "recursive"; + outputHash = "lV4UxmSdv/I+HwvnT8CLcHpSKyDvKnldA5/Lw1GsJ/M="; + }; + +in stdenv.mkDerivation rec { + inherit name version src unpackCmd; + + installPhase = '' + mkdir -p $out/{bin,lib/forge} + cp -rv ${deps}/* $out/lib/forge/ + + cat > $out/bin/forge-server << EOF + #!${runtimeShell} + set -eu + + exec ${jre_headless}/bin/java \$@ -jar $out'/lib/forge/forge-${version}.jar' nogui + EOF + + chmod +x $out/bin/forge-server + ''; + + phases = "installPhase"; + + meta = with lib; { + description = "Forge Minecraft Server"; + homepage = "https://files.minecraftforge.net/"; + # Forge itself is open source, but this package pulls in + # minecraft. + license = licenses.unfreeRedistributable; + platforms = platforms.unix; + }; +}