mirror of https://github.com/deavminet/dnetd-ng
Some configuration parsing added with error checking, reworked Configuration sub-system (now the configuration file path is stored such that we can rehash the configuration later)
This commit is contained in:
parent
38f202321f
commit
58265272be
|
@ -11,7 +11,8 @@
|
|||
}
|
||||
},
|
||||
"info": {
|
||||
"networkName" : "my custom network",
|
||||
"serverName" : "MyServer",
|
||||
"networkName" : "networkNameGoesHere",
|
||||
"motd" : "This is my server, hello",
|
||||
"motdFile" : "./motd"
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ module dnetd.app;
|
|||
import dlog;
|
||||
import dnetd.exceptions : GeneralException;
|
||||
import std.json : JSONValue;
|
||||
import dnetd.config : readConfig, Configuration;
|
||||
import dnetd.config : Configuration;
|
||||
import dnetd.server : Server;
|
||||
|
||||
public Logger logger;
|
||||
string VERSION = "v0.0.1";
|
||||
string VERSION = "0.0.1";
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -23,8 +23,8 @@ void main()
|
|||
|
||||
try
|
||||
{
|
||||
JSONValue jsonConfig = readConfig("config.json");
|
||||
Configuration config = Configuration.fromJSON(jsonConfig);
|
||||
|
||||
Configuration config = Configuration.getConfig("config.json");
|
||||
|
||||
/* TODO: Server init with config here */
|
||||
Server server = new Server(config);
|
||||
|
|
|
@ -7,6 +7,7 @@ import dnetd.app : logger;
|
|||
import std.json : JSONValue, JSONException, parseJSON;
|
||||
import dnetd.exceptions;
|
||||
import std.stdio : File;
|
||||
import std.string : cmp, strip;
|
||||
|
||||
/**
|
||||
* In its instance-form this represents a read-in and parsed configuration
|
||||
|
@ -18,15 +19,31 @@ import std.stdio : File;
|
|||
*/
|
||||
public final class Configuration
|
||||
{
|
||||
string configPath;
|
||||
NetworkInformation netInfo;
|
||||
|
||||
public static Configuration getConfig(string configPath)
|
||||
{
|
||||
JSONValue jsonConfig = readConfig("config.json");
|
||||
Configuration config = Configuration.fromJSON(jsonConfig);
|
||||
|
||||
/* Save the path so we can rehash later on */
|
||||
config.configPath = configPath;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load the configuration from a JSON source, returning the
|
||||
* configuration as a Configuration object, on error, null (TODO: Throw exception rather)
|
||||
*
|
||||
* @param jsonConfig the JSONValue configuration
|
||||
*/
|
||||
public static Configuration fromJSON(JSONValue jsonConfig)
|
||||
private static Configuration fromJSON(JSONValue jsonConfig)
|
||||
{
|
||||
Configuration config;
|
||||
Configuration config = new Configuration();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -35,6 +52,10 @@ public final class Configuration
|
|||
/* Retrieve the `network` block */
|
||||
JSONValue networkBlock = jsonConfig["network"];
|
||||
|
||||
config.netInfo = confNetInfo(networkBlock["info"]);
|
||||
// TODO: Log the above logger.log()
|
||||
|
||||
|
||||
/* Retrieve the `accounting` block */
|
||||
JSONValue accountingBlock = jsonConfig["accounting"];
|
||||
|
||||
|
@ -51,47 +72,85 @@ public final class Configuration
|
|||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in the JSON from the given path to the configuration
|
||||
* file
|
||||
*
|
||||
* On error throws TODO
|
||||
*/
|
||||
public JSONValue readConfig(string path)
|
||||
{
|
||||
File file;
|
||||
file.open(path); /* TODO:Check this for errors */
|
||||
/* TODO: Only open with read rights */
|
||||
|
||||
/* Allocate a buffer for the file */
|
||||
byte[] contents;
|
||||
contents.length = file.size(); /* TODO: Check size here */
|
||||
|
||||
/* TODO: Check this */
|
||||
/* TODO: Technically the below is fine */
|
||||
file.rawRead(contents);
|
||||
|
||||
JSONValue config;
|
||||
|
||||
try
|
||||
private static NetworkInformation confNetInfo(JSONValue infoBlock)
|
||||
{
|
||||
config = parseJSON(cast(string)contents);
|
||||
}
|
||||
catch(JSONException e)
|
||||
{
|
||||
/* TODO: Get specific error here to show where config syntax is wrong */
|
||||
NetworkInformation netInfo;
|
||||
|
||||
/**
|
||||
* TODO (keycheck): Make sure that `serverName` is present
|
||||
* and `networkName`
|
||||
*
|
||||
* `motd` is optional
|
||||
*/
|
||||
bool foundNetworkName;
|
||||
bool foundServerName;
|
||||
|
||||
string[] keys = infoBlock.object.keys();
|
||||
foreach(string key; keys)
|
||||
{
|
||||
if(cmp(key, "serverName") == 0)
|
||||
{
|
||||
foundServerName = true;
|
||||
netInfo.serverName = infoBlock[key].str();
|
||||
}
|
||||
else if(cmp(key, "networkName") == 0)
|
||||
{
|
||||
foundNetworkName = true;
|
||||
netInfo.networkName = infoBlock[key].str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
throw new ConfigurationError(e);
|
||||
/**
|
||||
* Make sure we found the required fields
|
||||
*
|
||||
* These are: serverName, networkName, sid (TODO: Finish these)
|
||||
*/
|
||||
if(!foundServerName)
|
||||
{
|
||||
throw new ConfigurationError("Missing server name");
|
||||
}
|
||||
else if(!foundNetworkName)
|
||||
{
|
||||
throw new ConfigurationError("Missing network name");
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip whitespace from the beginnings and endings of
|
||||
* `serverName`, `networkName`, (TODO: Complete list)
|
||||
*/
|
||||
netInfo.serverName = strip(netInfo.serverName);
|
||||
netInfo.networkName = strip(netInfo.networkName);
|
||||
|
||||
/**
|
||||
* Make sure the required fields were set to a valid
|
||||
* value
|
||||
*/
|
||||
if(cmp(netInfo.networkName, "") == 0)
|
||||
{
|
||||
throw new ConfigurationError("Network name cannot be empty");
|
||||
}
|
||||
else if(cmp(netInfo.serverName, "") == 0)
|
||||
{
|
||||
throw new ConfigurationError("Server name cannot be empty");
|
||||
}
|
||||
|
||||
/* TODO: Add handling for motd and motdFile */
|
||||
|
||||
|
||||
return netInfo;
|
||||
}
|
||||
|
||||
|
||||
return config;
|
||||
private this()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Configuration error
|
||||
*/
|
||||
|
@ -107,3 +166,59 @@ public final class ConfigurationError : GeneralException
|
|||
super("JSON configuration has a syntax error ("~e.msg~")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Network information
|
||||
*
|
||||
* This holds information that pertains to network-wide
|
||||
* information (such as the network's name) and server-specific
|
||||
* information such as the message-of-the-day or the server's
|
||||
* name
|
||||
*/
|
||||
struct NetworkInformation
|
||||
{
|
||||
string serverName;
|
||||
string motd;
|
||||
|
||||
string networkName;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in the JSON from the given path to the configuration
|
||||
* file
|
||||
*
|
||||
* On error throws TODO
|
||||
*/
|
||||
private JSONValue readConfig(string path)
|
||||
{
|
||||
File file;
|
||||
file.open(path); /* TODO:Check this for errors */
|
||||
/* TODO: Only open with read rights */
|
||||
|
||||
/* Allocate a buffer for the file */
|
||||
byte[] contents;
|
||||
contents.length = file.size(); /* TODO: Check size here */
|
||||
|
||||
/* TODO: Check this */
|
||||
/* TODO: Technically the below is fine */
|
||||
file.rawRead(contents);
|
||||
|
||||
JSONValue config;
|
||||
|
||||
try
|
||||
{
|
||||
config = parseJSON(cast(string)contents);
|
||||
}
|
||||
catch(JSONException e)
|
||||
{
|
||||
/* TODO: Get specific error here to show where config syntax is wrong */
|
||||
|
||||
|
||||
throw new ConfigurationError(e);
|
||||
}
|
||||
|
||||
|
||||
return config;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* TODO
|
||||
*/
|
||||
module dnetd.listeners;
|
||||
|
||||
public abstract class Listener
|
||||
{
|
||||
}
|
|
@ -16,8 +16,14 @@ import dnetd.config : Configuration;
|
|||
*/
|
||||
public final class Server
|
||||
{
|
||||
/* Server Conifguration */
|
||||
private Configuration config;
|
||||
|
||||
this(Configuration config)
|
||||
{
|
||||
logger.log("Server instance '"~"PUT ID HERE"~"' starting up...");
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/* Rehash server configuration */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue