mirror of
https://github.com/nmasur/dotfiles
synced 2024-11-22 15:45:38 +00:00
autostart and stop minecraft server
This commit is contained in:
parent
e2af159c26
commit
c2d0037bab
@ -1,4 +1,13 @@
|
|||||||
{ ... }: {
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
localPort = 25564;
|
||||||
|
publicPort = 25565;
|
||||||
|
rconPort = 25575;
|
||||||
|
rconPassword = "thiscanbeanything";
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
unfreePackages = [ "minecraft-server" ];
|
unfreePackages = [ "minecraft-server" ];
|
||||||
|
|
||||||
@ -7,9 +16,9 @@
|
|||||||
eula = true;
|
eula = true;
|
||||||
declarative = true;
|
declarative = true;
|
||||||
whitelist = { };
|
whitelist = { };
|
||||||
openFirewall = true;
|
openFirewall = false;
|
||||||
serverProperties = {
|
serverProperties = {
|
||||||
server-port = 25565;
|
server-port = localPort;
|
||||||
difficulty = "normal";
|
difficulty = "normal";
|
||||||
gamemode = "survival";
|
gamemode = "survival";
|
||||||
white-list = false;
|
white-list = false;
|
||||||
@ -26,7 +35,112 @@
|
|||||||
spawn-monsters = true;
|
spawn-monsters = true;
|
||||||
allow-nether = true;
|
allow-nether = true;
|
||||||
allow-flight = false;
|
allow-flight = false;
|
||||||
|
enable-rcon = true;
|
||||||
|
"rcon.port" = rconPort;
|
||||||
|
"rcon.password" = rconPassword;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ publicPort ];
|
||||||
|
|
||||||
|
## Automatically start and stop Minecraft server based on player connections
|
||||||
|
|
||||||
|
# Adapted shamelessly from:
|
||||||
|
# https://dataswamp.org/~solene/2022-08-20-on-demand-minecraft-with-systemd.html
|
||||||
|
|
||||||
|
# Prevent Minecraft from starting by default
|
||||||
|
systemd.services.minecraft-server = { wantedBy = pkgs.lib.mkForce [ ]; };
|
||||||
|
|
||||||
|
# Listen for connections on the public port, to trigger the actual
|
||||||
|
# listen-minecraft service.
|
||||||
|
systemd.sockets.listen-minecraft = {
|
||||||
|
wantedBy = [ "sockets.target" ];
|
||||||
|
requires = [ "network.target" ];
|
||||||
|
listenStreams = [ "${toString publicPort}" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Proxy traffic to local port, and trigger hook-minecraft
|
||||||
|
systemd.services.listen-minecraft = {
|
||||||
|
path = [ pkgs.systemd ];
|
||||||
|
requires = [ "hook-minecraft.service" "listen-minecraft.socket" ];
|
||||||
|
after = [ "hook-minecraft.service" "listen-minecraft.socket" ];
|
||||||
|
serviceConfig.ExecStart =
|
||||||
|
"${pkgs.systemd.out}/lib/systemd/systemd-socket-proxyd 127.0.0.1:${
|
||||||
|
toString localPort
|
||||||
|
}";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Start Minecraft if required and wait for it to be available
|
||||||
|
# Then unlock the listen-minecraft.service
|
||||||
|
systemd.services.hook-minecraft = {
|
||||||
|
path = with pkgs; [ systemd libressl busybox ];
|
||||||
|
|
||||||
|
# Start Minecraft and the auto-shutdown timer
|
||||||
|
script = ''
|
||||||
|
systemctl start minecraft-server.service
|
||||||
|
systemctl start stop-minecraft.timer
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Keep checking until the service is available
|
||||||
|
postStart = ''
|
||||||
|
for i in $(seq 60); do
|
||||||
|
if ${pkgs.libressl.nc}/bin/nc -z 127.0.0.1 ${
|
||||||
|
toString localPort
|
||||||
|
} > /dev/null ; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
${pkgs.busybox.out}/bin/sleep 1
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Run a player check on a schedule for auto-shutdown
|
||||||
|
systemd.timers.stop-minecraft = {
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "*-*-* *:*:0/20"; # Every 20 seconds
|
||||||
|
Unit = "stop-minecraft.service";
|
||||||
|
};
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
# If no players are connected, then stop services and prepare to resume again
|
||||||
|
systemd.services.stop-minecraft = {
|
||||||
|
serviceConfig.Type = "oneshot";
|
||||||
|
script = ''
|
||||||
|
# Check when service was launched
|
||||||
|
servicestartsec=$(
|
||||||
|
date -d \
|
||||||
|
"$(systemctl show \
|
||||||
|
--property=ActiveEnterTimestamp \
|
||||||
|
minecraft-server.service \
|
||||||
|
| cut -d= -f2)" \
|
||||||
|
+%s)
|
||||||
|
|
||||||
|
# Calculate elapsed time
|
||||||
|
serviceelapsedsec=$(( $(date +%s) - servicestartsec))
|
||||||
|
|
||||||
|
# Ignore if service just started
|
||||||
|
if [ $serviceelapsedsec -lt 180 ]
|
||||||
|
then
|
||||||
|
echo "Server was just started"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
PLAYERS=$(
|
||||||
|
printf "list\n" \
|
||||||
|
| ${pkgs.rcon.out}/bin/rcon -m \
|
||||||
|
-H 127.0.0.1 -p ${builtins.toString rconPort} -P ${rconPassword} \
|
||||||
|
)
|
||||||
|
|
||||||
|
if echo "$PLAYERS" | grep "are 0 of a"
|
||||||
|
then
|
||||||
|
echo "Stopping server"
|
||||||
|
systemctl stop minecraft-server.service
|
||||||
|
systemctl stop hook-minecraft.service
|
||||||
|
systemctl stop stop-minecraft.timer
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user