diff options
| author | Markus Mittendrein <git@maxmitti.tk> | 2015-01-01 16:04:07 +0100 |
|---|---|---|
| committer | Markus Mittendrein <git@maxmitti.tk> | 2015-01-01 16:04:07 +0100 |
| commit | a92aea252411f86657081587633a88083a3b14a9 (patch) | |
| tree | 754abad814d07dc339cb3025dd31faf186e4cfe4 /crsm.cpp | |
| parent | 529f38bd8878b6b1bea2b5457031ce936aab8d80 (diff) | |
| download | manager-a92aea252411f86657081587633a88083a3b14a9.tar.gz manager-a92aea252411f86657081587633a88083a3b14a9.zip | |
Massive changes.
Can't remember them.
Diffstat (limited to 'crsm.cpp')
| -rw-r--r-- | crsm.cpp | 1025 |
1 files changed, 909 insertions, 116 deletions
@@ -12,6 +12,7 @@ CRSM::CRSM(QObject *parent) : QObject(parent) { + codec = QTextCodec::codecForName("Windows-1252"); qout = new QTextStream(stdout,QIODevice::WriteOnly); qin = new QTextStream(stdin, QIODevice::ReadOnly); qout->setCodec(QTextCodec::codecForName("UTF-8")); @@ -22,10 +23,12 @@ CRSM::CRSM(QObject *parent) : finish = false; readConfig(); - cleanUp(); + //cleanUp(); listC4Folders(); readScenarios(); + connect(&greetMapper, SIGNAL(mapped(QString)), this, SLOT(greet(QString))); + autoHost = settings["AutoHost"] == "true"; //QString fifopath(settings["ClonkDirectory"]+"Clonk.log"); @@ -43,18 +46,35 @@ CRSM::CRSM(QObject *parent) : //connect(logNotifier,SIGNAL(activated(int)),this, SLOT(readLog())); QFile *reallog = new QFile(settings["ClonkDirectory"]+"CRSM.log"); - reallog->open(QIODevice::WriteOnly|QIODevice::Text); - logstream = new QTextStream(reallog); + reallog->open(QIODevice::Append|QIODevice::Text); + logstream.setDevice(reallog); - connection = new IrcConnection("irc.rbx.fr.euirc.net"); - connection->setUserName(settings["IrcNick"]); - connection->setNickName(settings["IrcNick"]); - connection->setRealName(settings["IrcRealName"]); - connection->sendCommand(IrcCommand::createJoin(settings["IrcChannel"])); - connection->setPassword(settings["IrcPassword"]); - //connection->sendCommand(IrcCommand::createMessage(settings["IrcChannel"], "Hi, kthxbye!")); - connection->open(); - connect(connection, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(ircMessageReceived(IrcMessage*))); + if(settings["UseIrc"] == "true") + { + connection = new IrcConnection(settings["IrcServer"]); + connection->setUserName(settings["IrcNick"]); + connection->setNickName(settings["IrcNick"]); + connection->setRealName(settings["IrcRealName"]); + 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.")); + } + else + { + settings["IrcUseIngameChat"] = "false"; + } + + connection->setPassword(settings["IrcPassword"]); + connect(connection, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(ircMessageReceived(IrcMessage*))); + connection->open(); + } + else + { + settings["IrcUseIngameChat"] = "false"; + } } CRSM::~CRSM() @@ -70,52 +90,97 @@ void CRSM::start() void CRSM::readServerOutput() { QRegExp timeRemover("^>?\\s*\\[\\d\\d:\\d\\d:\\d\\d\\]\\s+(.*)$"); + //QString what(codec->toUnicode(serverprocess->readAll())); //QString what(QTextCodec::codecForName("Windows-1250")->toUnicode(serverprocess->readAll())); + //QString what = QString::fromLatin1(serverprocess->readAll()); QString what(serverprocess->readAll()); + + if(settings["ServerUsesReadline"] == "true") + { + while(writtenToServer.length() > 0 && what.length() > 0 && writtenToServer.at(0) == what.at(0)) + { + writtenToServer.remove(0, 1); + what.remove(0, 1); + } + + if(what.at(0) == '>') + what.remove(0, 1); + } + + if(what.isEmpty()) + return; + + logstream << what.trimmed() << endl; + + if(settings["UseIrc"] == "true") + { + foreach(const QString &mess, what.split("\n", QString::SkipEmptyParts)) + foreach(const QString &mod, ircModIOList) + { + connection->sendCommand(IrcCommand::createNotice(mod, mess)); + } + } *qout << what.trimmed() << endl; if(!timeRemover.exactMatch(what)) return; what=timeRemover.cap(1).trimmed(); + //*qout << what << endl; - QRegExp userexp("^<([^>]*)>\\s+(.*)"); + //QRegExp userexp("^<([^>]*)>\\s+(.*)"); + QRegExp userexp("^>?\\s*<(.*)\\|(\\d+)\\|([^>]*)>\\s+(.*)$"); if(userexp.exactMatch(what)) { - QString user = userexp.cap(1).trimmed(); + QString user = userexp.cap(3); + QString pcName = userexp.cap(1); + QString cuid = userexp.cap(2); + ClientInfo& info = clients[pcName]; if(user!=settings["ServerNick"]) { - QString msg = userexp.cap(2).trimmed(); + QString msg = userexp.cap(4).trimmed(); QRegExp commandExp("^\\" CMD_SIGN "([^ ]+)(\\s+(.*)\\s*)?$"); if(commandExp.exactMatch(msg)) { QString command=commandExp.cap(1).trimmed(); QString commandArgs=commandExp.cap(2).trimmed(); if(command=="help") - serverprocess->write(CMD_SIGN"host <[Rundenordner.c4f/]Szenarioname.c4s> - Startet das gewaehlte Szenario, solange die Warteliste nicht zu gross ist.\n" - CMD_SIGN"queue - Zeigt die naechsten 3 Szenarien auf der Warteliste.\n" + writeToServer(QString(CMD_SIGN "host <[Rundenordner.c4f/]Szenarioname.c4s> - Startet das gewählte Szenario, solange die Warteliste nicht zu groß ist.\n" + CMD_SIGN "queue - Zeigt die nächsten %1 Szenarien auf der Warteliste.\n" + CMD_SIGN "list [Aliase¦Rundenordner[.c4f]] - Listet alle definierten Aliase oder alle möglichen Szenarien und Ordner auf, bzw. alle Szenarien im Ordner oder Rundenordner\n" + CMD_SIGN "admin [Chatnick oder PC-Name] - 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.\n" + CMD_SIGN "teamdist <none¦free¦host¦random¦randominv> - Ändert die Teamverteilung.\n" + CMD_SIGN "plrteam <Spielername> <Teamname> - Verschiebt den angegebenen Spieler ins angegebene Team.\n" + CMD_SIGN "aliaswish <Alias> = <Szenario> - Deponiert den Wunsch, <Alias> als Alias für <Szenario> einzutragen. Ein Moderator entscheidet darüber.\n" + CMD_SIGN "help - Zeigt diese Hilfe an.\n" + + (settings["IrcUseIngameChat"] == "true" ? QString(CMD_SIGN "ircchat <on¦off> - Schaltet den Irc-Ingame-Chat ein bzw. aus.\n") : QString("")) + + "Szenarionamen sind Case-Sensitive (Groß- Kleinschreibung beachten)!\n" + "Der Rundenadmin kann alle Clonk-Befehle mit " CMD_SIGN " statt / ausführen. Bspw.: " CMD_SIGN "kick Client-123\n" + "Zusätzlich zu den bekannten Clonk-Befehlen gibt es noch: stop, pause, unpause, teamcolorson, teamcolorsoff.\n" + "Ein Rundenadmin kann gegebenfalls einen anderen Spieler als Rundenadmin eintragen.\n" "[Sachen in eckigen Klammern sind optional]\n" "<Sachen in spitzen Klammern sind benoetigte Argumente>\n" - "Weitere Befehle folgen.\n"); + "Von ¦ getrennten Werten ist einer auszuwählen.\n" + "Weitere Befehle folgen.\n").arg(settings["UserListLength"])); if(command=="host") { if(userlist.length()>=settings["UserListLength"].toInt()) - serverprocess->write(QString("Maximale Warteschlangenlänge von "+settings["UserListLength"]+" erreicht!\n").toLatin1()); + writeToServer(QString("Maximale Warteschlangenlänge von "+settings["UserListLength"]+" erreicht!\n")); else { if(commandArgs=="") - serverprocess->write("Bitte gib einen Szenarionamen an!\n"); + writeToServer("Bitte gib einen Szenarionamen an!\n"); else { //extractC4Folders(); if(scenExists(commandArgs)) { userlist << commandArgs; - serverprocess->write(QString("Szenario "+commandArgs+" wurde der Warteschlange hinzugefügt.\n").toLatin1()); + writeToServer("Szenario "+commandArgs+" wurde der Warteschlange hinzugefügt.\n"); if(userlist.length() == 1 && session["userwish"] != "true" && session["running"] != "true") - serverprocess->write(QString("Überrede alle Spieler zu leaven und dein Wunsch wird sofort gehostet ;-)\n").toLatin1()); + writeToServer("Überrede alle Spieler zu leaven und dein Wunsch wird sofort gehostet ;-)\n"); } else { - serverprocess->write(QString("Szenario "+commandArgs+" wurde nicht gefunden!\n").toLatin1()); + writeToServer(QString("Szenario \"" + commandArgs + "\" wurde nicht gefunden!\n")); } } } @@ -125,101 +190,195 @@ void CRSM::readServerOutput() { if(commandArgs!="") { - if(session["admin"]==""||user==session["admin"] || lists["Moderators"].contains(user)) + if(commandArgs == settings["ServerNick"] || commandArgs == settings["ServerPCName"]) { - session["admin"]=commandArgs.trimmed(); - serverprocess->write(QString("Spieler "+commandArgs+" wurde als Rundenadmin eingetragen.\n").toLatin1()); + writeToServer("Der Server kann nicht als Rundenadmin eingetragen werden!\n"); + return; + } + if(commandArgs == sessionAdmin.pcName) + { + writeToServer(QString(sessionAdmin.nick + " (" + sessionAdmin.pcName + ") ist bereits Rundenadmin!\n")); + return; + } + if(sessionAdmin == ClientInfo() || info == sessionAdmin || lists["Moderators"].contains(cuid)) + { + if(clients.contains(commandArgs)) + { + sessionAdmin = clients.value(commandArgs); + } + else + { + bool notFound = true, ambigous = false; + ClientInfo foundClient; + foreach(const ClientInfo& client, clients) + { + if(client.nick == commandArgs) + { + if(!notFound) + { + ambigous = true; + break; + } + foundClient = client; + notFound = false; + } + } + if(ambigous) + { + writeToServer(QString("Chat-Nickname " + commandArgs + " ist nicht eindeutig. Bitte PC-Namen verwenden.\n")); + return; + } + else if(notFound) + { + writeToServer(QString("Spieler " + commandArgs + " wurde nicht gefunden!\n")); + return; + } + else if(sessionAdmin == foundClient) + { + writeToServer(QString(sessionAdmin.nick + " (" + sessionAdmin.pcName + ") ist bereits Rundenadmin!\n")); + return; + } + else + { + sessionAdmin = foundClient; + } + } + writeToServer(QString("Spieler " + sessionAdmin.nick + " (" + sessionAdmin.pcName + ") wurde als Rundenadmin eingetragen.\n")); } else { - serverprocess->write(QString(session["admin"]+" ist bereits Rundenadmin!\n").toLatin1()); + writeToServer(QString(sessionAdmin.nick + " (" + sessionAdmin.pcName + ") ist bereits Rundenadmin!\n")); } } else { - if(session["admin"]=="") - serverprocess->write(QString("Es gibt noch keinen Rundenadmin.\n").toLatin1()); + if(sessionAdmin == info) + { + writeToServer(QString("Du bist bereits Rundenadmin!\n")); + } + else if(sessionAdmin == ClientInfo() || lists["Moderators"].contains(cuid)) + { + sessionAdmin = info; + writeToServer(QString("Spieler " + info.nick + " (" + info.pcName + ") wurde als Rundenadmin eingetragen!\n")); + } else - serverprocess->write(QString(session["admin"]+" ist Rundenadmin!\n").toLatin1()); + writeToServer(QString(sessionAdmin.nick + " (" + sessionAdmin.pcName + ") ist bereits Rundenadmin!\n")); } } - if(command=="chatadmin") + /*if(command=="chatadmin") { if(commandArgs!="") { if(session["chatadmin"]==""||user==session["chatadmin"] || lists["Moderators"].contains(user)) { session["chatadmin"]=commandArgs.trimmed(); - serverprocess->write(QString("Spieler "+commandArgs+" wurde als Chat-Rundenadmin eingetragen.\n").toLatin1()); + writeToServer(QString("Spieler "+commandArgs+" wurde als Chat-Rundenadmin eingetragen.\n")); } else { - serverprocess->write(QString(session["chatadmin"]+" ist bereits Chat-Rundenadmin!\n").toLatin1()); + writeToServer(QString(session["chatadmin"]+" ist bereits Chat-Rundenadmin!\n")); } } else { if(session["chatadmin"]=="") { - serverprocess->write(QString(user + " wurde als Chat-Rundenadmin eingetragen.\n").toLatin1()); + writeToServer(QString(user + " wurde als Chat-Rundenadmin eingetragen.\n")); } else - serverprocess->write(QString(session["admin"]+" ist Chat-Rundenadmin!\n").toLatin1()); + writeToServer(QString(session["admin"]+" ist Chat-Rundenadmin!\n")); } - } + }*/ - if((command=="observer"||command=="deactivate"||command=="activate"||command=="kick"||command=="set"||command=="script"||command=="asyncctrl"||command=="centralctrl"||command=="decentralctrl"||command=="start"||command=="nodebug"||command=="stop"||command=="pause"||command=="unpause")&&(user==session["admin"] || user==session["chatadmin"] || lists["Moderators"].contains(user))) + else if((command=="observer"||command=="deactivate"||command=="activate"||command=="kick"||command=="set"||command=="script"||command=="asyncctrl"||command=="centralctrl"||command=="decentralctrl"||command=="start"||command=="nodebug"||command=="stop"||command=="pause"||command=="unpause"||command=="teamcolorsoff"||command=="teamcolorson"||command=="teamdist"||command=="plrteam")&&(sessionAdmin == info || lists["Moderators"].contains(cuid))) { + if(command=="kick") + { + if(clients.contains(commandArgs)) + { + if(lists["Moderators"].contains(QString::number(clients.value(commandArgs).CUID)) && !lists["Moderators"].contains(cuid)) + { + writeToServer(QString("Moderatoren können nicht gekickt werden!\n")); + return; + } + } + } if(!(command=="set"&&(commandArgs.simplified()=="faircrew on"||commandArgs.simplified()=="faircrew off")&&session["running"]!="true")) - serverprocess->write(QString("/"+command+" "+commandArgs+"\n").toLatin1()); + writeToServer(QString("/"+command+" "+commandArgs+"\n")); } - if(command=="queue") + else if(command=="queue") { - serverprocess->write("Folgende Szenarien befinden sich in der Warteschlange:\n"); - for(int i=0;i<settings["UserListLength"].toInt();i++) - { - /*if(userlist.length() + scenlist.length() < i) - break;*/ - serverprocess->write(QString("\t"+QString::number(i+1)+". "+(userlist.length()>i?userlist.at(i):scenlist.at((i-userlist.length() + current)%scenlist.length()) + " (auto)")+"\n").toLatin1()); - } + writeToServer(printQueue()); } - if(command=="list") + else if(command=="list") { - serverprocess->write(listScenarios(commandArgs).toLatin1()); + writeToServer(listScenarios(commandArgs)); + } + else if(command=="aliaswish") + { + writeToServer(addAliasWish(commandArgs) + "\n"); + } + else if(command=="ircchat"&&(sessionAdmin == info || lists["Moderators"].contains(cuid))) + { + writeToServer(ircActivateIngameChat(commandArgs.toLower() == "on") + "\n"); } } - if(msg.trimmed().toLower() == "hi" && !greeted.contains(user)) + else if(session["IrcUseIngameChat"] == "true") { - serverprocess->write("Hallo " + user .toLatin1()+ "!\n"); - greeted.push_back(user); + connection->sendCommand(IrcCommand::createMessage(settings["IrcIngameChannel"], "[Clonk]<" + user + "> " + msg)); } } } QRegExp joinExp("^Client (.+) (?:verbunden|connected)\\.\\s*$"); - joinExp.setMinimal(true); + //joinExp.setMinimal(true); if(joinExp.exactMatch(what)) { //waitinggreets << joinExp.cap(1); + QRegExp infoMatch("^<(.*)\\|(\\d+)\\|(.*)>$"); + if(infoMatch.exactMatch(joinExp.cap(1))) + { + ClientInfo info; + info.CUID = infoMatch.cap(2).toInt(); + info.nick = infoMatch.cap(3); + info.pcName = infoMatch.cap(1); + clients.insert(info.pcName, info); + QTimer *timer = new QTimer; + connect(timer, SIGNAL(timeout()), &greetMapper, SLOT(map())); + connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); + greetMapper.setMapping(timer, info.pcName); + timer->start(500); + } ++clientcount; } - /*joinExp = QRegExp("^Client (.+) (?:aktiviert|activated)\\.\\s*$"); - joinExp.setMinimal(true); - if(joinExp.exactMatch(what)) - if(waitinggreets.contains(joinExp.cap(1))) + joinExp = QRegExp("^Client (.+) (?:aktiviert|activated)\\.\\s*$"); + { + QRegExp infoMatch("^<(.*)\\|(\\d+)\\|(.*)>$"); + if(infoMatch.exactMatch(joinExp.cap(1))) + { + ClientInfo &info = clients[infoMatch.cap(1)]; + info.activated = true; + } + } + + joinExp = QRegExp("^Client (.+) (?:deaktiviert|deactivated)\\.\\s*$"); + { + QRegExp infoMatch("^<(.*)\\|(\\d+)\\|(.*)>$"); + if(infoMatch.exactMatch(joinExp.cap(1))) { - serverprocess->write(QString("Hallo "+joinExp.cap(1) +"!\n").toLatin1()); - waitinggreets.removeAll(joinExp.cap(1)); - }*/ + ClientInfo &info = clients[infoMatch.cap(1)]; + info.activated = false; + } + } QRegExp startExp("^Start!\\s*$"); if(startExp.exactMatch(what)) { - serverprocess->write(QString("/set maxplayer 0\n").toLatin1()); + writeToServer(QString("/set maxplayer 0\n")); session["running"]="true"; } @@ -228,7 +387,13 @@ void CRSM::readServerOutput() //leaveExp.setMinimal(true); if(leaveExp.exactMatch(what)) { - serverprocess->write(QString(leaveExp.cap(1) +" ist ein L34V0R!\n").toLatin1()); + QRegExp infoMatch("^<(.*)\\|(\\d+)\\|(.*)>$"); + if(infoMatch.exactMatch(leaveExp.cap(1))) + { + ClientInfo &info = clients[infoMatch.cap(1)]; + writeToServer(QString(info.nick +" ist ein L34V0R!\n")); + clients.remove(info.pcName); + } if(--clientcount == 0 && userlist.length() > 0 && session["userwish"] != "true") { serverprocess->closeWriteChannel(); @@ -256,16 +421,40 @@ void CRSM::readInput() if(what=="/exitafter") { finish=true; + *qout << "Will exit after this round." << endl; return; } if(what=="/next") { - serverprocess->closeWriteChannel(); + skipCurrent(); + return; + } + if(what=="/skip") + { + QString skipped; + if((skipped = skipScen()) != "") + { + *qout << "Skipped \"" << skipped << "\"." << endl; + } + else + *qout << "User list is empty!" << endl; + + return; + } + if(what=="/reload") + { + *qout << "Reloading config..." << endl; + lists.clear(); + settings.clear(); + ircModChecks.clear(); + ircMods.clear(); + ircModIOList.clear(); + readConfig(); return; } if(what=="/help") printAdditionalHelp(); - serverprocess->write(what.toLatin1()+"\n"); + writeToServer(what+"\n"); } void CRSM::nextScen() @@ -287,42 +476,96 @@ void CRSM::nextScen() void CRSM::printAdditionalHelp() { *qout << "/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; } void CRSM::readLog() { QString temp(logfile->readLine().trimmed()); - if(temp!="") *logstream << temp << endl; + if(temp!="") logstream << temp << endl; } void CRSM::scenarioFinished() { if(finish) { - connection->quit(settings["IrcQuitMessage"]); - connect(connection, SIGNAL(disconnected()), QCoreApplication::instance(), SLOT(quit())); - QTimer::singleShot(500, QCoreApplication::instance(), SLOT(quit())); + writeConfig(); + if(connection != 0) + { + connection->quit(settings["IrcQuitMessage"]); + connect(connection, SIGNAL(disconnected()), QCoreApplication::instance(), SLOT(quit())); + QTimer::singleShot(500, QCoreApplication::instance(), SLOT(quit())); + } + else + QCoreApplication::quit(); return; } session.clear(); - //waitinggreets.clear(); + sessionAdmin = ClientInfo(); + clients.clear(); greeted.clear(); clientcount = 0; if((autoHost || userlist.length() > 0) && !finish) nextScen(); + else if(!settings["IrcIngameChannel"].isEmpty()) + { + connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Kein laufendes Spiel.")); + QFile lastScenFile(LAST_SCEN_FILE_NAME); + QFile curScenFile(CUR_SCEN_FILE_NAME); + curScenFile.open(QFile::ReadOnly); + lastScenFile.open(QFile::WriteOnly); + lastScenFile.write(curScenFile.readAll()); + lastScenFile.close(); + curScenFile.close(); + curScenFile.open(QFile::WriteOnly); + curScenFile.close(); + } } void CRSM::ircMessageReceived(IrcMessage *message) { if(message->isOwn()) return; - if(message->type() == IrcMessage::Private) + if(message->type() == IrcMessage::Notice) + { + if(message->nick() == "NickServ") + { + QStringList split = message->parameters().at(1).split(' ', QString::SkipEmptyParts); + if(split.first() == "STATUS") + { + QString statusNick = split.at(1); + int status = split.at(2).toInt(); + if(ircModChecks.contains(statusNick)) + { + ircModChecks.removeAll(statusNick); + if(status == 3 && lists["IrcModerators"].contains(statusNick)) + { + ircMods.append(statusNick); + ircModJoined(statusNick); + } + else + { + ircModFifos.remove(statusNick); + } + } + } + } + } + else if(message->type() == IrcMessage::Private) { QString target = message->parameters().at(0); + if(message->parameters().at(0) == connection->nickName()) + target = message->nick(); QString mess = message->parameters().at(1).trimmed(); - if(mess.left(QString(CMD_SIGN).length()) == CMD_SIGN) + if(target == settings["IrcIngameChannel"]) + { + writeToServer("[IRC]<" + message->nick() + "> " + mess + "\n"); + } + else if(mess.left(QString(CMD_SIGN).length()) == CMD_SIGN && mess.length() > QString(CMD_SIGN).length()) { QStringList args = mess.right(mess.length() - QString(CMD_SIGN).length()).split(" ", QString::SkipEmptyParts); QString cmd = args.first().trimmed(); @@ -332,21 +575,15 @@ void CRSM::ircMessageReceived(IrcMessage *message) { /*foreach(const QString &line, listScenarios(arg).split('\n')) connection->sendCommand(IrcCommand::createMessage(message->nick(), line));*/ - connection->sendCommand(IrcCommand::createMessage(target, "Szenarioliste ist zurzeit nur in der Lobby und im laufenden Spiel verfügbar.")); + connection->sendCommand(IrcCommand::createMessage(target, settings["IrcScenListMessage"]/*"Szenarioliste ist zurzeit nur in der Lobby und im laufenden Spiel verfügbar."*/)); } else if(cmd == "autohost") { - autoHost = true; - connection->sendCommand(IrcCommand::createMessage(target, "Automatisches Hosting aktiviert.")); - if(session["hosting"] != "true") - { - nextScen(); - } + ircCheckModCmd(message->nick(), IrcModOperations::Autohost); } else if(cmd == "noautohost") { - autoHost = false; - connection->sendCommand(IrcCommand::createMessage(target, "Automatisches Hosting deaktiviert.")); + ircCheckModCmd(message->nick(), IrcModOperations::NoAutohost); } else if(cmd=="host") { @@ -374,35 +611,180 @@ void CRSM::ircMessageReceived(IrcMessage *message) } else { - connection->sendCommand(IrcCommand::createMessage(target, "Szenario " + arg + " wurde nicht gefunden!")); + connection->sendCommand(IrcCommand::createMessage(target, "Szenario \"" + arg + "\" wurde nicht gefunden!")); } } } } + else if(cmd=="queue") + { + foreach(const QString &line, printQueue().split('\n')) + connection->sendCommand(IrcCommand::createNotice(target, line)); + } + else if(cmd=="help") + { + connection->sendCommand(IrcCommand::createNotice(target, CMD_SIGN "list - Zeigt Möglichkeiten zur Betrachtung einer Szenarienliste an.")); + connection->sendCommand(IrcCommand::createNotice(target, CMD_SIGN "host <[Rundenordner.c4f/]Szenarioname.c4s> - Startet das gewählte Szenario, solange die Warteliste nicht zu groß ist.")); + connection->sendCommand(IrcCommand::createNotice(target, QString(CMD_SIGN "queue - Zeigt die nächsten %1 Szenarien auf der Warteliste.").arg(settings["UserListLength"]))); + connection->sendCommand(IrcCommand::createNotice(target, CMD_SIGN "aliaswish <Alias> = <Szenario> - Deponiert den Wunsch, <Alias> als Alias für <Szenario> einzutragen. Ein Moderator entscheidet darüber.")); + connection->sendCommand(IrcCommand::createNotice(target, CMD_SIGN "help - Zeigt diese Hilfe an.")); + ircCheckModCmd(message->nick(), ModHelp); + } + else if(cmd=="moderatorcheck") + { + ircCheckModCmd(message->nick(), IrcModOperations::ModCheck); + } + else if(cmd=="modinfo") + { + ircCheckModCmd(message->nick(), IrcModOperations::ModInfo); + } + else if(cmd=="skip") + { + ircCheckModCmd(message->nick(), IrcModOperations::SkipScen); + } + else if(cmd=="clear") + { + ircCheckModCmd(message->nick(), IrcModOperations::ClearUserList); + } + else if(cmd=="next") + { + ircCheckModCmd(message->nick(), IrcModOperations::SkipCurrentScen); + } + else if(cmd=="kill") + { + ircCheckModCmd(message->nick(), IrcModOperations::Kill); + } + else if(cmd=="io") + { + ircCheckModCmd(message->nick(), IrcModOperations::IO); + } + else if(cmd=="newalias") + { + ircCheckModCmd(message->nick(), IrcModOperations::NewAlias, arg); + } + else if(cmd=="aliaswish") + { + connection->sendCommand(IrcCommand::createMessage(target, addAliasWish(arg))); + } + else if(cmd=="aliaswishes") + { + ircCheckModCmd(message->nick(), IrcModOperations::AliasWishes); + } + else if(cmd=="ingamechat") + { + ircCheckModCmd(message->nick(), IrcModOperations::IngameChat, arg); + } + } + else if(message->nick() == target && ircMods.contains(target)) + { + if(aliasWishEditor == target) + { + editAliasWishes(mess); + } + else if(ircModIOList.contains(message->nick())) + { + QString writeMessage; + if(mess.at(0) == '\\') + { + mess[0] = '/'; + } + else + { + writeMessage = "[IRC]<" + message->nick() + "> "; + } + writeMessage += mess; + writeToServer(writeMessage + "\n"); + } } } else if(message->type() == IrcMessage::Join) { - connection->sendCommand(IrcCommand::createMessage(settings["IrcChannel"], "Hallo " + message->nick() + "!")); + QString joinChannel = message->parameters().at(0); + connection->sendCommand(IrcCommand::createMessage(joinChannel, "Hallo " + message->nick() + "!")); + if(joinChannel == settings["IrcIngameChannel"]) + { + writeToServer("[IRC] " + message->nick() + " hat den Channel betreten." + "\n"); + } + else + ircCheckModCmd(message->nick(), IrcModOperations::CheckOnly); + } + else if(message->type() == IrcMessage::Quit) + { + ircMods.removeAll(message->nick()); + ircModChecks.removeAll(message->nick()); + ircModIOList.removeAll(message->nick()); + if(aliasWishEditor == message->nick()) + { + stopAliasWishEditing(); + } } else if(message->type() == IrcMessage::Kick) { if(message->parameters().at(1) == connection->nickName()) { - connection->sendCommand(IrcCommand::createJoin(settings["IrcChannel"])); + connection->sendCommand(IrcCommand::createJoin(message->parameters().at(0))); + } + } + else if(message->type() == IrcMessage::Part) + { + QString leaveChannel = message->parameters().at(0); + if(leaveChannel == settings["IrcIngameChannel"]) + { + writeToServer("[IRC] " + message->nick() + " hat den Channel verlassen." + "\n"); + } + } + 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(settings["IrcUseIngameChat"] == "true" && !settings["IrcIngameChannel"].isEmpty()) + { + connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Kein laufendes Spiel.")); + } } } } +void CRSM::greet(QString pcName) +{ + if(!clients.contains(pcName)) + return; + ClientInfo &info = clients[pcName]; + writeToServer(QString("Hallo " + info.nick + "!\n")); +} + void CRSM::startScen(QString scen, QStringList argList) { + QFile lastScenFile(LAST_SCEN_FILE_NAME); + QFile curScenFile(CUR_SCEN_FILE_NAME); + curScenFile.open(QFile::ReadOnly); + lastScenFile.open(QFile::WriteOnly); + lastScenFile.write(curScenFile.readAll()); + lastScenFile.close(); + curScenFile.close(); + curScenFile.open(QFile::WriteOnly); + curScenFile.write(scen.toUtf8()); + curScenFile.close(); + QFile scoreboardFile(SCOREBOARD_FILE_NAME); + scoreboardFile.open(QFile::WriteOnly); + scoreboardFile.close(); + + session["scenname"] = scen; + session["IrcUseIngameChat"] = settings["IrcUseIngameChat"]; + if(settings["IrcUseIngameChat"] == "true" && !settings["IrcIngameChannel"].isEmpty()) + { + connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); + } + while(maps["Alias"].contains(scen)) + scen = maps["Alias"].value(scen); serverprocess->setWorkingDirectory(QDir::currentPath()); serverprocess->start(settings["ServerExecutable"], argList << scen); } void CRSM::readConfig() { - QFile config("CrServerManager.conf"); + QFile config(CONFIG_FILE_NAME); if(!config.exists()||!config.open(QIODevice::ReadOnly | QIODevice::Text)) { config.open(QIODevice::WriteOnly | QIODevice::Text); @@ -416,22 +798,31 @@ void CRSM::readConfig() { QRegExp confExp("^([^=]+)=(.*)$"); QRegExp confPlusExp("^([^=]+)\\+=(.*)$"); - for(QString line=config.readLine().trimmed(); !config.atEnd(); line=config.readLine().trimmed()) + 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; } *qout << "config:" << endl; foreach(const QString &key, settings.keys()) { - *qout << key << " = " << settings.value(key) << endl; + *qout << key << " = " << settings.value(key) << endl; } *qout << endl; foreach(const QString &key, lists.keys()) @@ -442,7 +833,16 @@ void CRSM::readConfig() *qout << "\t" << val << endl; } } - + *qout << endl; + foreach(const QString &key, maps.keys()) + { + *qout << key << ":" << endl; + foreach(const QString &mapkey, maps.value(key).keys()) + { + *qout << "\t[" << mapkey << "]" << " = " << maps.value(key).value(mapkey) << endl; + } + } + *qout << endl; args=settings["Arguments"].split(" "); args << "/config:"+settings["ClonkConfig"]; } @@ -455,18 +855,25 @@ void CRSM::readConfig() else { clonkconfig.open(QFile::ReadOnly); - QRegExp nickexp("^\\s*Nick=\"(.*)\"\\s*$"); + QRegExp nickExp("^\\s*Nick=\"(.*)\"\\s*$"); + QRegExp pcNameExp("^\\s*LocalName=\"(.*)\"\\s*$"); foreach(const QString &line, QString(clonkconfig.readAll().trimmed()).split("\n")) { //*qout << line << endl; - if(nickexp.exactMatch(line)) + if(nickExp.exactMatch(line)) + { + settings["ServerNick"]=nickExp.cap(1); + break; + } + else if(pcNameExp.exactMatch(line)) { - settings["ServerNick"]=nickexp.cap(1); + settings["ServerPCName"]=pcNameExp.cap(1); break; } } - *qout << "ClonkDirectory" << " = " << settings.value("ClonkDirectory") << endl; - *qout << "ServerNick" << " = " << settings.value("ServerNick") << endl; + *qout << endl; + *qout << "ClonkDirectory" << " = " << settings.value("ClonkDirectory") << endl; + *qout << "ServerNick" << " = " << settings.value("ServerNick") << endl; } *qout << endl; } @@ -535,33 +942,21 @@ void CRSM::listC4Folders() QDirIterator it(settings["ClonkDirectory"], 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())) { -#ifdef Q_OS_LINUX64 - QString executable = "c4group64"; -#else - QString executable = "c4group"; -#endif - QProcess c4group; - c4group.start(settings["ClonkDirectory"]+executable, QStringList() << it.filePath() << "-l", QProcess::ReadOnly); - c4group.waitForFinished(); - c4group.readLine(); - QRegExp finishExp("^\\d+ Entries, \\d+ Bytes$"); - QRegExp entryExp("^(.*\\.c4s)\\s+\\d+ Bytes\\s.*$"); - QFile listFile(it.filePath()+".lst"); - listFile.open(QFile::WriteOnly); - QString line; - while(!c4group.atEnd()) + const QStringList& list = listC4Folder(it.filePath()); + if(!list.isEmpty()) { - line = c4group.readLine().trimmed(); - if(line.isEmpty()) - continue; - if(finishExp.exactMatch(line)) - break; - if(entryExp.exactMatch(line)) - listFile.write(entryExp.cap(1).toUtf8() + '\n'); + QFile listFile(it.filePath()+".lst"); + listFile.open(QFile::WriteOnly); + foreach(const QString& scen, list) + { + listFile.write(scen.toUtf8() + "\n"); + } + listFile.close(); } - listFile.close(); } } *qout << QString(3, '\b') << ": Finished" << endl; @@ -583,7 +978,12 @@ void CRSM::cleanUp() bool CRSM::scenExists(QString filePath) { - bool exists = QFile(settings["ClonkDirectory"]+filePath).exists(); + while(maps["Alias"].contains(filePath)) + filePath = maps["Alias"].value(filePath); + QFileInfo fileInfo(settings["ClonkDirectory"]+filePath); + if(fileInfo.suffix() != "c4s") + return false; + bool exists = fileInfo.exists(); if(!exists) { QStringList split = filePath.split('/'); @@ -632,6 +1032,14 @@ QString CRSM::listScenarios(QString commandArgs) ret += QString(" "+folderIt.fileInfo().absoluteFilePath().left(folderIt.fileInfo().absoluteFilePath().length() - 4).replace(settings["ClonkDirectory"],"")+"\n"); } } + else if(commandArgs.toLower() == "aliase") + { + ret += "Vorhandene Aliase:\n"; + foreach(const QString &alias, maps["Alias"].keys()) + { + ret += QString(" " + alias + " = " + maps["Alias"].value(alias) + "\n"); + } + } else { QFile file(settings["ClonkDirectory"] + commandArgs + ".lst"); @@ -640,10 +1048,395 @@ QString CRSM::listScenarios(QString commandArgs) ret += "Der Ordner \"" + commandArgs + QString("\" enthält folgende Szenarien:\n"); file.open(QFile::ReadOnly); while(!file.atEnd()) - ret += " " + QString::fromUtf8(file.readLine()).toLatin1().trimmed() + "\n"; + ret += " " + QString::fromUtf8(file.readLine()).trimmed() + "\n"; } else ret += "Der Ordner \"" + commandArgs + "\" wurde nicht gefunden!\n"; } return ret; } + +QString CRSM::printQueue() +{ + QString ret("Folgende Szenarien befinden sich in der Warteschlange:\n"); + for(int i=0;i<settings["UserListLength"].toInt();i++) + { + ret += "\t"+QString::number(i+1)+". "+(userlist.length()>i?userlist.at(i):scenlist.at((i-userlist.length() + current)%scenlist.length()) + " (auto)")+"\n"; + } + return ret; +} + +/*QByteArray CRSM::toClonkFormat(const QString &str) +{ + QByteArray ret; + foreach(const QChar& c, str) + { + if(c == QString("™")) + ret.append(c); + else + ret.append(c.toLatin1()); + } + + return ret; +}*/ + +void CRSM::ircCheckModCmd(const QString &nick, CRSM::IrcModOperations operation, QString arg) +{ + if(!lists["IrcModerators"].contains(nick)) + return; + if(ircMods.contains(nick)) + ircModOperation(nick, operation, arg); + else + { + if(!ircModChecks.contains(nick)) + { + ircModChecks.append(nick); + connection->sendCommand(IrcCommand::createMessage("NickServ", "STATUS " + nick)); + } + ircModFifos[nick].append(qMakePair<IrcModOperations, QString>(operation, arg)); + } +} + +void CRSM::ircModOperation(const QString &nick, CRSM::IrcModOperations operation, QString arg) +{ + QString answer, skipped; + QRegExp aliasExp("^([^=]+)=(.*)$"); + switch(operation) + { + case IrcModOperations::ModCheck: + connection->sendCommand(IrcCommand::createMessage(nick, "Du bist Moderator.")); + break; + case IrcModOperations::ModInfo: + connection->sendCommand(IrcCommand::createMessage(nick, "Moderatoren sind (* ist aktiv, + verwendet IO):")); + foreach(const QString &mod, lists["IrcModerators"]) + { + connection->sendCommand(IrcCommand::createMessage(nick, (ircMods.contains(mod) ? QString("*") : QString(" ")) + (ircModIOList.contains(mod) ? QString("+") : QString(" ")) + " " + mod)); + } + break; + case IrcModOperations::SkipScen: + if((skipped = skipScen()) != "") + { + answer = "\"" + skipped + "\" übersprungen."; + } + else + answer = "Userliste ist leer!"; + connection->sendCommand(IrcCommand::createMessage(nick, answer)); + break; + case IrcModOperations::ClearUserList: + if(userlist.length() > 0) + { + userlist.clear(); + answer = "Userliste geleert."; + } + else + { + answer = "Userliste ist leer!"; + } + connection->sendCommand(IrcCommand::createMessage(nick, answer)); + break; + case IrcModOperations::SkipCurrentScen: + skipCurrent(); + connection->sendCommand(IrcCommand::createMessage(nick, "Versuche zu überspringen...")); + break; + case IrcModOperations::Autohost: + autoHost = true; + connection->sendCommand(IrcCommand::createMessage(nick, "Automatisches Hosting aktiviert.")); + if(session["hosting"] != "true") + { + nextScen(); + } + break; + case IrcModOperations::NoAutohost: + autoHost = false; + connection->sendCommand(IrcCommand::createMessage(nick, "Automatisches Hosting deaktiviert.")); + break; + case IrcModOperations::ModHelp: + connection->sendCommand(IrcCommand::createMessage(nick, "Moderatorbefehle:")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "next - Schließt stdin vom Clonk-Server, vorausgesetzt es läuft einer. Wenn dieser ordnungsgemäß läuft beendet er sich.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "kill - Tötet den Clonk-Server, vorausgesetzt es läuft einer. Bitte nur verwenden wenn " CMD_SIGN "next nicht funktioniert.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "skip - Entfernt das nächste Szenario aus der Wunschliste.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "clear - Löscht die Wunschliste.")); + if(settings["IrcUseIngameChat"] == "true") + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "ingamechat <on¦off> - Schaltet den Irc-Ingame-Chat ein bzw. aus.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "modinfo - Listet alle Moderatoren auf.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "io - 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 /.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "newalias <Alias> = <Szenario> - Trägt <Alias> als Alias für <Szenario> ein.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "aliaswishes - Zum geführten Bearbeiten der Aliaswünsche.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "autohost - Schaltet Autohosting ein.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "noautohost - Schaltet Autohosting aus.")); + connection->sendCommand(IrcCommand::createMessage(nick, CMD_SIGN "aliaswishes - Zum geführten Bearbeiten der Aliaswünsche.")); + break; + case IrcModOperations::Kill: + serverprocess->kill(); + connection->sendCommand(IrcCommand::createMessage(nick, "Clonk-Server wurde gekillt.")); + break; + case IrcModOperations::IO: + if(ircModIOList.contains(nick)) + ircModIOList.removeAll(nick); + else + ircModIOList.append(nick); + case IrcModOperations::CheckOnly: + break; + case IrcModOperations::NewAlias: + if(aliasExp.exactMatch(arg)) + { + const QString &scen = aliasExp.cap(2).trimmed(); + const QString &alias = aliasExp.cap(1).trimmed(); + if(scenExists(scen)) + { + if(maps["AliasWishes"].contains(alias)) + { + connection->sendCommand(IrcCommand::createMessage(nick, "Aliaswunsch für \"" + maps["AliasWishes"].value(alias) + "\" entfernt und Alias hinzugefügt!")); + maps["AliasWishes"].remove(alias); + } + else if(maps["Alias"].contains(alias)) + { + connection->sendCommand(IrcCommand::createMessage(nick, "Alias für \"" + maps["Alias"][alias] + "\" überschrieben!")); + } + else + { + connection->sendCommand(IrcCommand::createMessage(nick, "Alias hinzugefügt!")); + } + maps["Alias"][alias] = scen; + } + else + connection->sendCommand(IrcCommand::createMessage(nick, "Szenario \"" + scen + "\" wurde nicht gefunden!")); + } + else + connection->sendCommand(IrcCommand::createMessage(nick, "Eingabefehler! Siehe !help für mehr Informationen.")); + break; + case IrcModOperations::AliasWishes: + if(aliasWishEditor == "") + { + aliasWishEditor = nick; + if(ircModIOList.contains(nick)) + connection->sendCommand(IrcCommand::createMessage(nick, "IO-Eingabe ist während dem Aliaswünsche-Bearbeiten deaktiviert.")); + editAliasWishes(); + } + else + connection->sendCommand(IrcCommand::createMessage(nick, aliasWishEditor + " bearbeitet bereits die Aliase. Danke für die Bemühung.")); + break; + case IrcModOperations::IngameChat: + connection->sendCommand(IrcCommand::createMessage(nick, ircActivateIngameChat(arg.toLower() == "on"))); + break; + } +} + +void CRSM::ircModOperation(const QString &nick, QPair<CRSM::IrcModOperations, QString> operationArg) +{ + ircModOperation(nick, operationArg.first, operationArg.second); +} + +QString CRSM::skipScen() +{ + if(userlist.length() > 0) + { + QString skipped = userlist.first(); + userlist.removeFirst(); + return skipped; + } + else + return ""; +} + +void CRSM::skipCurrent() +{ + serverprocess->closeWriteChannel(); +} + +void CRSM::writeToServer(const QString &message) +{ + if(!serverprocess->isWritable()) + return; + serverprocess->write(codec->fromUnicode(message)); + if(settings["ServerUsesReadline"] == "true") + { + if(writtenToServer.length() > settings["ReadlineRereadLimit"].toInt()) + writtenToServer.clear(); + writtenToServer += codec->fromUnicode(message); + } +} + +void CRSM::writeConfig() +{ + QFile config(CONFIG_FILE_NAME); + config.open(QFile::WriteOnly); + + QTextStream configStream(&config); + + foreach(const QString &key, settings.keys()) + { + configStream << key << " = " << settings.value(key) << endl; + } + configStream << endl; + foreach(const QString &key, lists.keys()) + { + foreach(const QString &val, lists.value(key)) + { + configStream << key << " += " << val << endl; + } + } + configStream << endl; + foreach(const QString &key, maps.keys()) + { + foreach(const QString &mapkey, maps.value(key).keys()) + { + configStream << key << "[" << mapkey << "]" << " = " << maps.value(key).value(mapkey) << endl; + } + } + configStream << endl; + + config.close(); +} + +QString CRSM::addAliasWish(const QString ¶m) +{ + QRegExp aliasExp("^([^=]+)=(.*)$"); + if(aliasExp.exactMatch(param)) + { + const QString &alias = aliasExp.cap(1).trimmed(); + const QString &scen = aliasExp.cap(2).trimmed(); + if(maps["Alias"].contains(alias)) + return "Alias ist bereits vergeben!"; + else if(maps["AliasWishes"].contains(alias)) + return "Alias ist bereits als Wunsch vergeben!"; + else if(scenExists(scen)) + { + maps["AliasWishes"].insert(alias, scen); + informModsAboutAliasWish(); + return "Aliaswunsch ist hinterlegt!"; + } + else + return "Szenario \"" + scen + "\" wurde nicht gefunden!"; + } + else + return "Eingabefehler! Siehe !help für mehr Informationen."; +} + +void CRSM::ircModJoined(const QString &nick) +{ + while(ircModFifos[nick].length() > 0) + { + ircModOperation(nick, ircModFifos[nick].first()); + ircModFifos[nick].removeFirst(); + } + if(!maps["AliasWishes"].isEmpty()) + { + connection->sendCommand(IrcCommand::createNotice(nick, 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.")); + connection->sendCommand(IrcCommand::createNotice(nick, "Bitte bei nächster Gelegenheit mit " CMD_SIGN "aliaswishes bearbeiten.")); + } +} + +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()))); + } +} + +void CRSM::editAliasWishes() +{ + if(maps["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]")); + } +} + +void CRSM::editAliasWishes(const QString &message) +{ + if(message.toLower() == "j" || message.toLower() == "ja") + { + maps["Alias"][currentAliasWish] = maps["AliasWishes"][currentAliasWish]; + maps["AliasWishes"].remove(currentAliasWish); + } + else if(message.toLower() == "n" || message.toLower() == "nein") + { + maps["AliasWishes"].remove(currentAliasWish); + } + else if(message.toLower() == "s" || message.toLower() == "stop") + { + connection->sendCommand(IrcCommand::createMessage(aliasWishEditor, "Aliaswunsch-Bearbeitung gestoppt.")); + stopAliasWishEditing(); + return; + } + else + { + connection->sendCommand(IrcCommand::createMessage(aliasWishEditor, "\"" + message + "\" ist keine Antwortmöglichkeit. Antwortmöglichkeiten: [Ja|Nein|Stop]")); + } + editAliasWishes(); +} + +void CRSM::stopAliasWishEditing() +{ + aliasWishEditor = ""; + currentAliasWish = ""; +} + +QString CRSM::ircActivateIngameChat(bool activated) +{ + if(settings["IrcUseIngameChat"] == "true" && !settings["IrcIngameChannel"].isEmpty()) + { + session["IrcUseIngameChat"] = activated ? "true" : "false"; + connection->sendCommand(IrcCommand::createTopic(settings["IrcIngameChannel"], "Aktuelles Szenario: " + session["scenname"] + " | Ingamechat ist " + (session["IrcUseIngameChat"] == "true" ? "" : "de") + "aktviert.")); + return "Ingamechat wurde " + (session["IrcUseIngameChat"] == "true" ? QString("") : QString("de")) + "aktviert."; + } + else + return "Ingamechat ist administrativ deaktiviert!"; +} + +QStringList CRSM::listC4Folder(const QString &path) +{ + QStringList ret; + QFileInfo fileInfo(path); + if(fileInfo.isDir()) + { + QDir dir(path); + const QStringList folderList = dir.entryList(QStringList() << "*.c4f", QDir::NoFilter, QDir::Name | QDir::IgnoreCase); + ret.append(dir.entryList(QStringList() << "*.c4s", QDir::NoFilter, QDir::Name | QDir::IgnoreCase)); + foreach(const QString &folder, folderList) + { + const QStringList &folderList = listC4Folder(path + '/' + folder); + foreach (const QString &scen, folderList) { + ret.append(folder + '/' + scen); + } + } + } + else + { + QProcess c4group; + c4group.start(settings["ClonkDirectory"]+C4GROUP_EXECUTABLE, QStringList() << path << "-l", QProcess::ReadOnly); + c4group.waitForFinished(); + c4group.readLine(); + QRegExp finishExp("^\\d+ Entries, \\d+ Bytes$"); + QRegExp scenarioExp("^(.*\\.c4s)\\s+\\d+ Bytes\\s.*$"); + QRegExp folderExp("^(.*\\.c4f)\\s+\\d+ Bytes\\s.*$"); + QString line; + while(!c4group.atEnd()) + { + line = codec->toUnicode(c4group.readLine().trimmed()); + if(line.isEmpty()) + continue; + if(finishExp.exactMatch(line)) + break; + if(scenarioExp.exactMatch(line)) + { + ret.append(scenarioExp.cap(1)); + } + else if(folderExp.exactMatch(line)) + { + const QStringList &folderList = listC4Folder(path + '/' + folderExp.cap(1)); + foreach (const QString &scen, folderList) { + ret.append(folderExp.cap(1) + '/' + scen); + } + } + } + } + return ret; +} |
