diff options
-rw-r--r-- | hosts/ahmed/minecraft/default.nix | 27 | ||||
-rw-r--r-- | modules/nixos/on-demand-minecraft/default.nix | 78 |
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. |