dotfiles
My PC Dotfiles & Websitegit clone https://github.com/maydayv7/dotfiles
commit 00aaf187e0c4729f91b52472aff8181d80de4396 parent 942d76a45b562bfce946f66814bde0d5ea100475 Author: maydayv7 <maydayv7@gmail.com> Date: Sun, 9 Nov 2025 14:47:51 +0530 feat: Support multiple concurrent Minecraft Servers
Diffstat:
| M | CHANGELOG.md | | | 1 | + |
| M | devices/valkyrie/minecraft.nix | | | 45 | ++++++++++++++++++++++++++++++--------------- |
| M | modules/README.md | | | 4 | +++- |
| M | modules/apps/games/mc-server.nix | | | 319 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
4 files changed, 212 insertions(+), 157 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -2,6 +2,7 @@ ### November +- Support multiple concurrent Minecraft Servers - Update Hyprland to v0.52 - Add modded skyblock Minecraft Server diff --git a/devices/valkyrie/minecraft.nix b/devices/valkyrie/minecraft.nix @@ -5,21 +5,36 @@ system.nixos.label = "special.minecraft"; apps = { games = [ "mc-server" ]; - mc-server = { - type = "skyblock"; - memory = 16; - vc-port = 24454; - config = { - motd = "My World"; - difficulty = "normal"; - gamemode = "survival"; - online-mode = false; - server-ip = "0.0.0.0"; - server-port = 25565; - spawn-protection = 0; - allow-flight = true; - }; - }; + mc-servers = + let + shared = { + gamemode = "survival"; + difficulty = "normal"; + online-mode = false; + server-ip = "0.0.0.0"; + spawn-protection = 0; + }; + in + [ + { + type = "fabric"; + memory = 16; + port = 25565; + vc-port = 24454; + config = shared // { + motd = "My World"; + }; + } + { + type = "skyblock"; + memory = 10; + port = 25567; + config = shared // { + motd = "Modded Skyblock"; + allow-flight = true; + }; + } + ]; }; # VPN Tunnel diff --git a/modules/README.md b/modules/README.md @@ -21,10 +21,12 @@ Configuration [Builder](./configuration.nix) - `logseq.style`: Path to Logseq Notes CSS - `ytmusic.style`: YouTube Music CSS - `games`: List of installed games - `[ "minecraft" "mc-server" "osu" ]` - - `mc-server`: Configure Minecraft Server - + - `mc-servers`: List of Minecraft Servers - + - `name`: Unique server name - `type`: Server Type - `[ "fabric" "skyblock" ]` - `memory`: Memory (GB) allocated to server - Ex. `12` - `config`: Server Properties (See [here](https://minecraft.fandom.com/wiki/Server.properties)) + - `port`: Main server TCP port - Ex. `25565` - `vc-port`: Port for [Simple Voice Chat](https://modrinth.com/plugin/simple-voice-chat) - Ex. `24454` - [`base`](./base): Module that contains the base common/shared configuration - diff --git a/modules/apps/games/mc-server.nix b/modules/apps/games/mc-server.nix @@ -11,171 +11,208 @@ let inherit (builtins) attrValues elem - isInt + listToAttrs toString ; inherit (lib) + concatMap mkIf + mkMerge mkOption types ; - inherit (pkgs) fetchurl linkFarmFromDrvs; + inherit (pkgs) fetchurl fetchzip linkFarmFromDrvs; - cfg = config.apps.mc-server; - mem = toString cfg.memory; - vc = isInt cfg.vc-port; + cfg = config.apps.mc-servers; dataDir = "/srv/minecraft"; in { - ## Minecraft Server ## imports = [ inputs.minecraft.nixosModules.minecraft-servers ]; - options.apps.mc-server = { - type = mkOption { - description = "Server Type"; - type = types.enum [ - "fabric" - "skyblock" - ]; - default = "default"; - }; + options.apps.mc-servers = mkOption { + description = "List of Minecraft Servers"; + default = [ ]; + type = types.listOf ( + types.submodule ( + { config, ... }: + { + options = { + name = mkOption { + description = "Unique server name"; + type = types.str; + default = config.type; + }; - config = mkOption { - description = "Server Properties"; - type = types.attrs; - default = { }; - }; + type = mkOption { + description = "Server Type"; + type = types.enum [ + "fabric" + "skyblock" + ]; + default = "fabric"; + }; - memory = mkOption { - description = "Memory (GB) allocated to Server"; - type = types.int; - default = 12; - }; + memory = mkOption { + description = "Memory (GB) allocated to server"; + type = types.int; + default = 12; + }; - vc-port = mkOption { - description = "Port for Simple Voice Chat"; - type = with types; nullOr int; - default = null; - }; + config = mkOption { + description = "Server Properties"; + type = types.attrs; + default = { }; + }; + + port = mkOption { + description = "Main server TCP port"; + type = types.int; + default = 25565; + }; + + vc-port = mkOption { + description = "Port for Simple Voice Chat"; + type = with types; nullOr int; + default = null; + }; + }; + } + ) + ); }; config = mkIf (elem "mc-server" config.apps.games) { hardware.fs.persist.directories = [ dataDir ]; - networking.firewall.allowedUDPPorts = mkIf vc [ cfg.vc-port ]; - services.minecraft-servers = - let - shared = { - autoStart = true; - serverProperties = cfg.config; - jvmOpts = "-Xms${mem}G -Xmx${mem}G --add-modules=jdk.incubator.vector -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=15"; - }; - in - { - enable = true; - inherit dataDir; - eula = true; - openFirewall = true; - managementSystem = { - tmux.enable = false; - systemd-socket.enable = true; - }; + networking.firewall = { + allowedTCPPorts = map (srv: srv.port) cfg; + allowedUDPPorts = concatMap (srv: if (srv.vc-port != null) then [ srv.vc-port ] else [ ]) cfg; + }; + + services.minecraft-servers = { + enable = true; + inherit dataDir; + eula = true; + openFirewall = true; + managementSystem = { + tmux.enable = false; + systemd-socket.enable = true; + }; + + servers = listToAttrs ( + map (srv: { + inherit (srv) name; + value = mkMerge [ + { + enable = true; + autoStart = false; + serverProperties = srv.config // { + server-port = srv.port; + }; + jvmOpts = + let + mem = toString srv.memory; + in + "-Xms${mem}G -Xmx${mem}G --add-modules=jdk.incubator.vector -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=15"; + } - servers = { - fabric = shared // { - enable = cfg.type == "fabric"; - package = pkgs.fabricServers.fabric-1_21_10; - symlinks.mods = linkFarmFromDrvs "mods" ( - attrValues ( - { - # Server - FabricAPI = fetchurl { - url = "https://cdn.modrinth.com/data/P7dR8mSH/versions/lxeiLRwe/fabric-api-0.136.0%2B1.21.10.jar"; - sha256 = "sha256-ADKAQNMSXhDUF/Fviupkr3JxmH6RFVRLuwvjK7PQV5c="; - }; - Lithium = fetchurl { - url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/oGKQMdyZ/lithium-fabric-0.20.0%2Bmc1.21.10.jar"; - sha256 = "sha256-567yN1D2eJgsAMQhjWIFljqZRVRFfCoWvZgY41IQAEs="; - }; - Krypton = fetchurl { - url = "https://cdn.modrinth.com/data/fQEb0iXm/versions/O9LmWYR7/krypton-0.2.10.jar"; - sha256 = "sha256-lCkdVpCgztf+fafzgP29y+A82sitQiegN4Zrp0Ve/4s="; - }; - FerriteCore = fetchurl { - url = "https://cdn.modrinth.com/data/uXXizFIs/versions/CtMpt7Jr/ferritecore-8.0.0-fabric.jar"; - sha256 = "sha256-K5C/AMKlgIw8U5cSpVaRGR+HFtW/pu76ujXpxMWijuo="; - }; - ScalableLux = fetchurl { - url = "https://cdn.modrinth.com/data/Ps1zyz6x/versions/PV9KcrYQ/ScalableLux-0.1.6%2Bfabric.c25518a-all.jar"; - sha256 = "sha256-ekpzcThhg8dVUjtWtVolHXWsLCP0Cvik8PijNbBdT8I="; - }; - C2ME = fetchurl { - url = "https://cdn.modrinth.com/data/VSNURh3q/versions/eY3dbqLu/c2me-fabric-mc1.21.10-0.3.5.0.0.jar"; - sha256 = "sha256-PZxX7IE3Zc+zsQrMc/LdI1jpUC9l/ov7z334OucWpgA="; - }; + ## Fabric Server + (mkIf (srv.type == "fabric") { + package = pkgs.fabricServers.fabric-1_21_10; + symlinks.mods = linkFarmFromDrvs "mods" ( + attrValues ( + { + # Server + FabricAPI = fetchurl { + url = "https://cdn.modrinth.com/data/P7dR8mSH/versions/lxeiLRwe/fabric-api-0.136.0%2B1.21.10.jar"; + sha256 = "sha256-ADKAQNMSXhDUF/Fviupkr3JxmH6RFVRLuwvjK7PQV5c="; + }; + Lithium = fetchurl { + url = "https://cdn.modrinth.com/data/gvQqBUqZ/versions/oGKQMdyZ/lithium-fabric-0.20.0%2Bmc1.21.10.jar"; + sha256 = "sha256-567yN1D2eJgsAMQhjWIFljqZRVRFfCoWvZgY41IQAEs="; + }; + Krypton = fetchurl { + url = "https://cdn.modrinth.com/data/fQEb0iXm/versions/O9LmWYR7/krypton-0.2.10.jar"; + sha256 = "sha256-lCkdVpCgztf+fafzgP29y+A82sitQiegN4Zrp0Ve/4s="; + }; + FerriteCore = fetchurl { + url = "https://cdn.modrinth.com/data/uXXizFIs/versions/CtMpt7Jr/ferritecore-8.0.0-fabric.jar"; + sha256 = "sha256-K5C/AMKlgIw8U5cSpVaRGR+HFtW/pu76ujXpxMWijuo="; + }; + ScalableLux = fetchurl { + url = "https://cdn.modrinth.com/data/Ps1zyz6x/versions/PV9KcrYQ/ScalableLux-0.1.6%2Bfabric.c25518a-all.jar"; + sha256 = "sha256-ekpzcThhg8dVUjtWtVolHXWsLCP0Cvik8PijNbBdT8I="; + }; + C2ME = fetchurl { + url = "https://cdn.modrinth.com/data/VSNURh3q/versions/eY3dbqLu/c2me-fabric-mc1.21.10-0.3.5.0.0.jar"; + sha256 = "sha256-PZxX7IE3Zc+zsQrMc/LdI1jpUC9l/ov7z334OucWpgA="; + }; - PlayerRoles = fetchurl { - url = "https://cdn.modrinth.com/data/Rt1mrUHm/versions/Qi5eDlej/player-roles-1.7.0.jar"; - sha256 = "sha256-+0nk/J2W3hVDdkKlZRHY4dBde3aF8e8Y1SPFOgDWNb0="; - }; - SkinRestorer = fetchurl { - url = "https://cdn.modrinth.com/data/ghrZDhGW/versions/MKWfnXfO/skinrestorer-2.4.3%2B1.21.9-fabric.jar"; - sha256 = "sha256-ypyDuX94HyUPlUI4CrFc0Pc01lUQXgYPqP/axaCi6Hc="; - }; - Silk = fetchurl { - url = "https://cdn.modrinth.com/data/aTaCgKLW/versions/2OisNxPN/silk-all-1.11.4.jar"; - sha256 = "sha256-C2VcLfFGweGOO+Xi1mOTkETX3NpoEdSz+9kYmEIDDv0="; - }; - FabricKotlin = fetchurl { - url = "https://cdn.modrinth.com/data/Ha28R6CL/versions/LcgnDDmT/fabric-language-kotlin-1.13.7%2Bkotlin.2.2.21.jar"; - sha256 = "sha256-d5UZY+3V19N+5PF0431GqHHkW5c0JvO0nWclyBm0uPI="; - }; - Veinminer = fetchurl { - url = "https://cdn.modrinth.com/data/OhduvhIc/versions/lCVEKyxE/veinminer-fabric-2.5.0.jar"; - sha256 = "sha256-13PbmxgTfM+WkQht7hsHrkEImXgTeBUpeKOcGtE/cOI="; - }; - VeinminerEnchant = fetchurl { - url = "https://cdn.modrinth.com/data/4sP0LXxp/versions/h5oKcjvq/veinminer-enchant-2.3.0.jar"; - sha256 = "sha256-NvGnsY9nfI+IMy2+Ljr1IahMqim9xOsRgojaFKWk/xQ="; - }; + PlayerRoles = fetchurl { + url = "https://cdn.modrinth.com/data/Rt1mrUHm/versions/Qi5eDlej/player-roles-1.7.0.jar"; + sha256 = "sha256-+0nk/J2W3hVDdkKlZRHY4dBde3aF8e8Y1SPFOgDWNb0="; + }; + SkinRestorer = fetchurl { + url = "https://cdn.modrinth.com/data/ghrZDhGW/versions/MKWfnXfO/skinrestorer-2.4.3%2B1.21.9-fabric.jar"; + sha256 = "sha256-ypyDuX94HyUPlUI4CrFc0Pc01lUQXgYPqP/axaCi6Hc="; + }; + Silk = fetchurl { + url = "https://cdn.modrinth.com/data/aTaCgKLW/versions/2OisNxPN/silk-all-1.11.4.jar"; + sha256 = "sha256-C2VcLfFGweGOO+Xi1mOTkETX3NpoEdSz+9kYmEIDDv0="; + }; + FabricKotlin = fetchurl { + url = "https://cdn.modrinth.com/data/Ha28R6CL/versions/LcgnDDmT/fabric-language-kotlin-1.13.7%2Bkotlin.2.2.21.jar"; + sha256 = "sha256-d5UZY+3V19N+5PF0431GqHHkW5c0JvO0nWclyBm0uPI="; + }; + Veinminer = fetchurl { + url = "https://cdn.modrinth.com/data/OhduvhIc/versions/lCVEKyxE/veinminer-fabric-2.5.0.jar"; + sha256 = "sha256-13PbmxgTfM+WkQht7hsHrkEImXgTeBUpeKOcGtE/cOI="; + }; + VeinminerEnchant = fetchurl { + url = "https://cdn.modrinth.com/data/4sP0LXxp/versions/h5oKcjvq/veinminer-enchant-2.3.0.jar"; + sha256 = "sha256-NvGnsY9nfI+IMy2+Ljr1IahMqim9xOsRgojaFKWk/xQ="; + }; - # Client and Server - Jade = fetchurl { - url = "https://cdn.modrinth.com/data/nvQzSEkH/versions/qC0qUqL5/Jade-1.21.9-Fabric-20.0.5.jar"; - sha256 = "sha256-HZfvnnYeRgbgQROdq6v9U7fnx1MhNaseaedNJPJpNxE="; - }; - } - // ( - if vc then - { - SimpleVC = fetchurl { - url = "https://cdn.modrinth.com/data/9eGKb6K1/versions/BjR2lc4k/voicechat-fabric-1.21.10-2.6.6.jar"; - sha256 = "sha256-yC5pMBLsi4BnUq4CxTfwe4MGTqoBg04ZaRrsBC3Ds3Y="; - }; - } - else - { } + # Client and Server + Jade = fetchurl { + url = "https://cdn.modrinth.com/data/nvQzSEkH/versions/qC0qUqL5/Jade-1.21.9-Fabric-20.0.5.jar"; + sha256 = "sha256-HZfvnnYeRgbgQROdq6v9U7fnx1MhNaseaedNJPJpNxE="; + }; + } + // ( + if (srv.vc-port != null) then + { + SimpleVC = fetchurl { + url = "https://cdn.modrinth.com/data/9eGKb6K1/versions/BjR2lc4k/voicechat-fabric-1.21.10-2.6.6.jar"; + sha256 = "sha256-yC5pMBLsi4BnUq4CxTfwe4MGTqoBg04ZaRrsBC3Ds3Y="; + }; + } + else + { } + ) ) - ) - ); - }; + ); + }) - # Ozone Skyblock Reborn 2 - skyblock = - let - inherit (inputs.minecraft.lib) collectFilesAt; - modpack = pkgs.fetchzip { - url = "https://mediafilez.forgecdn.net/files/7165/375/OSR2%201.1.5%20-%20Server.zip"; - sha256 = "sha256-5oVl3zcQQ6ad6Yx79+9m7K5wHzFVgK1zlEXE4NAuOfQ="; - }; - in - shared - // { - enable = cfg.type == "skyblock"; - package = pkgs.neoforgeServers.neoforge-1_21_1; - files = (collectFilesAt modpack "config") // (collectFilesAt modpack "kubejs"); - symlinks = collectFilesAt modpack "mods"; - }; - }; - }; + ## Modded Skyblock Server + (mkIf (srv.type == "skyblock") ( + let + inherit (inputs.minecraft.lib) collectFilesAt; + + # Ozone Skyblock Reborn 2 + modpack = fetchzip { + url = "https://mediafilez.forgecdn.net/files/7165/375/OSR2%201.1.5%20-%20Server.zip"; + sha256 = "sha256-5oVl3zcQQ6ad6Yx79+9m7K5wHzFVgK1zlEXE4NAuOfQ="; + }; + in + { + package = pkgs.neoforgeServers.neoforge-1_21_1; + files = (collectFilesAt modpack "config") // (collectFilesAt modpack "kubejs"); + symlinks = collectFilesAt modpack "mods"; + } + )) + ]; + }) cfg + ); + }; }; }