summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2015-01-04 13:57:11 +0100
committerMarkus Mittendrein <git@maxmitti.tk>2015-01-04 13:57:11 +0100
commitfbe3c5fbe1327fd81e2eb8fe30a75c4cf5d7b35c (patch)
tree02c7bd3f23e18ffcd2d75257ab215e87ead72c96
parenta92aea252411f86657081587633a88083a3b14a9 (diff)
downloadmanager-fbe3c5fbe1327fd81e2eb8fe30a75c4cf5d7b35c.tar.gz
manager-fbe3c5fbe1327fd81e2eb8fe30a75c4cf5d7b35c.zip
Cleanup completed. New Interface based system.
-rw-r--r--ClientInfo.hpp54
-rw-r--r--CmdFunctionRef.hpp45
-rw-r--r--CrServerManager.pro5
-rw-r--r--crsm.cpp1218
-rw-r--r--crsm.hpp (renamed from crsm.h)65
-rw-r--r--main.cpp2
6 files changed, 831 insertions, 558 deletions
diff --git a/ClientInfo.hpp b/ClientInfo.hpp
index 61e1b34..f3def0e 100644
--- a/ClientInfo.hpp
+++ b/ClientInfo.hpp
@@ -2,14 +2,60 @@
#include <QString>
-struct ClientInfo
+enum ClientInterface {
+ Clonk = 1,
+ IRC = 1 << 1
+};
+
+class ClientInfo
{
- int CUID = 0;
+
+public:
+ ClientInterface interface = Clonk;
QString nick = "";
+
+ int CUID = 0;
QString pcName = "";
bool activated = false;
- bool operator==(const ClientInfo& other)
+
+ QString target = "";
+
+ static inline ClientInfo ircClient(QString nick, QString target = "")
+ {
+ ClientInfo ret;
+ ret.interface = IRC;
+ ret.nick = nick;
+ if(target.isEmpty())
+ {
+ target = nick;
+ }
+ ret.target = target;
+ return ret;
+ }
+
+ static inline ClientInfo clonkClient(QString nick, QString pcName, int CUID, bool activated = false)
+ {
+ ClientInfo ret;
+ ret.interface = Clonk;
+ ret.nick = nick;
+ ret.nick = pcName;
+ ret.CUID = CUID;
+ ret.activated = activated;
+ return ret;
+ }
+
+ inline bool operator==(const ClientInfo& other)
+ {
+ return other.interface == interface && other.nick == nick && (interface == Clonk ? other.pcName == pcName && other.CUID == CUID : true);
+ }
+
+ inline bool operator!=(const ClientInfo& other)
+ {
+ return !operator==(other);
+ }
+
+ inline QString toString() const
{
- return other.nick == nick && other.pcName == pcName && other.CUID == CUID;
+ return (!nick.isEmpty() ? nick + (interface == Clonk ? " (" + pcName + ")" : " (IRC)") : "");
}
};
diff --git a/CmdFunctionRef.hpp b/CmdFunctionRef.hpp
new file mode 100644
index 0000000..586090a
--- /dev/null
+++ b/CmdFunctionRef.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <QString>
+#include <QMap>
+#include <ClientInfo.hpp>
+
+class CRSM;
+
+#define CMD_FUNCTION(name) void name(const QString& cmd, const QString& args, const ClientInfo& client, UserType userTypeModerator)
+#define CMD_FUNCTION_IMPL(name) void CRSM::name(const QString& cmd, const QString& args, const ClientInfo& client, UserType userType)
+
+enum UserType {
+ User = 0,
+ Admin = 1,
+ Moderator = 2
+};
+
+typedef void (CRSM::*CmdFunction)(const QString&, const QString&, const ClientInfo&, UserType);
+
+const QMap<UserType, QString> userTypeStrings {
+ {User, "Benutzer"},
+ {Admin, "Rundenadmin oder Moderator"},
+ {Moderator, "Moderator"}
+};
+
+struct CmdFunctionRef
+{
+ CmdFunction func = nullptr;
+ int interfaces = Clonk | IRC;
+ UserType userType = User;
+ QString shortDescription = "";
+ QString longDescription = "";
+ QString name = "";
+ QString argList = "";
+
+ CmdFunctionRef(QString name, CmdFunction func, int interfaces, UserType userType, const QString& shortDescription = "", QString argList = "", const QString &longDescription = "") : func(func), interfaces(interfaces), userType(userType), shortDescription(shortDescription), longDescription(longDescription), name(name), argList(argList)
+ {
+
+ }
+
+ CmdFunctionRef()
+ {
+
+ }
+};
diff --git a/CrServerManager.pro b/CrServerManager.pro
index da55d93..40f76a6 100644
--- a/CrServerManager.pro
+++ b/CrServerManager.pro
@@ -21,8 +21,9 @@ SOURCES += main.cpp \
crsm.cpp
HEADERS += \
- crsm.h \
- ClientInfo.hpp
+ CmdFunctionRef.hpp \
+ ClientInfo.hpp \
+ crsm.hpp
equals(QT_ARCH, "x86_64"):linux-*: DEFINES += Q_OS_LINUX64
QMAKE_CXXFLAGS *= -std=c++11
diff --git a/crsm.cpp b/crsm.cpp
index 14d54a9..2a4a1b8 100644
--- a/crsm.cpp
+++ b/crsm.cpp
@@ -1,4 +1,4 @@
-#include "crsm.h"
+#include "crsm.hpp"
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
@@ -17,7 +17,7 @@ CRSM::CRSM(QObject *parent) :
qin = new QTextStream(stdin, QIODevice::ReadOnly);
qout->setCodec(QTextCodec::codecForName("UTF-8"));
- serverprocess=new QProcess;
+ serverprocess = new QProcess;
args << "/fullscreen" << "/config:config" << "/lobby:60" << "/nosignup";
current = 0;
finish = false;
@@ -27,26 +27,20 @@ CRSM::CRSM(QObject *parent) :
listC4Folders();
readScenarios();
+ setupCmds();
+
connect(&greetMapper, SIGNAL(mapped(QString)), this, SLOT(greet(QString)));
autoHost = settings["AutoHost"] == "true";
- //QString fifopath(settings["ClonkDirectory"]+"Clonk.log");
- //mkfifo(fifopath.toUtf8(),0666);
-
- connect(serverprocess, SIGNAL(readyReadStandardOutput()), this, SLOT(readServerOutput()));
+ connect(serverprocess, SIGNAL(readyRead()), this, SLOT(readServerOutput()));
connect(serverprocess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError()));
connect(serverprocess, SIGNAL(finished(int)), this, SLOT(scenarioFinished()));
- //int fp=open(fifopath.toUtf8(),O_RDONLY|O_NONBLOCK);
- //logfile=new QFile();
- //logfile->open(fp,QIODevice::ReadOnly);
- //QSocketNotifier *logNotifier = new QSocketNotifier(logfile->handle(),QSocketNotifier::Read,this);
QSocketNotifier *inNotifier = new QSocketNotifier(STDIN_FILENO,QSocketNotifier::Read,this);
connect(inNotifier, SIGNAL(activated(int)), this, SLOT(readInput()));
- //connect(logNotifier,SIGNAL(activated(int)),this, SLOT(readLog()));
QFile *reallog = new QFile(settings["ClonkDirectory"]+"CRSM.log");
- reallog->open(QIODevice::Append|QIODevice::Text);
+ reallog->open(QIODevice::Append | QIODevice::Text);
logstream.setDevice(reallog);
if(settings["UseIrc"] == "true")
@@ -90,9 +84,6 @@ 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")
@@ -123,10 +114,8 @@ void CRSM::readServerOutput()
*qout << what.trimmed() << endl;
if(!timeRemover.exactMatch(what))
return;
- what=timeRemover.cap(1).trimmed();
+ what = timeRemover.cap(1).trimmed();
- //*qout << what << endl;
- //QRegExp userexp("^<([^>]*)>\\s+(.*)");
QRegExp userexp("^>?\\s*<(.*)\\|(\\d+)\\|([^>]*)>\\s+(.*)$");
if(userexp.exactMatch(what))
{
@@ -134,197 +123,19 @@ void CRSM::readServerOutput()
QString pcName = userexp.cap(1);
QString cuid = userexp.cap(2);
ClientInfo& info = clients[pcName];
- if(user!=settings["ServerNick"])
+ if(user != settings["ServerNick"])
{
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")
- 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"
- "Von ¦ getrennten Werten ist einer auszuwählen.\n"
- "Weitere Befehle folgen.\n").arg(settings["UserListLength"]));
- if(command=="host")
+ QString command = commandExp.cap(1).trimmed();
+ QString commandArgs = commandExp.cap(2).trimmed();
+ if(!cmd(command, commandArgs, info))
{
- if(userlist.length()>=settings["UserListLength"].toInt())
- writeToServer(QString("Maximale Warteschlangenlänge von "+settings["UserListLength"]+" erreicht!\n"));
- else
- {
- if(commandArgs=="")
- writeToServer("Bitte gib einen Szenarionamen an!\n");
- else
- {
- //extractC4Folders();
- if(scenExists(commandArgs))
- {
- userlist << commandArgs;
- writeToServer("Szenario "+commandArgs+" wurde der Warteschlange hinzugefügt.\n");
- if(userlist.length() == 1 && session["userwish"] != "true" && session["running"] != "true")
- writeToServer("Überrede alle Spieler zu leaven und dein Wunsch wird sofort gehostet ;-)\n");
- }
- else
- {
- writeToServer(QString("Szenario \"" + commandArgs + "\" wurde nicht gefunden!\n"));
- }
- }
- }
- }
-
- if(command=="admin")
- {
- if(commandArgs!="")
- {
- if(commandArgs == settings["ServerNick"] || commandArgs == settings["ServerPCName"])
- {
- 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
- {
- writeToServer(QString(sessionAdmin.nick + " (" + sessionAdmin.pcName + ") ist bereits Rundenadmin!\n"));
- }
- }
- else
- {
- 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
- writeToServer(QString(sessionAdmin.nick + " (" + sessionAdmin.pcName + ") ist bereits Rundenadmin!\n"));
- }
+ respond(info, "Unbekannter Befehl: \"" + command + "\"!\n");
}
- /*if(command=="chatadmin")
- {
- if(commandArgs!="")
- {
- if(session["chatadmin"]==""||user==session["chatadmin"] || lists["Moderators"].contains(user))
- {
- session["chatadmin"]=commandArgs.trimmed();
- writeToServer(QString("Spieler "+commandArgs+" wurde als Chat-Rundenadmin eingetragen.\n"));
- }
- else
- {
- writeToServer(QString(session["chatadmin"]+" ist bereits Chat-Rundenadmin!\n"));
- }
- }
- else
- {
- if(session["chatadmin"]=="")
- {
- writeToServer(QString(user + " wurde als Chat-Rundenadmin eingetragen.\n"));
- }
- else
- writeToServer(QString(session["admin"]+" ist Chat-Rundenadmin!\n"));
- }
- }*/
-
- 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"))
- writeToServer(QString("/"+command+" "+commandArgs+"\n"));
- }
-
- else if(command=="queue")
- {
- writeToServer(printQueue());
- }
-
- else if(command=="list")
- {
- 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");
- }
}
else if(session["IrcUseIngameChat"] == "true")
{
@@ -332,12 +143,9 @@ void CRSM::readServerOutput()
}
}
}
-
QRegExp joinExp("^Client (.+) (?:verbunden|connected)\\.\\s*$");
- //joinExp.setMinimal(true);
if(joinExp.exactMatch(what))
{
- //waitinggreets << joinExp.cap(1);
QRegExp infoMatch("^<(.*)\\|(\\d+)\\|(.*)>$");
if(infoMatch.exactMatch(joinExp.cap(1)))
{
@@ -345,6 +153,7 @@ void CRSM::readServerOutput()
info.CUID = infoMatch.cap(2).toInt();
info.nick = infoMatch.cap(3);
info.pcName = infoMatch.cap(1);
+ info.interface = Clonk;
clients.insert(info.pcName, info);
QTimer *timer = new QTimer;
connect(timer, SIGNAL(timeout()), &greetMapper, SLOT(map()));
@@ -379,12 +188,11 @@ void CRSM::readServerOutput()
if(startExp.exactMatch(what))
{
writeToServer(QString("/set maxplayer 0\n"));
- session["running"]="true";
+ session["running"] = "true";
}
QRegExp leaveExp("^Client (.+) (?:entfernt|removed)(.*)");
- //leaveExp.setMinimal(true);
if(leaveExp.exactMatch(what))
{
QRegExp infoMatch("^<(.*)\\|(\\d+)\\|(.*)>$");
@@ -409,27 +217,27 @@ void CRSM::processError()
void CRSM::readInput()
{
QString what(qin->readLine());
- if(what=="/exit")
+ if(what == "/exit")
{
serverprocess->closeWriteChannel();
- finish=true;
+ finish = true;
cleanUp();
if(session["hosting"] != "true")
scenarioFinished();
return;
}
- if(what=="/exitafter")
+ if(what == "/exitafter")
{
- finish=true;
+ finish = true;
*qout << "Will exit after this round." << endl;
return;
}
- if(what=="/next")
+ if(what == "/next")
{
skipCurrent();
return;
}
- if(what=="/skip")
+ if(what == "/skip")
{
QString skipped;
if((skipped = skipScen()) != "")
@@ -441,19 +249,21 @@ void CRSM::readInput()
return;
}
- if(what=="/reload")
+ if(what == "/reload")
{
*qout << "Reloading config..." << endl;
lists.clear();
settings.clear();
ircModChecks.clear();
ircMods.clear();
+ ircModFifosOld.clear();
ircModIOList.clear();
+ ircStatusFifos.clear();
readConfig();
return;
}
- if(what=="/help") printAdditionalHelp();
+ if(what == "/help") printAdditionalHelp();
writeToServer(what+"\n");
}
@@ -469,7 +279,7 @@ void CRSM::nextScen()
else
{
startScen(scenlist.at(current), args);
- if(++current>=scenlist.length()) current = 0;
+ if(++current >= scenlist.length()) current = 0;
}
}
@@ -486,7 +296,7 @@ void CRSM::printAdditionalHelp()
void CRSM::readLog()
{
QString temp(logfile->readLine().trimmed());
- if(temp!="") logstream << temp << endl;
+ if(temp != "") logstream << temp << endl;
}
void CRSM::scenarioFinished()
@@ -506,6 +316,7 @@ void CRSM::scenarioFinished()
}
session.clear();
sessionAdmin = ClientInfo();
+ ircAdmin = ClientInfo();
clients.clear();
greeted.clear();
clientcount = 0;
@@ -539,17 +350,13 @@ void CRSM::ircMessageReceived(IrcMessage *message)
{
QString statusNick = split.at(1);
int status = split.at(2).toInt();
- if(ircModChecks.contains(statusNick))
+ if(ircStatusFifos.contains(statusNick))
{
- ircModChecks.removeAll(statusNick);
- if(status == 3 && lists["IrcModerators"].contains(statusNick))
- {
- ircMods.append(statusNick);
- ircModJoined(statusNick);
- }
- else
+ QList<QPair<ClientInfo, IrcCheckCallback>> &fifo = ircStatusFifos[statusNick];
+ while(fifo.size() > 0)
{
- ircModFifos.remove(statusNick);
+ (this->*fifo.first().second)(fifo.first().first, status, ClientInfo::ircClient(statusNick));
+ fifo.removeFirst();
}
}
}
@@ -568,111 +375,13 @@ void CRSM::ircMessageReceived(IrcMessage *message)
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();
+ QString command = args.first().trimmed();
args.removeFirst();
QString arg = args.join(" ").trimmed();
- if(cmd == "list")
- {
- /*foreach(const QString &line, listScenarios(arg).split('\n'))
- connection->sendCommand(IrcCommand::createMessage(message->nick(), line));*/
- connection->sendCommand(IrcCommand::createMessage(target, settings["IrcScenListMessage"]/*"Szenarioliste ist zurzeit nur in der Lobby und im laufenden Spiel verfügbar."*/));
- }
- else if(cmd == "autohost")
- {
- ircCheckModCmd(message->nick(), IrcModOperations::Autohost);
- }
- else if(cmd == "noautohost")
- {
- ircCheckModCmd(message->nick(), IrcModOperations::NoAutohost);
- }
- else if(cmd=="host")
- {
- if(userlist.length()>=settings["UserListLength"].toInt())
- connection->sendCommand(IrcCommand::createMessage(target, "Maximale Warteschlangenlänge von "+settings["UserListLength"]+" erreicht!"));
- else
- {
- if(arg=="")
- connection->sendCommand(IrcCommand::createMessage(target, "Bitte gib einen Szenarionamen an!"));
- else
- {
- if(scenExists(arg))
- {
- bool skipCurrent = false;
- if(userlist.isEmpty() && session["userwish"] != "true")
- skipCurrent = true;
- userlist << arg;
- connection->sendCommand(IrcCommand::createMessage(target, "Szenario " + arg + " wurde der Warteschlange hinzugefügt."));
- if(session["hosting"] != "true")
- nextScen();
- else if(clientcount == 0 && skipCurrent)
- {
- serverprocess->closeWriteChannel();
- }
- }
- else
- {
- 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")
+ const ClientInfo& client = ClientInfo::ircClient(message->nick(), target);
+ if(!cmd(command, arg, client))
{
- 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);
+ respond(client, "Unbekannter Befehl: \"" + command + "\"!");
}
}
else if(message->nick() == target && ircMods.contains(target))
@@ -706,7 +415,7 @@ void CRSM::ircMessageReceived(IrcMessage *message)
writeToServer("[IRC] " + message->nick() + " hat den Channel betreten." + "\n");
}
else
- ircCheckModCmd(message->nick(), IrcModOperations::CheckOnly);
+ ircCheckUserStatus(ClientInfo::ircClient(message->nick()), ClientInfo::ircClient(message->nick()), &CRSM::ircModCmd);
}
else if(message->type() == IrcMessage::Quit)
{
@@ -785,7 +494,7 @@ void CRSM::startScen(QString scen, QStringList argList)
void CRSM::readConfig()
{
QFile config(CONFIG_FILE_NAME);
- if(!config.exists()||!config.open(QIODevice::ReadOnly | QIODevice::Text))
+ if(!config.exists() || !config.open(QIODevice::ReadOnly | QIODevice::Text))
{
config.open(QIODevice::WriteOnly | QIODevice::Text);
settings = defaultSettings();
@@ -802,7 +511,7 @@ void CRSM::readConfig()
QString line;
for(;;)
{
- line=config.readLine().trimmed();
+ line = config.readLine().trimmed();
if(confPlusExp.exactMatch(line))
{
lists[confPlusExp.cap(1).trimmed()].push_back(confPlusExp.cap(2).trimmed());
@@ -843,10 +552,9 @@ void CRSM::readConfig()
}
}
*qout << endl;
- args=settings["Arguments"].split(" ");
+ args = settings["Arguments"].split(" ");
args << "/config:"+settings["ClonkConfig"];
}
- //settings["ClonkDirectory"]= QDir().absoluteFilePath(settings["ServerExecutable"]).replace(QRegExp("^(.*)"+QFileInfo(settings["ServerExecutable"]).fileName()+"$"),"\\1");
settings["ClonkDirectory"] = QFileInfo(settings["ServerExecutable"]).absoluteDir().absolutePath()+QDir::separator();
QFile clonkconfig(settings["ClonkConfig"]);
@@ -859,15 +567,14 @@ void CRSM::readConfig()
QRegExp pcNameExp("^\\s*LocalName=\"(.*)\"\\s*$");
foreach(const QString &line, QString(clonkconfig.readAll().trimmed()).split("\n"))
{
- //*qout << line << endl;
if(nickExp.exactMatch(line))
{
- settings["ServerNick"]=nickExp.cap(1);
+ settings["ServerNick"] = nickExp.cap(1);
break;
}
else if(pcNameExp.exactMatch(line))
{
- settings["ServerPCName"]=pcNameExp.cap(1);
+ settings["ServerPCName"] = pcNameExp.cap(1);
break;
}
}
@@ -916,31 +623,9 @@ QMap<QString, QString> CRSM::defaultSettings()
void CRSM::listC4Folders()
{
- /*// *qout << "Executable Setting: " << settings["ServerExecutable"] << endl;
- // *qout << "Path: " << clonkdir << endl;
- QDirIterator it(settings["ClonkDirectory"], QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
- bool extracting=false;
- for(;it.hasNext();it.next())
- {
- if(it.fileInfo().suffix()=="c4f"&&!it.fileInfo().isDir()&&!it.fileInfo().absoluteFilePath().contains(settings["ClonkDirectory"]+"Network/"))
- {
- if(!extracting)
- {
- extracting=true;
- *qout << endl << "Extracting scenario folders for hosting through Lobby..." << endl;
- }
- *qout << it.fileInfo().absoluteFilePath().replace(settings["ClonkDirectory"],"") << "..." << endl;
- QProcess c4group(this);
- QStringList c4gargs;
- c4gargs << it.fileInfo().absoluteFilePath() << "-u";
- c4group.start(settings["ClonkDirectory"]+"c4group",c4gargs);
- c4group.waitForFinished();
- }
- }
- if(extracting) *qout << endl;*/ //Old extracting is now replaced by listing the scenarios with c4group
*qout << "Listing Contents of C4Folders...";
QDirIterator it(settings["ClonkDirectory"], QDirIterator::FollowSymlinks);
- for(;it.hasNext();it.next())
+ for(; it.hasNext(); it.next())
{
if(it.fileName() == ".." || it.fileName() == ".")
continue;
@@ -966,13 +651,8 @@ void CRSM::cleanUp()
{
*qout << endl << "Cleaning up Clonk Folder..." << endl;
QDirIterator it(settings["ClonkDirectory"]+"Network/", QDirIterator::FollowSymlinks | QDirIterator::Subdirectories);
- for(;it.hasNext();it.next())
+ for(; it.hasNext(); it.next())
if(it.fileInfo().exists()) QFile(it.fileInfo().absoluteFilePath()).remove();
- /*QDirIterator lstIt(settings["ClonkDirectory"], QStringList() << "*.lst", QDir::NoFilter, QDirIterator::FollowSymlinks);
- for(;lstIt.hasNext();lstIt.next())
- if(!lists["IgnoreFolders"].contains(lstIt.fileInfo().baseName()))
- QFile(lstIt.fileInfo().absoluteFilePath()).remove();*/
-
*qout << endl;
}
@@ -1019,16 +699,16 @@ QString CRSM::listScenarios(QString commandArgs)
{
ret += "Folgende Szenarien stehen zur Auswahl:\n";
QDirIterator it(settings["ClonkDirectory"], QDirIterator::FollowSymlinks);
- for(;it.hasNext();it.next())
+ for(; it.hasNext(); it.next())
{
- if(it.fileInfo().suffix()=="c4s"&&!it.fileInfo().absoluteFilePath().contains(settings["ClonkDirectory"]+"Network/"))
+ if(it.fileInfo().suffix() == "c4s" && !it.fileInfo().absoluteFilePath().contains(settings["ClonkDirectory"]+"Network/"))
ret += QString(" "+it.fileInfo().absoluteFilePath().replace(settings["ClonkDirectory"],"")+"\n");
}
ret += "-----------------------------------------------------------------\nFolgende Ordner stehen zur Auswahl:\n";
QDirIterator folderIt(settings["ClonkDirectory"], QDirIterator::FollowSymlinks);
- for(;folderIt.hasNext();folderIt.next())
+ for(; folderIt.hasNext(); folderIt.next())
{
- if(folderIt.fileInfo().suffix()=="lst"&&!folderIt.fileInfo().absoluteFilePath().contains(settings["ClonkDirectory"]+"Network/") && !lists["IgnoreFolders"].contains(folderIt.fileInfo().baseName()))
+ if(folderIt.fileInfo().suffix() == "lst" && !folderIt.fileInfo().absoluteFilePath().contains(settings["ClonkDirectory"]+"Network/") && !lists["IgnoreFolders"].contains(folderIt.fileInfo().baseName()))
ret += QString(" "+folderIt.fileInfo().absoluteFilePath().left(folderIt.fileInfo().absoluteFilePath().length() - 4).replace(settings["ClonkDirectory"],"")+"\n");
}
}
@@ -1058,173 +738,33 @@ QString CRSM::listScenarios(QString commandArgs)
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)
+ QString ret;
+ if(userlist.length() == 0 && !autoHost)
+ return "Die Warteschlange ist leer.\n";
+ if(autoHost)
{
- if(c == QString("™"))
- ret.append(c);
- else
- ret.append(c.toLatin1());
+ 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;
-}*/
-
-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))
+ int i = 1;
+ foreach(const QString& scen, userlist)
{
- ircModChecks.append(nick);
- connection->sendCommand(IrcCommand::createMessage("NickServ", "STATUS " + nick));
+ ret += "\t" + QString::number(i) + ". " + scen + "\n";
+ ++i;
}
- 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;
}
+ return ret;
}
-void CRSM::ircModOperation(const QString &nick, QPair<CRSM::IrcModOperations, QString> operationArg)
+void CRSM::ircCheckModCmd(const QString &nick, CmdFunctionRef func, QString arg)
{
- ircModOperation(nick, operationArg.first, operationArg.second);
+ ircModFifos[nick].append(qMakePair<CmdFunctionRef, QString>(func, arg));
+ ircCheckUserStatus(ClientInfo::ircClient(nick), ClientInfo::ircClient(nick), &CRSM::ircModCmd);
}
QString CRSM::skipScen()
@@ -1248,12 +788,48 @@ void CRSM::writeToServer(const QString &message)
{
if(!serverprocess->isWritable())
return;
- serverprocess->write(codec->fromUnicode(message));
- if(settings["ServerUsesReadline"] == "true")
+ int i = 0;
+ QStringList split = message.split('\n', QString::KeepEmptyParts);
+ foreach(QString line, split)
{
- if(writtenToServer.length() > settings["ReadlineRereadLimit"].toInt())
- writtenToServer.clear();
- writtenToServer += codec->fromUnicode(message);
+ if(!line.isEmpty())
+ {
+ if(i < split.length() - 1)
+ line += "\n";
+ while(line.length() > 240)
+ {
+ QString linePart = line.left(240);
+ int pos = linePart.lastIndexOf(QRegExp("\\s"));
+ bool wordSplit = false;
+ if(pos <= 0)
+ {
+ pos = 240;
+ wordSplit = true;
+ }
+ linePart = line.left(pos);
+ line = line.right(line.length() - pos);
+ if(wordSplit)
+ {
+ linePart += "-";
+ }
+ linePart += "\n";
+ serverprocess->write(codec->fromUnicode(linePart));
+ if(settings["ServerUsesReadline"] == "true")
+ {
+ if(writtenToServer.length() > settings["ReadlineRereadLimit"].toInt())
+ writtenToServer.clear();
+ writtenToServer += codec->fromUnicode(linePart);
+ }
+ }
+ serverprocess->write(codec->fromUnicode(line));
+ if(settings["ServerUsesReadline"] == "true")
+ {
+ if(writtenToServer.length() > settings["ReadlineRereadLimit"].toInt())
+ writtenToServer.clear();
+ writtenToServer += codec->fromUnicode(line);
+ }
+ }
+ ++i;
}
}
@@ -1313,20 +889,6 @@ QString CRSM::addAliasWish(const QString &param)
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)
@@ -1440,3 +1002,571 @@ QStringList CRSM::listC4Folder(const QString &path)
}
return ret;
}
+
+void CRSM::addCommand(const QString &name, CmdFunction func, int interfaces, UserType userType, const QString &shortDescription, const QString &argList, const QString &longDescription)
+{
+ cmds.insert(name.trimmed(), CmdFunctionRef(name.trimmed(), func, interfaces, userType, shortDescription, argList, longDescription));
+}
+
+bool CRSM::cmdExists(const QString &name, ClientInterface interface)
+{
+ return cmds.contains(name) && cmds.value(name).interfaces & interface;
+}
+
+bool CRSM::cmd(const QString &name, const QString &args, const ClientInfo &client)
+{
+ if(cmdExists(name, client.interface))
+ {
+ const CmdFunctionRef& cmdRef = cmds.value(name);
+ switch(client.interface)
+ {
+ case Clonk:
+ if(clientUserType(client) >= cmdRef.userType)
+ {
+ (this->*cmdRef.func)(name, args, client, clientUserType(client));
+ }
+ else
+ {
+ rightsFailMessage(client, cmdRef.userType);
+ }
+ break;
+ case IRC:
+ if(cmdRef.userType == User || ((cmdRef.userType == Admin && (clientUserType(client) >= Admin)) || (cmdRef.userType == Moderator && clientUserType(client) >= Moderator)))
+ {
+ (this->*cmdRef.func)(name, args, client, clientUserType(client));
+ }
+ else if(cmdRef.userType >= Admin)
+ {
+ ircCheckModCmd(client.nick, cmdRef, args);
+ }
+ break;
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void CRSM::rightsFailMessage(const ClientInfo &info, UserType minUserType)
+{
+ respond(info, "Nur ein " + userTypeStrings.value(minUserType) + " kann diesen Befehl verwenden.\n", RespondType::Private);
+}
+
+UserType CRSM::clientUserType(const ClientInfo &client)
+{
+ switch(client.interface)
+ {
+ case Clonk:
+ if(lists["Moderators"].contains(QString::number(client.CUID)))
+ return Moderator;
+ if(sessionAdmin == client)
+ return Admin;
+ case IRC:
+ if(ircMods.contains(client.nick))
+ return Moderator;
+ if(ircAdmin == client)
+ return Admin;
+ }
+
+ return User;
+}
+
+void CRSM::setupCmds()
+{
+ addCommand("admin", &CRSM::admin, Clonk | IRC, User, "Ohne Name trägt es den Autor der Nachricht als Rundenadmin ein, bzw. mit Name den Spieler mit entsprechendem Namen, insofern nicht bereits ein Rundenadmin feststeht.", "[Chatnick¦PC-Name]");
+ addCommand("ingameadmin", &CRSM::ingameadmin, IRC, Admin, "Legt den Ingame-Rundenadmin fest.", "<Ingame-Nick¦PC-Name>");
+ if(settings["UseIrc"] == "true")
+ {
+ addCommand("ircadmin", &CRSM::ircadmin, Clonk, Admin, "Legt den IRC-Rundenadmin fest.", "<IRC-Nick>", "Legt den IRC-Rundenadmin fest. Der IRC-Admin kann über den IRC dieselben Aktionen durchführen wie der Ingame-Rundenadmin.");
+ }
+ addCommand("noadmin", &CRSM::noadmin, Clonk | IRC, Admin, "Entzieht dem (IRC-)Rundenadmin seine Rechte, damit jemand anders Rundenadmin sein kann.");
+ addCommand("aliaswish", &CRSM::aliaswish, Clonk | IRC, User, "Deponiert den Wunsch, <Alias> als Alias für <Szenario> einzutragen. Ein Moderator entscheidet darüber.", "<Alias> = <Szenario>");
+ if(settings["IrcUseIngameChat"] == "true")
+ {
+ addCommand("ircchat", &CRSM::ircchat, Clonk, Admin, "Schaltet den Irc-Ingame-Chat ein bzw. aus.", "<on¦off>");
+ addCommand("ingamechat", &CRSM::ircchat, IRC, Admin, "Schaltet den Irc-Ingame-Chat ein bzw. aus.", "<on¦off>");
+ }
+ addCommand("queue", &CRSM::queue, Clonk | IRC, User, "Zeigt die nächsten " + settings["UserListLength"] + " Szenarien auf der Warteliste.");
+ addCommand("host", &CRSM::host, Clonk | IRC, User, "Nimmt das angegebene Szenario in die Wunschliste auf.", "<Szenarioname¦Alias>");
+ addCommand("list", &CRSM::list, Clonk | IRC, User, "Listet alle definierten Aliase oder alle möglichen Szenarien und Ordner auf, bzw. alle Szenarien im Ordner oder Rundenordner.", "[Aliase¦Rundenordner[.c4f]]");
+ addCommand("clientlist", &CRSM::clientlist, Clonk | IRC, User, "Listet alle verbundenen Clients mit PC-Name und Chatnick auf.");
+ addCommand("help", &CRSM::help, Clonk | IRC, User, "Zeigt die Hilfe an.", "[long¦Befehlsname]", "Listet alle verfügbaren Befehle auf. Mit long werden alle verfügbaren Befehle mit Kurzbeschreibung aufgelistet.");
+ addCommand("stop", &CRSM::passToClonk, Clonk | IRC, Admin, "Stoppt einen laufenden Countdown.");
+ addCommand("start", &CRSM::passToClonk, Clonk | IRC, Admin, "Startet den Countdown.", "[Countdownzeit in s]");
+ addCommand("teamdist", &CRSM::passToClonk, Clonk | IRC, Admin, "Ändert die Teamverteilung.", "<none¦free¦host¦random¦radnominv>");
+ addCommand("plrteam", &CRSM::passToClonk, Clonk | IRC, Admin, "Ändert das Team eines Spielers.", "<Spieler> <neues Team>", "Verschiebt <Spieler> in das <neue Team>.");
+ addCommand("pause", &CRSM::passToClonk, Clonk | IRC, Admin, "Pausiert das Spiel.");
+ addCommand("unpause", &CRSM::passToClonk, Clonk | IRC, Admin, "Setzt das pausierte Spiel fort.");
+ addCommand("teamcolorson", &CRSM::passToClonk, Clonk | IRC, Admin, "Schaltet Teamfarben ein.");
+ addCommand("teamcolorsoff", &CRSM::passToClonk, Clonk | IRC, Admin, "Schaltet Teamfarben aus.");
+ addCommand("observer", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Der angegebene Host muss zuschauen.", "<PC-Name¦Chatnick>");
+ addCommand("deactivate", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Deaktiviert den angegebenen Host.", "<PC-Name¦Chatnick>");
+ addCommand("activate", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Aktiviert den angegebenen Host.", "<PC-Name¦Chatnick>");
+ addCommand("kick", &CRSM::pcNamePassToClonk, Clonk | IRC, Admin, "Kickt den angegebenen Host.", "<PC-Name¦Chatnick>");
+ addCommand("script", &CRSM::passToClonk, Clonk | IRC, Admin, "Führt das angegebene Script aus.", "<Script>");
+ addCommand("asyncctrl", &CRSM::passToClonk, Clonk | IRC, Admin, "Aktiviert den asynchronen Netzwerkmodus.");
+ addCommand("centralctrl", &CRSM::passToClonk, Clonk | IRC, Admin, "Aktiviert den zentralen Netzwerkmodus.");
+ addCommand("decentralctrl", &CRSM::passToClonk, Clonk | IRC, Admin, "Aktiviert den dezentralen Netzwerkmodus.");
+ addCommand("nodebug", &CRSM::passToClonk, Clonk | IRC, Admin, "Deaktiviert den Debug-Modus zwingend für alle.");
+ addCommand("autohost", &CRSM::autohost, Clonk | IRC, Moderator, "Deaktiviert den Debug-Modus zwingend für alle.");
+ addCommand("noautohost", &CRSM::autohost, Clonk | IRC, Moderator, "Deaktiviert den Debug-Modus zwingend für alle.");
+
+ addCommand("skip", &CRSM::skip, Clonk | IRC, Moderator, "Entfernt das nächste Szenario aus der Wunschliste.");
+ addCommand("next", &CRSM::next, Clonk | IRC, Moderator, "Versucht das aktuelle Szenario zu überspringen.");
+ addCommand("kill", &CRSM::kill, IRC, Moderator, "Tötet den Clonk-Server, vorausgesetzt es läuft einer.", "Tötet den Clonk-Server, vorausgesetzt es läuft einer. Bitte nur verwenden wenn " CMD_SIGN "next nicht funktioniert.");
+ addCommand("clear", &CRSM::clear, Clonk | IRC, Moderator, "Löscht die Wunschliste.");
+ addCommand("aliaswishes", &CRSM::aliaswishes, IRC, Moderator, "Zum geführten Bearbeiten der Aliaswünsche.");
+ addCommand("newalias", &CRSM::newalias, IRC, Moderator, "Trägt <Alias> als Alias für <Szenario> ein.", "<Alias> = <Szenario>");
+ addCommand("modinfo", &CRSM::modinfo, IRC, Moderator, "Listet alle Moderatoren auf.");
+ addCommand("io", &CRSM::io, IRC, Moderator, "Schaltet den IO-Modus ein bzw. aus.", "", "Schaltet den IO-Modus ein bzw. aus. Im IO-Modus wird die Ausgabe vom Clonk-Server an den Privat-Chat weitergeleitet und der Privat-Chat wird an den Clonk-Server weitergeleitet. Clonk-Befehle mit \\ statt /.");
+
+}
+
+void CRSM::respond(const ClientInfo &client, const QString &message, const RespondType type)
+{
+ switch(client.interface)
+ {
+ case Clonk:
+ writeToServer(message);
+ break;
+ case IRC:
+ foreach(const QString line, message.split('\n', QString::SkipEmptyParts))
+ {
+ switch(type)
+ {
+ case RespondType::Normal:
+ case RespondType::Private:
+ connection->sendCommand(IrcCommand::createMessage(type == Normal ? client.target : client.nick, line));
+ break;
+ case RespondType::Notice:
+ case RespondType::PrivateNotice:
+ connection->sendCommand(IrcCommand::createNotice(type == Notice ? client.target : client.nick, line));
+ break;
+ }
+ }
+ break;
+ }
+}
+
+void CRSM::ircCheckUserStatus(const ClientInfo &requester, const ClientInfo &subject, IrcCheckCallback callback)
+{
+ ircStatusFifos[subject.nick].append(qMakePair<ClientInfo, IrcCheckCallback>(requester, callback));
+ connection->sendCommand(IrcCommand::createMessage("NickServ", "STATUS " + subject.nick));
+}
+
+void CRSM::setIngameAdmin(const ClientInfo &client, const QString& newAdmin)
+{
+ if(clients.contains(newAdmin))
+ {
+ sessionAdmin = clients.value(newAdmin);
+ }
+ else
+ {
+ bool notFound = true, ambigous = false;
+ ClientInfo foundClient;
+ foreach(const ClientInfo& client, clients)
+ {
+ if(client.nick == newAdmin)
+ {
+ if(!notFound)
+ {
+ ambigous = true;
+ break;
+ }
+ foundClient = client;
+ notFound = false;
+ }
+ }
+ if(ambigous)
+ {
+ respond(client, "Chat-Nickname " + newAdmin + " ist nicht eindeutig. Bitte PC-Namen verwenden.\n");
+ return;
+ }
+ else if(notFound)
+ {
+ respond(client, newAdmin + " wurde nicht gefunden!\n");
+ return;
+ }
+ else if(sessionAdmin == foundClient)
+ {
+ respond(client, sessionAdmin.toString() + " ist bereits Rundenadmin!\n");
+ return;
+ }
+ else
+ {
+ sessionAdmin = foundClient;
+ }
+ respond(client, sessionAdmin.toString() + " wurde als Rundenadmin eingetragen.\n");
+ }
+}
+
+CMD_FUNCTION_IMPL(help)
+{
+ bool longHelp = args == "long";
+ if(args.isEmpty() || longHelp)
+ {
+ QString response = "Verfügbare Befehle: ";
+ UserType clientType = clientUserType(client);
+ foreach(const CmdFunctionRef& cmd, cmds)
+ {
+ if((cmd.interfaces & client.interface) == client.interface && clientType >= cmd.userType)
+ {
+ if(longHelp)
+ {
+ response += "\n" CMD_SIGN + cmd.name + QString(" ") + (!cmd.argList.isEmpty() ? cmd.argList + QString(" ") : QString("")) + (!cmd.shortDescription.isEmpty() ? QString("- ") + cmd.shortDescription : QString(""));
+ }
+ else
+ response += cmd.name + ", ";
+ }
+ }
+ if(!longHelp)
+ response = response.left(response.length() - 2);
+ respond(client, response + "\n");
+ respond(client, "Genauere Informationen zu einem Befehl mit " CMD_SIGN "help <Befehlsname>\n");
+ }
+ else
+ {
+ if(cmdExists(args, client.interface))
+ {
+ const CmdFunctionRef& cmd = cmds.value(args);
+ respond(client, CMD_SIGN + cmd.name + " " + (!cmd.argList.isEmpty() ? cmd.argList + " " : "") + (!cmd.longDescription.isEmpty() ? "- " + cmd.longDescription : !cmd.shortDescription.isEmpty() ? "- " + cmd.shortDescription : "") + "\n");
+ }
+ else
+ {
+ respond(client, "Befehl " + args + " existiert nicht.\n");
+ }
+ }
+}
+
+CMD_FUNCTION_IMPL(passToClonk)
+{
+ writeToServer('/' + cmd + ' ' + args + '\n');
+}
+
+CMD_FUNCTION_IMPL(admin)
+{
+ ClientInfo *interfaceAdminPtr;
+ switch(client.interface)
+ {
+ case Clonk:
+ interfaceAdminPtr = &sessionAdmin;
+ if(args == settings["ServerNick"] || args == settings["ServerPCName"])
+ {
+ respond(client, "Der Server kann nicht als Rundenadmin eingetragen werden!\n");
+ return;
+ }
+ break;
+ case IRC:
+ interfaceAdminPtr = &ircAdmin;
+ break;
+ default:
+ return;
+ }
+ ClientInfo& interfaceAdmin = *interfaceAdminPtr;
+ if(ircAdmin != ClientInfo() && userType < Admin)
+ {
+ respond(client, ircAdmin.toString() + (!ircAdmin.nick.isEmpty() && !sessionAdmin.nick.isEmpty() ? " und " : "") + sessionAdmin.toString() + " ist bereits Rundenadmin!\n");
+ return;
+ }
+ else if(args == "")
+ {
+ interfaceAdmin = client;
+ respond(client, client.toString() + " wurde als Rundenadmin eingetragen!\n");
+ return;
+ }
+ else if(client.interface == Clonk)
+ {
+ setIngameAdmin(client, args);
+ }
+ else if(client.interface == IRC)
+ {
+ ircCheckUserStatus(client, ClientInfo::ircClient(args), &CRSM::ircSetAdmin);
+ }
+}
+
+CMD_FUNCTION_IMPL(host)
+{
+ if(userlist.length() >= settings["UserListLength"].toInt())
+ respond(client, "Maximale Warteschlangenlänge von "+settings["UserListLength"]+" erreicht!\n");
+ else
+ {
+ if(args == "")
+ writeToServer("Bitte gib einen Szenarionamen an!\n");
+ else
+ {
+ if(scenExists(args))
+ {
+ userlist << args;
+ respond(client, "Szenario " + args + " wurde der Warteschlange hinzugefügt.\n");
+ if(userlist.length() == 1 && session["userwish"] != "true" && session["running"] != "true")
+ respond(client, "Überrede alle Spieler zu leaven und dein Wunsch wird sofort gehostet ;-)\n");
+ }
+ else
+ {
+ respond(client, "Szenario \"" + args + "\" wurde nicht gefunden!\n");
+ }
+ }
+ }
+}
+
+CMD_FUNCTION_IMPL(list)
+{
+ if(client.interface == Clonk)
+ {
+ respond(client, listScenarios(args));
+ }
+ else if(client.interface == IRC)
+ {
+ respond(client, settings["IrcScenListMessage"]);
+ }
+}
+
+CMD_FUNCTION_IMPL(queue)
+{
+ respond(client, printQueue(), RespondType::Notice);
+}
+
+CMD_FUNCTION_IMPL(aliaswish)
+{
+ respond(client, addAliasWish(args) + "\n");
+}
+
+CMD_FUNCTION_IMPL(ircchat)
+{
+ respond(client, ircActivateIngameChat(args.toLower() == "on") + "\n");
+}
+
+CMD_FUNCTION_IMPL(autohost)
+{
+ if(cmd == "autohost")
+ {
+ autoHost = true;
+ respond(client, "Automatisches Hosting aktiviert.\n");
+ if(session["hosting"] != "true")
+ {
+ nextScen();
+ }
+ }
+ else if(cmd == "noautohost")
+ {
+ autoHost = false;
+ respond(client, "Automatisches Hosting deaktiviert.\n");
+ }
+
+}
+
+CMD_FUNCTION_IMPL(skip)
+{
+ QString skipped;
+ if((skipped = skipScen()) != "")
+ {
+ respond(client, "\"" + skipped + "\" übersprungen.\n");
+ }
+ else
+ {
+ respond(client, "Userliste ist leer!\n");
+ }
+}
+
+CMD_FUNCTION_IMPL(next)
+{
+ skipCurrent();
+ respond(client, "Versuche zu überspringen...\n");
+}
+
+CMD_FUNCTION_IMPL(kill)
+{
+ serverprocess->kill();
+ respond(client, "Clonk-Server wurde gekillt.\n");
+}
+
+CMD_FUNCTION_IMPL(clear)
+{
+ if(userlist.length() > 0)
+ {
+ userlist.clear();
+ respond(client, "Userliste geleert.\n");
+ }
+ else
+ {
+ respond(client, "Userliste ist leer!\n");
+ }
+}
+
+CMD_FUNCTION_IMPL(aliaswishes)
+{
+ if(aliasWishEditor == "")
+ {
+ aliasWishEditor = client.nick;
+ if(ircModIOList.contains(client.nick))
+ respond(client, "IO-Eingabe ist während dem Aliaswünsche-Bearbeiten deaktiviert.\n", RespondType::Private);
+ editAliasWishes();
+ }
+ else
+ respond(client, aliasWishEditor + " bearbeitet bereits die Aliase. Danke für die Bemühung.\n", RespondType::Private);
+}
+
+CMD_FUNCTION_IMPL(newalias)
+{
+ QRegExp aliasExp("^([^=]+)=(.*)$");
+ if(aliasExp.exactMatch(args))
+ {
+ const QString &scen = aliasExp.cap(2).trimmed();
+ const QString &alias = aliasExp.cap(1).trimmed();
+ if(scenExists(scen))
+ {
+ if(maps["AliasWishes"].contains(alias))
+ {
+ respond(client, "Aliaswunsch für \"" + maps["AliasWishes"].value(alias) + "\" entfernt und Alias hinzugefügt!\n");
+ maps["AliasWishes"].remove(alias);
+ }
+ else if(maps["Alias"].contains(alias))
+ {
+ respond(client, "Alias für \"" + maps["Alias"][alias] + "\" überschrieben!\n");
+ }
+ else
+ {
+ respond(client, "Alias hinzugefügt!\n");
+ }
+ maps["Alias"][alias] = scen;
+ }
+ else
+ respond(client, "Szenario \"" + scen + "\" wurde nicht gefunden!\n");
+ }
+ else
+ respond(client, "Eingabefehler! Siehe !help newalias für mehr Informationen.\n");
+}
+
+CMD_FUNCTION_IMPL(modinfo)
+{
+ respond(client, "Moderatoren sind (* ist aktiv, + verwendet IO):\n", RespondType::Private);
+ foreach(const QString &mod, lists["IrcModerators"])
+ {
+ respond(client, (ircMods.contains(mod) ? QString("*") : QString(" ")) + (ircModIOList.contains(mod) ? QString("+") : QString(" ")) + " " + mod + "\n", RespondType::Private);
+ }
+}
+
+CMD_FUNCTION_IMPL(io)
+{
+ if(ircModIOList.contains(client.nick))
+ ircModIOList.removeAll(client.nick);
+ else
+ ircModIOList.append(client.nick);
+}
+
+CMD_FUNCTION_IMPL(pcNamePassToClonk)
+{
+ ClientInfo info;
+ if(clients.contains(args))
+ {
+ info = clients.value(args);
+ }
+ else
+ {
+ bool notFound = true, ambigous = false;
+ ClientInfo foundClient;
+ foreach(const ClientInfo& client, clients)
+ {
+ if(client.nick == args)
+ {
+ if(!notFound)
+ {
+ ambigous = true;
+ break;
+ }
+ foundClient = client;
+ notFound = false;
+ }
+ }
+ if(ambigous)
+ {
+ respond(client, "Chat-Nickname " + args + " ist nicht eindeutig. Bitte PC-Namen verwenden.\n");
+ return;
+ }
+ else if(notFound)
+ {
+ respond(client, args + " wurde nicht gefunden!\n");
+ return;
+ }
+ else
+ {
+ info = foundClient;
+ }
+ }
+ if(cmd == "kick" && clientUserType(info) > userType)
+ {
+ respond(client, "Moderatoren können nur von anderen Moderatoren gekickt werden.\n");
+ return;
+ }
+ writeToServer("/" + cmd + " " + info.pcName + "\n");
+}
+
+CMD_FUNCTION_IMPL(ircadmin)
+{
+ ircCheckUserStatus(client, ClientInfo::ircClient(args), &CRSM::ircSetAdmin);
+}
+
+CMD_FUNCTION_IMPL(ingameadmin)
+{
+ setIngameAdmin(client, args);
+}
+
+CMD_FUNCTION_IMPL(noadmin)
+{
+ ircAdmin = ClientInfo();
+ sessionAdmin = ClientInfo();
+ respond(client, "Rundenadmin wurde freigegeben.\n");
+}
+
+CMD_FUNCTION_IMPL(clientlist)
+{
+ QString response = "Verbundene Clients (Chatnick (PC-Name)): ";
+ foreach(const ClientInfo& connectedClient, clients)
+ {
+ if(connectedClient.nick.isEmpty())
+ continue;
+ response += connectedClient.toString() + ", ";
+ }
+ response = response.left(response.length() - 2);
+ respond(client, response + "\n");
+}
+
+IRC_CHECK_CALLBACK_IMPL(ircSetAdmin)
+{
+ if(status <= 0)
+ {
+ respond(requester, "IRC-Nutzer " + subject.toString() + " wurde nicht gefunden!\n");
+ }
+ else
+ {
+ ircAdmin = subject;
+ respond(requester, subject.toString() + " wurde als Rundenadmin eingetragen.\n");
+ }
+}
+
+IRC_CHECK_CALLBACK_IMPL(ircModCmd)
+{
+ if(status == 3)
+ {
+ ircMods.append(subject.nick);
+ QList<QPair<CmdFunctionRef, QString>> &fifo = ircModFifos[subject.nick];
+ while(fifo.size() > 0)
+ {
+ (this->*fifo.first().first.func)(fifo.first().first.name, fifo.first().second, subject, clientUserType(subject));
+ fifo.removeFirst();
+ }
+ if(!maps["AliasWishes"].isEmpty())
+ {
+ respond(subject, 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.", RespondType::PrivateNotice);
+ respond(subject, "Bitte bei nächster Gelegenheit mit " CMD_SIGN "aliaswishes bearbeiten.", RespondType::PrivateNotice);
+ }
+ }
+ else
+ {
+ rightsFailMessage(subject, ircModFifos[subject.nick].first().first.userType);
+ ircModFifos.remove(subject.nick);
+ }
+}
diff --git a/crsm.h b/crsm.hpp
index 249a36d..de90241 100644
--- a/crsm.h
+++ b/crsm.hpp
@@ -16,19 +16,25 @@
#include <IrcCommand>
#include <QSignalMapper>
-#include "ClientInfo.hpp"
+#include "CmdFunctionRef.hpp"
#define CONFIG_FILE_NAME "CrServerManager.conf"
#define CUR_SCEN_FILE_NAME "curscen.txt"
#define LAST_SCEN_FILE_NAME "lastscen.txt"
#define SCOREBOARD_FILE_NAME settings["ClonkDirectory"] + "scoreboard.html"
+#define IRC_CHECK_CALLBACK(name) void name(const ClientInfo& requester, int status, const ClientInfo& subject)
+#define IRC_CHECK_CALLBACK_IMPL(name) void CRSM::name(const ClientInfo& requester, int status, const ClientInfo& subject)
+
#ifdef Q_OS_LINUX64
#define C4GROUP_EXECUTABLE "c4group64"
#else
#define C4GROUP_EXECUTABLE "c4group"
#endif
+class CRSM;
+typedef void (CRSM::*IrcCheckCallback)(const ClientInfo&, int, const ClientInfo&);
+
class CRSM : public QObject
{
private:
@@ -49,6 +55,12 @@ private:
IngameChat
};
+ enum RespondType {
+ Normal,
+ Notice,
+ Private,
+ PrivateNotice
+ };
Q_OBJECT
public:
@@ -76,9 +88,11 @@ private:
QStringList args;
QStringList ircModChecks;
QStringList ircMods;
+ QMap<QString, QList<QPair<ClientInfo, IrcCheckCallback>>> ircStatusFifos;
+ QMap<QString, QList<QPair<CmdFunctionRef, QString>>> ircModFifos;
+ QMap<QString, QList<QPair<IrcModOperations, QString>>> ircModFifosOld;
QString aliasWishEditor = "";
QString currentAliasWish = "";
- QMap<QString, QList<QPair<IrcModOperations, QString>>> ircModFifos;
int current;
QTextStream *qout;
QTextStream *qin;
@@ -94,11 +108,13 @@ private:
bool autoHost = true;
QSignalMapper greetMapper;
ClientInfo sessionAdmin;
+ ClientInfo ircAdmin;
QFile *logfile;
QTextStream logstream;
QTextCodec *codec;
QStringList ircModIOList;
QString writtenToServer;
+ QMap<QString, CmdFunctionRef> cmds;
void startScen(QString, QStringList);
void readConfig();
@@ -109,20 +125,55 @@ private:
bool scenExists(QString filePath);
QString listScenarios(QString commandArgs);
QString printQueue();
- //QByteArray toClonkFormat(const QString&);
- void ircCheckModCmd(const QString &nick, IrcModOperations operation, QString arg = "");
- void ircModOperation(const QString &nick, IrcModOperations operation, QString arg);
- void ircModOperation(const QString &nick, QPair<IrcModOperations, QString> operationArg);
+ void ircCheckModCmd(const QString &nick, CmdFunctionRef func, QString arg = "");
QString skipScen();
void skipCurrent();
void writeToServer(const QString& message);
void writeConfig();
QString addAliasWish(const QString& param);
- void ircModJoined(const QString& nick);
void informModsAboutAliasWish();
void editAliasWishes();
void editAliasWishes(const QString &message);
void stopAliasWishEditing();
QString ircActivateIngameChat(bool activated = true);
QStringList listC4Folder(const QString &path);
+
+ void addCommand(const QString& name, CmdFunction func, int interfaces = Clonk | IRC, UserType userType = User, const QString& shortDescription = "", const QString &argList = "", const QString &longDescription = "");
+ bool cmdExists(const QString& name, ClientInterface interface);
+ bool cmd(const QString& name, const QString& args, const ClientInfo& client);
+ void rightsFailMessage(const ClientInfo& info, UserType minUserType);
+ UserType clientUserType(const ClientInfo& client);
+
+ void setupCmds();
+
+ void respond(const ClientInfo& client, const QString& message, const RespondType type = Normal);
+ void ircCheckUserStatus(const ClientInfo& requester, const ClientInfo& subject, IrcCheckCallback callback);
+ void setIngameAdmin(const ClientInfo &client, const QString& newAdmin);
+
+ CMD_FUNCTION(help);
+ CMD_FUNCTION(passToClonk);
+ CMD_FUNCTION(admin);
+ CMD_FUNCTION(host);
+ CMD_FUNCTION(list);
+ CMD_FUNCTION(queue);
+ CMD_FUNCTION(aliaswish);
+ CMD_FUNCTION(ircchat);
+ CMD_FUNCTION(autohost);
+ CMD_FUNCTION(skip);
+ CMD_FUNCTION(next);
+ CMD_FUNCTION(kill);
+ CMD_FUNCTION(clear);
+ CMD_FUNCTION(aliaswishes);
+ CMD_FUNCTION(newalias);
+ CMD_FUNCTION(modinfo);
+ CMD_FUNCTION(io);
+ CMD_FUNCTION(pcNamePassToClonk);
+ CMD_FUNCTION(ingameadmin);
+ CMD_FUNCTION(ircadmin);
+ CMD_FUNCTION(noadmin);
+ CMD_FUNCTION(clientlist);
+
+ IRC_CHECK_CALLBACK(ircSetAdmin);
+ IRC_CHECK_CALLBACK(ircModCmd);
};
+
diff --git a/main.cpp b/main.cpp
index cffbf9a..5eed945 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,5 +1,5 @@
#include <QCoreApplication>
-#include "crsm.h"
+#include "crsm.hpp"
int main(int argc, char *argv[])
{