87 lines
2.8 KiB
D
87 lines
2.8 KiB
D
|
module server_metadata;
|
||
|
|
||
|
import std.json;
|
||
|
import std.file;
|
||
|
import std.path;
|
||
|
import std.string : endsWith;
|
||
|
import std.array;
|
||
|
import std.algorithm;
|
||
|
import std.stdio;
|
||
|
|
||
|
import properd;
|
||
|
|
||
|
/**
|
||
|
* The set of information about each server that we can obtain by reading the
|
||
|
* server's directory and files in it (service file, properties, etc.).
|
||
|
*/
|
||
|
struct ServerMetaData {
|
||
|
/// The name of the server, as declared in servers.json.
|
||
|
const string name;
|
||
|
/// The display name of the server, as declared in servers.json.
|
||
|
const string displayName;
|
||
|
/// The description of the server, as declared in servers.json.
|
||
|
const string description;
|
||
|
/// The directory to find the server's files in.
|
||
|
const string directory;
|
||
|
/// The name of the server's SystemD service, as determined by searching the server's directory.
|
||
|
const string serviceName;
|
||
|
/// The port used for player connections.
|
||
|
const ushort port;
|
||
|
/// The password for connecting to the RCON service of the server.
|
||
|
const string rconPassword;
|
||
|
/// The port for connecting to the RCON service.
|
||
|
const ushort rconPort;
|
||
|
/// The maximum number of players for the server.
|
||
|
const int maxPlayers;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reads server metadata from each server defined in "servers.json", by parsing
|
||
|
* its "server.properties" file, SystemD service file, and more.
|
||
|
* Returns: The list of server metadata structs.
|
||
|
*/
|
||
|
ServerMetaData[] readServerMetaData() {
|
||
|
import properd;
|
||
|
|
||
|
JSONValue arr = parseJSON(readText("servers.json"));
|
||
|
return arr.array.map!((s) {
|
||
|
string name = s.object["name"].str;
|
||
|
string displayName = s.object["displayName"].str;
|
||
|
string description = s.object["description"].str;
|
||
|
string directory = s.object["directory"].str;
|
||
|
string systemDServiceName = findSystemDServiceName(directory);
|
||
|
string propsFile = buildPath(directory, "server.properties");
|
||
|
if (!exists(propsFile)) throw new Exception("Missing server properties file: " ~ propsFile);
|
||
|
try {
|
||
|
auto props = readProperties(propsFile);
|
||
|
ushort port = props.as!(ushort)("server-port");
|
||
|
string rconPassword = props["rcon.password"];
|
||
|
ushort rconPort = props.as!(ushort)("rcon.port");
|
||
|
int maxPlayers = props.as!(int)("max-players");
|
||
|
return ServerMetaData(
|
||
|
name,
|
||
|
displayName,
|
||
|
description,
|
||
|
directory,
|
||
|
systemDServiceName,
|
||
|
port,
|
||
|
rconPassword,
|
||
|
rconPort,
|
||
|
maxPlayers
|
||
|
);
|
||
|
} catch (PropertyException e) {
|
||
|
stderr.writefln!"Error parsing properties from %s: %s"(propsFile, e.msg);
|
||
|
throw e;
|
||
|
}
|
||
|
}).array;
|
||
|
}
|
||
|
|
||
|
private string findSystemDServiceName(string serverDir) {
|
||
|
foreach (DirEntry entry; dirEntries(serverDir, SpanMode.shallow, false)) {
|
||
|
if (entry.name.endsWith(".service")) {
|
||
|
return baseName(stripExtension(entry.name));
|
||
|
}
|
||
|
}
|
||
|
throw new Exception("No SystemD service file found in " ~ serverDir);
|
||
|
}
|