feat(minecraft): allowlist

This commit is contained in:
arcnmx 2024-04-27 14:56:06 -07:00
parent 15a0034cc7
commit 2de8a52d0a
5 changed files with 138 additions and 61 deletions

View file

@ -6,9 +6,9 @@
nixlib = inputs.nixpkgs.lib; nixlib = inputs.nixpkgs.lib;
inherit (nixlib.modules) mkOrder mkOverride defaultOverridePriority; inherit (nixlib.modules) mkOrder mkOverride defaultOverridePriority;
inherit (nixlib.strings) splitString toLower; inherit (nixlib.strings) splitString toLower;
inherit (nixlib.lists) imap0 elemAt findFirst; inherit (nixlib.lists) imap0 elemAt findFirst foldl;
inherit (nixlib.attrsets) mapAttrs listToAttrs nameValuePair; inherit (nixlib.attrsets) mapAttrs listToAttrs nameValuePair;
inherit (nixlib.strings) hasPrefix hasInfix removePrefix substring fixedWidthString replaceStrings concatMapStringsSep match toInt; inherit (nixlib.strings) hasPrefix hasInfix removePrefix substring fixedWidthString replaceStrings concatMapStringsSep stringToCharacters match toInt;
inherit (nixlib.trivial) flip toHexString bitOr; inherit (nixlib.trivial) flip toHexString bitOr;
toHexStringLower = v: toLower (toHexString v); toHexStringLower = v: toLower (toHexString v);
@ -19,6 +19,7 @@
idx = listToAttrs pairs; idx = listToAttrs pairs;
in in
char: idx.${char}; char: idx.${char};
hexToInt = str: foldl (value: chr: value * 16 + hexCharToInt chr) 0 (stringToCharacters (toLower str));
eui64 = mac: let eui64 = mac: let
parts = map toLower (splitString ":" mac); parts = map toLower (splitString ":" mac);
@ -98,7 +99,7 @@ in {
domain = "gensokyo.zone"; domain = "gensokyo.zone";
inherit treeToModulesOutput userIs inherit treeToModulesOutput userIs
eui64 parseUrl mkWinPath mkBaseDn mkAddress6 eui64 parseUrl mkWinPath mkBaseDn mkAddress6
toHexStringLower hexCharToInt toHexStringLower hexToInt hexCharToInt
mapListToAttrs coalesce mapListToAttrs coalesce
mkAlmostOptionDefault mkAlmostDefault mkAlmostForce mapOverride mapOptionDefaults mapAlmostOptionDefaults mapDefaults mkAlmostOptionDefault mkAlmostDefault mkAlmostForce mapOverride mapOptionDefaults mapAlmostOptionDefaults mapDefaults
overrideOptionDefault overrideAlmostOptionDefault overrideDefault overrideAlmostDefault overrideNone overrideAlmostForce overrideForce overrideVM overrideOptionDefault overrideAlmostOptionDefault overrideDefault overrideAlmostDefault overrideNone overrideAlmostForce overrideForce overrideVM

View file

@ -1,7 +1,37 @@
{ config, lib, pkgs, ... }: let let
allowListModule = {config, name, gensokyo-zone, lib, ...}: let
inherit (gensokyo-zone.lib) hexToInt;
inherit (lib.options) mkOption;
inherit (lib.modules) mkOptionDefault;
inherit (builtins) typeOf;
in {
options = with lib.types; {
name = mkOption {
type = str;
default = name;
};
xuid = mkOption {
type = oneOf [ int str ];
};
settings = mkOption {
type = attrsOf str;
};
};
config = {
settings = {
name = mkOptionDefault config.name;
xuid = mkOptionDefault {
string = toString (hexToInt config.xuid);
int = toString config.xuid;
}.${typeOf config.xuid};
};
};
};
in { config, gensokyo-zone, lib, pkgs, ... }: let
# see https://gist.github.com/datakurre/cfdf627fb23ed8ff62bb7b3520b92674 # see https://gist.github.com/datakurre/cfdf627fb23ed8ff62bb7b3520b92674
inherit (gensokyo-zone.lib) mapOptionDefaults;
inherit (lib.options) mkOption mkPackageOption; inherit (lib.options) mkOption mkPackageOption;
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf mkMerge mkOptionDefault;
inherit (lib.attrsets) mapAttrsToList; inherit (lib.attrsets) mapAttrsToList;
inherit (lib.strings) concatStringsSep; inherit (lib.strings) concatStringsSep;
inherit (lib.trivial) boolToString; inherit (lib.trivial) boolToString;
@ -35,32 +65,6 @@ in {
serverProperties = mkOption { serverProperties = mkOption {
type = attrsOf (oneOf [ bool int str float ]); type = attrsOf (oneOf [ bool int str float ]);
default = {
server-name = "Dedicated Server";
gamemode = "survival";
difficulty = "easy";
allow-cheats = false;
max-players = 10;
online-mode = false;
white-list = false;
server-port = 19132;
server-portv6 = 19133;
view-distance = 32;
tick-distance = 4;
player-idle-timeout = 30;
max-threads = 8;
level-name = "Bedrock level";
level-seed = "";
default-player-permission-level = "member";
texturepack-required = false;
content-log-file-enabled = false;
compression-threshold = 1;
server-authoritative-movement = "server-auth";
player-movement-score-threshold = 20;
player-movement-distance-threshold = 0.3;
player-movement-duration-threshold-in-ms = 500;
correct-player-movement = false;
};
example = literalExample '' example = literalExample ''
{ {
server-name = "Dedicated Server"; server-name = "Dedicated Server";
@ -111,43 +115,123 @@ in {
type = str; type = str;
default = cfg.user; default = cfg.user;
}; };
allowPlayers = mkOption {
type = nullOr (attrsOf (submoduleWith {
modules = [ allowListModule ];
specialArgs = {
inherit gensokyo-zone;
nixosConfig = config;
};
}));
default = null;
};
allowList = mkOption {
type = nullOr path;
};
}; };
config = mkIf cfg.enable { config = let
users.users.${cfg.user} = { confService.services.minecraft-bedrock-server = {
serverProperties = mapOptionDefaults {
server-name = "Dedicated Server";
gamemode = "survival";
difficulty = "easy";
allow-cheats = false;
max-players = 10;
online-mode = false;
allow-list = cfg.allowList != null;
server-port = 19132;
server-portv6 = 19133;
view-distance = 32;
tick-distance = 4;
player-idle-timeout = 30;
max-threads = 8;
level-name = "Bedrock level";
level-seed = "";
default-player-permission-level = "member";
texturepack-required = false;
content-log-file-enabled = false;
compression-threshold = 1;
server-authoritative-movement = "server-auth";
player-movement-score-threshold = 20;
player-movement-distance-threshold = 0.3;
player-movement-duration-threshold-in-ms = 500;
correct-player-movement = false;
};
allowList = let
allowPlayers = mapAttrsToList (_: allow: allow.settings) cfg.allowPlayers;
allowListJson = pkgs.writeText "minecraft-bedrock-server-allowlist.json" (
builtins.toJSON allowPlayers
);
in mkOptionDefault (
if cfg.allowPlayers != null then allowListJson
else null
);
};
conf.users.users.${cfg.user} = {
inherit (cfg) group; inherit (cfg) group;
description = "Minecraft server service user"; description = "Minecraft server service user";
home = cfg.dataDir; home = cfg.dataDir;
createHome = true; createHome = true;
isSystemUser = true; isSystemUser = true;
}; };
users.groups.${cfg.group} = {}; conf.users.groups.${cfg.group} = {};
systemd.services.minecraft-bedrock-server = { conf.systemd.services.minecraft-bedrock-server = {
description = "Minecraft Bedrock Server Service"; description = "Minecraft Bedrock Server Service";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; after = [ "network.target" ];
serviceConfig = { serviceConfig = {
BindReadOnlyPaths = let
packageResources = map (subpath: "${cfg.package}/var/lib/${subpath}:${cfg.dataDir}/${subpath}") [
"definitions/attachables"
"definitions/biomes"
"definitions/feature_rules"
"definitions/features"
"definitions/persona"
"definitions/sdl_layouts"
"definitions/spawn_groups"
"resource_packs/vanilla"
"resource_packs/chemistry"
"config/default"
"bedrock_server_symbols.debug"
"env-vars"
"permissions.json"
];
in mkMerge [
packageResources
(mkIf (cfg.allowList != null) "${cfg.allowList}:${cfg.dataDir}/allowlist.json")
];
ExecStart = [ ExecStart = [
"${cfg.package}/bin/bedrock_server" "${cfg.package}/bin/bedrock_server"
]; ];
Restart = "always"; Restart = "always";
User = cfg.user; User = cfg.user;
WorkingDirectory = cfg.dataDir; WorkingDirectory = cfg.dataDir;
LogFilterPatterns = [
"~.*minecraft:trial_chambers/chamber/end"
"~Running AutoCompaction"
];
}; };
preStart = '' preStart = ''
cp -a -n ${cfg.package}/var/lib/* . mkdir -p behavior_packs
ln -sf ${cfg.package}/var/lib/behavior_packs/* behavior_packs/
cp -f ${serverPropertiesFile} server.properties cp -f ${serverPropertiesFile} server.properties
chmod +w server.properties chmod +w server.properties
''; '';
}; };
networking.firewall = let conf.networking.firewall = let
ports = [ cfg.serverProperties.server-port cfg.serverProperties.server-portv6 ]; ports = [ cfg.serverProperties.server-port cfg.serverProperties.server-portv6 ];
in mkIf cfg.openFirewall { in mkIf cfg.openFirewall {
allowedUDPPorts = ports; allowedUDPPorts = ports;
}; };
}; in mkMerge [
confService
(mkIf cfg.enable conf)
];
} }

View file

@ -90,6 +90,7 @@ in {
"play.inpvp.net" "play.inpvp.net"
"mco.lbsg.net" "mco.lbsg.net"
"play.galaxite.net" "play.galaxite.net"
"mco.cubecraft.net"
]; ];
bedrockRecords = map (flip mkHostRecord bedrockRecord) bedrockRecordNames; bedrockRecords = map (flip mkHostRecord bedrockRecord) bedrockRecordNames;
in mkMerge [ in mkMerge [

View file

@ -6,29 +6,20 @@ in {
enable = mkDefault true; enable = mkDefault true;
serverProperties = { serverProperties = {
server-name = "Kat's Server"; server-name = "Kat's Server";
gamemode = "survival";
difficulty = "easy";
allow-cheats = false;
max-players = 10;
online-mode = true; online-mode = true;
white-list = false; level-name = "KatBedrock";
server-port = 19132; };
server-portv6 = 19133; allowPlayers = let
view-distance = 32; base = 2535460000000000;
tick-distance = 4; in {
player-idle-timeout = 30; Kyxna.xuid = base + 4308966797;
max-threads = 8; arcnmx.xuid = base + 13399068799;
level-name = "Bedrock level"; };
level-seed = ""; };
default-player-permission-level = "member"; systemd.services.minecraft-bedrock-server = mkIf cfg.enable {
texturepack-required = false; gensokyo-zone.sharedMounts."minecraft/bedrock" = {config, ...}: {
content-log-file-enabled = false; root = config.rootDir + "/${config.subpath}";
compression-threshold = 1; path = mkDefault cfg.dataDir;
server-authoritative-movement = "server-auth";
player-movement-score-threshold = 20;
player-movement-distance-threshold = 0.3;
player-movement-duration-threshold-in-ms = 500;
correct-player-movement = false;
}; };
}; };
users = mkIf cfg.enable { users = mkIf cfg.enable {

View file

@ -160,7 +160,7 @@ mkshared plex 100193 100193 0750
mkshared postgresql 100071 100071 0750 mkshared postgresql 100071 100071 0750
mkshared unifi 100990 100990 0750 mkshared unifi 100990 100990 0750
mkshared zigbee2mqtt 100317 100317 0700 mkshared zigbee2mqtt 100317 100317 0700
mkshared minecraft 0 0 0750 mkshared minecraft 100913 100913 0750
mkshared minecraft/bedrock 100913 100913 0750 mkshared minecraft/bedrock 100913 100913 0750
ln -sf /lib/systemd/system/auth-rpcgss-module.service /etc/systemd/system/ ln -sf /lib/systemd/system/auth-rpcgss-module.service /etc/systemd/system/