anchor.diff:        wantedBy      = [ "multi-user.target" ];
         after         = [ "network.target" ];
   
  -      serviceConfig.Restart = "always";
  -      serviceConfig.User    = "minecraft";
  -      script = ''
  -        cd ${cfg.dataDir}
  -        exec ${pkgs.minecraft-server}/bin/minecraft-server ${cfg.jvmOpts}
  -      '';
  +      serviceConfig = {
  +        ExecStart = "${cfg.package}/bin/minecraft-server ${cfg.jvmOpts}";
  +        Restart = "always";
  +        User = "minecraft";
  +        WorkingDirectory = cfg.dataDir;
  +      };
  +
  +      preStart = ''
  +        ln -sf ${eulaFile} eula.txt
  +      '' + (if cfg.declarative then ''
  +
  +        if [ -e .declarative ]; then
  +
  +          # Was declarative before, no need to back up anything
  +          ln -sf ${whitelistFile} whitelist.json
  +          cp -f ${serverPropertiesFile} server.properties
  +
  +        else
  +
  +          # Declarative for the first time, backup stateful files
  +          ln -sb --suffix=.stateful ${whitelistFile} whitelist.json
  +          cp -b --suffix=.stateful ${serverPropertiesFile} server.properties
  +
  +          # server.properties must have write permissions, because every time
  +          # the server starts it first parses the file and then regenerates it..
  +          chmod +w server.properties
  +          echo "Autogenerated file that signifies that this server configuration is managed declaratively by NixOS" \
  +            > .declarative
  +
  +        fi
  +      '' else ''
  +        if [ -e .declarative ]; then
  +          rm .declarative
  +        fi
  +      '');
       };
   
  -    networking.firewall = mkIf cfg.openFirewall {
  -      allowedUDPPorts = [ 25565 ];
  -      allowedTCPPorts = [ 25565 ];
  -    };
  +    networking.firewall = mkIf cfg.openFirewall (if cfg.declarative then {
  +      allowedUDPPorts = [ serverPort ];
  +      allowedTCPPorts = [ serverPort ]
  +        ++ optional (! isNull queryPort) queryPort
  +        ++ optional (! isNull rconPort) rconPort;
  +    } else {
  +      allowedUDPPorts = [ defaultServerPort ];
  +      allowedTCPPorts = [ defaultServerPort ];
  +    });
  +
  +    assertions = [
  +      { assertion = cfg.eula;
  +        message = "You must agree to Mojangs EULA to run minecraft-server."
  +          + " Read https://account.mojang.com/documents/minecraft_eula and"
  +          + " set `services.minecraft-server.eula` to `true` if you agree.";
  +      }
  +    ];
  +
     };
   }
  
positive.code:         type = types.bool;
          default = false;
          description = ''
            If enabled, start a Minecraft Server. The listening port for
            the server is always <literal>25565</literal>. The server
            data will be loaded from and saved to
            <literal>${cfg.dataDir}</literal>.
          '';
        };
  
  
negative.code: 
  let
    cfg = config.services.minecraft-server;
  
    # We don't allow eula=false anyways
    eulaFile = builtins.toFile "eula.txt" ''
      # eula.txt managed by NixOS Configuration
      eula=true
    '';
  
    whitelistFile = pkgs.writeText "whitelist.json"
      (builtins.toJSON
        (mapAttrsToList (n: v: { name = n; uuid = v; }) cfg.whitelist));
  
    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));
  
  
    # To be able to open the firewall, we need to read out port values in the
    # server properties, but fall back to the defaults when those don't exist.
    # These defaults are from https://minecraft.gamepedia.com/Server.properties#Java_Edition_3
    defaultServerPort = 25565;
  
    serverPort = cfg.serverProperties.server-port or defaultServerPort;
  
    rconPort = if cfg.serverProperties.enable-rcon or false
      then cfg.serverProperties."rcon.port" or 25575
      else null;
  
    queryPort = if cfg.serverProperties.enable-query or false
      then cfg.serverProperties."query.port" or 25565
      else null;
  
  in {
    options = {
      services.minecraft-server = {
  
  