diff --git a/nki-home/configuration.nix b/nki-home/configuration.nix index 9846344..b3a4f99 100644 --- a/nki-home/configuration.nix +++ b/nki-home/configuration.nix @@ -34,6 +34,7 @@ in ../modules/personal/u2f.nix ./peertube-runner.nix ./deluge.nix + ./minecraft.nix openrazer ]; diff --git a/nki-home/minecraft.nix b/nki-home/minecraft.nix new file mode 100644 index 0000000..72541c0 --- /dev/null +++ b/nki-home/minecraft.nix @@ -0,0 +1,103 @@ +{ + 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" ]; + }; +}