103 lines
3.3 KiB
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" ];
|
|
};
|
|
}
|