nixos/spec/eientei/minecraft.nix
2025-01-13 11:52:09 +08:00

132 lines
4.1 KiB
Nix

{
pkgs,
lib,
config,
...
}:
let
inherit (lib) mapAttrs' nameValuePair;
servers = {
#bungeecord = {
# cmdline = "${pkgs.graalvmCEPackages.graalvm-ce}/bin/java -Xms2G -Xmx4G -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:+UnlockExperimentalVMOptions -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -jar waterfall-1.20-578.jar";
# stop = "end";
#};
#limbo = {
# cmdline = "${pkgs.graalvmCEPackages.graalvm-ce}/bin/java -Xms1G -Xmx1G -jar NanoLimbo-1.8-all.jar";
# stop = "stop";
#};
greedycraft = {
cmdline = "${pkgs.jdk8}/bin/java -Xmx10G -Xms10G -Xss4M -Dfile.encoding=GBK -Dsun.rmi.dgc.server.gcInterval=1800000 -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:+AlwaysPreTouch -XX:+UseStringDeduplication -Dfml.ignorePatchDiscrepancies=true -Dfml.ignoreInvalidMinecraftCertificates=true -XX:-OmitStackTraceInFastThrow -XX:+OptimizeStringConcat -XX:+UseAdaptiveGCBoundary -XX:G1HeapRegionSize=32M -jar forge-1.12.2-14.23.5.2855.jar nogui";
stop = "stop";
};
nfwc = {
cmdline = "${pkgs.jdk}/bin/java @user_jvm_args.txt @libraries/net/minecraftforge/forge/1.19.2-43.3.8/unix_args.txt";
stop = "stop";
};
};
prefix = "minecraft-server-";
data = "/nix/persist/service/minecraft";
in
{
# https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/services/games/minecraft-server.nix
users.users.minecraft = {
description = "Minecraft server service user";
home = data;
createHome = true;
isSystemUser = true;
uid = 1021;
group = "minecraft";
};
users.groups.minecraft.gid = 1021;
systemd.sockets = mapAttrs' (
name: value:
with value;
(nameValuePair "${prefix}${name}" {
bindsTo = [ "${prefix}${name}.service" ];
socketConfig = {
ListenFIFO = "/run/minecraft-server/${name}.stdin";
SocketMode = "0660";
SocketUser = "minecraft";
SocketGroup = "minecraft";
RemoveOnStop = true;
FlushPending = true;
};
})
) servers;
systemd.services =
let
stopScript =
{ name, stop }:
pkgs.writeShellScript "minecraft-server-stop" ''
echo ${stop} > ${config.systemd.sockets."${prefix}${name}".socketConfig.ListenFIFO}
# Wait for the PID of the minecraft server to disappear before
# returning, so systemd doesn't attempt to SIGKILL it.
while kill -0 "$1" 2> /dev/null; do
sleep 1s
done
'';
in
mapAttrs' (
name: value:
with value;
(nameValuePair "${prefix}${name}" {
description = "Minecraft Server Service for ${name}";
wantedBy = [ "multi-user.target" ];
requires = [ "${prefix}${name}.socket" ];
after = [
"network.target"
"${prefix}${name}.socket"
];
path = [ pkgs.bash ];
serviceConfig = {
ExecStart = cmdline;
ExecStop = "${stopScript { inherit name stop; }} $MAINPID";
Restart = "always";
User = "minecraft";
WorkingDirectory = "${data}/${name}";
StandardInput = "socket";
StandardOutput = "journal";
StandardError = "journal";
# Hardening
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
LockPersonality = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
UMask = "0077";
};
})
) servers;
global.fs.zfs.mountpoints.${data} = "service/minecraft";
networking.firewall.allowedTCPPorts = [ 25565 ];
}