summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hosts/ahmed/minecraft/default.nix27
-rw-r--r--modules/nixos/on-demand-minecraft/default.nix78
2 files changed, 91 insertions, 14 deletions
diff --git a/hosts/ahmed/minecraft/default.nix b/hosts/ahmed/minecraft/default.nix
index fdcad2c..bd4d081 100644
--- a/hosts/ahmed/minecraft/default.nix
+++ b/hosts/ahmed/minecraft/default.nix
@@ -14,17 +14,19 @@
# Try shutting down every 10 minutes.
frequency-check-players = "*-*-* *:00/10:00";
- # Seed requested by Tobias.
- server-properties."level-seed" = "1727502807";
-
# I changed the default location after creating the world.
data-dir = "/srv/minecrafter/papermc-1.21.4-15";
+ # Gameplay settings.
+ server-properties.level-seed = "1727502807"; # Seed requested by Tobias.
+ server-properties.difficulty = "hard"; # Required for some game mechanic.
+ server-properties.allow-cheats = true;
+
# Whitelist generated with this command:
# ```sh
# journalctl --grep='UUID of' --unit=minecraft-server.service \
- # | sed -E 's/.*UUID of player (.*) is (.*).*/"\1" = "\2";/p' -n \
- # | sort -u
+ # | sed -E 's/.*UUID of player (.*) is (.*).*/"\1" = "\2";/p' -n \
+ # | sort -u
# ```
server-properties."white-list" = true;
whitelist = {
@@ -34,6 +36,21 @@
"TobiKanob1" = "07931771-f2eb-4894-ac84-d3a121086d9f";
"Alfholm" = "6a0a1d3b-ad0f-4a73-8e0c-97782a380ff4";
};
+
+ ops = [
+ {
+ username = "BANANABARBARA";
+ uuid = "b3fa0532-e49c-4783-8ba4-e20082983d30";
+ level = 4;
+ # I always need to get on in case something is going wrong.
+ bypasses-player-limit = true;
+ }
+ {
+ username = "Alfholm";
+ uuid = "6a0a1d3b-ad0f-4a73-8e0c-97782a380ff4";
+ level = 2;
+ }
+ ];
};
# Update the DDNS.
diff --git a/modules/nixos/on-demand-minecraft/default.nix b/modules/nixos/on-demand-minecraft/default.nix
index 9497d3f..c84e2ed 100644
--- a/modules/nixos/on-demand-minecraft/default.nix
+++ b/modules/nixos/on-demand-minecraft/default.nix
@@ -8,6 +8,9 @@
}: let
inherit (lib) mkIf mkOption mkEnableOption types;
+ # Custom type for Minecraft UUIDs which are used to uniquely identify players.
+ minecraftUuid = lib.types.strMatching "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" // {description = "Minecraft UUID";};
+
cfg = config.services.on-demand-minecraft;
in {
options.services.on-demand-minecraft = {
@@ -113,15 +116,7 @@ in {
`services.on-demand-minecraft.server-properties` by setting `white-list
= true`.
'';
- type = with types; let
- minecraftUuid =
- strMatching
- "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
- // {
- description = "Minecraft UUID";
- };
- in
- attrsOf minecraftUuid;
+ type = with types; attrsOf minecraftUuid;
example = lib.literalExpression ''
{
username1 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
@@ -131,6 +126,56 @@ in {
default = {};
};
+ ops = mkOption {
+ description = ''
+ List of players with operator status.
+
+ See <https://minecraft.wiki/w/Ops.json> for a description of how ops work.
+ '';
+ type = with types; let
+ opsEntry = submodule {
+ options = {
+ username = mkOption {
+ description = "The player's username";
+ type = nonEmptyStr;
+ };
+
+ uuid = mkOption {
+ description = ''
+ The UUID associated with the player.
+
+ You can use <https://mcuuid.net/> to get a Minecraft UUID for a username.
+ '';
+ type = minecraftUuid;
+ };
+
+ level = mkOption {
+ description = ''
+ The permission level that this user should be given. There are 5 possible levels:
+
+ - Level 0: Everyone
+ - Level 1: Moderator
+ - Level 2: Gamemaster
+ - Level 3: Administrator
+ - Level 4: Owner
+
+ See <https://minecraft.wiki/w/Permission_level> for an explanation of user permission levels.
+ '';
+ type = ints.between 0 4;
+ };
+
+ bypasses-player-limit = mkOption {
+ description = "If true, the operator can join the server even if the player limit has been reached.";
+ type = bool;
+ default = false;
+ };
+ };
+ };
+ in
+ listOf opsEntry;
+ default = [];
+ };
+
jvm-options = mkOption {
description = "JVM options for the Minecraft server. List of command line arguments.";
type = with types; listOf str;
@@ -217,6 +262,20 @@ in {
})
cfg.whitelist));
+ # Takes a mapping of old attribute name -> new attribute name and applies
+ # it to the given attribute set.
+ renameAttrs = mappings: attrset: lib.attrsets.mapAttrs' (name: value: lib.attrsets.nameValuePair (mappings.${name} or name) value) attrset;
+
+ ops-file =
+ pkgs.writeText "ops.json"
+ (builtins.toJSON (
+ map (renameAttrs {
+ "bypasses-player-limit" = "bypassesPlayerlimit";
+ "username" = "name";
+ })
+ cfg.ops
+ ));
+
start-server = pkgs.writeShellScript "minecraft-server-start.sh" ''
# Switch to runtime directory.
${pkgs.busybox}/bin/mkdir -p "${cfg.data-dir}"
@@ -226,6 +285,7 @@ in {
# Set up/update environment for server
ln -sf ${eula-file} eula.txt
ln -sf ${whitelist-file} whitelist.json
+ ln -sf ${ops-file} ops.json
cp -f ${server-properties-file} server.properties
chmod u+w server.properties # Must be writable because server regenerates it.