summaryrefslogtreecommitdiffstats
path: root/crsm.cpp
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2015-03-19 00:59:37 +0100
committerMarkus Mittendrein <git@maxmitti.tk>2015-03-19 00:59:37 +0100
commit3d01ec1643191822370ba01c11ec6cc247e06599 (patch)
tree20177a2f860de93203533e4c051880d11f98697b /crsm.cpp
parent8983d3b38421843db67a05edee180028959c1b51 (diff)
downloadmanager-3d01ec1643191822370ba01c11ec6cc247e06599.tar.gz
manager-3d01ec1643191822370ba01c11ec6cc247e06599.zip
Added Managemen-Interface on TCP port 9372 listening on localhost.
Diffstat (limited to 'crsm.cpp')
-rw-r--r--crsm.cpp330
1 files changed, 258 insertions, 72 deletions
diff --git a/crsm.cpp b/crsm.cpp
index 69af23b..44ef4c5 100644
--- a/crsm.cpp
+++ b/crsm.cpp
@@ -6,22 +6,32 @@
#include <fcntl.h>
#include <QThread>
#include <QTimer>
+#include <QRegularExpression>
#define CMD_SIGN "!"
+#define MGMT_BUFFER_FILENAME "CRSM-MGMT-Buffer"
+
CRSM::CRSM(QObject *parent) :
QObject(parent)
{
codec = QTextCodec::codecForName("Windows-1252");
- qout = new QTextStream(stdout,QIODevice::WriteOnly);
+ qout = new QTextStream(stdout, QIODevice::WriteOnly | QIODevice::Unbuffered);
qin = new QTextStream(stdin, QIODevice::ReadOnly);
qout->setCodec(QTextCodec::codecForName("UTF-8"));
+ outputBuffer.setFileName(MGMT_BUFFER_FILENAME);
+ outputBuffer.open(QFile::WriteOnly | QFile::Unbuffered);
+
args << "/fullscreen" << "/config:config" << "/lobby:60" << "/nosignup";
current = 0;
finish = false;
readConfig();
+
+ connect(&managementServer, SIGNAL(newConnection()), this, SLOT(newManagementConnection()));
+ managementServer.listen(QHostAddress::LocalHostIPv6, settings["ManagementPort"].toUInt());
+
//cleanUp();
listC4Folders();
readScenarios();
@@ -38,7 +48,7 @@ CRSM::CRSM(QObject *parent) :
if(!processManager->isOk())
{
- *qout << "Could not start Process Manager!" << endl;
+ out("Could not start Process Manager!");
settings.remove("ReattachId");
writeConfig();
return;
@@ -143,7 +153,7 @@ void CRSM::readServerOutput()
connection->sendCommand(IrcCommand::createNotice(mod, mess));
}
}
- *qout << what.trimmed() << endl;
+ out(what.trimmed() + "\n");
if(!timeRemover.exactMatch(what))
return;
what = timeRemover.cap(1).trimmed();
@@ -219,7 +229,10 @@ void CRSM::readServerOutput()
QRegExp startExp("^Start!\\s*$");
if(startExp.exactMatch(what))
{
- writeToServer(QString("/set maxplayer 0\n"));
+ if(session["league"] != "true")
+ {
+ writeToServer(QString("/set maxplayer 0\n"));
+ }
session["running"] = "true";
}
@@ -272,7 +285,7 @@ void CRSM::readInput()
if(what == "/exitafter")
{
finish = true;
- *qout << "Will exit after this round." << endl;
+ out("Will exit after this round.");
return;
}
if(what == "/next")
@@ -285,16 +298,16 @@ void CRSM::readInput()
QString skipped;
if((skipped = skipScen()) != "")
{
- *qout << "Skipped \"" << skipped << "\"." << endl;
+ out("Skipped \"" + skipped + "\".\n");
}
else
- *qout << "User list is empty!" << endl;
+ out("User list is empty!\n");
return;
}
if(what == "/reload")
{
- *qout << "Reloading config..." << endl;
+ out("Reloading config...\n");
lists.clear();
settings.clear();
ircModChecks.clear();
@@ -328,12 +341,12 @@ void CRSM::nextScen()
void CRSM::printAdditionalHelp()
{
- *qout << "/exit stops the actual Clonk Server and exits the Server Manager.\n"
+ out("/exit stops the actual Clonk Server and exits the Server Manager.\n"
"/exitafter exits the Server Manager after the current round.\n"
"/next stops the actual Clonk Server and starts a new one.\n"
"/reload rereads the config file.\n"
"/skip removes the first scenario in user wish list.\n"
- "Clonk commands following..." << endl;
+ "Clonk commands following...\n");
}
void CRSM::readLog()
@@ -511,6 +524,74 @@ void CRSM::greet(QString pcName)
writeToServer(QString("Hallo " + info.nick + "!\n"));
}
+void CRSM::newManagementConnection()
+{
+ QTcpSocket* sock = managementServer.nextPendingConnection();
+ connect(sock, SIGNAL(readyRead()), this, SLOT(newManagementData()));
+ connect(sock, SIGNAL(disconnected()), this, SLOT(managementConnectionDisconnected()));
+ sock->write(QString("Willkommen beim CRSM-Management-Interface!\nIhr Name: ").toUtf8());
+}
+
+void CRSM::newManagementData()
+{
+ QTcpSocket* sock = (QTcpSocket*)sender();
+ QString allData = sock->readAll().trimmed();
+ foreach(const QString& data, allData.split('\n'))
+ {
+ if(!managementConnections.contains(sock))
+ {
+ if(data.isEmpty())
+ {
+ sock->write("Ihr Name: ");
+ }
+ else
+ {
+ ManagementConnection conn;
+ conn.socket = sock;
+ conn.name = data;
+ managementConnections.insert(sock, ManagementConnection(sock));
+ out(conn.name + " logged in on Management-Interface.\n");
+ replayOutputBuffer(sock);
+ }
+ }
+ else
+ {
+ if(data.isEmpty())
+ {
+ continue;
+ }
+ ManagementConnection& conn = managementConnections[sock];
+ if(data.at(0) == '/')
+ {
+ QStringList split = data.right(data.length() - 1).split(' ');
+ QString cmdName = split.first();
+ split.removeFirst();
+ if(cmd(cmdName, split.join(' '), ClientInfo::managementClient(conn)))
+ {
+ continue;
+ }
+ else
+ {
+ writeToServer(data + "\n");
+ }
+ }
+ else
+ {
+ writeToServer("[CLI]<" + conn.name + "> " + data + "\n");
+ }
+ }
+ }
+}
+
+void CRSM::managementConnectionDisconnected()
+{
+ QTcpSocket* sock = (QTcpSocket*)sender();
+ if(managementConnections.contains(sock))
+ {
+ managementConnections.remove(sock);
+ }
+}
+
void CRSM::startScen(const ScenarioSettings &scen, QStringList argList)
{
QString filename;
@@ -541,6 +622,7 @@ void CRSM::startScen(const ScenarioSettings &scen, QStringList argList)
if(scen.league)
{
argList << "/league";
+ session["league"] = "true";
}
else
{
@@ -588,30 +670,30 @@ void CRSM::readConfig()
break;
}
- *qout << "config:" << endl;
+ out("config:\n");
foreach(const QString &key, settings.keys())
{
- *qout << key << " = " << settings.value(key) << endl;
+ out(key + " = " + settings.value(key) + "\n");
}
- *qout << endl;
+ out("\n");
foreach(const QString &key, lists.keys())
{
- *qout << key << ":" << endl;
+ out(key + ":\n");
foreach(const QString &val, lists.value(key))
{
- *qout << "\t" << val << endl;
+ out("\t" + val + "\n");
}
}
- *qout << endl;
+ out("\n");
foreach(const QString &key, maps.keys())
{
- *qout << key << ":" << endl;
+ out(key + ":\n");
foreach(const QString &mapkey, maps.value(key).keys())
{
- *qout << "\t[" << mapkey << "]" << " = " << maps.value(key).value(mapkey) << endl;
+ out("\t[" + mapkey + "]" + " = " + maps.value(key).value(mapkey) + "\n");
}
}
- *qout << endl;
+ out("\n");
args = settings["Arguments"].split(" ");
args << "/config:"+settings["ClonkConfig"];
}
@@ -619,7 +701,7 @@ void CRSM::readConfig()
QFile clonkconfig(settings["ClonkConfig"]);
if(!clonkconfig.exists())
- *qout << "WARNING: Clonk's config file is not existing!";
+ out("WARNING: Clonk's config file is not existing!");
else
{
clonkconfig.open(QFile::ReadOnly);
@@ -638,11 +720,17 @@ void CRSM::readConfig()
break;
}
}
- *qout << endl;
- *qout << "ClonkDirectory" << " = " << settings.value("ClonkDirectory") << endl;
- *qout << "ServerNick" << " = " << settings.value("ServerNick") << endl;
+ 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";
}
- *qout << endl;
}
void CRSM::readScenarios()
@@ -650,23 +738,23 @@ void CRSM::readScenarios()
QFile scenfile("scenarios.lst");
if(!scenfile.exists())
{
- *qout << "No scenarios.lst found!";
+ out("No scenarios.lst found!");
scenfile.open(QFile::WriteOnly);
scenfile.write("Worlds.c4f/Goldmine.c4s");
scenfile.close();
}
scenfile.open(QFile::ReadOnly);
scenlist = QString(scenfile.readAll()).trimmed().split("\n",QString::SkipEmptyParts);
- *qout << "Scenarios in list:" << endl;
+ out("Scenarios in list:\n");
foreach(const QString &scen, scenlist)
{
if(scenExists(scen))
- *qout << scen << endl;
+ out(scen + "\n");
else
- *qout << "WARNING: Scenario " << scen << " not found!" << endl;
+ out("WARNING: Scenario " + scen + " not found!\n");
}
- *qout << endl;
+ out("\n");
scenfile.close();
}
@@ -683,8 +771,7 @@ QMap<QString, QString> CRSM::defaultSettings()
void CRSM::listC4Folders()
{
- *qout << "Listing Contents of C4Folders...";
- qout->flush();
+ out("Listing Contents of C4Folders...");
QDirIterator it(settings["ClonkDirectory"], QDirIterator::FollowSymlinks);
for(; it.hasNext(); it.next())
{
@@ -705,16 +792,16 @@ void CRSM::listC4Folders()
}
}
}
- *qout << QString(3, '\b') << ": Finished" << endl;
+ out(QString(3, '\b') + ": Finished\n");
}
void CRSM::cleanUp()
{
- *qout << endl << "Cleaning up Clonk Folder..." << endl;
+ out("\nCleaning up Clonk Folder...\n");
QDirIterator it(settings["ClonkDirectory"]+"Network/", QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
for(; it.hasNext(); it.next())
if(it.fileInfo().exists()) QFile(it.fileInfo().absoluteFilePath()).remove();
- *qout << endl;
+ out("\n");
}
bool CRSM::scenExists(QString filePath)
@@ -1109,6 +1196,9 @@ bool CRSM::cmd(const QString &name, const QString &args, const ClientInfo &clien
ircCheckModCmd(client.nick, cmdRef, args);
}
break;
+ case Management:
+ (this->*cmdRef.func)(name, args, client, UserType::Max);
+ break;
}
return true;
@@ -1146,51 +1236,57 @@ UserType CRSM::clientUserType(const ClientInfo &client)
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, Admin, "Legt den Ingame-Rundenadmin fest.", "<Ingame-Nick¦PC-Name>");
+ addCommand("ingameadmin", &CRSM::ingameadmin, IRC | Management, Admin, "Legt den Ingame-Rundenadmin fest.", "<Ingame-Nick¦PC-Name>");
if(settings["UseIrc"] == "true")
{
- addCommand("ircadmin", &CRSM::ircadmin, Clonk, 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("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, Admin, "Entzieht dem (IRC-)Rundenadmin seine Rechte, damit jemand anders Rundenadmin sein kann.");
+ 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")
{
- addCommand("ircchat", &CRSM::ircchat, Clonk, Admin, "Schaltet den Irc-Ingame-Chat ein bzw. aus.", "<on¦off>");
- addCommand("ingamechat", &CRSM::ircchat, IRC, Admin, "Schaltet den Irc-Ingame-Chat ein bzw. aus.", "<on¦off>");
- }
- addCommand("queue", &CRSM::queue, Clonk | IRC, User, "Zeigt die nächsten " + settings["UserListLength"] + " Szenarien auf der Warteliste.");
- addCommand("host", &CRSM::host, Clonk | IRC, User, "Nimmt das angegebene Szenario in die Wunschliste auf. Optional in der Liga, wenn \"--league\" angegeben wird.", "[--league] <Szenarioname¦Alias>");
- addCommand("list", &CRSM::list, Clonk | IRC, 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, Clonk | IRC, User, "Listet alle verbundenen Clients mit PC-Name und Chatnick auf.");
- addCommand("help", &CRSM::help, Clonk | IRC, User, "Zeigt die Hilfe an.", "[long¦Befehlsname]", "Listet alle verfügbaren Befehle auf. Mit long werden alle verfügbaren Befehle mit Kurzbeschreibung aufgelistet.");
- addCommand("stop", &CRSM::passToClonk, Clonk | IRC, Admin, "Stoppt einen laufenden Countdown.");
- addCommand("start", &CRSM::passToClonk, Clonk | IRC, Admin, "Startet den Countdown.", "[Countdownzeit in s]");
- addCommand("teamdist", &CRSM::passToClonk, Clonk | IRC, Admin, "Ändert die Teamverteilung.", "<none¦free¦host¦random¦radnominv>");
+ 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("host", &CRSM::host, Clonk | IRC | Management, User, "Nimmt das angegebene Szenario in die Wunschliste 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.");
+ addCommand("help", &CRSM::help, Clonk | IRC | Management, User, "Zeigt die Hilfe an.", "[long¦Befehlsname]", "Listet alle verfügbaren Befehle auf. Mit long werden alle verfügbaren Befehle mit Kurzbeschreibung aufgelistet.");
+ addCommand("stop", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Stoppt einen laufenden Countdown.");
+ addCommand("start", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Startet den Countdown.", "[Countdownzeit in s]");
+ addCommand("teamdist", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Ändert die Teamverteilung.", "<none¦free¦host¦random¦radnominv>");
addCommand("plrteam", &CRSM::passToClonk, Clonk | IRC, Admin, "Ändert das Team eines Spielers.", "<Spieler> <neues Team>", "Verschiebt <Spieler> in das <neue Team>.");
- addCommand("pause", &CRSM::passToClonk, Clonk | IRC, Admin, "Pausiert das Spiel.");
- addCommand("unpause", &CRSM::passToClonk, Clonk | IRC, Admin, "Setzt das pausierte Spiel fort.");
- addCommand("observer", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Der angegebene Host muss zuschauen.", "<PC-Name¦Chatnick>");
- addCommand("deactivate", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Deaktiviert den angegebenen Host.", "<PC-Name¦Chatnick>");
- addCommand("activate", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Aktiviert den angegebenen Host.", "<PC-Name¦Chatnick>");
- addCommand("kick", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Kickt den angegebenen Host.", "<PC-Name¦Chatnick>");
- addCommand("script", &CRSM::passToClonk, Clonk | IRC, Admin, "Führt das angegebene Script aus.", "<Script>");
- addCommand("asyncctrl", &CRSM::passToClonk, Clonk | IRC, Admin, "Aktiviert den asynchronen Netzwerkmodus.");
- addCommand("centralctrl", &CRSM::passToClonk, Clonk | IRC, Admin, "Aktiviert den zentralen Netzwerkmodus.");
- addCommand("decentralctrl", &CRSM::passToClonk, Clonk | IRC, Admin, "Aktiviert den dezentralen Netzwerkmodus.");
- addCommand("nodebug", &CRSM::passToClonk, Clonk | IRC, Admin, "Deaktiviert den Debug-Modus zwingend für alle.");
- addCommand("autohost", &CRSM::autohost, Clonk | IRC, Moderator, "Deaktiviert den Debug-Modus zwingend für alle.");
- addCommand("noautohost", &CRSM::autohost, Clonk | IRC, Moderator, "Deaktiviert den Debug-Modus zwingend für alle.");
- addCommand("set", &CRSM::set, Clonk | IRC, Admin, "Setzt diverse Einstellungen entsprechend dem /set Befehl von Clonk.", "<maxplayer¦password¦faircrew¦teamcolors¦runtimejoin> [on¦off¦<Passwort>¦<Spieleranzahl>]");
-
- addCommand("skip", &CRSM::skip, Clonk | IRC, Moderator, "Entfernt das nächste Szenario aus der Wunschliste.");
- addCommand("next", &CRSM::next, Clonk | IRC, Moderator, "Versucht das aktuelle Szenario zu überspringen.");
- addCommand("kill", &CRSM::kill, IRC, Moderator, "Tötet den Clonk-Server, vorausgesetzt es läuft einer.", "", "Tötet den Clonk-Server, vorausgesetzt es läuft einer. Bitte nur verwenden wenn " CMD_SIGN "next nicht funktioniert.");
- addCommand("clear", &CRSM::clear, Clonk | IRC, Moderator, "Löscht die Wunschliste.");
- addCommand("aliaswishes", &CRSM::aliaswishes, IRC, Moderator, "Zum geführten Bearbeiten der Aliaswünsche.");
- addCommand("newalias", &CRSM::newalias, IRC, Moderator, "Trägt <Alias> als Alias für <Szenario> ein.", "<Alias> = <Szenario>");
- addCommand("modinfo", &CRSM::modinfo, IRC, Moderator, "Listet alle Moderatoren auf.");
+ addCommand("pause", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Pausiert das Spiel.");
+ addCommand("unpause", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Setzt das pausierte Spiel fort.");
+ addCommand("observer", &CRSM::pcNamePassToClonk, Clonk | IRC | Management, Admin, "Der angegebene Host muss zuschauen.", "<PC-Name¦Chatnick>");
+ addCommand("deactivate", &CRSM::pcNamePassToClonk, Clonk | IRC | Management, Admin, "Deaktiviert den angegebenen Host.", "<PC-Name¦Chatnick>");
+ addCommand("activate", &CRSM::pcNamePassToClonk, Clonk | IRC | Management, Admin, "Aktiviert den angegebenen Host.", "<PC-Name¦Chatnick>");
+ addCommand("kick", &CRSM::pcNamePassToClonk, Clonk | IRC | Management, Admin, "Kickt den angegebenen Host.", "<PC-Name¦Chatnick>");
+ addCommand("script", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Führt das angegebene Script aus.", "<Script>");
+ addCommand("asyncctrl", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Aktiviert den asynchronen Netzwerkmodus.");
+ addCommand("centralctrl", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Aktiviert den zentralen Netzwerkmodus.");
+ addCommand("decentralctrl", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Aktiviert den dezentralen Netzwerkmodus.");
+ addCommand("nodebug", &CRSM::passToClonk, Clonk | IRC | Management, Admin, "Deaktiviert den Debug-Modus zwingend für alle.");
+ addCommand("autohost", &CRSM::autohost, Clonk | IRC | Management, Moderator, "Deaktiviert den Debug-Modus zwingend für alle.");
+ addCommand("noautohost", &CRSM::autohost, Clonk | IRC | Management, Moderator, "Deaktiviert den Debug-Modus zwingend für alle.");
+ addCommand("set", &CRSM::set, Clonk | IRC | Management, Admin, "Setzt diverse Einstellungen entsprechend dem /set Befehl von Clonk.", "<maxplayer¦password¦faircrew¦teamcolors¦runtimejoin> [on¦off¦<Passwort>¦<Spieleranzahl>]");
+
+ addCommand("skip", &CRSM::skip, Clonk | IRC | Management, Moderator, "Entfernt das nächste Szenario aus der Wunschliste.");
+ addCommand("next", &CRSM::next, Clonk | IRC | Management, Moderator, "Versucht das aktuelle Szenario zu überspringen.");
+ addCommand("kill", &CRSM::kill, IRC | Management, Moderator, "Tötet den Clonk-Server, vorausgesetzt es läuft einer.", "", "Tötet den Clonk-Server, vorausgesetzt es läuft einer. Bitte nur verwenden wenn " CMD_SIGN "next nicht funktioniert.");
+ addCommand("clear", &CRSM::clear, Clonk | IRC | Management, Moderator, "Löscht die Wunschliste.");
+ addCommand("aliaswishes", &CRSM::aliaswishes, IRC | Management, Moderator, "Zum geführten Bearbeiten der Aliaswünsche.");
+ addCommand("newalias", &CRSM::newalias, IRC | Management, Moderator, "Trägt <Alias> als Alias für <Szenario> ein.", "<Alias> = <Szenario>");
+ addCommand("modinfo", &CRSM::modinfo, IRC | Management, Moderator, "Listet alle Moderatoren auf.");
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 /.");
+ addCommand("exit", &CRSM::exit, Management, UserType::Max, "Beendet den Server Mananger.", "", "Beendet den Server Mananger und falls ein Clonk-Server läuft auch diesen.");
+ addCommand("exitdetach", &CRSM::exitDetach, Management, UserType::Max, "Beendet den Server Mananger, lässt den Clonk-Server weiterlaufen.", "", "Beendet den Server Mananger und falls ein Clonk-Server läuft, läuft dieser weiter.");
+ addCommand("exitupdate", &CRSM::exitUpdate, Management, UserType::Max, "Zusätzlich zu exitdetach wird im laufenden Spiel angekündigt, dass der Server-Manager wegen eines Updates beendet wird.");
+ addCommand("exitafter", &CRSM::exitAfter, Management, UserType::Max, "Beendet den Server-Manager, sobald das laufende Spiel vorbei ist.");
+ addCommand("reload", &CRSM::reload, Management, UserType::Max, "Liest die Konfigurationsdatei neu ein.");
+ addCommand("saveconfig", &CRSM::saveConfig, Management, UserType::Max, "Speichert die aktuelle Konfiguration in die Konfigurationsdatei.");
}
void CRSM::respond(const ClientInfo &client, const QString &message, const RespondType type)
@@ -1216,6 +1312,9 @@ void CRSM::respond(const ClientInfo &client, const QString &message, const Respo
}
}
break;
+ case Management:
+ client.management.socket->write(message.toUtf8());
+ break;
}
}
@@ -1276,16 +1375,46 @@ void CRSM::setIngameAdmin(const ClientInfo &client, const QString& newAdmin)
}
}
+void CRSM::out(const QString &text)
+{
+ *qout << text;
+ qout->flush();
+ if(managementConnections.size() == 0)
+ {
+ outputBuffer.write(text.toUtf8());
+ }
+ else
+ {
+ foreach(const ManagementConnection& conn, managementConnections)
+ {
+ conn.socket->write(text.toUtf8());
+ }
+ }
+}
+
+void CRSM::replayOutputBuffer(QTcpSocket *socket, bool clear)
+{
+ QFile outputBufferRead(MGMT_BUFFER_FILENAME);
+ outputBufferRead.open(QFile::ReadOnly);
+ const QByteArray& data = outputBufferRead.readAll();
+ outputBufferRead.close();
+ socket->write(data);
+ if(clear)
+ {
+ outputBuffer.close();
+ outputBuffer.open(QFile::WriteOnly | QFile::Unbuffered);
+ }
+}
+
CMD_FUNCTION_IMPL(help)
{
bool longHelp = args == "long";
if(args.isEmpty() || longHelp)
{
QString response = "Verfügbare Befehle: ";
- UserType clientType = clientUserType(client);
foreach(const CmdFunctionRef& cmd, cmds)
{
- if((cmd.interfaces & client.interface) == client.interface && clientType >= cmd.userType)
+ if((cmd.interfaces & client.interface) == client.interface && userType >= cmd.userType)
{
if(longHelp)
{
@@ -1676,6 +1805,63 @@ CMD_FUNCTION_IMPL(set)
}
}
+CMD_FUNCTION_IMPL(exit)
+{
+ processManager->closeProgFifos();
+ settings.remove("ReattachId");
+ finish = true;
+ if(session["hosting"] != "true")
+ scenarioFinished();
+}
+
+CMD_FUNCTION_IMPL(exitDetach)
+{
+ settings["ReattachId"] = processManager->ID();
+ writeConfig();
+ QCoreApplication::quit();
+}
+
+CMD_FUNCTION_IMPL(exitUpdate)
+{
+ writeToServer("Der Server Manager wird upgedatet. Befehle funktionieren temporär nicht.\n");
+ exitDetach(cmd, args, client, userType);
+}
+
+CMD_FUNCTION_IMPL(exitAfter)
+{
+ if(processManager->isRunning())
+ {
+ finish = true;
+ respond(client, "Beende nach dieser runde.\n");
+ }
+ else
+ {
+ respond(client, "Es läuft gerade kein Spiel, beende sofort.\n");
+ exit(cmd, args, client, userType);
+ }
+}
+
+CMD_FUNCTION_IMPL(reload)
+{
+ out("Reloading configuration...");
+ lists.clear();
+ settings.clear();
+ ircModChecks.clear();
+ ircMods.clear();
+ ircModFifosOld.clear();
+ ircModIOList.clear();
+ ircStatusFifos.clear();
+ readConfig();
+ out("Configuration reloaded.");
+}
+
+CMD_FUNCTION_IMPL(saveConfig)
+{
+ out("Saving Configuration...");
+ writeConfig();
+ out("Configuration saved.");
+}
+
IRC_CHECK_CALLBACK_IMPL(ircSetAdmin)
{
if(status <= 0)