···
1
+
{ config, lib, pkgs, ... }:
6
+
cfg = config.services.mchprs;
7
+
settingsFormat = pkgs.formats.toml { };
9
+
whitelistFile = pkgs.writeText "whitelist.json"
11
+
(mapAttrsToList (n: v: { name = n; uuid = v; }) cfg.whitelist.list));
14
+
(removeAttrs cfg.settings [ "address" "port" ]) //
16
+
bind_address = cfg.settings.address + ":" + toString cfg.settings.port;
17
+
whitelist = cfg.whitelist.enable;
20
+
configTomlFile = settingsFormat.generate "Config.toml" configToml;
25
+
enable = mkEnableOption "MCHPRS";
27
+
declarativeSettings = mkOption {
30
+
description = mdDoc ''
31
+
Whether to use a declarative configuration for MCHPRS.
35
+
declarativeWhitelist = mkOption {
38
+
description = mdDoc ''
39
+
Whether to use a declarative whitelist.
40
+
The options {option}`services.mchprs.whitelist.list`
41
+
will be applied if and only if set to `true`.
45
+
dataDir = mkOption {
47
+
default = "/var/lib/mchprs";
48
+
description = mdDoc ''
49
+
Directory to store MCHPRS database and other state/data files.
53
+
openFirewall = mkOption {
56
+
description = mdDoc ''
57
+
Whether to open ports in the firewall for the server.
58
+
Only has effect when
59
+
{option}`services.mchprs.declarativeSettings` is `true`.
63
+
maxRuntime = mkOption {
65
+
default = "infinity";
67
+
description = mdDoc ''
68
+
Automatically restart the server after
69
+
{option}`services.mchprs.maxRuntime`.
70
+
The time span format is described here:
71
+
https://www.freedesktop.org/software/systemd/man/systemd.time.html#Parsing%20Time%20Spans.
72
+
If `null`, then the server is not restarted automatically.
76
+
package = mkOption {
77
+
type = types.package;
78
+
default = pkgs.mchprs;
79
+
defaultText = literalExpression "pkgs.mchprs";
80
+
description = mdDoc "Version of MCHPRS to run.";
83
+
settings = mkOption {
84
+
type = types.submodule {
85
+
freeformType = settingsFormat.type;
91
+
description = mdDoc ''
92
+
Port for the server.
93
+
Only has effect when
94
+
{option}`services.mchprs.declarativeSettings` is `true`.
98
+
address = mkOption {
100
+
default = "0.0.0.0";
101
+
description = mdDoc ''
102
+
Address for the server.
103
+
Please use enclosing square brackets when using ipv6.
104
+
Only has effect when
105
+
{option}`services.mchprs.declarativeSettings` is `true`.
111
+
default = "Minecraft High Performance Redstone Server";
112
+
description = mdDoc ''
113
+
Message of the day.
114
+
Only has effect when
115
+
{option}`services.mchprs.declarativeSettings` is `true`.
119
+
chat_format = mkOption {
121
+
default = "<{username}> {message}";
122
+
description = mdDoc ''
123
+
How to format chat message interpolating `username`
124
+
and `message` with curly braces.
125
+
Only has effect when
126
+
{option}`services.mchprs.declarativeSettings` is `true`.
130
+
max_players = mkOption {
131
+
type = types.ints.positive;
133
+
description = mdDoc ''
134
+
Maximum number of simultaneous players.
135
+
Only has effect when
136
+
{option}`services.mchprs.declarativeSettings` is `true`.
140
+
view_distance = mkOption {
141
+
type = types.ints.positive;
143
+
description = mdDoc ''
144
+
Maximal distance (in chunks) between players and loaded chunks.
145
+
Only has effect when
146
+
{option}`services.mchprs.declarativeSettings` is `true`.
150
+
bungeecord = mkOption {
153
+
description = mdDoc ''
154
+
Enable compatibility with
155
+
[BungeeCord](https://github.com/SpigotMC/BungeeCord).
156
+
Only has effect when
157
+
{option}`services.mchprs.declarativeSettings` is `true`.
161
+
schemati = mkOption {
164
+
description = mdDoc ''
165
+
Mimic the verification and directory layout used by the
166
+
Open Redstone Engineers
167
+
[Schemati plugin](https://github.com/OpenRedstoneEngineers/Schemati).
168
+
Only has effect when
169
+
{option}`services.mchprs.declarativeSettings` is `true`.
173
+
block_in_hitbox = mkOption {
176
+
description = mdDoc ''
177
+
Allow placing blocks inside of players
178
+
(hitbox logic is simplified).
179
+
Only has effect when
180
+
{option}`services.mchprs.declarativeSettings` is `true`.
184
+
auto_redpiler = mkOption {
187
+
description = mdDoc ''
188
+
Use redpiler automatically.
189
+
Only has effect when
190
+
{option}`services.mchprs.declarativeSettings` is `true`.
197
+
description = mdDoc ''
198
+
Configuration for MCHPRS via `Config.toml`.
199
+
See https://github.com/MCHPR/MCHPRS/blob/master/README.md for documentation.
204
+
enable = mkOption {
207
+
description = mdDoc ''
208
+
Whether or not the whitelist (in `whitelist.json`) shoud be enabled.
209
+
Only has effect when {option}`services.mchprs.declarativeSettings` is `true`.
216
+
minecraftUUID = types.strMatching
217
+
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" // {
218
+
description = "Minecraft UUID";
221
+
types.attrsOf minecraftUUID;
223
+
example = literalExpression ''
225
+
username1 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
226
+
username2 = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy";
229
+
description = mdDoc ''
230
+
Whitelisted players, only has an effect when
231
+
{option}`services.mchprs.declarativeWhitelist` is
232
+
`true` and the whitelist is enabled
233
+
via {option}`services.mchprs.whitelist.enable`.
234
+
This is a mapping from Minecraft usernames to UUIDs.
235
+
You can use <https://mcuuid.net/> to get a
236
+
Minecraft UUID for a username.
243
+
config = mkIf cfg.enable {
244
+
users.users.mchprs = {
245
+
description = "MCHPRS service user";
246
+
home = cfg.dataDir;
248
+
isSystemUser = true;
251
+
users.groups.mchprs = { };
253
+
systemd.services.mchprs = {
254
+
description = "MCHPRS Service";
255
+
wantedBy = [ "multi-user.target" ];
256
+
after = [ "network.target" ];
259
+
ExecStart = "${lib.getExe cfg.package}";
260
+
Restart = "always";
261
+
RuntimeMaxSec = cfg.maxRuntime;
263
+
WorkingDirectory = cfg.dataDir;
265
+
StandardOutput = "journal";
266
+
StandardError = "journal";
269
+
CapabilityBoundingSet = [ "" ];
270
+
DeviceAllow = [ "" ];
271
+
LockPersonality = true;
272
+
MemoryDenyWriteExecute = true;
273
+
PrivateDevices = true;
275
+
PrivateUsers = true;
276
+
ProtectClock = true;
277
+
ProtectControlGroups = true;
278
+
ProtectHome = true;
279
+
ProtectHostname = true;
280
+
ProtectKernelLogs = true;
281
+
ProtectKernelModules = true;
282
+
ProtectKernelTunables = true;
283
+
ProtectProc = "invisible";
284
+
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
285
+
RestrictNamespaces = true;
286
+
RestrictRealtime = true;
287
+
RestrictSUIDSGID = true;
288
+
SystemCallArchitectures = "native";
293
+
(if cfg.declarativeSettings then ''
294
+
if [ -e .declarativeSettings ]; then
296
+
# Settings were declarative before, no need to back up anything
297
+
cp -f ${configTomlFile} Config.toml
301
+
# Declarative settings for the first time, backup stateful files
302
+
cp -b --suffix=.stateful ${configTomlFile} Config.toml
304
+
echo "Autogenerated file that implies that this server configuration is managed declaratively by NixOS" \
305
+
> .declarativeSettings
309
+
if [ -e .declarativeSettings ]; then
310
+
rm .declarativeSettings
312
+
'') + (if cfg.declarativeWhitelist then ''
313
+
if [ -e .declarativeWhitelist ]; then
315
+
# Whitelist was declarative before, no need to back up anything
316
+
ln -sf ${whitelistFile} whitelist.json
320
+
# Declarative whitelist for the first time, backup stateful files
321
+
ln -sb --suffix=.stateful ${whitelistFile} whitelist.json
323
+
echo "Autogenerated file that implies that this server's whitelist is managed declaratively by NixOS" \
324
+
> .declarativeWhitelist
328
+
if [ -e .declarativeWhitelist ]; then
329
+
rm .declarativeWhitelist
334
+
networking.firewall = mkIf (cfg.declarativeSettings && cfg.openFirewall) {
335
+
allowedUDPPorts = [ cfg.settings.port ];
336
+
allowedTCPPorts = [ cfg.settings.port ];
340
+
meta.maintainers = with maintainers; [ gdd ];