summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CRSMConfig.hpp2
-rw-r--r--src/CRSMPackCompatibility.cpp169
-rw-r--r--src/CRSMPackCompatibility.hpp39
-rw-r--r--src/CrServerManager.pro6
-rw-r--r--src/crsm.cpp186
-rw-r--r--src/crsm.hpp12
6 files changed, 396 insertions, 18 deletions
diff --git a/src/CRSMConfig.hpp b/src/CRSMConfig.hpp
index 0494aaf..1aee360 100644
--- a/src/CRSMConfig.hpp
+++ b/src/CRSMConfig.hpp
@@ -10,6 +10,7 @@ public:
String CommandSign = "!";
String StatsFile = "CrServerManager.stats";
String SessionFile = "CrServerManager.session";
+ String PacksFile = "CrServerManager.packs";
} CRSM;
struct {
@@ -88,6 +89,7 @@ public:
ConfigVal(CRSM.CommandSign),
ConfigVal(CRSM.StatsFile),
ConfigVal(CRSM.SessionFile),
+ ConfigVal(CRSM.PacksFile),
diff --git a/src/CRSMPackCompatibility.cpp b/src/CRSMPackCompatibility.cpp
index 481cf44..cea57f7 100644
--- a/src/CRSMPackCompatibility.cpp
+++ b/src/CRSMPackCompatibility.cpp
@@ -1,7 +1,172 @@
-#include "PackCompatibility.hpp"
+#include "CRSMPackCompatibility.hpp"
-PackCompatibility::PackCompatibility()
+#include <QFile>
+
+void CRSMPackCompatibility::clear()
{
+ auto configVals = configValues;
+ *this = CRSMPackCompatibility();
+ configValues = configVals;
+}
+
+QString CRSMPackCompatibility::linkScenarioPacks(const QString &scenario)
+{
+ QStringList parts;
+ parts.append(scenario);
+ QString ret;
+ int position = scenario.length();
+ while((position = scenario.lastIndexOf('/', position - 1)) != -1)
+ {
+ parts.append(scenario.left(position));
+ }
+
+ QMap<QString, QString> packs = PackDefaultVersion;
+ foreach(const QString& filePathPart, parts)
+ {
+ foreach(const QString& packVersion, ScenarioPacks.value(filePathPart))
+ {
+ packs[PackVersions[packVersion]] = packVersion;
+ }
+ }
+ foreach(const QString& packName, packs.keys())
+ {
+ QFile packFile(clonkPath + packName);
+ if(packFile.exists())
+ {
+ packFile.remove();
+ }
+ if(!QFile::link(clonkPath + packs[packName], clonkPath + packName))
+ {
+ ret.append("Warning: Could not link pack \"" + packName + "\" to \"" + packs[packName] + "\".\n");
+ }
+ }
+
+ return ret;
}
+QString CRSMPackCompatibility::read(const QString &fileName, const QString& clonkPath, bool writeDefault)
+{
+ this->clonkPath = clonkPath;
+ QString ret = ConfigBase::read(fileName, writeDefault);
+
+ foreach(const QString& packVersion, PackVersions.keys())
+ {
+ ret.append(checkPackVersion(packVersion, PackVersions[packVersion]));
+ }
+
+ foreach(const QString& scenario, ScenarioPacks.keys())
+ {
+ foreach(const QString& scenarioPack, ScenarioPacks[scenario])
+ {
+ ret.append(checkScenarioPack(scenarioPack, scenario));
+ }
+ }
+
+ return ret;
+}
+
+QString CRSMPackCompatibility::addPackVersion(const QString &packVersion, const QString &pack)
+{
+ PackVersions[packVersion] = pack;
+ if(!PackDefaultVersion.contains(pack))
+ {
+ PackDefaultVersion[pack] = packVersion;
+ }
+ return checkPackVersion(packVersion, pack);
+}
+
+QString CRSMPackCompatibility::deletePackVersion(const QString &packVersion)
+{
+ if(PackVersions.contains(packVersion))
+ {
+ const QString& pack = PackVersions.value(packVersion);
+ PackVersions.remove(packVersion);
+ if(PackVersions.values().count(pack) == 0)
+ {
+ PackDefaultVersion.remove(pack);
+ }
+ else if(PackDefaultVersion.value(pack) == packVersion)
+ {
+ PackDefaultVersion[pack] = PackVersions.key(pack);
+ return "Warning: Changing default version of \"" + pack + "\" to \"" + PackDefaultVersion[pack] + "\".\n";
+ }
+ return "";
+ }
+ else
+ {
+ return "Error: Can not remove unknown PackVersion.";
+ }
+}
+
+QString CRSMPackCompatibility::setDefaultPackVersion(const QString &packVersion, const QString &pack)
+{
+ PackDefaultVersion[pack] = packVersion;
+ QString ret = addPackVersion(packVersion, pack);
+ return ret;
+}
+
+QString CRSMPackCompatibility::addScenarioPackVersion(const QString &packVersion, const QString &scenario)
+{
+ QString ret = checkScenarioPack(packVersion, scenario);
+ if(ret.isEmpty())
+ {
+ QString pack = PackVersions.value(packVersion);
+ foreach(const QString& scenarioPack, ScenarioPacks[scenario])
+ {
+ if(pack == PackVersions.value(scenarioPack))
+ {
+ ScenarioPacks[scenario].removeAll(scenarioPack);
+ ret = "Overwriting old PackVersion \"" + scenarioPack + "\" with \"" + packVersion + "\".\n";
+ }
+ }
+ }
+
+ ScenarioPacks[scenario].append(packVersion);
+ return ret;
+}
+
+QString CRSMPackCompatibility::deleteScenarioPackVersion(const QString &packVersion, const QString &scenario)
+{
+ if(!ScenarioPacks.contains(scenario))
+ {
+ return "Warning: The scenario \"" + scenario + "\" has no ScenarioPacks defined.\n";
+ }
+ else if(!ScenarioPacks[scenario].contains(packVersion))
+ {
+ return "Warning: The scenario \"" + scenario + "\" has no ScenarioPack \"" + packVersion + "\" defined.\n";
+ }
+ else
+ {
+ ScenarioPacks[scenario].removeAll(packVersion);
+ if(ScenarioPacks[scenario].length() == 0)
+ {
+ ScenarioPacks.remove(scenario);
+ }
+ return "";
+ }
+}
+
+QString CRSMPackCompatibility::checkPackVersion(const QString &packVersion, const QString &pack)
+{
+ if(!QFile(clonkPath + packVersion).exists())
+ {
+ return "Warning: PackVersion \"" + packVersion + "\" of pack \"" + pack + "\" does not exist.\n";
+ }
+ else
+ {
+ return "";
+ }
+}
+
+QString CRSMPackCompatibility::checkScenarioPack(const QString &packVersion, const QString &scenario)
+{
+ if(!PackVersions.contains(packVersion))
+ {
+ return "Warning: Unknown ScenarioPack \"" + packVersion + "\" of scenario \"" + scenario + "\" will not be linked.\n";
+ }
+ else
+ {
+ return "";
+ }
+}
diff --git a/src/CRSMPackCompatibility.hpp b/src/CRSMPackCompatibility.hpp
index eddc350..a35ed95 100644
--- a/src/CRSMPackCompatibility.hpp
+++ b/src/CRSMPackCompatibility.hpp
@@ -1,11 +1,36 @@
-#ifndef PACKCOMPATIBILITY_HPP
-#define PACKCOMPATIBILITY_HPP
+#pragma once
+#include "ConfigBase.hpp"
-
-class PackCompatibility : public ConfigBase
+class CRSMPackCompatibility : public ConfigBase
{
public:
- PackCompatibility();
-};
+ Map(String, String) PackDefaultVersion;
+ Map(String, String) PackVersions;
+ Map(String, List(String)) ScenarioPacks;
+
+ CRSMPackCompatibility() : ConfigBase::ConfigBase({
+ ConfigVal(PackDefaultVersion),
+ ConfigVal(PackVersions),
+ ConfigVal(ScenarioPacks)
+ }) { }
+
+ void clear();
+
+ QString linkScenarioPacks(const QString& scenario);
-#endif // PACKCOMPATIBILITY_HPP
+ QString read(const QString &fileName, const QString &clonkPath, bool writeDefault = true);
+
+ QString addPackVersion(const QString& packVersion, const QString& pack);
+ QString deletePackVersion(const QString& packVersion);
+ QString setDefaultPackVersion(const QString& packVersion, const QString& pack);
+
+ QString addScenarioPackVersion(const QString& packVersion, const QString& scenario);
+ QString deleteScenarioPackVersion(const QString& packVersion, const QString& scenario);
+
+protected:
+ QString checkPackVersion(const QString& packVersion, const QString& pack);
+ QString checkScenarioPack(const QString& packVersion, const QString& scenario);
+
+private:
+ QString clonkPath;
+};
diff --git a/src/CrServerManager.pro b/src/CrServerManager.pro
index fa0a7a2..4c27668 100644
--- a/src/CrServerManager.pro
+++ b/src/CrServerManager.pro
@@ -22,7 +22,8 @@ SOURCES += main.cpp \
ProcessManager.cpp \
ConfigBase.cpp \
Util.cpp \
- CRSMStats.cpp
+ CRSMStats.cpp \
+ CRSMPackCompatibility.cpp
HEADERS += \
CmdFunctionRef.hpp \
@@ -32,7 +33,8 @@ HEADERS += \
CRSMConfig.hpp \
ConfigBase.hpp \
Util.hpp \
- CRSMStats.hpp
+ CRSMStats.hpp \
+ CRSMPackCompatibility.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 def9231..a6262fa 100644
--- a/src/crsm.cpp
+++ b/src/crsm.cpp
@@ -309,8 +309,7 @@ void CRSM::scenarioFinished()
{
if(finish)
{
- writeConfig();
- Stats.write();
+ writeFiles();
if(processManager != nullptr) processManager->exit();
if(connection != 0)
{
@@ -616,7 +615,7 @@ void CRSM::startScen(const ScenarioSettings &scen, QStringList argList)
scoreboardFile.open(QFile::WriteOnly);
scoreboardFile.close();
- Session.Scenario= scen;
+ Session.Scenario = scen;
Session.IRC.UseIngameChat = Config.IRC.UseIngameChat;
Session.State = CRSMSession::Lobby;
ircSetIngameChannelTopic();
@@ -633,6 +632,7 @@ void CRSM::startScen(const ScenarioSettings &scen, QStringList argList)
}
argList << filename;
processManager->setWorkingDirectory(Config.Auto.Volatile.Clonk.Directory);
+ out(Packs.linkScenarioPacks(filename));
processManager->start(Config.Clonk.Server.Executable, argList);
}
@@ -1343,6 +1343,17 @@ void CRSM::setupCmds()
addCommand("config get", &CRSM::getConfigValue, Management, UserType::Max, "Gibt den aktuellen Wert <Wertname> von der Konfiguration an.", "<Wertname>");
addCommand("config set", &CRSM::setConfigValue, Management, UserType::Max, "Setzt einen Konfigurationswert.", "<Konfigurationszeile>", "Setzt einen Konfigurationswert. Der Wert wird wie eine Zeile in der Konfigurationsdatei angegeben.");
+ addCommandGroup("packs", Management, UserType::Max, "Über die packs-Befehlsgruppe lassen sich mehrere Versionen eines Objektpakets für unterschiedliche Szenarien verwalten.");
+ addCommand("packs list", &CRSM::packsList, Management, UserType::Max, "Listet alle bekannten Packs und ihre Versionen auf.");
+ addCommandGroup("packs versions", Management, UserType::Max, "Über die packs versions-Befehlsgruppe werden die einzelnen bekannten Packs und vorhandenen Versionen verwaltet.");
+ addCommand("packs versions add", &CRSM::packsVersionsAdd, Management, UserType::Max, "Fügt eine neue <Packversion> für das <Pack> hinzu.", "<Packversion> = <Pack>");
+ addCommand("packs versions delete", &CRSM::packsVersionsDelete, Management, UserType::Max, "Löscht eine <Packversion>.", "<Packversion>");
+ addCommand("packs versions default", &CRSM::packsVersionsDefault, Management, UserType::Max, "Fragt die Packversion ab, die standardmäßig für das <Pack> verwendet wird, oder setzt sie, wenn <Packversion> angegeben wird.", "<Pack> [= <Packversion>]");
+ addCommandGroup("packs scenarios", Management, UserType::Max, "Über die packs scenarios-Befehlsgruppe werden die einzelnen Packversionen den Szenarien zugeteilt.");
+ addCommand("packs scenarios add", &CRSM::packsScenariosAdd, Management, UserType::Max, "Aktiviert für das <Szenario> die <Packversion>.", "<Szenario> <Packversion>");
+ addCommand("packs scenarios delete", &CRSM::packsScenariosDelete, Management, UserType::Max, "Löscht für das <Szenario> die <Packversion>.", "<Szenario> <Packversion>");
+ addCommand("packs scenarios list", &CRSM::packsScenariosList, Management, UserType::Max, "Listet alle Szenarien mit ihren Packversionen auf.");
+
addCommand("relist", &CRSM::relist, Management, UserType::Max, "Durchsucht veränderte Rundenordner erneut.");
}
@@ -1549,7 +1560,7 @@ void CRSM::exit()
void CRSM::applyConfig()
{
- Stats.write();
+ writeFiles(false, true);
args.clear();
args << "/config:" + Config.Clonk.Server.Config;
args << Config.Clonk.Server.Arguments.split(" ");
@@ -1604,6 +1615,7 @@ void CRSM::applyConfig()
}
setupCmds();
out(Stats.read(Config.CRSM.StatsFile));
+ out(Packs.read(Config.CRSM.PacksFile, Config.Auto.Volatile.Clonk.Directory));
}
QString CRSM::scenarioFileName(QString name)
@@ -1620,6 +1632,20 @@ CmdResult CRSM::callCommand(const CmdFunctionRef &func, const QString &args, con
return ret;
}
+void CRSM::writeFiles(bool writeSession, bool writeNoConfig)
+{
+ if(writeSession)
+ {
+ Session.write(Config.CRSM.SessionFile);
+ }
+ Stats.write();
+ Packs.write();
+ if(!writeNoConfig)
+ {
+ writeConfig();
+ }
+}
+
CMD_FUNCTION_IMPL(help)
bool longHelp = (args == "long");
if(args.isEmpty() || longHelp)
@@ -2134,9 +2160,7 @@ CMD_FUNCTION_IMPL(exit)
CMD_FUNCTION_IMPL(exitDetach)
Config.Auto.ProcessManager.ReattachId = processManager->ID();
- writeConfig();
- Session.write(Config.CRSM.SessionFile);
- Stats.write();
+ writeFiles(true);
connection->quit(Config.IRC.QuitMessage);
QCoreApplication::quit();
return Success;
@@ -2335,6 +2359,154 @@ CMD_FUNCTION_IMPL(getAdmin)
return Success;
}
+CMD_FUNCTION_IMPL(packsList)
+ if(Packs.PackDefaultVersion.size() == 0)
+ {
+ respond(client, "Es sind noch keine speziellen Packversionen bekannt.\n");
+ return Success;
+ }
+ QString response("Folgende Packs und ihre Versionen sind bekannt:\n");
+
+ QMap<QString, QStringList> packVersions;
+ foreach(const QString& packVersion, Packs.PackVersions.keys())
+ {
+ packVersions[Packs.PackVersions.value(packVersion)].append(packVersion);
+ }
+
+ foreach(const QString& pack, Packs.PackDefaultVersion.keys())
+ {
+ response.append("\t" + pack + "\t-\t" + packVersions[pack].join(", ") + "\n");
+ }
+
+ respond(client, response);
+ return Success;
+}
+
+CMD_FUNCTION_IMPL(packsVersionsAdd)
+ const QStringList& argList = Util::splitEscaped(args, '=');
+ if(argList.length() != 2)
+ {
+ respond(client, "Eingabefehler! Siehe " + Config.CRSM.CommandSign + "help für mehr Informationen.\n");
+ return SyntaxFail;
+ }
+ else
+ {
+ QString response = Packs.addPackVersion(argList.first().trimmed(), argList.at(1).trimmed());
+ if(response.isEmpty())
+ {
+ response = "PackVersion wurde erfolgreich eingetragen.\n";
+ }
+ respond(client, response);
+ return Success;
+ }
+}
+
+CMD_FUNCTION_IMPL(packsVersionsDelete)
+ QString pack = Packs.PackVersions[args];
+ QString response = Packs.deletePackVersion(args);
+ if(response.isEmpty())
+ {
+ response = "PackVersion \"" + args + "\" vom Pack \"" + pack + "\" wurde erfolgreich entfernt.\n";
+ }
+ respond(client, response);
+ return Success;
+}
+
+CMD_FUNCTION_IMPL(packsVersionsDefault)
+ const QStringList& argList = Util::splitEscaped(args, '=');
+ if(argList.length() != 2 && argList.length() != 1)
+ {
+ respond(client, "Eingabefehler! Siehe " + Config.CRSM.CommandSign + "help für mehr Informationen.\n");
+ return SyntaxFail;
+ }
+ else if(argList.length() == 2)
+ {
+ QString oldDefault = Packs.PackDefaultVersion[argList.first().trimmed()];
+ QString response = Packs.setDefaultPackVersion(argList.at(1).trimmed(), argList.first().trimmed());
+ if(response.isEmpty())
+ {
+ if(oldDefault.isEmpty())
+ {
+ response = "Neues PackDefault wurde erfolgreich eingetragen.\n";
+ }
+ else
+ {
+ response = "Altes PackDefault \"" + oldDefault + "\" wurde erfolgreich überschrieben.\n";
+ }
+ }
+ respond(client, response);
+ return Success;
+ }
+ else
+ {
+ if(Packs.PackDefaultVersion.contains(args))
+ {
+ respond(client, "Standardversion für \"" + args + "\" ist \"" + Packs.PackDefaultVersion.value(args) + "\".\n");
+ }
+ else
+ {
+ respond(client, "Unbekanntes Pack: \"" + args + "\"!\n");
+ }
+ return Success;
+ }
+}
+
+CMD_FUNCTION_IMPL(packsScenariosAdd)
+ const QStringList& argList = Util::splitEscaped(args, ' ');
+ if(argList.length() != 2)
+ {
+ respond(client, "Eingabefehler! Siehe " + Config.CRSM.CommandSign + "help für mehr Informationen.\n");
+ return SyntaxFail;
+ }
+ else
+ {
+ QString response = Packs.addScenarioPackVersion(argList.at(1).trimmed(), argList.first().trimmed());
+ if(response.isEmpty())
+ {
+ response = "Packversion für das Szenario wurde erfolgreich hinzugefügt.\n";
+ }
+ respond(client, response);
+ return Success;
+ }
+}
+
+CMD_FUNCTION_IMPL(packsScenariosDelete)
+ const QStringList& argList = Util::splitEscaped(args, ' ');
+ if(argList.length() != 2)
+ {
+ respond(client, "Eingabefehler! Siehe " + Config.CRSM.CommandSign + "help für mehr Informationen.\n");
+ return SyntaxFail;
+ }
+ else
+ {
+ QString response = Packs.deleteScenarioPackVersion(argList.at(1).trimmed(), argList.first().trimmed());
+ if(response.isEmpty())
+ {
+ response = "Packversion für das Szenario wurde erfolgreich entfernt.\n";
+ }
+ respond(client, response);
+ return Success;
+ }
+}
+
+CMD_FUNCTION_IMPL(packsScenariosList)
+ if(Packs.ScenarioPacks.size() == 0)
+ {
+ respond(client, "Es sind noch keine Szenarios mit speziellen Packversionen bekannt.\n");
+ return Success;
+ }
+ QString response("Folgende Szenarien mit speziellen Packversionen sind bekannt:\n");
+
+ foreach(const QString& scenario, Packs.ScenarioPacks.keys())
+ {
+ response.append("\t" + scenario + "\t-\t" + Packs.ScenarioPacks.value(scenario).join(", ") + "\n");
+ }
+
+ respond(client, response);
+
+ return Success;
+}
+
IRC_CHECK_CALLBACK_IMPL(ircSayQuery)
if(status <= 0)
{
diff --git a/src/crsm.hpp b/src/crsm.hpp
index 63e6156..af3b5cf 100644
--- a/src/crsm.hpp
+++ b/src/crsm.hpp
@@ -22,6 +22,7 @@
#include "ProcessManager.hpp"
#include "CRSMConfig.hpp"
#include "CRSMStats.hpp"
+#include "CRSMPackCompatibility.hpp"
#define CONFIG_FILE_NAME "CrServerManager.conf"
#define SESSION_FILE_NAME "CrServerManager.session"
@@ -187,6 +188,7 @@ private:
CRSMSession Session;
CRSMStats Stats;
+ CRSMPackCompatibility Packs;
QList<ScenarioSettings> userlist;
QList<ScenarioSettings> autolist;
@@ -275,6 +277,8 @@ private:
QString scenarioFileName(QString name);
CmdResult callCommand(const CmdFunctionRef& func, const QString& args, const ClientInfo& client, UserType userType);
+ void writeFiles(bool writeSession = false, bool writeNoConfig = false);
+
CMD_FUNCTION(help);
CMD_FUNCTION(passToClonk);
CMD_FUNCTION(passToClonkOnOff);
@@ -326,6 +330,14 @@ private:
CMD_FUNCTION(ircSay);
CMD_FUNCTION(ircWatch);
+ CMD_FUNCTION(packsList);
+ CMD_FUNCTION(packsVersionsAdd);
+ CMD_FUNCTION(packsVersionsDelete);
+ CMD_FUNCTION(packsVersionsDefault);
+ CMD_FUNCTION(packsScenariosAdd);
+ CMD_FUNCTION(packsScenariosDelete);
+ CMD_FUNCTION(packsScenariosList);
+
IRC_CHECK_CALLBACK(ircSetAdmin);
IRC_CHECK_CALLBACK(ircModCmd);
IRC_CHECK_CALLBACK(ircSayQuery);