summaryrefslogtreecommitdiffstats
path: root/crsm.cpp
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2015-01-01 16:04:07 +0100
committerMarkus Mittendrein <git@maxmitti.tk>2015-01-01 16:04:07 +0100
commita92aea252411f86657081587633a88083a3b14a9 (patch)
tree754abad814d07dc339cb3025dd31faf186e4cfe4 /crsm.cpp
parent529f38bd8878b6b1bea2b5457031ce936aab8d80 (diff)
downloadmanager-a92aea252411f86657081587633a88083a3b14a9.tar.gz
manager-a92aea252411f86657081587633a88083a3b14a9.zip
Massive changes.
Can't remember them.
Diffstat (limited to 'crsm.cpp')
-rw-r--r--crsm.cpp1025
1 files changed, 909 insertions, 116 deletions
diff --git a/crsm.cpp b/crsm.cpp
index 004be22..14d54a9 100644
--- a/crsm.cpp
+++ b/crsm.cpp
@@ -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 &param)
+{
+ 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;
+}