mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 12:29:19 -08:00
feat(minecraft): bedrock server
This commit is contained in:
parent
f05b50b53e
commit
9f98934a17
11 changed files with 383 additions and 11 deletions
153
modules/nixos/minecraft-bedrock.nix
Normal file
153
modules/nixos/minecraft-bedrock.nix
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
{ config, lib, pkgs, ... }: let
|
||||
# see https://gist.github.com/datakurre/cfdf627fb23ed8ff62bb7b3520b92674
|
||||
inherit (lib.options) mkOption mkPackageOption;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (lib.trivial) boolToString;
|
||||
cfg = config.services.minecraft-bedrock-server;
|
||||
|
||||
cfgToString = v: if builtins.isBool v then boolToString v else toString v;
|
||||
|
||||
serverPropertiesFile = pkgs.writeText "server.properties" (''
|
||||
# server.properties managed by NixOS configuration
|
||||
'' + concatStringsSep "\n" (mapAttrsToList
|
||||
(n: v: "${n}=${cfgToString v}") cfg.serverProperties));
|
||||
in {
|
||||
options.services.minecraft-bedrock-server = with lib.types; {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If enabled, start a Minecraft Bedrock Server. The server
|
||||
data will be loaded from and saved to
|
||||
<option>services.minecraft-bedrock-server.dataDir</option>.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = path;
|
||||
default = "/var/lib/minecraft-bedrock";
|
||||
description = ''
|
||||
Directory to store Minecraft Bedrock database and other state/data files.
|
||||
'';
|
||||
};
|
||||
|
||||
serverProperties = mkOption {
|
||||
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 ''
|
||||
{
|
||||
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;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Minecraft Bedrock server properties for the server.properties file.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "minecraft-bedrock-server" { }// {
|
||||
description = "Version of minecraft-bedrock-server to run.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = str;
|
||||
default = "minecraft-bedrock";
|
||||
};
|
||||
group = mkOption {
|
||||
type = str;
|
||||
default = cfg.user;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.${cfg.user} = {
|
||||
inherit (cfg) group;
|
||||
description = "Minecraft server service user";
|
||||
home = cfg.dataDir;
|
||||
createHome = true;
|
||||
isSystemUser = true;
|
||||
};
|
||||
users.groups.${cfg.group} = {};
|
||||
|
||||
systemd.services.minecraft-bedrock-server = {
|
||||
description = "Minecraft Bedrock Server Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = [
|
||||
"${cfg.package}/bin/bedrock_server"
|
||||
];
|
||||
Restart = "always";
|
||||
User = cfg.user;
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
cp -a -n ${cfg.package}/var/lib/* .
|
||||
cp -f ${serverPropertiesFile} server.properties
|
||||
chmod +w server.properties
|
||||
'';
|
||||
};
|
||||
|
||||
networking.firewall = let
|
||||
ports = [ cfg.serverProperties.server-port cfg.serverProperties.server-portv6 ];
|
||||
in mkIf cfg.openFirewall {
|
||||
allowedUDPPorts = ports;
|
||||
};
|
||||
};
|
||||
}
|
||||
40
modules/system/exports/minecraft-bedrock.nix
Normal file
40
modules/system/exports/minecraft-bedrock.nix
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{lib, gensokyo-zone, ...}: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkIf;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
in {
|
||||
config.exports.services.minecraft-bedrock-server = { config, ... }: let
|
||||
mkAssertion = f: nixosConfig: let
|
||||
cfg = nixosConfig.services.minecraft-bedrock-server;
|
||||
in f nixosConfig cfg;
|
||||
in {
|
||||
nixos = {
|
||||
serviceAttr = "minecraft-bedrock-server";
|
||||
assertions = mkIf config.enable [
|
||||
(mkAssertion (nixosConfig: cfg: {
|
||||
assertion = config.ports.default.port == cfg.serverProperties.server-port;
|
||||
message = "server-port mismatch";
|
||||
}))
|
||||
(mkAssertion (nixosConfig: cfg: {
|
||||
assertion = config.ports.v6.port == cfg.serverProperties.server-portv6;
|
||||
message = "server-portv6 mismatch";
|
||||
}))
|
||||
];
|
||||
};
|
||||
defaults.port.listen = mkAlmostOptionDefault "lan";
|
||||
ports = mapAttrs (_: mapAlmostOptionDefaults) {
|
||||
default = {
|
||||
port = 19132;
|
||||
transport = "udp";
|
||||
};
|
||||
tcp = {
|
||||
port = config.ports.default.port;
|
||||
transport = "tcp";
|
||||
};
|
||||
v6 = {
|
||||
port = 19133;
|
||||
transport = "udp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
access,
|
||||
gensokyo-zone,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkIf mkBefore mkDefault mkForce;
|
||||
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault mkForce;
|
||||
inherit (lib.attrsets) filterAttrs mapAttrsToList nameValuePair listToAttrs;
|
||||
inherit (lib.lists) filter concatLists;
|
||||
inherit (lib.lists) filter optional singleton concatLists;
|
||||
inherit (lib.strings) hasPrefix replaceStrings concatStringsSep;
|
||||
inherit (lib.trivial) mapNullable;
|
||||
inherit (lib.trivial) mapNullable flip;
|
||||
cfg = config.services.dnsmasq;
|
||||
inherit (inputs.self.lib) systems;
|
||||
inherit (gensokyo-zone) systems;
|
||||
localSystems = filterAttrs (_: system:
|
||||
system.config.access.online.enable && system.config.network.networks.local.enable or false
|
||||
) systems;
|
||||
|
|
@ -27,11 +28,11 @@
|
|||
address6 = system.config.network.networks.local.address6 or null;
|
||||
in concatStringsSep "," ([
|
||||
system.config.access.fqdn
|
||||
] ++ lib.optional (address4 != null)
|
||||
] ++ optional (address4 != null)
|
||||
(toString (mapNullable mapDynamic4 address4))
|
||||
++ lib.optional (address6 != null)
|
||||
++ optional (address6 != null)
|
||||
(toString (mapNullable mapDynamic6 address6))
|
||||
++ lib.singleton
|
||||
++ singleton
|
||||
cfg.dynamic.interface
|
||||
);
|
||||
mkHostRecordPair = network: system: let
|
||||
|
|
@ -41,9 +42,9 @@
|
|||
in nameValuePair
|
||||
(if fqdn != null then fqdn else "${network}.${system.config.access.fqdn}")
|
||||
(concatStringsSep "," (
|
||||
lib.optional (address4 != null)
|
||||
optional (address4 != null)
|
||||
(toString address4)
|
||||
++ lib.optional (address6 != null)
|
||||
++ optional (address6 != null)
|
||||
(toString address6)
|
||||
));
|
||||
systemHosts = filterAttrs (_: value: value != "") (
|
||||
|
|
@ -63,13 +64,38 @@ in {
|
|||
type = str;
|
||||
default = config.systemd.network.networks._00-local.name or "eth0";
|
||||
};
|
||||
bedrockConnect = {
|
||||
address = mkOption {
|
||||
type = nullOr str;
|
||||
};
|
||||
address6 = mkOption {
|
||||
type = nullOr str;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = {
|
||||
services.dnsmasq = {
|
||||
enable = mkDefault true;
|
||||
resolveLocalQueries = mkForce false;
|
||||
settings = {
|
||||
host-record = mapAttrsToList mkHostRecord systemHosts;
|
||||
host-record = let
|
||||
bedrockRecord = concatStringsSep "," (
|
||||
optional (cfg.bedrockConnect.address != null) cfg.bedrockConnect.address
|
||||
++ optional (cfg.bedrockConnect.address6 != null) cfg.bedrockConnect.address6
|
||||
);
|
||||
bedrockRecordNames = [
|
||||
# https://github.com/Pugmatt/BedrockConnect?tab=readme-ov-file#using-your-own-dns-server
|
||||
"geo.hivebedrock.network"
|
||||
"hivebedrock.network"
|
||||
"play.inpvp.net"
|
||||
"mco.lbsg.net"
|
||||
"play.galaxite.net"
|
||||
];
|
||||
bedrockRecords = map (flip mkHostRecord bedrockRecord) bedrockRecordNames;
|
||||
in mkMerge [
|
||||
(mapAttrsToList mkHostRecord systemHosts)
|
||||
(mkIf (cfg.bedrockConnect.address != null || cfg.bedrockConnect.address6 != null) bedrockRecords)
|
||||
];
|
||||
dynamic-host = mapAttrsToList mkDynamicHostRecord localSystems;
|
||||
server =
|
||||
if config.networking.nameservers' != [ ] then map (ns: ns.address) (filter filterns' config.networking.nameservers')
|
||||
|
|
@ -77,6 +103,12 @@ in {
|
|||
;
|
||||
max-cache-ttl = 60;
|
||||
};
|
||||
bedrockConnect = let
|
||||
system = access.systemForService "minecraft-bedrock-server";
|
||||
in {
|
||||
address = mkDefault (access.getAddress4For system.name "local");
|
||||
address6 = mkDefault (access.getAddress6For system.name "local");
|
||||
};
|
||||
};
|
||||
services.resolved = mkIf cfg.enable {
|
||||
extraConfig = ''
|
||||
|
|
|
|||
43
nixos/minecraft/bedrock.nix
Normal file
43
nixos/minecraft/bedrock.nix
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{config, lib, ...}: let
|
||||
inherit (lib.modules) mkIf mkDefault;
|
||||
cfg = config.services.minecraft-bedrock-server;
|
||||
in {
|
||||
services.minecraft-bedrock-server = {
|
||||
enable = mkDefault true;
|
||||
serverProperties = {
|
||||
server-name = "Kat's Server";
|
||||
gamemode = "survival";
|
||||
difficulty = "easy";
|
||||
allow-cheats = false;
|
||||
max-players = 10;
|
||||
online-mode = true;
|
||||
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;
|
||||
};
|
||||
};
|
||||
users = mkIf cfg.enable {
|
||||
users.${cfg.user}.uid = 913;
|
||||
groups.${cfg.group}.gid = config.users.users.${cfg.user}.uid;
|
||||
};
|
||||
networking.firewall.interfaces.local = let
|
||||
ports = [ cfg.serverProperties.server-port cfg.serverProperties.server-portv6 ];
|
||||
in mkIf cfg.enable {
|
||||
allowedUDPPorts = ports;
|
||||
};
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
in rec {
|
||||
default = nixlib.composeManyExtensions [
|
||||
barcodebuddy
|
||||
minecraft
|
||||
krb5
|
||||
nfs
|
||||
nginx
|
||||
|
|
@ -13,6 +14,7 @@ in rec {
|
|||
];
|
||||
barcodebuddy = import ./barcodebuddy.nix;
|
||||
krb5 = import ./krb5.nix;
|
||||
minecraft = import ./minecraft.nix;
|
||||
nfs = import ./nfs.nix;
|
||||
nginx = import ./nginx.nix;
|
||||
samba = import ./samba.nix;
|
||||
|
|
|
|||
57
overlays/minecraft.nix
Normal file
57
overlays/minecraft.nix
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
final: prev: let
|
||||
inherit (final) lib;
|
||||
in {
|
||||
minecraft-bedrock-server-libCrypto = let
|
||||
inherit (final) minecraft-bedrock-server;
|
||||
in minecraft-bedrock-server.stdenv.mkDerivation {
|
||||
pname = "${minecraft-bedrock-server.pname}-libcrypto";
|
||||
inherit (minecraft-bedrock-server) version src sourceRoot;
|
||||
nativeBuildInputs = with final; [
|
||||
autoPatchelfHook
|
||||
curl
|
||||
gcc-unwrapped
|
||||
openssl
|
||||
unzip
|
||||
];
|
||||
installPhase = ''
|
||||
install -m755 -D libCrypto.so $out/lib/libCrypto.so
|
||||
'';
|
||||
fixupPhase = ''
|
||||
autoPatchelf $out/lib/libCrypto.so
|
||||
'';
|
||||
meta.broken = true;
|
||||
};
|
||||
|
||||
minecraft-bedrock-server-patchdebug = let
|
||||
# https://github.com/minecraft-linux/server-modloader/tree/master?tab=readme-ov-file#getting-mods-to-work-on-newer-versions-116
|
||||
python = final.python3.withPackages (p: [ p.lief ]);
|
||||
script = ''
|
||||
import lief
|
||||
import sys
|
||||
|
||||
lib_symbols = lief.parse(sys.argv[1])
|
||||
for s in filter(lambda e: e.exported, lib_symbols.static_symbols):
|
||||
lib_symbols.add_dynamic_symbol(s)
|
||||
lib_symbols.write(sys.argv[2])
|
||||
'';
|
||||
name = "minecraft-bedrock-server-patchdebug";
|
||||
in final.writeTextFile {
|
||||
name = "${name}.py";
|
||||
destination = "/bin/${name}";
|
||||
executable = true;
|
||||
text = ''
|
||||
#!${lib.getExe python}
|
||||
${script}
|
||||
'';
|
||||
meta.mainProgram = name;
|
||||
};
|
||||
|
||||
minecraft-bedrock-server-patchelf = prev.patchelf.overrideDerivation (old: {
|
||||
postPatch = ''
|
||||
substituteInPlace src/patchelf.cc \
|
||||
--replace "32 * 1024 * 1024" "512 * 1024 * 1024"
|
||||
'';
|
||||
});
|
||||
|
||||
minecraft-bedrock-server = final.callPackage ../packages/minecraft-bedrock.nix { };
|
||||
}
|
||||
40
packages/minecraft-bedrock.nix
Normal file
40
packages/minecraft-bedrock.nix
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{ stdenv
|
||||
, fetchurl
|
||||
, minecraft-bedrock-server-patchelf
|
||||
, minecraft-bedrock-server-patchdebug
|
||||
#, minecraft-bedrock-server-libCrypto
|
||||
, autoPatchelfHook
|
||||
, curl, gcc-unwrapped, openssl, unzip
|
||||
}: stdenv.mkDerivation rec {
|
||||
pname = "minecraft-bedrock-server";
|
||||
version = "1.20.80.05";
|
||||
src = fetchurl {
|
||||
url = "https://minecraft.azureedge.net/bin-linux/bedrock-server-${version}.zip";
|
||||
sha256 = "sha256-6vZx29FOXRR7Rzx82Axo3a/Em+9cpK7Hj3cuDRnW9+8=";
|
||||
};
|
||||
sourceRoot = ".";
|
||||
nativeBuildInputs = [
|
||||
minecraft-bedrock-server-patchelf
|
||||
minecraft-bedrock-server-patchdebug
|
||||
autoPatchelfHook
|
||||
curl
|
||||
gcc-unwrapped
|
||||
#minecraft-bedrock-server-libCrypto
|
||||
openssl
|
||||
unzip
|
||||
];
|
||||
buildPhase = ''
|
||||
minecraft-bedrock-server-patchdebug bedrock_server_symbols.debug bedrock_server_symbols_patched.debug
|
||||
'';
|
||||
installPhase = ''
|
||||
install -m755 -D bedrock_server $out/bin/bedrock_server
|
||||
rm bedrock_server
|
||||
rm server.properties
|
||||
mkdir -p $out/var
|
||||
cp -a . $out/var/lib
|
||||
'';
|
||||
fixupPhase = ''
|
||||
autoPatchelf $out/bin/bedrock_server
|
||||
'';
|
||||
dontStrip = true;
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ _: {
|
|||
services = {
|
||||
sshd.enable = true;
|
||||
tailscale.enable = true;
|
||||
minecraft-bedrock-server.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
"lxc.mount.entry": [
|
||||
"/rpool/shared/nix/store nix/store none bind,create=dir",
|
||||
"/rpool/shared/nix/var nix/var none bind,create=dir",
|
||||
"/rpool/shared/minecraft/bedrock mnt/shared/minecraft/bedrock none bind,optional,create=dir",
|
||||
"/dev/net/tun dev/net/tun none bind,optional,create=file"
|
||||
],
|
||||
"lxc.idmap": [
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
nixos.nixbld
|
||||
nixos.tailscale
|
||||
nixos.github-runner.zone
|
||||
nixos.minecraft.bedrock
|
||||
];
|
||||
|
||||
nix.gc = {
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ mkshared plex 100193 100193 0750
|
|||
mkshared postgresql 100071 100071 0750
|
||||
mkshared unifi 100990 100990 0750
|
||||
mkshared zigbee2mqtt 100317 100317 0700
|
||||
mkshared minecraft 0 0 0750
|
||||
mkshared minecraft/bedrock 100913 100913 0750
|
||||
|
||||
ln -sf /lib/systemd/system/auth-rpcgss-module.service /etc/systemd/system/
|
||||
mkdir -p /etc/systemd/system/auth-rpcgss-module.service.d
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue