From 3fe710cb029522b86ef27c322f0cb793b1368051 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Tue, 21 Mar 2017 22:00:59 +0100 Subject: Move Parser into own class --- src/crsm.cpp | 359 +++++++++++++++++++++++++---------------------------------- 1 file changed, 150 insertions(+), 209 deletions(-) (limited to 'src/crsm.cpp') diff --git a/src/crsm.cpp b/src/crsm.cpp index e887836..754e73c 100644 --- a/src/crsm.cpp +++ b/src/crsm.cpp @@ -12,8 +12,10 @@ #define MGMT_BUFFER_FILENAME "CRSM-MGMT-Buffer" CRSM::CRSM(QObject *parent) : - QObject(parent), Session(this) + QObject(parent), Session(this), parser(Session) { + parser.addTarget(this); + qsrand((uint)QDateTime::currentMSecsSinceEpoch()); codec = QTextCodec::codecForName("Windows-1252"); @@ -212,261 +214,200 @@ QString CRSM::findClientByName(ClientInfo &info, const QString &name) } } -void CRSM::readServerOutput() +void CRSM::lobbyCountdown(unsigned int seconds) { - QString what(processManager->readLine().trimmed()); + Session.CountDown = (int)seconds; +} - if(Config.Readline.ServerUses) - { - while(writtenToServer.length() > 0 && what.length() > 0 && writtenToServer.at(0) == what.at(0)) - { - writtenToServer.remove(0, 1); - what.remove(0, 1); - } +void CRSM::lobbyCountdownAborted() +{ + Session.CountDown = -1; +} - if(what.at(0) == '>') - { - what.remove(0, 1); - } - what = what.trimmed(); +void CRSM::watchdog(const QString& id) +{ + if(id == watchDogString) + { + watchDogString.clear(); + watchDogTimer.start(Config.Clonk.Server.Watchdog.Interval * 1000); } +} - if(what.isEmpty()) - return; - - if(Config.IRC.Use) +void CRSM::clientMessage(ClientInfo& client, const QString& message, ClonkOutputInterface::MessageType type, const QTime& time) +{ + bool isMeMessage = (type == Action); + if(type == Sound) { - foreach(const QString &mess, what.split("\n", QString::SkipEmptyParts)) - foreach(const QString &mod, ircModIOList) - { - sendIrcMessage(mess, mod, false, true, true); - } + Log.clonkChatLog("Sound: " + client.toString(true, true) + " " + message); } - out(what + "\n"); - if(what.length() < 12 || what.at(0) != '[' || what.at(9) != ']' || what.at(10) != ' ') + else if(isMeMessage) { - return; + Log.clonkChatLog("* " + client.toString(true, true) + " " + message); } - - const QTime& msgTime = QTime::fromString(what.mid(1, 8), "hh:mm:ss"); - what = what.mid(11); - - Log.clonkLog(what); - - if(what.length() > 5 && what.midRef(3, 2) == ": ") + else { - const QString& type = what.left(3); - what = what.mid(5); - - static ClientInfo* playerInfoClient = nullptr; - - if(type == "Plr" && playerInfoClient != nullptr) - { - playerInfoClient->players.append(what); - } - else - { - playerInfoClient = nullptr; - - if(type == "Cnt") - { - Session.CountDown = what.toInt(); - return; - } - } - - if(type == "Prm") - { - if(Session.Clonk.Server.players.contains(what)) - { - Session.Clonk.Server.players.removeAll(what); - return; - } - - for(ClientInfo& client : Session.Clonk.Clients) - { - if(client.players.contains(what)) - { - client.players.removeAll(what); - return; - } - } - return; - } - - if(type == "Wtd") - { - if(what == watchDogString) - { - watchDogString.clear(); - watchDogTimer.start(Config.Clonk.Server.Watchdog.Interval * 1000); - } - return; - } + Log.clonkChatLog(client.toString(true, true) + " " + message); + } - ClientInfo* clientPtr = parseClientInfo(what); - if(clientPtr == nullptr) + if(client.pcName != Config.Auto.Volatile.Clonk.ServerPCName) + { + Log.clonkUserLog(message, client, isMeMessage); + if(client == Session.Clonk.Admin) { - return; + checkActivity(Session.Clonk.Admin); } - ClientInfo& client = *clientPtr; - - if(type == "Pli" || type == "Pla") + if(client.floodCheck(Config.Clonk.Chat.AntiFlood.Count, Config.Clonk.Chat.AntiFlood.Time, QDateTime(QDate::currentDate(), time))) { - playerInfoClient = clientPtr; - - if(type == "Pli") - { - playerInfoClient->players.clear(); - } + kick(client.pcName, "Flooding! Maximal " + QString::number(Config.Clonk.Chat.AntiFlood.Count) + " Nachrichten in " + QString::number(Config.Clonk.Chat.AntiFlood.Time) + "s"); } - else if(clientPtr == &Session.Clonk.Server) + else if(type == Sound) { return; } - - if(type == "Msg" || type == "Mac" || type == "Snd") + else if(!isMeMessage) { - bool isMeMessage = (type == "Mac"); - if(type == "Snd") - { - Log.clonkChatLog("Sound: " + client.toString(true, true) + " " + what); - } - else if(isMeMessage) - { - Log.clonkChatLog("* " + client.toString(true, true) + " " + what); - } - else - { - Log.clonkChatLog(client.toString(true, true) + " " + what); - } - - if(client.pcName != Config.Auto.Volatile.Clonk.ServerPCName) + QString command = getCommand(message); + if(!command.isEmpty()) { - Log.clonkUserLog(what, client, isMeMessage); - if(client == Session.Clonk.Admin) - { - checkActivity(Session.Clonk.Admin); - } - if(client.floodCheck(Config.Clonk.Chat.AntiFlood.Count, Config.Clonk.Chat.AntiFlood.Time, QDateTime(QDate::currentDate(), msgTime))) - { - kick(client.pcName, "Flooding! Maximal " + QString::number(Config.Clonk.Chat.AntiFlood.Count) + " Nachrichten in " + QString::number(Config.Clonk.Chat.AntiFlood.Time) + "s"); - } - else if(type == "Snd") + if(!cmd(command, client)) { - return; + respond(client, "Unbekannter Befehl: \"" + command + "\"!\n"); } - else if(!isMeMessage) - { - QString command = getCommand(what); - if(!command.isEmpty()) - { - if(!cmd(command, client)) - { - respond(client, "Unbekannter Befehl: \"" + command + "\"!\n"); - } - } - else if(Session.IRC.UseIngameChat) - { - sendIrcMessage("[Clonk]<" + client.nick+ "> " + what, Config.IRC.IngameChannel, false, false); - } - } - else if(Session.IRC.UseIngameChat) - { - sendIrcMessage("[Clonk] " + client.nick + " " + what, Config.IRC.IngameChannel, true, false); - } } - } - else if(type == "Con") - { - QTimer *timer = new QTimer; - connect(timer, SIGNAL(timeout()), &greetMapper, SLOT(map())); - connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); - greetMapper.setMapping(timer, client.pcName); - timer->start(1000); - if(Session.IRC.UseIngameChat) + else if(Session.IRC.UseIngameChat) { - sendIrcMessage("[Clonk] " + client.toString() + " verbunden.", Config.IRC.IngameChannel, false, false); + sendIrcMessage("[Clonk]<" + client.nick+ "> " + message, Config.IRC.IngameChannel, false, false); } } - else if(type == "Act" || type == "Dct") + else if(Session.IRC.UseIngameChat) { - client.activated = type == "Act"; + sendIrcMessage("[Clonk] " + client.nick + " " + message, Config.IRC.IngameChannel, true, false); } - else if(type == "Rem") - { - writeToServer(QString(client.nick +" ist ein L34V0R!\n")); + } +} - if(Session.IRC.UseIngameChat) - { - sendIrcMessage("[Clonk] " + client.toString() + " entfernt (" + what + ").", Config.IRC.IngameChannel, false, false); - } +void CRSM::clientConnected(const ClientInfo& client) +{ + QTimer *timer = new QTimer; + connect(timer, SIGNAL(timeout()), &greetMapper, SLOT(map())); + connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); + greetMapper.setMapping(timer, client.pcName); + timer->start(1000); + if(Session.IRC.UseIngameChat) + { + sendIrcMessage("[Clonk] " + client.toString() + " verbunden.", Config.IRC.IngameChannel, false, false); + } +} - if(client == Session.Clonk.Admin) - { - Session.Clonk.LeaveAdmins.insert(client, QDateTime::currentDateTime()); - afkAdminTimer.stop(); - Session.AfkAdmin = false; - writeToServer("Rundenadmin wurde freigegeben.\n"); - Session.Clonk.Admin.clear(); - } +void CRSM::clientRemoved(const ClientInfo& client, const QString& reason) +{ + writeToServer(QString(client.nick +" ist ein L34V0R!\n")); - Session.Clonk.Clients.remove(client.pcName); + if(Session.IRC.UseIngameChat) + { + sendIrcMessage("[Clonk] " + client.toString() + " entfernt (" + reason + ").", Config.IRC.IngameChannel, false, false); + } - if(Session.Clonk.Clients.size() == 0 && ((userlist.length() > 0 && !Session.UserWish) || (Session.State == CRSMSession::Running || Session.State == CRSMSession::Loading))) - { - processManager->closeProgFifos(); - } - else if(Session.Clonk.Clients.size() == 0 && Config.Clonk.Server.EmptyTimer != -1 && (Session.CountDown == -1 || Session.CountDown > Config.Clonk.Server.EmptyTimer)) - { - writeToServer("/start " + QString::number(Config.Clonk.Server.EmptyTimer) + "\n"); - } - } - return; + if(client == Session.Clonk.Admin) + { + Session.Clonk.LeaveAdmins.insert(client, QDateTime::currentDateTime()); + afkAdminTimer.stop(); + Session.AfkAdmin = false; + writeToServer("Rundenadmin wurde freigegeben.\n"); + Session.Clonk.Admin.clear(); } - if((what == "Los geht's!" || what == "Action go!") && Session.State == CRSMSession::Lobby) + Session.Clonk.Clients.remove(client.pcName); + + if(Session.Clonk.Clients.size() == 0 && ((userlist.length() > 0 && !Session.UserWish) || (Session.State == CRSMSession::Running || Session.State == CRSMSession::Loading))) { - setSessionState(CRSMSession::Loading); - return; + processManager->closeProgFifos(); } + else if(Session.Clonk.Clients.size() == 0 && Config.Clonk.Server.EmptyTimer != -1 && (Session.CountDown == -1 || Session.CountDown > Config.Clonk.Server.EmptyTimer)) + { + writeToServer("/start " + QString::number(Config.Clonk.Server.EmptyTimer) + "\n"); + } +} - if(what == "Start!") +void CRSM::gameLoading() +{ + setSessionState(CRSMSession::Loading); +} + +void CRSM::gameStarted() +{ + Stats.AddScenarioStart(Session.Scenario.wishClient, scenarioFileName(Session.Scenario.name)); + if(!Session.League) { - Stats.AddScenarioStart(Session.Scenario.wishClient, scenarioFileName(Session.Scenario.name)); - if(!Session.League) - { - writeToServer(QString("/set maxplayer 0\n")); - } - setSessionState(CRSMSession::Running); - watchdog(); - return; + writeToServer(QString("/set maxplayer 0\n")); } + setSessionState(CRSMSession::Running); + watchdog(); +} - if(what == "Spielstart abgebrochen." || what == "Game start aborted.") +void CRSM::masterserverError(const QString& msg) +{ + userlist.clear(); + if(autoHost && !hostingIsErrorDeactivated) { - Session.CountDown = -1; - return; + hostingIsErrorDeactivated = true; + gameRegisterFailTimer.start(); } + autoHost = false; + static const QString gameRegisterFailMessage = "Aufgrund eines Problems beim Registrieren des Spiels am Masterserver (%1) wird Hosting temporär (für 5 Minuten) deaktiviert.\n"; + announceInfo(gameRegisterFailMessage.arg(msg)); +} - for(const QString& text : {"Spiel konnte nicht registriert werden: ", "Could not register game: ", "FATALER FEHLER: Liga konnte nicht initialisiert werden: ", "FATAL ERROR: Could not initialize league: "}) +void CRSM::raw(const QString &line) +{ + if(Config.IRC.Use) { - if(what.startsWith(text)) - { - QString reason = what.mid(text.length()); - userlist.clear(); - if(autoHost && !hostingIsErrorDeactivated) + foreach(const QString &mess, line.split("\n", QString::SkipEmptyParts)) + foreach(const QString &mod, ircModIOList) { - hostingIsErrorDeactivated = true; - gameRegisterFailTimer.start(); + sendIrcMessage(mess, mod, false, true, true); } - autoHost = false; - static const QString gameRegisterFailMessage = "Aufgrund eines Problems beim Registrieren des Spiels am Masterserver (%1) wird Hosting temporär (für 5 Minuten) deaktiviert.\n"; - announceInfo(gameRegisterFailMessage.arg(reason)); - return; + } + out(line + "\n"); +} + +void CRSM::rawTimed(const QString &line, const QTime &time) +{ + Q_UNUSED(time); + Log.clonkLog(line); +} + +void CRSM::playerRemoved(const QString& name) +{ + Q_UNUSED(name); +} + +void CRSM::readServerOutput() +{ + QString what(processManager->readLine().trimmed()); + + if(Config.Readline.ServerUses) + { + 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); } + what = what.trimmed(); } + + if(what.isEmpty()) + { + return; + } + + parser.parseMessage(what); } void CRSM::nextScen() @@ -1608,7 +1549,7 @@ void CRSM::setupCmds() addCommand("admin clear", &CRSM::noadmin, Clonk | IRC | Management, Admin, "Entzieht dem (IRC-)Rundenadmin seine Rechte, damit jemand anders Rundenadmin sein kann."); addCommandGroup("client", Clonk | IRC | Management, User, "Verwaltet die verbundenen Clients."); - addCommand("client list", &CRSM::clientlist, IRC | Management, User, "Listet alle verbundenen Clients auf."); + addCommand("client list", &CRSM::clientlist, IRC | Management, User, "Listet alle verbundenen Clients auf."); // TODO: optional player list addCommand("client kick", &CRSM::passToClonkPcNameGrouped, Clonk | IRC | Management, Admin, "Kickt den angegebenen Client.", ""); addCommand("client observer", &CRSM::passToClonkPcNameGrouped, Clonk | IRC | Management, Admin, "Der angegebene Client muss zuschauen.", ""); addCommand("client deactivate", &CRSM::passToClonkPcNameGrouped, Clonk | IRC | Management, Admin, "Deaktiviert den angegebenen Client.", ""); @@ -2604,7 +2545,7 @@ CMD_FUNCTION_IMPL(admin) } else if(client.interface == IRC) { - ircCheckUserStatus(client, ClientInfo::ircClient(args), &CRSM::ircSetAdmin); + ircCheckUserStatus(client, ClientInfo::ircClient(args), &CRSM::ircSetAdmin); // use ISON? } return Success; } -- cgit v1.2.3-54-g00ecf