#include "PatchedClonkParser.hpp" PatchedClonkParser::PatchedClonkParser(CRSMSession& session) : ClonkParser(session) { } namespace { void parseClientInfo(QString& message, QString& pcName, QString& user) { if(!message.isEmpty() && message.at(0) == '\\') { QString parts[2]; for(int i = 1, part = 0; i < message.length() && part < 2; ++i) { bool last = (i == message.length() -1); QChar c = message.at(i); QChar next = '\0'; if(!last) { next = message.at(i + 1); } if(c == '\\') { if((last || next == ' ') && part == 1) { message = message.mid(i + 2); pcName = parts[0]; user = parts[1]; return; } else { if(next == '\\' || next == '"') { i += 2; parts[part].append(next); } else { ++part; } } } else { parts[part].append(c); } } } } }; void PatchedClonkParser::parseMessage(const QString &line) { QString what = line; raw(what); if(what.length() < 12 || what.at(0) != '[' || what.at(9) != ']' || what.at(10) != ' ') { return; } const QTime& msgTime = QTime::fromString(what.mid(1, 8), "hh:mm:ss"); what = what.mid(11); rawTimed(what, msgTime); if(what.length() > 5 && what.midRef(3, 2) == ": ") { 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") { lobbyCountdown(what.toUInt()); 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; } } playerRemoved(what); return; } if(type == "Wtd") { watchdog(what); return; } QString pcName, user; parseClientInfo(what, pcName, user); if(pcName.isEmpty()) { return; } ClientInfo& client = getClientInfo(pcName, user); if(type == "Pli" || type == "Pla") { playerInfoClient = &client; if(type == "Pli") { playerInfoClient->players.clear(); } } else if(&client == &Session.Clonk.Server) { return; } if(type == "Msg" || type == "Mac" || type == "Snd") { ClonkOutputInterface::MessageType msgType = ClonkOutputInterface::Message; if(type == "Mac") { msgType = ClonkOutputInterface::Action; } else if(type == "Snd") { msgType = ClonkOutputInterface::Sound; } clientMessage(client, what, msgType, msgTime); } else if(type == "Con") { clientConnected(client); } else if(type == "Act" || type == "Dct") { clientStateChanged(client, type == "Act"); client.activated = type == "Act"; } else if(type == "Rem") { clientRemoved(client, what); } return; } if((what == "Los geht's!" || what == "Action go!") && Session.State == CRSMSession::Lobby) { gameLoading(); return; } if(what == "Start!") { gameStarted(); return; } if(what == "Spielstart abgebrochen." || what == "Game start aborted.") { lobbyCountdownAborted(); return; } 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: "}) { if(what.startsWith(text)) { masterserverError(what.mid(text.length())); return; } } } ClientInfo &PatchedClonkParser::getClientInfo(const QString &pcName, const QString &user) { if(pcName == Session.Clonk.Server.pcName) { return Session.Clonk.Server; } if(!Session.Clonk.Clients.contains(pcName)) { Session.Clonk.Clients.insert(pcName, ClientInfo::clonkClient(user, pcName)); } return Session.Clonk.Clients[pcName]; }