{ config, options, lib, pkgs, ... }: let inherit (lib) types; cfg = config.plusultra.services.minecraft; in { options.plusultra.services.minecraft = { enable = lib.mkEnableOption "Minecraft server"; eula = lib.mkOption { type = types.bool; default = false; description = lib.mdDoc '' Whether you agree to [Mojang's EULA](https://account.mojang.com/documents/minecraft_eula). This option must be set to `true` to run Minecraft server. ''; }; infrared = { enable = lib.mkEnableOption "Infrared"; }; servers = lib.mkOption { default = { }; description = "The Minecraft servers to run."; example = lib.literalExpression '' { # A default vanilla server. vanilla-1 = {}; # A vanilla server with a custom port. vanilla-2 = { port = 4000; }; # A vanilla server proxied by Infrared (when enabled). vanilla-3 = { domain = "minecraft.example.com"; }; # A Forge server. forge-1 = { type = "forge"; }; # Use a custom Minecraft server version. custom-vanilla = { package = pkgs.minecraft-server_1_12_2; }; # Use a custom Forge server version. custom-forge = { type = "forge"; package = pkgs.minecraft-forge_1_19_2-43_1_25; }; } ''; type = types.attrsOf (types.submodule ({ config, name, ... }: { options = { type = lib.mkOption { type = types.enum [ "vanilla" "forge" ]; default = "vanilla"; description = "The kind of Minecraft server to create."; }; package = lib.mkOption { type = types.package; default = if config.type == "vanilla" then pkgs.minecraft-server else pkgs.plusultra.minecraft-forge; defaultText = lib.literalExpression '' pkgs.minecraft-server ''; }; dataDir = lib.mkOption { type = types.path; default = "/var/lib/minecraft/${name}"; defaultText = "/var/lib/minecraft/"; description = "The datrectory where data for the server is stored."; }; port = lib.mkOption { type = types.port; default = 25565; description = "The port for the server to listen on."; }; domain = lib.mkOption { type = types.str; default = ""; description = "The domain to pass to Infrared (if enabled)."; }; jvmOpts = lib.mkOption { type = types.separatedString " "; default = "-Xmx2048M -Xms2048M"; # Example options from https://minecraft.gamepedia.com/Tutorials/Server_startup_script example = "-Xms4092M -Xmx4092M -XX:+UseG1GC -XX:+CMSIncrementalPacing " + "-XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 " + "-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10"; description = lib.mdDoc "JVM options for the Minecraft server."; }; serverProperties = lib.mkOption { type = types.attrsOf (types.oneOf [ types.bool types.int types.str ]); default = { }; example = lib.literalExpression '' { server-port = 43000; difficulty = 3; gamemode = 1; max-players = 5; motd = "NixOS Minecraft server!"; white-list = true; enable-rcon = true; "rcon.password" = "hunter2"; } ''; description = lib.mdDoc '' Minecraft server properties for the server.properties file. Only has an effect when {option}`services.minecraft-server.declarative` is set to `true`. See for documentation on these values. ''; }; whitelist = lib.mkOption { type = let 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"; }; in lib.types.attrsOf minecraftUUID; default = { }; description = lib.mdDoc '' Whitelisted players, only has an effect when {option}`services.minecraft-server.declarative` is `true` and the whitelist is enabled via {option}`services.minecraft-server.serverProperties` by setting `white-list` to `true`. This is a mapping from Minecraft usernames to UUIDs. You can use to get a Minecraft UUID for a username. ''; example = lib.literalExpression '' { username1 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; username2 = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"; }; ''; }; openFirewall = lib.mkOption { type = types.bool; default = false; description = lib.mdDoc '' Whether to open ports in the firewall for the server. ''; }; declarative = lib.mkOption { type = types.bool; default = false; description = lib.mdDoc '' Whether to use a declarative Minecraft server configuration. Only if set to `true`, the options {option}`plusultra.services.minecraft.servers..whitelist` and {option}`plusultra.services.minecraft.servers..serverProperties` will be applied. ''; }; extraInfraredOptions = lib.mkOption { type = types.attrs; default = { }; description = lib.mdDoc '' Extra options passed to Infrared (if enabled) when configuring this server. ''; }; }; })); }; }; }