diff options
| author | Markus Mittendrein <git@maxmitti.tk> | 2015-03-19 00:59:37 +0100 |
|---|---|---|
| committer | Markus Mittendrein <git@maxmitti.tk> | 2015-03-19 00:59:37 +0100 |
| commit | 3d01ec1643191822370ba01c11ec6cc247e06599 (patch) | |
| tree | 20177a2f860de93203533e4c051880d11f98697b /crsm.cpp | |
| parent | 8983d3b38421843db67a05edee180028959c1b51 (diff) | |
| download | manager-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.cpp | 330 |
1 files changed, 258 insertions, 72 deletions
@@ -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) |
