nix-home/nki-home/minecraft.nix

103 lines
3.3 KiB
Nix

{
pkgs,
lib,
...
}:
let
dataDir = "/mnt/steam/mc/";
javaOpts = "-Xms4096M -Xmx4096M -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+ParallelRefProcEnabled -XX:+PerfDisableSharedMem -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:G1HeapWastePercent=5 -XX:G1MaxNewSizePercent=40 -XX:G1MixedGCCountTarget=4 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1NewSizePercent=30 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:G1ReservePercent=20 -XX:InitiatingHeapOccupancyPercent=15 -XX:MaxGCPauseMillis=200 -XX:MaxTenuringThreshold=1 -XX:SurvivorRatio=32 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true";
name = "paper-mc";
socketName = "${name}.stdin";
socket = "/run/${socketName}";
console = pkgs.writeScriptBin "papermc-console" ''
#!${lib.getExe pkgs.python3}
# https://github.com/AtomicSponge/paper-systemd/blob/main/minecraft-console.py
import curses
import subprocess
import threading
def run_journalctl(win):
process = subprocess.Popen(['journalctl', '-u', '${name}', '--follow'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
line = process.stdout.readline()
if not line:
break
win.addstr(line.decode())
win.refresh()
def input_commands(win):
with open('${socket}', 'a') as f:
while True:
win.clear()
win.addstr("Enter command (Ctrl-C to exit): ")
curses.echo()
win.move(1, 0)
command = win.getstr().decode()
f.write(command + "\n")
f.flush()
curses.noecho()
win.clear()
def main(stdscr):
try:
curses.curs_set(1)
stdscr.clear()
height, width = stdscr.getmaxyx()
journal_height = int(height * 0.9)
input_height = height - journal_height
journal_win = stdscr.subwin(journal_height, width, 0, 0)
journal_win.scrollok(True)
input_win = stdscr.subwin(input_height, width, journal_height, 0)
thread = threading.Thread(target=run_journalctl, args=(journal_win,))
thread.daemon = True
thread.start()
input_commands(input_win)
except KeyboardInterrupt:
stdscr.clear()
stdscr.refresh()
finally:
curses.endwin()
if __name__ == "__main__":
curses.wrapper(main)
'';
in
{
environment.systemPackages = [ console ];
users.users.${name} = {
isSystemUser = true;
group = name;
};
users.users.nki.extraGroups = [ name ];
users.groups.${name} = {
};
systemd.sockets.${name} = {
partOf = [ "${name}.service" ];
socketConfig.ListenFIFO = "%t/${socketName}";
};
systemd.services.${name} = {
description = "Minecraft Server";
serviceConfig = {
Type = "simple";
WorkingDirectory = dataDir;
User = name;
Restart = "on-failure";
Sockets = "${name}.socket";
StandardInput = "socket";
StandardOutput = "journal";
StandardError = "journal";
ReadWritePaths = [ dataDir ];
};
environment.JAVA_OPTS = javaOpts;
script = "${lib.getExe pkgs.papermc}";
preStop = "echo stop > ${socket}";
wantedBy = [ "multi-user.target" ];
};
}