diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CRSMConfig.cpp | 155 | ||||
| -rw-r--r-- | src/CRSMConfig.hpp | 352 | ||||
| -rw-r--r-- | src/CrServerManager.pro | 6 | ||||
| -rw-r--r-- | src/crsm.cpp | 467 | ||||
| -rw-r--r-- | src/crsm.hpp | 11 |
5 files changed, 752 insertions, 239 deletions
diff --git a/src/CRSMConfig.cpp b/src/CRSMConfig.cpp new file mode 100644 index 0000000..25f8bd1 --- /dev/null +++ b/src/CRSMConfig.cpp @@ -0,0 +1,155 @@ +#include "CRSMConfig.hpp" + +#include <QFile> + +CRSMConfig::CRSMConfig() +{ + +} + +void CRSMConfig::addConfigValue(QString name, CRSMConfigValueBase* value) +{ + configValues[name] = value; +} + +void CRSMConfig::setConfigValue(const QString &name, const QString &value) +{ + CRSMConfigValueBase& configValue = getConfigValue(name); + configValue.setValue(value); +} + +void CRSMConfig::addConfigListEntry(const QString &name, const QString &value) +{ + CRSMConfigValueBase& configValue = getConfigValue(name); + if(configValue.type() != CRSMConfigValueType::List) + { + throw CRSMConfigException("Cannot add a list entry to a non-list-config value \"" + name.toStdString() + "\""); + } + ((CRSMConfigValueList*)&configValue)->append(value); +} + +void CRSMConfig::setConfigMapValue(const QString &name, const QString &key, const QString &value) +{ + CRSMConfigValueBase& configValue = getConfigValue(name); + if(configValue.type() != CRSMConfigValueType::Map) + { + throw CRSMConfigException("Cannot set a map value on a non-map-config value \"" + name.toStdString() + "\""); + } + ((CRSMConfigValueMap*)&configValue)->setKeyValue(key, value); +} + +CRSMConfigValueBase& CRSMConfig::getConfigValue(const QString& name) +{ + if(!configValues.contains(name)) + { + throw CRSMConfigException("Unknown config value \"" + name.toStdString() + "\""); + } + else + { + return *configValues[name]; + } +} + +QString CRSMConfig::read(const QString &fileName) +{ + QString ret = ""; + + QFile config(fileName); + if(!config.exists()) + { + if(write(fileName)) + { + return fileName + ": The config-file did not exist, a new one with default values has been created.\n"; + } + else + { + return fileName + ": The config-file did not exist, a new one could not be created.\n"; + } + } + else if(config.open(QIODevice::ReadOnly | QIODevice::Text)) + { + static QRegExp valueExp(R"(^([^=]+)=(.*)$)"); + static QRegExp listExp(R"(^([^=]+)\+=(.*)$)"); + static QRegExp mapExp(R"(^([^\[]+)\[([^\]]+)\]\s*=\s*(.*)$)"); + QString line; + for(size_t lineNr = 1; !config.atEnd(); ++lineNr) + { + try + { + line = config.readLine().trimmed(); + if(listExp.exactMatch(line)) + { + addConfigListEntry(listExp.cap(1).trimmed(), listExp.cap(2).trimmed()); + } + else if(mapExp.exactMatch(line)) + { + setConfigMapValue(mapExp.cap(1).trimmed(), mapExp.cap(2).trimmed(), mapExp.cap(3).trimmed()); + } + else if(valueExp.exactMatch(line)) + { + setConfigValue(valueExp.cap(1).trimmed(), valueExp.cap(2).trimmed()); + } + } + catch(CRSMConfigException e) + { + ret += fileName + ":" + QString::number(lineNr) + ": " + e.what() + "\n"; + } + } + } + else + { + return fileName + ": The config-file could not be read.\n"; + } + + return ret; +} + +bool CRSMConfig::write(const QString &fileName) +{ + QFile config(fileName); + if(config.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) + { + foreach(const QString& key, configValues.keys()) + { + CRSMConfigValueBase& value = *configValues[key]; + switch(value.type()) + { + case CRSMConfigValueType::Map: + { + const QMap<QString, QString> values = (dynamic_cast<CRSMConfigValueMap*>(&value))->getValues(); + foreach(const QString& mapKey, values.keys()) + { + config.write(QString(key + "[" + mapKey + "]" + " = " + values.value(mapKey) + "\n").toUtf8()); + } + break; + } + case CRSMConfigValueType::List: + foreach(const QString& val, (dynamic_cast<CRSMConfigValueList*>(&value))->getValues()) + { + config.write(QString(key + " += " + val + "\n").toUtf8()); + } + break; + default: + config.write(QString(key + " = " + value.value() + "\n").toUtf8()); + } + } + + return true; + } + else + { + return false; + } +} + +void CRSMConfig::operator()(CRSMConfig &&other) +{ + auto curConfigValues(configValues); + *this = other; + configValues = curConfigValues; +} + +void CRSMConfig::clear() +{ + (*this)(CRSMConfig()); +} diff --git a/src/CRSMConfig.hpp b/src/CRSMConfig.hpp new file mode 100644 index 0000000..ef77716 --- /dev/null +++ b/src/CRSMConfig.hpp @@ -0,0 +1,352 @@ +#pragma once + +#include <QString> +#include <QStringList> +#include <QList> +#include <QMap> + +#include <exception> + +using CRSMConfigException = std::logic_error; + +namespace CRSMConfigValueType { +enum Type { + None, + String, + Integer, + Boolean, + List, + Map +}; +} + +class CRSMConfigValueBase { +public: + + virtual void setValue(const QString&) { } + virtual QString value() { return ""; } + virtual CRSMConfigValueType::Type type() { return CRSMConfigValueType::Type::None; } +}; + +template<typename Type> +class CRSMConfigValue : public CRSMConfigValueBase { +public: +// CRSMConfigValue(Type&) { } + + virtual void setValue(const QString&) { throw CRSMConfigException("Cannot assign"); } + virtual QString value() { throw CRSMConfigException("Cannot get the value"); } +}; + +using String = QString; +using Integer = int; +using Boolean = bool; +#define List(Type) QList<Type> +#define Map(KeyType, ValueType) QMap<KeyType, ValueType> + +template<> +class CRSMConfigValue<String> : public CRSMConfigValueBase { + String& config; + +public: + CRSMConfigValue(String& config) : config(config) { } + + virtual void setValue(const QString& value) { config = value; } + virtual QString value() { return config; } + virtual CRSMConfigValueType::Type type() { return CRSMConfigValueType::Type::String; } +}; + +template<> +class CRSMConfigValue<Integer> : public CRSMConfigValueBase { + Integer& config; + +public: + CRSMConfigValue(Integer& config) : config(config) { } + + virtual void setValue(const QString& value) + { + bool ok = true; + Integer val = value.toInt(&ok, 0); + if(!ok) throw CRSMConfigException("\"" + value.toStdString() + "\" could not be parsed as an Integer"); + config = val; + } + virtual QString value() { return QString::number(config); } + virtual CRSMConfigValueType::Type type() { return CRSMConfigValueType::Type::Integer; } +}; + +template<> +class CRSMConfigValue<Boolean> : public CRSMConfigValueBase { + Boolean& config; + +public: + CRSMConfigValue(Boolean& config) : config(config) { } + + virtual void setValue(const QString& value) + { + if(value == "true") + { + config = true; + } + else if(value == "false") + { + config = false; + } + else + { + throw CRSMConfigException("\"" + value.toStdString() + "\" could not be parsed as a Boolean"); + } + } + virtual QString value() { return config ? "true" : "false"; } + virtual CRSMConfigValueType::Type type() { return CRSMConfigValueType::Type::Boolean; } +}; + +class CRSMConfigValueList : public CRSMConfigValueBase { +public: + virtual void append(const QString& entry) = 0; + virtual QStringList getValues() = 0; +}; + +class CRSMConfigValueMap : public CRSMConfigValueBase { +public: + virtual void setKeyValue(const QString& key, const QString& value) = 0; + virtual QMap<QString, QString> getValues() = 0; +}; + +template<typename Type> +class CRSMConfigValue<QList<Type>> : public CRSMConfigValueList { + using ListType = QList<Type>; + + ListType& config; + +public: + CRSMConfigValue(ListType& config) : config(config) {} + + virtual ListType& list() { return config; } + virtual CRSMConfigValueType::Type type() { return CRSMConfigValueType::Type::List; } + + virtual void append(const QString &entry) + { + Type val; + CRSMConfigValue<Type> configValue(val); + configValue.setValue(entry); + config.append(val); + } + + virtual QStringList getValues() + { + QStringList ret; + + foreach(Type val, config) + { + CRSMConfigValue<Type> value(val); + ret.append(value.value()); + } + + return ret; + } +}; + +template<typename KeyType, typename ValueType> +class CRSMConfigValue<QMap<KeyType, ValueType>> : public CRSMConfigValueMap { + using MapType = QMap<KeyType, ValueType>; + + MapType& config; + +public: + CRSMConfigValue(MapType& config) : config(config) {} + + virtual MapType& map() { return config; } + virtual CRSMConfigValueType::Type type() { return CRSMConfigValueType::Type::Map; } + + virtual void setKeyValue(const QString& key, const QString& value) + { + KeyType keyVal; + CRSMConfigValue<KeyType> keyConfigValue(keyVal); + keyConfigValue.setValue(key); + ValueType valueVal; + CRSMConfigValue<ValueType> valueConfigValue(valueVal); + valueConfigValue.setValue(value); + config[key] = value; + } + + virtual QMap<QString, QString> getValues() + { + QMap<QString, QString> ret; + + foreach(KeyType key, config.keys()) + { + CRSMConfigValue<KeyType> keyValue(key); + CRSMConfigValue<KeyType> valValue(config[key]); + ret[keyValue.value()] = valValue.value(); + } + + return ret; + } +}; + +template<typename Type> +CRSMConfigValue<Type>* mkConfigValue(Type& Value) +{ + return new CRSMConfigValue<Type>(Value); +} + +class CRSMConfig +{ +public: + struct { + Integer ManagementPort = 9372; + } CRSM; + + struct { + struct { + String Arguments = "/fullscreen /lobby:300 /nosignup Objects.c4d"; + String Config = "config"; + String Executable = "clonk-server"; + List(String) IgnoreFolders = {"Network", "Records.c4f", "Savegames.c4f"}; + + Integer EmptyTimer = 60; + } Server; + + struct { + struct { + Integer Count = 5; + Integer Time = 3; + } AntiFlood; + + List(Integer) Moderators = List(Integer)(); + Integer RegainAdminTime = 120; + } Chat; + } Clonk; + + struct { + Boolean Auto = true; + Boolean RandomizeAuto = true; + + Integer MaxWishesPerScen = 2; + Integer MaxWishesPerUser = 2; + Integer UserListLength = 5; + + Map(String, String) Alias; + } Hosting; + + struct { + Boolean Use = false; + String Server = "irc.euirc.net"; + String Nick = "CRSM"; + String Password = ""; + String RealName = "Dedicated Clonk server powered by CRSM"; + String Channel = "#crsm"; + Boolean UseIngameChat = false; + String IngameChannel = "#crsm-ingame"; + String QuitMessage = "Dedicated Clonk server powered by CRSM"; + Integer ReconnectDelay = 10; + String ScenListMessage = "A list of available scenarios is available ingame or in a lobby."; + List(String) Moderators = List(String)(); + } IRC; + + + struct { + struct { + String ReattachId = ""; + } ProcessManager; + struct { + struct { + String Directory; + String ServerNick; + String ServerPCName; + } Clonk; + } Volatile; + struct { + Map(String, String) AliasWishes; + } Hosting; + } Auto; + + struct { + Boolean ServerUses = false; + Boolean PromptEnabled = false; + Integer RereadLimit = 50; + } Readline; + + explicit CRSMConfig(); + + void operator()(CRSMConfig&& other); + + void setConfigValue(const QString& name, const QString& value); + void addConfigListEntry(const QString& name, const QString& value); + void setConfigMapValue(const QString& name, const QString& key, const QString& value); + + QString read(const QString& fileName); + bool write(const QString& fileName); + + void clear(); + +protected: + void addConfigValue(QString name, CRSMConfigValueBase *value); + CRSMConfigValueBase& getConfigValue(const QString &name); + +private: +#define ConfigValue(Value) {#Value, mkConfigValue(Value)} + QMap<QString, CRSMConfigValueBase*> configValues { + ConfigValue(CRSM.ManagementPort), + + + + ConfigValue(Clonk.Server.Arguments), + ConfigValue(Clonk.Server.Config), + ConfigValue(Clonk.Server.Executable), + ConfigValue(Clonk.Server.EmptyTimer), + ConfigValue(Clonk.Server.IgnoreFolders), + + + ConfigValue(Clonk.Chat.AntiFlood.Count), + ConfigValue(Clonk.Chat.AntiFlood.Time), + + ConfigValue(Clonk.Chat.Moderators), + ConfigValue(Clonk.Chat.RegainAdminTime), + + + + ConfigValue(Hosting.Auto), + ConfigValue(Hosting.RandomizeAuto), + ConfigValue(Hosting.MaxWishesPerScen), + ConfigValue(Hosting.MaxWishesPerUser), + ConfigValue(Hosting.UserListLength), + ConfigValue(Hosting.Alias), + + + + ConfigValue(IRC.Use), + ConfigValue(IRC.Server), + ConfigValue(IRC.Nick), + ConfigValue(IRC.Password), + ConfigValue(IRC.RealName), + ConfigValue(IRC.Channel), + ConfigValue(IRC.UseIngameChat), + ConfigValue(IRC.IngameChannel), + ConfigValue(IRC.QuitMessage), + ConfigValue(IRC.ReconnectDelay), + ConfigValue(IRC.ScenListMessage), + ConfigValue(IRC.Moderators), + + + + ConfigValue(Auto.ProcessManager.ReattachId), + + + ConfigValue(Auto.Hosting.AliasWishes), + + + + ConfigValue(Readline.ServerUses), + ConfigValue(Readline.PromptEnabled), + ConfigValue(Readline.RereadLimit) + }; + +#undef ConfigValue +}; + + +#undef String +#undef Integer +#undef Boolean +#undef List +#undef Map diff --git a/src/CrServerManager.pro b/src/CrServerManager.pro index 5323fea..eab24e6 100644 --- a/src/CrServerManager.pro +++ b/src/CrServerManager.pro @@ -19,13 +19,15 @@ TEMPLATE = app SOURCES += main.cpp \ crsm.cpp \ - ProcessManager.cpp + ProcessManager.cpp \ + CRSMConfig.cpp HEADERS += \ CmdFunctionRef.hpp \ ClientInfo.hpp \ crsm.hpp \ - ProcessManager.hpp + ProcessManager.hpp \ + CRSMConfig.hpp equals(QT_ARCH, "x86_64"):linux-*: DEFINES += Q_OS_LINUX64 QMAKE_CXXFLAGS *= -std=c++11 -Wall -Wextra -Werror -Wunused diff --git a/src/crsm.cpp b/src/crsm.cpp index 0111721..ec249a6 100644 --- a/src/crsm.cpp +++ b/src/crsm.cpp @@ -30,14 +30,14 @@ CRSM::CRSM(QObject *parent) : readConfig(); connect(&managementServer, SIGNAL(newConnection()), this, SLOT(newManagementConnection())); - managementServer.listen(QHostAddress::LocalHostIPv6, settings["ManagementPort"].toUInt()); + managementServer.listen(QHostAddress::LocalHostIPv6, Config.CRSM.ManagementPort); listC4Folders(); readScenarios(); - if(settings.contains("ReattachId")) + if(!Config.Auto.ProcessManager.ReattachId.isEmpty()) { - processManager = new ProcessManager("CRSM-Clonkserver-", settings["ReattachId"]); + processManager = new ProcessManager("CRSM-Clonkserver-", Config.Auto.ProcessManager.ReattachId); } else { @@ -48,12 +48,12 @@ CRSM::CRSM(QObject *parent) : if(!processManager->isOk()) { out("Could not start Process Manager!"); - settings.remove("ReattachId"); + Config.Auto.ProcessManager.ReattachId.clear(); writeConfig(); return; } - settings["ReattachId"] = processManager->ID(); + Config.Auto.ProcessManager.ReattachId = processManager->ID(); writeConfig(); if(processManager->isRunning()) @@ -65,7 +65,7 @@ CRSM::CRSM(QObject *parent) : connect(&greetMapper, SIGNAL(mapped(QString)), this, SLOT(greet(QString))); - autoHost = settings["AutoHost"] == "true"; + autoHost = Config.Hosting.Auto; connect(processManager, SIGNAL(readyRead()), this, SLOT(readServerOutput())); //connect(processManager, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError())); @@ -73,17 +73,17 @@ CRSM::CRSM(QObject *parent) : //QSocketNotifier *inNotifier = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read,this); //connect(inNotifier, SIGNAL(activated(int)), this, SLOT(readInput())); - QFile *reallog = new QFile(settings["ClonkDirectory"]+"CRSM.log"); + QFile *reallog = new QFile(Config.Auto.Volatile.Clonk.Directory + "CRSM.log"); reallog->open(QIODevice::Append | QIODevice::Text); logstream.setDevice(reallog); - if(settings["UseIrc"] == "true") + if(Config.IRC.Use) { prepareAndConnectIrc(); } else { - settings["IrcUseIngameChat"] = "false"; + Config.IRC.UseIngameChat = false; } ok = true; @@ -109,7 +109,7 @@ void CRSM::readServerOutput() static QRegExp timeRemover("^>?\\s*\\[(\\d\\d:\\d\\d:\\d\\d)\\]\\s+(.*)$"); QString what(processManager->readLine()); - if(settings["ServerUsesReadline"] == "true") + if(Config.Readline.ServerUses) { while(writtenToServer.length() > 0 && what.length() > 0 && writtenToServer.at(0) == what.at(0)) { @@ -126,7 +126,7 @@ void CRSM::readServerOutput() logstream << what.trimmed() << endl; - if(settings["UseIrc"] == "true") + if(Config.IRC.Use) { foreach(const QString &mess, what.split("\n", QString::SkipEmptyParts)) foreach(const QString &mod, ircModIOList) @@ -146,12 +146,12 @@ void CRSM::readServerOutput() QString user = userexp.cap(4); QString pcName = userexp.cap(2); int cuid = userexp.cap(3).toInt(); - if(pcName != settings["ServerPCName"]) + if(pcName != Config.Auto.Volatile.Clonk.ServerPCName) { ClientInfo& info = getClientInfo(pcName, cuid, user); - if(info.floodCheck(settings["AntiFloodCount"].toInt(), settings["AntiFloodTime"].toInt(), QDateTime(QDate::currentDate(), QTime::fromString(timeRemover.cap(1), "hh:mm:ss")))) + if(info.floodCheck(Config.Clonk.Chat.AntiFlood.Count, Config.Clonk.Chat.AntiFlood.Time, QDateTime(QDate::currentDate(), QTime::fromString(timeRemover.cap(1), "hh:mm:ss")))) { - kick(pcName, "Flooding! Maximal " + settings["AntiFloodCount"] + " Nachrichten in " + settings["AntiFloodTime"] + "s"); + kick(pcName, "Flooding! Maximal " + QString::number(Config.Clonk.Chat.AntiFlood.Count) + " Nachrichten in " + QString::number(Config.Clonk.Chat.AntiFlood.Time) + "s"); } else if(!isMeMessage) { @@ -169,7 +169,7 @@ void CRSM::readServerOutput() } else if(session["IrcUseIngameChat"] == "true") { - connection->sendCommand(IrcCommand::createMessage(settings["IrcIngameChannel"], "[Clonk]<" + user + "> " + msg)); + connection->sendCommand(IrcCommand::createMessage(Config.IRC.IngameChannel, "[Clonk]<" + user + "> " + msg)); } } } @@ -189,7 +189,7 @@ void CRSM::readServerOutput() timer->start(1000); if(session["IrcUseIngameChat"] == "true") { - connection->sendCommand(IrcCommand::createMessage(settings["IrcIngameChannel"], "[Clonk] " + info.toString() + " verbunden.")); + connection->sendCommand(IrcCommand::createMessage(Config.IRC.IngameChannel, "[Clonk] " + info.toString() + " verbunden.")); } } } @@ -238,7 +238,7 @@ void CRSM::readServerOutput() if(session["IrcUseIngameChat"] == "true") { - connection->sendCommand(IrcCommand::createMessage(settings["IrcIngameChannel"], "[Clonk] " + info.toString() + " entfernt" + leaveExp.cap(2))); + connection->sendCommand(IrcCommand::createMessage(Config.IRC.IngameChannel, "[Clonk] " + info.toString() + " entfernt" + leaveExp.cap(2))); } if(info == sessionAdmin) @@ -254,9 +254,9 @@ void CRSM::readServerOutput() { processManager->closeProgFifos(); } - else if(clients.size() == 0 && settings["EmptyTimer"] != "-1" && (session["CountDown"] == "false" || session["CountDown"].toInt() > settings["EmptyTimer"].toInt())) + else if(clients.size() == 0 && Config.Clonk.Server.EmptyTimer != -1 && (session["CountDown"] == "false" || session["CountDown"].toInt() > Config.Clonk.Server.EmptyTimer)) { - writeToServer("/start " + settings["EmptyTimer"] + "\n"); + writeToServer("/start " + QString::number(Config.Clonk.Server.EmptyTimer) + "\n"); } } @@ -287,7 +287,7 @@ void CRSM::readInput() { writeToServer("Der Server Manager wird upgedatet. Befehle funktionieren temporär nicht.\n"); } - settings["ReattachId"] = processManager->ID(); + Config.Auto.ProcessManager.ReattachId = processManager->ID(); writeConfig(); QCoreApplication::quit(); return; @@ -295,7 +295,7 @@ void CRSM::readInput() if(what == "/exit") { processManager->closeProgFifos(); - settings.remove("ReattachId"); + Config.Auto.ProcessManager.ReattachId.clear(); finish = true; if(session["hosting"] != "true") scenarioFinished(); @@ -327,8 +327,7 @@ void CRSM::readInput() if(what == "/reload") { out("Reloading config...\n"); - lists.clear(); - settings.clear(); + Config.clear(); ircModChecks.clear(); ircMods.clear(); ircModFifosOld.clear(); @@ -383,7 +382,7 @@ void CRSM::scenarioFinished() processManager->exit(); if(connection != 0) { - connection->quit(settings["IrcQuitMessage"]); + connection->quit(Config.IRC.QuitMessage); connect(connection, SIGNAL(disconnected()), QCoreApplication::instance(), SLOT(quit())); QTimer::singleShot(500, QCoreApplication::instance(), SLOT(quit())); } @@ -398,9 +397,9 @@ void CRSM::scenarioFinished() leaveAdmins.clear(); if((autoHost || userlist.length() > 0) && !finish) nextScen(); - else if(!settings["IrcIngameChannel"].isEmpty()) + else if(!Config.IRC.IngameChannel.isEmpty()) { - connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Kein laufendes Spiel.")); + connection->sendCommand(IrcCommand::createTopic(Config.IRC.IngameChannel, "Kein laufendes Spiel.")); QFile lastScenFile(LAST_SCEN_FILE_NAME); QFile curScenFile(CUR_SCEN_FILE_NAME); curScenFile.open(QFile::ReadOnly); @@ -424,7 +423,7 @@ void CRSM::ircMessageReceived(IrcMessage *message) QStringList split = message->parameters().at(1).split(' ', QString::SkipEmptyParts); if(((IrcNoticeMessage*)message)->content().contains("nickname is registered")) { - connection->sendCommand(IrcCommand::createMessage("NickServ", "IDENTIFY " + settings["IrcNick"] + " " + settings["IrcPassword"])); + connection->sendCommand(IrcCommand::createMessage("NickServ", "IDENTIFY " + Config.IRC.Nick + " " + Config.IRC.Password)); } else if(split.first() == "STATUS") { @@ -448,7 +447,7 @@ void CRSM::ircMessageReceived(IrcMessage *message) if(message->parameters().at(0) == connection->nickName()) target = message->nick(); QString mess = message->parameters().at(1).trimmed(); - if(target == settings["IrcIngameChannel"]) + if(target == Config.IRC.IngameChannel) { writeToServer("[IRC]<" + message->nick() + "> " + mess + "\n"); } @@ -490,7 +489,7 @@ void CRSM::ircMessageReceived(IrcMessage *message) { QString joinChannel = message->parameters().at(0); connection->sendCommand(IrcCommand::createMessage(joinChannel, "Hallo " + message->nick() + "!")); - if(joinChannel == settings["IrcIngameChannel"]) + if(joinChannel == Config.IRC.IngameChannel) { writeToServer("[IRC] " + message->nick() + " hat den Channel betreten." + "\n"); } @@ -521,7 +520,7 @@ void CRSM::ircMessageReceived(IrcMessage *message) else if(message->type() == IrcMessage::Part) { QString leaveChannel = message->parameters().at(0); - if(leaveChannel == settings["IrcIngameChannel"]) + if(leaveChannel == Config.IRC.IngameChannel) { writeToServer("[IRC] " + message->nick() + " hat den Channel verlassen." + "\n"); } @@ -529,17 +528,17 @@ void CRSM::ircMessageReceived(IrcMessage *message) else if(message->type() == IrcMessage::Mode) { QRegExp modeExp("^\\+[a-zA-Z]*(a|o)"); - if(message->parameters().size() >= 3 && message->parameters().at(0) == settings["IrcIngameChannel"] && modeExp.exactMatch(message->parameters().at(1)) && message->parameters().at(2) == settings["IrcNick"]) + if(message->parameters().size() >= 3 && message->parameters().at(0) == Config.IRC.IngameChannel && modeExp.exactMatch(message->parameters().at(1)) && message->parameters().at(2) == Config.IRC.Nick) { - if(settings["IrcUseIngameChat"] == "true" && !settings["IrcIngameChannel"].isEmpty()) + if(Config.IRC.UseIngameChat && !Config.IRC.IngameChannel.isEmpty()) { if(session["hosting"] != "true") { - connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Kein laufendes Spiel.")); + connection->sendCommand(IrcCommand::createTopic(Config.IRC.IngameChannel, "Kein laufendes Spiel.")); } else { - connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); + connection->sendCommand(IrcCommand::createTopic(Config.IRC.IngameChannel, "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); } } } @@ -555,9 +554,9 @@ void CRSM::greet(QString pcName) if(leaveAdmins.contains(info)) { int timeGone; - if((timeGone = leaveAdmins.value(info).secsTo(QDateTime::currentDateTime())) < settings["RegainAdminTime"].toInt() && sessionAdmin != ClientInfo()) + if((timeGone = leaveAdmins.value(info).secsTo(QDateTime::currentDateTime())) < Config.Clonk.Chat.RegainAdminTime && sessionAdmin != ClientInfo()) { - writeToServer(info.nick + "! Der Rundenadmin wurde freigegeben, weil du das Spiel verlassen hast.\nDu hast noch " + QString::number(settings["RegainAdminTime"].toInt() - timeGone) + "s Zeit um den Rundenadmin zurückzuholen.\n"); + writeToServer(info.nick + "! Der Rundenadmin wurde freigegeben, weil du das Spiel verlassen hast.\nDu hast noch " + QString::number(Config.Clonk.Chat.RegainAdminTime - timeGone) + "s Zeit um den Rundenadmin zurückzuholen.\n"); } else { @@ -627,7 +626,8 @@ void CRSM::newManagementData() void CRSM::managementConnectionDisconnected() { - QTcpSocket* sock = (QTcpSocket*)sender(); + QTcpSocket* sock = dynamic_cast<QTcpSocket*>(sender()); + if(sock == nullptr) return; out(managementConnections.value(sock).name + "disconnected from Management-Interface.\n"); if(managementConnections.contains(sock)) { @@ -637,10 +637,10 @@ void CRSM::managementConnectionDisconnected() void CRSM::updateNextAutoScens() { - while(nextAutoScens.length() < settings["UserListLength"].toInt()) + while(nextAutoScens.length() < Config.Hosting.UserListLength) { ScenarioSettings next(""); - if(settings["RandomizeAutoHosting"] == "true") + if(Config.Hosting.RandomizeAuto) { next = autolist.at(qrand() % autolist.length()); } @@ -675,14 +675,14 @@ void CRSM::startScen(const ScenarioSettings &scen, QStringList argList) scoreboardFile.close(); session["scenname"] = scen.name; - session["IrcUseIngameChat"] = settings["IrcUseIngameChat"]; - if(settings["IrcUseIngameChat"] == "true" && !settings["IrcIngameChannel"].isEmpty()) + session["IrcUseIngameChat"] = Config.IRC.UseIngameChat ? "true" : "false"; + if(Config.IRC.UseIngameChat && !Config.IRC.IngameChannel.isEmpty()) { - connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); + connection->sendCommand(IrcCommand::createTopic(Config.IRC.IngameChannel, "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); } filename = scen.name; - while(maps["Alias"].contains(filename)) - filename = maps["Alias"].value(filename); + while(Config.Hosting.Alias.contains(filename)) + filename = Config.Hosting.Alias.value(filename); //processManager->setWorkingDirectory(QDir::currentPath()); if(scen.league) { @@ -694,120 +694,120 @@ void CRSM::startScen(const ScenarioSettings &scen, QStringList argList) argList << "/noleague"; } argList << filename; - processManager->setWorkingDirectory(settings["ClonkDirectory"]); - processManager->start(settings["ServerExecutable"], argList); + processManager->setWorkingDirectory(Config.Auto.Volatile.Clonk.Directory); + processManager->start(Config.Clonk.Server.Executable, argList); } void CRSM::readConfig() { - maps.clear(); - lists.clear(); - settings.clear(); - settings["IrcReconnectDelay"] = "10"; - settings["EmptyTimer"] = "60"; - settings["MaxUserWishes"] = "2"; - settings["MaxScenWishes"] = "2"; - settings["AntiFloodCount"] = "5"; - settings["AntiFloodTime"] = "3"; - settings["RegainAdminTime"] = "120"; - settings["ServerExecutable"] = "clonk-server"; - settings["Arguments"] = "/fullscreen /lobby:300 /nosignup Objects.c4d"; - settings["ClonkConfig"] = "config"; - settings["UserListLength"] ="5"; - settings["ManagementPort"] = "9372"; - - QFile config(CONFIG_FILE_NAME); - if(!config.exists()) - { - config.open(QIODevice::WriteOnly | QIODevice::Text); - writeConfig(); - } - else if(config.open(QIODevice::ReadOnly | QIODevice::Text)) - { - QRegExp confExp("^([^=]+)=(.*)$"); - QRegExp confPlusExp("^([^=]+)\\+=(.*)$"); - QRegExp confMapExp("^([^\\[]+)\\[([^\\]]+)\\]\\s*=\\s*(.*)$"); - QString line; - for(;;) - { - line = config.readLine().trimmed(); - if(confPlusExp.exactMatch(line)) - { - lists[confPlusExp.cap(1).trimmed()].push_back(confPlusExp.cap(2).trimmed()); - } - else if(confMapExp.exactMatch(line)) - { - maps[confMapExp.cap(1).trimmed()][confMapExp.cap(2).trimmed()] = confMapExp.cap(3).trimmed(); - } - else if(confExp.exactMatch(line)) - { - settings.insert(confExp.cap(1).trimmed(),confExp.cap(2).trimmed()); - } - if(config.atEnd()) - break; - } - } - - out("config:\n"); - foreach(const QString &key, settings.keys()) - { - out(key + " = " + settings.value(key) + "\n"); - } - out("\n"); - foreach(const QString &key, lists.keys()) - { - out(key + ":\n"); - foreach(const QString &val, lists.value(key)) - { - out("\t" + val + "\n"); - } - } - out("\n"); - foreach(const QString &key, maps.keys()) - { - out(key + ":\n"); - foreach(const QString &mapkey, maps.value(key).keys()) - { - out("\t[" + mapkey + "]" + " = " + maps.value(key).value(mapkey) + "\n"); - } - } - out("\n"); - args = settings["Arguments"].split(" "); - args << "/config:"+settings["ClonkConfig"]; - settings["ClonkDirectory"] = QFileInfo(settings["ServerExecutable"]).absoluteDir().absolutePath()+QDir::separator(); - - QFile clonkconfig(settings["ClonkConfig"]); - if(!clonkconfig.exists()) - out("WARNING: Clonk's config file is not existing!"); - else - { - clonkconfig.open(QFile::ReadOnly); - QRegExp nickExp("^\\s*Nick=\"(.*)\"\\s*$"); - QRegExp pcNameExp("^\\s*LocalName=\"(.*)\"\\s*$"); - foreach(const QString &line, QString(clonkconfig.readAll().trimmed()).split("\n")) - { - if(nickExp.exactMatch(line)) - { - settings["ServerNick"] = nickExp.cap(1); - break; - } - else if(pcNameExp.exactMatch(line)) - { - settings["ServerPCName"] = pcNameExp.cap(1); - break; - } - } - out("\n"); - out("ClonkDirectory = " + settings.value("ClonkDirectory") + "\n"); - out("ServerNick = " + settings.value("ServerNick") + "\n"); - } - out("\n"); - bool ok; - ushort mgmtPort = settings["ManagementPort"].toUShort(&ok); - if(!ok || mgmtPort == 0) - { - settings["ManagementPort"] = "9372"; - } + Config.clear(); + out(Config.read(CONFIG_FILE_NAME)); + return; +// settings["IrcReconnectDelay"] = "10"; +// settings["EmptyTimer"] = "60"; +// settings["MaxUserWishes"] = "2"; +// settings["MaxScenWishes"] = "2"; +// settings["AntiFloodCount"] = "5"; +// settings["AntiFloodTime"] = "3"; +// settings["RegainAdminTime"] = "120"; +// settings["ServerExecutable"] = "clonk-server"; +// settings["Arguments"] = "/fullscreen /lobby:300 /nosignup Objects.c4d"; +// settings["ClonkConfig"] = "config"; +// settings["UserListLength"] ="5"; +// settings["ManagementPort"] = "9372"; + +// QFile config(CONFIG_FILE_NAME); +// if(!config.exists()) +// { +// config.open(QIODevice::WriteOnly | QIODevice::Text); +// writeConfig(); +// } +// else if(config.open(QIODevice::ReadOnly | QIODevice::Text)) +// { +// QRegExp confExp("^([^=]+)=(.*)$"); +// QRegExp confPlusExp("^([^=]+)\\+=(.*)$"); +// QRegExp confMapExp("^([^\\[]+)\\[([^\\]]+)\\]\\s*=\\s*(.*)$"); +// QString line; +// for(;;) +// { +// line = config.readLine().trimmed(); +// if(confPlusExp.exactMatch(line)) +// { +// lists[confPlusExp.cap(1).trimmed()].push_back(confPlusExp.cap(2).trimmed()); +// } +// else if(confMapExp.exactMatch(line)) +// { +// maps[confMapExp.cap(1).trimmed()][confMapExp.cap(2).trimmed()] = confMapExp.cap(3).trimmed(); +// } +// else if(confExp.exactMatch(line)) +// { +// settings.insert(confExp.cap(1).trimmed(),confExp.cap(2).trimmed()); +// } +// if(config.atEnd()) +// break; +// } +// } + +// out("config:\n"); +// foreach(const QString &key, settings.keys()) +// { +// out(key + " = " + settings.value(key) + "\n"); +// } +// out("\n"); +// foreach(const QString &key, lists.keys()) +// { +// out(key + ":\n"); +// foreach(const QString &val, lists.value(key)) +// { +// out("\t" + val + "\n"); +// } +// } +// out("\n"); +// foreach(const QString &key, maps.keys()) +// { +// out(key + ":\n"); +// foreach(const QString &mapkey, maps.value(key).keys()) +// { +// out("\t[" + mapkey + "]" + " = " + maps.value(key).value(mapkey) + "\n"); +// } +// } +// out("\n"); +// args = settings["Arguments"].split(" "); +// args << "/config:"+settings["ClonkConfig"]; +// settings["ClonkDirectory"] = QFileInfo(settings["ServerExecutable"]).absoluteDir().absolutePath()+QDir::separator(); + +// QFile clonkconfig(settings["ClonkConfig"]); +// if(!clonkconfig.exists()) +// out("WARNING: Clonk's config file is not existing!"); +// else +// { +// clonkconfig.open(QFile::ReadOnly); +// QRegExp nickExp("^\\s*Nick=\"(.*)\"\\s*$"); +// QRegExp pcNameExp("^\\s*LocalName=\"(.*)\"\\s*$"); +// foreach(const QString &line, QString(clonkconfig.readAll().trimmed()).split("\n")) +// { +// if(nickExp.exactMatch(line)) +// { +// settings["ServerNick"] = nickExp.cap(1); +// break; +// } +// else if(pcNameExp.exactMatch(line)) +// { +// settings["ServerPCName"] = pcNameExp.cap(1); +// break; +// } +// } +// out("\n"); +// out("ClonkDirectory = " + settings.value("ClonkDirectory") + "\n"); +// out("ServerNick = " + settings.value("ServerNick") + "\n"); +// } +// out("\n"); +// bool ok; +// ushort mgmtPort = settings["ManagementPort"].toUShort(&ok); +// if(!ok || mgmtPort == 0) +// { +// settings["ManagementPort"] = "9372"; +// } } @@ -864,12 +864,12 @@ void CRSM::readScenarios() void CRSM::listC4Folders() { out("Listing Contents of C4Folders..."); - QDirIterator it(settings["ClonkDirectory"], QDirIterator::FollowSymlinks); + QDirIterator it(Config.Auto.Volatile.Clonk.Directory, QDirIterator::FollowSymlinks); for(; it.hasNext(); it.next()) { if(it.fileName() == ".." || it.fileName() == ".") continue; - if((it.fileInfo().suffix() == "c4f" || (it.fileInfo().isDir() && !QDir(it.fileInfo().absoluteFilePath()).entryList(QStringList() << "*.c4f" << "*.c4s").isEmpty())) && it.fileName() != "." && it.fileName() != ".." && !lists["IgnoreFolders"].contains(it.fileInfo().baseName())) + if((it.fileInfo().suffix() == "c4f" || (it.fileInfo().isDir() && !QDir(it.fileInfo().absoluteFilePath()).entryList(QStringList() << "*.c4f" << "*.c4s").isEmpty())) && it.fileName() != "." && it.fileName() != ".." && Config.Clonk.Server.IgnoreFolders.contains(it.fileInfo().baseName())) { const QStringList& list = listC4Folder(it.filePath()); if(!list.isEmpty()) @@ -890,7 +890,7 @@ void CRSM::listC4Folders() void CRSM::cleanUp() { out("\nCleaning up Clonk Folder...\n"); - QDirIterator it(settings["ClonkDirectory"]+"Network/", QDirIterator::FollowSymlinks | QDirIterator::Subdirectories); + QDirIterator it(Config.Auto.Volatile.Clonk.Directory+"Network/", QDirIterator::FollowSymlinks | QDirIterator::Subdirectories); for(; it.hasNext(); it.next()) if(it.fileInfo().exists()) QFile(it.fileInfo().absoluteFilePath()).remove(); out("\n"); @@ -900,7 +900,7 @@ QString CRSM::scenPath(QString scenName) { bool isAlias = false; QString aliasName; - foreach(const QString& alias, maps["Alias"].keys()) + foreach(const QString& alias, Config.Hosting.Alias.keys()) { if(alias.compare(scenName, Qt::CaseInsensitive) == 0) { @@ -908,12 +908,12 @@ QString CRSM::scenPath(QString scenName) break; } } - while(maps["Alias"].contains(scenName)) + while(Config.Hosting.Alias.contains(scenName)) { - scenName = maps["Alias"].value(scenName); + scenName = Config.Hosting.Alias.value(scenName); isAlias = true; } - QFileInfo fileInfo(settings["ClonkDirectory"] + scenName); + QFileInfo fileInfo(Config.Auto.Volatile.Clonk.Directory + scenName); if(fileInfo.suffix() != "c4s") { return QString(); @@ -935,7 +935,7 @@ QString CRSM::scenPath(QString scenName) { if(split.first().right(4) == ".c4f") { - const QStringList& entryList = QDir(settings["ClonkDirectory"]).entryList(QStringList() << "*.c4f"); + const QStringList& entryList = QDir(Config.Auto.Volatile.Clonk.Directory).entryList(QStringList() << "*.c4f"); QString folderName = split.first(); foreach(const QString& entry, entryList) { @@ -945,7 +945,7 @@ QString CRSM::scenPath(QString scenName) break; } } - QFile lstFile(settings["ClonkDirectory"] + folderName + ".lst"); + QFile lstFile(Config.Auto.Volatile.Clonk.Directory + folderName + ".lst"); if(lstFile.exists()) { lstFile.open(QFile::ReadOnly); @@ -979,31 +979,31 @@ QString CRSM::listScenarios(QString commandArgs) if(commandArgs.isEmpty()) { ret += "Folgende Szenarien stehen zur Auswahl:\n"; - QDirIterator it(settings["ClonkDirectory"], QDirIterator::FollowSymlinks); + QDirIterator it(Config.Auto.Volatile.Clonk.Directory, QDirIterator::FollowSymlinks); for(; it.hasNext(); it.next()) { - if(it.fileInfo().suffix() == "c4s" && !it.fileInfo().absoluteFilePath().contains(settings["ClonkDirectory"]+"Network/")) - ret += QString(" "+it.fileInfo().absoluteFilePath().replace(settings["ClonkDirectory"],"")+"\n"); + if(it.fileInfo().suffix() == "c4s" && !it.fileInfo().absoluteFilePath().contains(Config.Auto.Volatile.Clonk.Directory+"Network/")) + ret += QString(" "+it.fileInfo().absoluteFilePath().replace(Config.Auto.Volatile.Clonk.Directory,"")+"\n"); } ret += "-----------------------------------------------------------------\nFolgende Ordner stehen zur Auswahl:\n"; - QDirIterator folderIt(settings["ClonkDirectory"], QDirIterator::FollowSymlinks); + QDirIterator folderIt(Config.Auto.Volatile.Clonk.Directory, QDirIterator::FollowSymlinks); for(; folderIt.hasNext(); folderIt.next()) { - if(folderIt.fileInfo().suffix() == "lst" && !folderIt.fileInfo().absoluteFilePath().contains(settings["ClonkDirectory"]+"Network/") && !lists["IgnoreFolders"].contains(folderIt.fileInfo().baseName())) - ret += QString(" "+folderIt.fileInfo().absoluteFilePath().left(folderIt.fileInfo().absoluteFilePath().length() - 4).replace(settings["ClonkDirectory"],"")+"\n"); + if(folderIt.fileInfo().suffix() == "lst" && !folderIt.fileInfo().absoluteFilePath().contains(Config.Auto.Volatile.Clonk.Directory+"Network/") && !Config.Clonk.Server.IgnoreFolders.contains(folderIt.fileInfo().baseName())) + ret += QString(" "+folderIt.fileInfo().absoluteFilePath().left(folderIt.fileInfo().absoluteFilePath().length() - 4).replace(Config.Auto.Volatile.Clonk.Directory,"")+"\n"); } } else if(commandArgs.toLower() == "aliase") { ret += "Vorhandene Aliase:\n"; - foreach(const QString &alias, maps["Alias"].keys()) + foreach(const QString &alias, Config.Hosting.Alias.keys()) { - ret += QString(" " + alias + " = " + maps["Alias"].value(alias) + "\n"); + ret += QString(" " + alias + " = " + Config.Hosting.Alias.value(alias) + "\n"); } } else { - QFile file(settings["ClonkDirectory"] + commandArgs + ".lst"); + QFile file(Config.Auto.Volatile.Clonk.Directory + commandArgs + ".lst"); if(file.exists()) { ret += "Der Ordner \"" + commandArgs + QString("\" enthält folgende Szenarien:\n"); @@ -1025,7 +1025,7 @@ QString CRSM::printQueue() return "Die Warteschlange ist leer.\n"; } ret = "Folgende Szenarien befinden sich in der Warteschlange:\n"; - for(int i = 0; i < settings["UserListLength"].toInt(); ++i) + for(int i = 0; i < Config.Hosting.UserListLength; ++i) { const ScenarioSettings *scen; if(i < userlist.length()) @@ -1103,17 +1103,17 @@ void CRSM::writeToServer(const QString &message) } linePart += "\n"; processManager->write(codec->fromUnicode(linePart)); - if(settings["ServerUsesReadline"] == "true") + if(Config.Readline.ServerUses) { - if(writtenToServer.length() > settings["ReadlineRereadLimit"].toInt()) + if(writtenToServer.length() > Config.Readline.RereadLimit) writtenToServer.clear(); writtenToServer += codec->fromUnicode(linePart); } } processManager->write(codec->fromUnicode(line)); - if(settings["ServerUsesReadline"] == "true") + if(Config.Readline.ServerUses) { - if(writtenToServer.length() > settings["ReadlineRereadLimit"].toInt()) + if(writtenToServer.length() > Config.Readline.RereadLimit) writtenToServer.clear(); writtenToServer += codec->fromUnicode(line); } @@ -1124,7 +1124,8 @@ void CRSM::writeToServer(const QString &message) void CRSM::writeConfig() { - QFile config(CONFIG_FILE_NAME); + Config.write(CONFIG_FILE_NAME); + /*QFile config(CONFIG_FILE_NAME); config.open(QFile::WriteOnly); QTextStream configStream(&config); @@ -1151,7 +1152,7 @@ void CRSM::writeConfig() } configStream << endl; - config.close(); + config.close();*/ } QString CRSM::addAliasWish(const QString ¶m) @@ -1162,17 +1163,17 @@ QString CRSM::addAliasWish(const QString ¶m) const QString &alias = aliasExp.cap(1).trimmed(); const QString &scen = aliasExp.cap(2).trimmed(); QString scenP = scen; - if(maps["Alias"].contains(alias)) + if(Config.Hosting.Alias.contains(alias)) { return "Alias ist bereits vergeben!"; } - else if(maps["AliasWishes"].contains(alias)) + else if(Config.Auto.Hosting.AliasWishes.contains(alias)) { return "Alias ist bereits als Wunsch vergeben!"; } else if(!(scenP = scenPath(scen)).isEmpty()) { - maps["AliasWishes"].insert(alias, scenP); + Config.Auto.Hosting.AliasWishes.insert(alias, scenP); informModsAboutAliasWish(); return "Aliaswunsch ist hinterlegt!"; } @@ -1191,21 +1192,21 @@ void CRSM::informModsAboutAliasWish() { foreach(const QString& mod, ircMods) { - connection->sendCommand(IrcCommand::createNotice(mod, "Ein neuer Aliaswunsch ist verfügbar. Insgesamt verfügbar: " + QString::number(maps["AliasWishes"].size()))); + connection->sendCommand(IrcCommand::createNotice(mod, "Ein neuer Aliaswunsch ist verfügbar. Insgesamt verfügbar: " + QString::number(Config.Auto.Hosting.AliasWishes.size()))); } } void CRSM::editAliasWishes() { - if(maps["AliasWishes"].isEmpty()) + if(Config.Auto.Hosting.AliasWishes.isEmpty()) { connection->sendCommand(IrcCommand::createMessage(aliasWishEditor, "Keine Aliaswünsche " + (currentAliasWish == "" ? QString("") : QString("mehr ")) + "vorhanden.")); stopAliasWishEditing(); } else { - currentAliasWish = maps["AliasWishes"].firstKey(); - connection->sendCommand(IrcCommand::createMessage(aliasWishEditor, currentAliasWish + " = " + maps["AliasWishes"][currentAliasWish] + " [Ja|Nein|Stop]")); + currentAliasWish = Config.Auto.Hosting.AliasWishes.firstKey(); + connection->sendCommand(IrcCommand::createMessage(aliasWishEditor, currentAliasWish + " = " + Config.Auto.Hosting.AliasWishes[currentAliasWish] + " [Ja|Nein|Stop]")); } } @@ -1213,12 +1214,12 @@ void CRSM::editAliasWishes(const QString &message) { if(message.toLower() == "j" || message.toLower() == "ja") { - maps["Alias"][currentAliasWish] = maps["AliasWishes"][currentAliasWish]; - maps["AliasWishes"].remove(currentAliasWish); + Config.Hosting.Alias[currentAliasWish] = Config.Auto.Hosting.AliasWishes[currentAliasWish]; + Config.Auto.Hosting.AliasWishes.remove(currentAliasWish); } else if(message.toLower() == "n" || message.toLower() == "nein") { - maps["AliasWishes"].remove(currentAliasWish); + Config.Auto.Hosting.AliasWishes.remove(currentAliasWish); } else if(message.toLower() == "s" || message.toLower() == "stop") { @@ -1241,10 +1242,10 @@ void CRSM::stopAliasWishEditing() QString CRSM::ircActivateIngameChat(bool activated) { - if(settings["IrcUseIngameChat"] == "true" && !settings["IrcIngameChannel"].isEmpty()) + if(Config.IRC.UseIngameChat && !Config.IRC.IngameChannel.isEmpty()) { session["IrcUseIngameChat"] = activated ? "true" : "false"; - connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); + connection->sendCommand(IrcCommand::createTopic(Config.IRC.IngameChannel, "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); return "Ingamechat wurde " + (session["IrcUseIngameChat"] == "true" ? QString("") : QString("de")) + "aktviert."; } else @@ -1271,7 +1272,7 @@ QStringList CRSM::listC4Folder(const QString &path) else { QProcess c4group; - c4group.start(settings["ClonkDirectory"]+C4GROUP_EXECUTABLE, QStringList() << path << "-l", QProcess::ReadOnly); + c4group.start(Config.Auto.Volatile.Clonk.Directory + C4GROUP_EXECUTABLE, QStringList() << path << "-l", QProcess::ReadOnly); c4group.waitForFinished(); c4group.readLine(); QRegExp finishExp("^\\d+ Entries, \\d+ Bytes$"); @@ -1363,7 +1364,7 @@ UserType CRSM::clientUserType(const ClientInfo &client) switch(client.interface) { case Clonk: - if(lists["Moderators"].contains(QString::number(client.CUID))) + if(Config.Clonk.Chat.Moderators.contains(client.CUID)) return Moderator; if(sessionAdmin == client) return Admin; @@ -1387,18 +1388,18 @@ void CRSM::setupCmds() { addCommand("admin", &CRSM::admin, Clonk | IRC, User, "Ohne Name trägt es den Autor der Nachricht als Rundenadmin ein, bzw. mit Name den Spieler mit entsprechendem Namen, insofern nicht bereits ein Rundenadmin feststeht.", "[Chatnick¦PC-Name]"); addCommand("ingameadmin", &CRSM::ingameadmin, IRC | Management, Admin, "Legt den Ingame-Rundenadmin fest.", "<Ingame-Nick¦PC-Name>"); - if(settings["UseIrc"] == "true") + if(Config.IRC.Use) { addCommand("ircadmin", &CRSM::ircadmin, Clonk | Management, Admin, "Legt den IRC-Rundenadmin fest.", "<IRC-Nick>", "Legt den IRC-Rundenadmin fest. Der IRC-Admin kann über den IRC dieselben Aktionen durchführen wie der Ingame-Rundenadmin."); } addCommand("noadmin", &CRSM::noadmin, Clonk | IRC | Management, Admin, "Entzieht dem (IRC-)Rundenadmin seine Rechte, damit jemand anders Rundenadmin sein kann."); addCommand("aliaswish", &CRSM::aliaswish, Clonk | IRC, User, "Deponiert den Wunsch, <Alias> als Alias für <Szenario> einzutragen. Ein Moderator entscheidet darüber.", "<Alias> = <Szenario>"); - if(settings["IrcUseIngameChat"] == "true") + if(Config.IRC.UseIngameChat) { addCommand("ircchat", &CRSM::ircchat, Clonk | Management, Admin, "Schaltet den Irc-Ingame-Chat ein bzw. aus.", "<on¦off>"); addCommand("ingamechat", &CRSM::ircchat, IRC | Management, Admin, "Schaltet den Irc-Ingame-Chat ein bzw. aus.", "<on¦off>"); } - addCommand("queue", &CRSM::queue, Clonk | IRC | Management, User, "Zeigt die nächsten " + settings["UserListLength"] + " Szenarien auf der Warteliste."); + addCommand("queue", &CRSM::queue, Clonk | IRC | Management, User, "Zeigt die nächsten " + QString::number(Config.Hosting.UserListLength) + " Szenarien auf der Warteliste."); addCommand("host", &CRSM::host, Clonk | IRC | Management, User, "Nimmt das angegebene Szenario in die Warteschlange auf. Optional in der Liga, wenn \"--league\" angegeben wird.", "[--league] <Szenarioname¦Alias>"); addCommand("list", &CRSM::list, Clonk | IRC | Management, User, "Listet alle definierten Aliase oder alle möglichen Szenarien und Ordner auf, bzw. alle Szenarien im Ordner oder Rundenordner.", "[Aliase¦Rundenordner[.c4f]]"); addCommand("clientlist", &CRSM::clientlist, IRC | Management, User, "Listet alle verbundenen Clients mit PC-Name und Chatnick auf."); @@ -1434,7 +1435,7 @@ void CRSM::setupCmds() addCommand("io", &CRSM::io, IRC, Moderator, "Schaltet den IO-Modus ein bzw. aus.", "", "Schaltet den IO-Modus ein bzw. aus. Im IO-Modus wird die Ausgabe vom Clonk-Server an den Privat-Chat weitergeleitet und der Privat-Chat wird an den Clonk-Server weitergeleitet. Clonk-Befehle mit \\ statt /."); - if(settings["UseIrc"] == "true") + if(Config.IRC.Use) { addCommand("join", &CRSM::join, IRC | Management, Moderator, "Betritt den angegebenen IRC-Channel, optional mit angegebenem Schlüssel.", "<channel> [channel-key]"); addCommand("leave", &CRSM::leave, IRC | Management, Moderator, "Verlässt den angegebenen oder aktuellen IRC-Channel, optional mit angegebenem Grund.", "[channel] [reason]"); @@ -1575,8 +1576,8 @@ bool CRSM::scenAllowed(const ScenarioSettings &scen, const ClientInfo &client, U return true; } QString scenName = scen.name; - while(maps["Alias"].contains(scenName)) - scenName = maps["Alias"].value(scenName); + while(Config.Hosting.Alias.contains(scenName)) + scenName = Config.Hosting.Alias.value(scenName); int scenCount = 0; int userCount = 0; @@ -1585,17 +1586,17 @@ bool CRSM::scenAllowed(const ScenarioSettings &scen, const ClientInfo &client, U userCount += (setting.wishClient == client); QString otherScenName = setting.name; - while(maps["Alias"].contains(otherScenName)) - otherScenName = maps["Alias"].value(otherScenName); + while(Config.Hosting.Alias.contains(otherScenName)) + otherScenName = Config.Hosting.Alias.value(otherScenName); scenCount += (otherScenName == scenName); } - if(scenCount >= settings["MaxScenWishes"].toInt()) + if(scenCount >= Config.Hosting.MaxWishesPerScen) { respond(client, "Dieses Szenario ist jetzt oft genug in der Wunschliste!\n"); return false; } - if(userCount >= settings["MaxUserWishes"].toInt()) + if(userCount >= Config.Hosting.MaxWishesPerUser) { respond(client, "Von dir sind jetzt genug Wünsche in der Liste!\n"); return false; @@ -1610,24 +1611,24 @@ void CRSM::kick(const QString& pcName, const QString& reason) void CRSM::prepareAndConnectIrc() { - connection = new IrcConnection(settings["IrcServer"]); - connection->setUserName(settings["IrcNick"]); - connection->setNickName(settings["IrcNick"]); - connection->setRealName(settings["IrcRealName"]); - connection->setReconnectDelay(settings["IrcReconnectDelay"].toInt()); - connection->sendCommand(IrcCommand::createMode(settings["IrcNick"], "+B")); - connection->sendCommand(IrcCommand::createJoin(settings["IrcChannel"])); - if(settings["IrcUseIngameChat"] == "true" && !settings["IrcIngameChannel"].isEmpty()) - { - connection->sendCommand(IrcCommand::createJoin(settings["IrcIngameChannel"])); - connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Kein laufendes Spiel.")); + connection = new IrcConnection(Config.IRC.Server); + connection->setUserName(Config.IRC.Nick); + connection->setNickName(Config.IRC.Nick); + connection->setRealName(Config.IRC.RealName); + connection->setReconnectDelay(Config.IRC.ReconnectDelay); + connection->sendCommand(IrcCommand::createMode(Config.IRC.Nick, "+B")); + connection->sendCommand(IrcCommand::createJoin(Config.IRC.Channel)); + if(Config.IRC.UseIngameChat && !Config.IRC.IngameChannel.isEmpty()) + { + connection->sendCommand(IrcCommand::createJoin(Config.IRC.IngameChannel)); + connection->sendCommand(IrcCommand::createTopic(Config.IRC.IngameChannel, "Kein laufendes Spiel.")); } else { - settings["IrcUseIngameChat"] = "false"; + Config.IRC.UseIngameChat = false; } - connection->setPassword(settings["IrcPassword"]); + connection->setPassword(Config.IRC.Password); connect(connection, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(ircMessageReceived(IrcMessage*))); connection->open(); } @@ -1689,7 +1690,7 @@ CMD_FUNCTION_IMPL(admin) { case Clonk: interfaceAdminPtr = &sessionAdmin; - if(args == settings["ServerNick"] || args == settings["ServerPCName"]) + if(args == Config.Auto.Volatile.Clonk.ServerNick || args == Config.Auto.Volatile.Clonk.ServerPCName) { respond(client, "Der Server kann nicht als Rundenadmin eingetragen werden!\n"); return; @@ -1707,7 +1708,7 @@ CMD_FUNCTION_IMPL(admin) respond(client, "Du ist bereits Rundenadmin!\n"); return; } - else if((ircAdmin != ClientInfo() || sessionAdmin != ClientInfo()) && userType < Admin && !(leaveAdmins.contains(client) && leaveAdmins.value(client).secsTo(QDateTime::currentDateTime()) < settings["RegainAdminTime"].toInt())) + else if((ircAdmin != ClientInfo() || sessionAdmin != ClientInfo()) && userType < Admin && !(leaveAdmins.contains(client) && leaveAdmins.value(client).secsTo(QDateTime::currentDateTime()) < Config.Clonk.Chat.RegainAdminTime)) { respond(client, ircAdmin.toString() + (!ircAdmin.nick.isEmpty() && !sessionAdmin.nick.isEmpty() ? " und " : "") + sessionAdmin.toString() + " ist bereits Rundenadmin!\n"); return; @@ -1729,8 +1730,8 @@ CMD_FUNCTION_IMPL(admin) } CMD_FUNCTION_IMPL(host) - if(userlist.length() >= settings["UserListLength"].toInt()) - respond(client, "Maximale Warteschlangenlänge von "+settings["UserListLength"]+" erreicht!\n"); + if(userlist.length() >= Config.Hosting.UserListLength) + respond(client, "Maximale Warteschlangenlänge von " + QString::number(Config.Hosting.UserListLength) + " erreicht!\n"); else { if(args.trimmed().isEmpty()) @@ -1778,7 +1779,7 @@ CMD_FUNCTION_IMPL(list) } else if(client.interface == IRC) { - respond(client, settings["IrcScenListMessage"]); + respond(client, Config.IRC.ScenListMessage); } } @@ -1869,20 +1870,20 @@ CMD_FUNCTION_IMPL(newalias) QString scenP = scen; if(!(scenP = scenPath(scen)).isEmpty()) { - if(maps["AliasWishes"].contains(alias)) + if(Config.Auto.Hosting.AliasWishes.contains(alias)) { - respond(client, "Aliaswunsch für \"" + maps["AliasWishes"].value(alias) + "\" entfernt und Alias hinzugefügt!\n"); - maps["AliasWishes"].remove(alias); + respond(client, "Aliaswunsch für \"" + Config.Auto.Hosting.AliasWishes.value(alias) + "\" entfernt und Alias hinzugefügt!\n"); + Config.Auto.Hosting.AliasWishes.remove(alias); } - else if(maps["Alias"].contains(alias)) + else if(Config.Hosting.Alias.contains(alias)) { - respond(client, "Alias für \"" + maps["Alias"][alias] + "\" überschrieben!\n"); + respond(client, "Alias für \"" + Config.Hosting.Alias[alias] + "\" überschrieben!\n"); } else { respond(client, "Alias hinzugefügt!\n"); } - maps["Alias"][alias] = scenP; + Config.Hosting.Alias[alias] = scenP; } else { @@ -1897,7 +1898,7 @@ CMD_FUNCTION_IMPL(newalias) CMD_FUNCTION_IMPL(modinfo) respond(client, "Moderatoren sind (* ist aktiv, + verwendet IO):\n", RespondType::Private); - foreach(const QString &mod, lists["IrcModerators"]) + foreach(const QString &mod, Config.IRC.Moderators) { respond(client, (ircMods.contains(mod) ? QString("*") : QString(" ")) + (ircModIOList.contains(mod) ? QString("+") : QString(" ")) + " " + mod + "\n", RespondType::Private); } @@ -2091,14 +2092,14 @@ CMD_FUNCTION_IMPL(leave) CMD_FUNCTION_IMPL(exit) processManager->closeProgFifos(); - settings.remove("ReattachId"); + Config.Auto.ProcessManager.ReattachId.clear(); finish = true; if(session["hosting"] != "true") scenarioFinished(); } CMD_FUNCTION_IMPL(exitDetach) - settings["ReattachId"] = processManager->ID(); + Config.Auto.ProcessManager.ReattachId = processManager->ID(); writeConfig(); QCoreApplication::quit(); } @@ -2159,7 +2160,7 @@ IRC_CHECK_CALLBACK_IMPL(ircSetAdmin) } IRC_CHECK_CALLBACK_IMPL(ircModCmd) - if(status == 3 && lists["IrcModerators"].contains(subject.nick)) + if(status == 3 && Config.IRC.Moderators.contains(subject.nick)) { ircMods.append(subject.nick); QList<QPair<CmdFunctionRef, QString>> &fifo = ircModFifos[subject.nick]; @@ -2168,9 +2169,9 @@ IRC_CHECK_CALLBACK_IMPL(ircModCmd) (this->*fifo.first().first.func)(fifo.first().first.name, fifo.first().second, subject, clientUserType(subject)); fifo.removeFirst(); } - if(!maps["AliasWishes"].isEmpty()) + if(!Config.Auto.Hosting.AliasWishes.isEmpty()) { - respond(subject, QString::number(maps["AliasWishes"].size()) + " neue" + (maps["AliasWishes"].size() > 1 ? QString("") : QString("r")) + " Aliasw" + (maps["AliasWishes"].size() > 1 ? QString("ü") : QString("u")) + "nsch" + (maps["AliasWishes"].size() > 1 ? QString("e") : QString("")) + " " + (maps["AliasWishes"].size() > 1 ? QString("sind") : QString("ist")) + " verfügbar.", RespondType::PrivateNotice); + respond(subject, QString::number(Config.Auto.Hosting.AliasWishes.size()) + " neue" + (Config.Auto.Hosting.AliasWishes.size() > 1 ? QString("") : QString("r")) + " Aliasw" + (Config.Auto.Hosting.AliasWishes.size() > 1 ? QString("ü") : QString("u")) + "nsch" + (Config.Auto.Hosting.AliasWishes.size() > 1 ? QString("e") : QString("")) + " " + (Config.Auto.Hosting.AliasWishes.size() > 1 ? QString("sind") : QString("ist")) + " verfügbar.", RespondType::PrivateNotice); respond(subject, "Bitte bei nächster Gelegenheit mit " CMD_SIGN "aliaswishes bearbeiten.", RespondType::PrivateNotice); } } diff --git a/src/crsm.hpp b/src/crsm.hpp index d96cc7b..d9740e6 100644 --- a/src/crsm.hpp +++ b/src/crsm.hpp @@ -20,11 +20,12 @@ #include "CmdFunctionRef.hpp" #include "ProcessManager.hpp" +#include "CRSMConfig.hpp" #define CONFIG_FILE_NAME "CrServerManager.conf" #define CUR_SCEN_FILE_NAME "curscen.txt" #define LAST_SCEN_FILE_NAME "lastscen.txt" -#define SCOREBOARD_FILE_NAME settings["ClonkDirectory"] + "scoreboard.html" +#define SCOREBOARD_FILE_NAME Config.Auto.Volatile.Clonk.Directory + "scoreboard.html" #define IRC_CHECK_CALLBACK(name) void name(const ClientInfo& requester, int status, const ClientInfo& subject) #define IRC_CHECK_CALLBACK_IMPL(name) void CRSM::name(const ClientInfo& requester, int status, const ClientInfo& subject) { (void)requester; (void)status; (void)subject; @@ -102,6 +103,8 @@ private slots: void updateNextAutoScens(); private: + CRSMConfig Config; + QList<ScenarioSettings> userlist; QList<ScenarioSettings> autolist; QList<ScenarioSettings> nextAutoScens; @@ -117,11 +120,11 @@ private: QTextStream *qout; QTextStream *qin; bool finish; - QMap<QString, QString> settings; + //QMap<QString, QString> settings; QMap<QString, QString> session; QMap<QString, ClientInfo> clients; - QMap<QString, QStringList> lists; - QMap<QString, QMap<QString, QString>> maps; + //QMap<QString, QStringList> lists; + //QMap<QString, QMap<QString, QString>> maps; IrcConnection *connection = 0; bool autoHost = true; QSignalMapper greetMapper; |
