diff options
Diffstat (limited to 'src/Settings')
| -rw-r--r-- | src/Settings/loadsettings.cpp | 144 | ||||
| -rw-r--r-- | src/Settings/loadsettings.h | 19 | ||||
| -rw-r--r-- | src/Settings/settingstructure.h | 119 | ||||
| -rw-r--r-- | src/Settings/writesettings.cpp | 76 |
4 files changed, 358 insertions, 0 deletions
diff --git a/src/Settings/loadsettings.cpp b/src/Settings/loadsettings.cpp new file mode 100644 index 0000000..943311b --- /dev/null +++ b/src/Settings/loadsettings.cpp @@ -0,0 +1,144 @@ +#include "loadsettings.h" + +SettingStructure loadSettings (const QString &applicationPath) +{ + // return object + SettingStructure settings; + + // determine if file exists + QString settingsFilePath = applicationPath + "/" + _settingsPath; + if ( ! QFile(settingsFilePath).exists() ) + { + // no settings file exists. ask to generate clean settings file. + logPrimitive() << "No valid settings file was found at " << settingsFilePath << endl + << "Do you want to generate a clean settings file? [y/N]" << endl; + + // if opted for new config, create a new config file at the provided location + if ( QTextStream(stdin).readLine().startsWith("y") ) + { + // generate new settings file + writeSettings(settingsFilePath); + + // inform that a file was written + logPrimitive() << "A new settings file was generated. Please update your " + << "settings in " << settingsFilePath << endl + << "and restart the application." << endl; + } + // do NOT init = true, the application is now intended to shut down due to init==false + return settings; + } + + // open settings + QSettings settingsFile(settingsFilePath, QSettings::IniFormat); + if ( settingsFile.status() != QSettings::NoError ) + { + // error occurred. report and quit. + logPrimitive() << "An error occurred while loading the configuration (" << QString::number( settingsFile.status() ) << ")."; + + // do NOT init = true, the application is now intended to shut down due to init==false + return settings; + } + + // logging settings + settings.LoggingSettings.cycle = settingsFile.value("Logging/CycleLogs", settings.LoggingSettings.cycle).toString(); + settings.LoggingSettings.suppressLog = settingsFile.value("Logging/SuppressLog", settings.LoggingSettings.suppressLog).toString(); + settings.LoggingSettings.suppressDisplay = settingsFile.value("Logging/SuppressDisplay", settings.LoggingSettings.suppressDisplay).toString(); + + // beacon server settings (udp server) + settings.BeaconServerSettings.beaconPort = static_cast<unsigned short>( settingsFile.value("BeaconServer/BeaconPort", settings.BeaconServerSettings.beaconPort).toInt() ); + settings.BeaconServerSettings.doUplink = settingsFile.value("BeaconServer/DoUplink", settings.BeaconServerSettings.doUplink).toBool(); + + // listen server settings (tcp server) + settings.ListenServerSettings.listenPort = static_cast<unsigned short>( settingsFile.value("ListenServer/ListenPort", settings.ListenServerSettings.listenPort).toInt() ); + settings.ListenServerSettings.serverttl_s = settingsFile.value("ListenServer/ServerLifeTime_s", settings.ListenServerSettings.serverttl_s).toInt(); + + // syncer settings (tcp client) + settings.SyncerSettings.doSync = settingsFile.value("Syncer/DoSync", settings.SyncerSettings.doSync).toBool(); + settings.SyncerSettings.syncGames = settingsFile.value("Syncer/SyncGames", settings.SyncerSettings.syncGames).toString().toLower(); + settings.SyncerSettings.syncInterval_s = settingsFile.value("Syncer/SyncInterval_s", settings.SyncerSettings.syncInterval_s).toInt(); + + // error and number of items + int parseError = -1; + int len = settingsFile.beginReadArray("Syncer"); + + // read list of syncer items + for (int i = 0; i < len; i++) + { + settingsFile.setArrayIndex(i); + SyncServer syncServer; + QStringList strServer = settingsFile.value("SyncServer").toString().split(","); + + if ( strServer.length() >= 3 ) + { + // parse + syncServer.remoteAddress = strServer.value(0).trimmed(); + syncServer.beaconPort = strServer.value(1).toUShort(); + syncServer.listenPort = strServer.value(2).toUShort(); + + // sanity checks + if (! syncServer.remoteAddress.isEmpty() and + syncServer.beaconPort > 0 and + syncServer.listenPort > 0) + { + // add + settings.SyncerSettings.syncServers.append(syncServer); + continue; + } + } + + // else input error, do not continue parsing + parseError = i; + break; + } + settingsFile.endArray(); + + // server checker (udp client ticker) + settings.CheckerSettings.doCheck = settingsFile.value("Checker/DoCheck", settings.CheckerSettings.doCheck).toBool(); + settings.CheckerSettings.getExtendedInfo = settingsFile.value("Checker/GetExtendedInformation", settings.CheckerSettings.getExtendedInfo).toBool(); + settings.CheckerSettings.timeServerInterval_ms = settingsFile.value("Checker/ServerCheckInterval_ms", settings.CheckerSettings.timeServerInterval_ms).toInt(); + settings.CheckerSettings.timeCheckerReset_s = settingsFile.value("Checker/CycleInterval_s", settings.CheckerSettings.timeCheckerReset_s).toInt(); + + // maintenance settings + settings.MaintenanceSettings.doMaintenance = settingsFile.value("Maintenance/DoMaintenance", settings.MaintenanceSettings.doMaintenance).toBool(); + settings.MaintenanceSettings.timeMaintenanceInterval_s = settingsFile.value("Maintenance/MaintainRate_s", settings.MaintenanceSettings.timeMaintenanceInterval_s).toInt(); + + // public details + settings.PublicInformationSettings.hostname = settingsFile.value("PublicDetails/Hostname", "").toString(); + settings.PublicInformationSettings.adminName = settingsFile.value("PublicDetails/AdminName", "").toString(); + settings.PublicInformationSettings.contact = settingsFile.value("PublicDetails/Contact", "").toString(); + + // sanity checks + try { + // beacon / udp server + if ( settings.BeaconServerSettings.beaconPort <= 0 ) throw QString("BeaconServer/BeaconPort"); + + // listen / tcp server + if ( settings.ListenServerSettings.listenPort <= 0 ) throw QString("ListenServer/ListenPort"); + if ( settings.ListenServerSettings.serverttl_s < 0) throw QString("ListenServer/ServerLifeTimeSeconds"); + + // syncer / tcp client + if ( settings.SyncerSettings.syncGames.isEmpty() ) throw QString("Syncer/SyncGames"); + if ( settings.SyncerSettings.syncInterval_s <= 0 ) throw QString(); + if (parseError >= 0) throw QStringLiteral("Syncer/SyncServer[%1]").arg(QString::number(parseError+1)); + + // server checker / udp client + if ( settings.CheckerSettings.timeServerInterval_ms < 10 ) throw QString("Checker/ServerCheckInterval_ms"); + if ( settings.CheckerSettings.timeCheckerReset_s < 1 ) throw QString("Checker/CycleInterval_s"); + + // make sure that details are filled in + if (settings.PublicInformationSettings.hostname.isEmpty()) throw QString("PublicDetails/Hostname"); + if (settings.PublicInformationSettings.adminName.isEmpty()) throw QString("PublicDetails/AdminName"); + if (settings.PublicInformationSettings.contact.isEmpty()) throw QString("PublicDetails/Contact"); + + } + catch (QString error) + { + logPrimitive() << "One or more settings are incorrect: setting \"" << error << "\" has an incorrect value! " + << "Please correct the value and restart the application." << endl; + return settings; + } + + // loading settings complete + settings.init = true; + return settings; +} diff --git a/src/Settings/loadsettings.h b/src/Settings/loadsettings.h new file mode 100644 index 0000000..540e1a9 --- /dev/null +++ b/src/Settings/loadsettings.h @@ -0,0 +1,19 @@ +#ifndef LOADSETTINGS_H +#define LOADSETTINGS_H + +#include <QFile> +#include <QSettings> + +#include "Logger/logprimitive.h" +#include "settingstructure.h" + +// settings path (following README structure) +const QString _settingsPath = "../data/MasterServer-Settings.ini"; + +// load all settings from the config file +SettingStructure loadSettings(const QString &applicationPath); + +// write all settings to the config file +void writeSettings(const QString &settingsFilePath); + +#endif // LOADSETTINGS_H diff --git a/src/Settings/settingstructure.h b/src/Settings/settingstructure.h new file mode 100644 index 0000000..b480164 --- /dev/null +++ b/src/Settings/settingstructure.h @@ -0,0 +1,119 @@ +#ifndef SETTINGSTRUCTURE_H +#define SETTINGSTRUCTURE_H + +#include <QString> +#include <QList> + +// masterservers sync options +struct SyncServer +{ + // domain name string, not QHostAddress + QString remoteAddress; + + // udp port + unsigned short int beaconPort = 27900; + + // tcp port + unsigned short int listenPort = 28900; +}; + +// cascaded struct with setting structure +struct SettingStructure +{ + // initialisation check + bool init = false; + + // log settings + struct LoggingSettings + { + // never, yearly, monthly, weekly, daily + QString cycle = "weekly"; + + // suppress type: [timestamp][type] <message> + QString suppressLog = "debug udp tcp"; + QString suppressDisplay = "debug udp tcp"; + } + LoggingSettings; + + // udp beacon server settings + struct BeaconServerSettings + { + // default port 27900 + unsigned short int beaconPort = 27900; + + // uplink settings enabled by default + bool doUplink = true; + } + BeaconServerSettings; + + // tcp listen server settings + struct ListenServerSettings + { + // default port 28900 + unsigned short int listenPort = 28900; + + // server time to live for client list + int serverttl_s = 1800; + } + ListenServerSettings; + + // synchronisation settings (works only with 333networks-compatible masterservers) + struct SyncerSettings + { + // syncer settings enabled by default + bool doSync = true; + + // sync games (which games to sync) + QString syncGames = "all"; + + // list of servers to sync + QList<SyncServer> syncServers; + + // sync event interval + int syncInterval_s = 1800; + } + SyncerSettings; + + // checker settings (query all individual servers to determine their state) + struct CheckerSettings + { + // check individual remote servers? + bool doCheck = true; + + // get information for the website too? + bool getExtendedInfo = true; + + // time between servers (ticker) + int timeServerInterval_ms = 250; + + // cycle time before a reset takes place + int timeCheckerReset_s = 900; // every 15 minutes + } CheckerSettings; + + // maintenance settings + struct MaintenanceSettings + { + // do maintenance? + bool doMaintenance = true; + + // interval + int timeMaintenanceInterval_s = 300; // every 5 minutes + } + MaintenanceSettings; + + // contact information + struct PublicInformationSettings + { + // your website, domain name, brand name or identity + QString hostname = ""; + + // your (nick)name + QString adminName = ""; + + // your e-mailaddress (format not checked, TODO) + QString contact = ""; + } + PublicInformationSettings; +}; + +#endif // SETTINGSTRUCTURE_H diff --git a/src/Settings/writesettings.cpp b/src/Settings/writesettings.cpp new file mode 100644 index 0000000..22d72af --- /dev/null +++ b/src/Settings/writesettings.cpp @@ -0,0 +1,76 @@ +#include "loadsettings.h" + +void writeSettings (const QString &settingsFilePath) +{ + // user already specified that config is to be written + QSettings settingsFile(settingsFilePath, QSettings::IniFormat); + + // initialise default settings to write to config + SettingStructure settings; + + // logging settings + settingsFile.setValue("Logging/CycleLogs", settings.LoggingSettings.cycle); + settingsFile.setValue("Logging/SuppressLog", settings.LoggingSettings.suppressLog); + settingsFile.setValue("Logging/SuppressDisplay", settings.LoggingSettings.suppressDisplay); + + // beacon server settings (udp server) + settingsFile.setValue("BeaconServer/BeaconPort", settings.BeaconServerSettings.beaconPort); + settingsFile.setValue("BeaconServer/DoUplink", settings.BeaconServerSettings.doUplink); + + // listen server settings (tcp server) + settingsFile.setValue("ListenServer/ListenPort", settings.ListenServerSettings.listenPort); + settingsFile.setValue("ListenServer/ServerLifeTime_s", settings.ListenServerSettings.serverttl_s); + + // syncer settings (tcp client) + settingsFile.setValue("Syncer/DoSync", settings.SyncerSettings.doSync); + settingsFile.setValue("Syncer/SyncGames", settings.SyncerSettings.syncGames); + settingsFile.setValue("Syncer/SyncInterval_s", settings.SyncerSettings.syncInterval_s); + + // if sync is set, but no servers are listed, generate default line with 333networks + if ( settings.SyncerSettings.doSync and settings.SyncerSettings.syncServers.size() <= 0 ) + { + SyncServer defaultServer; + defaultServer.remoteAddress = "master.333networks.com"; // default settings are correct + settings.SyncerSettings.syncServers.append(defaultServer); + } + + // write list of servers + QListIterator<SyncServer> syncRecordIterator(settings.SyncerSettings.syncServers); + int i = 0; + + settingsFile.beginWriteArray("Syncer"); + while ( syncRecordIterator.hasNext() ) + { + // next list item + SyncServer syncServer = syncRecordIterator.next(); + if ( syncServer.remoteAddress.size() > 0 ) + { + // write to settings file + settingsFile.setArrayIndex(i++); + + // output format 1\SyncServer=master.333networks.com, 27900, 28900 + QString strServer = QStringLiteral("%1, %2, %3") + .arg(syncServer.remoteAddress, + QString::number(syncServer.beaconPort), + QString::number(syncServer.listenPort) ); + settingsFile.setValue("SyncServer", strServer); + } + + } + settingsFile.endArray(); + + // server checker (udp client ticker) + settingsFile.setValue("Checker/DoCheck", settings.CheckerSettings.doCheck); + settingsFile.setValue("Checker/GetExtendedInformation", settings.CheckerSettings.getExtendedInfo); + settingsFile.setValue("Checker/ServerCheckInterval_ms", settings.CheckerSettings.timeServerInterval_ms); + settingsFile.setValue("Checker/CycleInterval_s", settings.CheckerSettings.timeCheckerReset_s); + + // maintenance settings + settingsFile.setValue("Maintenance/DoMaintenance", settings.MaintenanceSettings.doMaintenance); + settingsFile.setValue("Maintenance/MaintainRate_s", settings.MaintenanceSettings.timeMaintenanceInterval_s); + + // public details + settingsFile.setValue("PublicDetails/Hostname", settings.PublicInformationSettings.hostname); + settingsFile.setValue("PublicDetails/AdminName", settings.PublicInformationSettings.adminName); + settingsFile.setValue("PublicDetails/Contact", settings.PublicInformationSettings.contact); +} |
