From 77baad2243f32fe2f2c4ffcb11ba142a3b23f7d5 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Mon, 2 Nov 2015 19:45:11 +0100 Subject: Add afkadmin-command --- src/CRSMConfig.hpp | 4 +++ src/crsm.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/crsm.hpp | 6 +++++ 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/CRSMConfig.hpp b/src/CRSMConfig.hpp index 1aee360..04c92ce 100644 --- a/src/CRSMConfig.hpp +++ b/src/CRSMConfig.hpp @@ -41,6 +41,8 @@ public: Integer MaxWishesPerScen = 2; Integer MaxWishesPerUser = 2; Integer UserListLength = 5; + Integer AfkAdminTime = 180; + Integer AfkAdminPreAfkTime = 60; Map(String, String) Alias; } Hosting; @@ -114,6 +116,8 @@ public: ConfigVal(Hosting.MaxWishesPerUser), ConfigVal(Hosting.UserListLength), ConfigVal(Hosting.Alias), + ConfigVal(Hosting.AfkAdminTime), + ConfigVal(Hosting.AfkAdminPreAfkTime), diff --git a/src/crsm.cpp b/src/crsm.cpp index 3263fe9..1c55ea1 100644 --- a/src/crsm.cpp +++ b/src/crsm.cpp @@ -73,6 +73,9 @@ CRSM::CRSM(QObject *parent) : connect(processManager, SIGNAL(finished(int)), this, SLOT(scenarioFinished())); + afkAdminTimer.setSingleShot(true); + connect(&afkAdminTimer, SIGNAL(timeout()), this, SLOT(afkAdminTimeout())); + QFile *reallog = new QFile(Config.Auto.Volatile.Clonk.Directory + "CRSM.log"); reallog->open(QIODevice::Append | QIODevice::Text); logstream.setDevice(reallog); @@ -140,6 +143,10 @@ void CRSM::readServerOutput() if(pcName != Config.Auto.Volatile.Clonk.ServerPCName) { ClientInfo& info = getClientInfo(pcName, cuid, user); + if(info == Session.Clonk.Admin) + { + checkActivity(Session.Clonk.Admin); + } QString msg = userexp.cap(5).trimmed(); if(info.floodCheck(Config.Clonk.Chat.AntiFlood.Count, Config.Clonk.Chat.AntiFlood.Time, QDateTime(QDate::currentDate(), QTime::fromString(timeRemover.cap(1), "hh:mm:ss")))) { @@ -395,6 +402,11 @@ void CRSM::ircMessageReceived(IrcMessage *message) if(target == connection->nickName()) target = message->nick(); QString mess = privMessage->content(); + const ClientInfo& client = ClientInfo::ircClient(message->nick(), target); + if(client == Session.IRC.Admin) + { + checkActivity(Session.IRC.Admin); + } if(target == Config.IRC.IngameChannel && Session.IRC.UseIngameChat) { if(privMessage->isAction()) @@ -409,7 +421,6 @@ void CRSM::ircMessageReceived(IrcMessage *message) else if(!privMessage->isAction() && (mess.length() > Config.CRSM.CommandSign.length() && mess.left(Config.CRSM.CommandSign.length()) == Config.CRSM.CommandSign)) { QString command = mess.mid(Config.CRSM.CommandSign.length()).trimmed(); - const ClientInfo& client = ClientInfo::ircClient(message->nick(), target); if(!cmd(command, client)) { respond(client, "Unbekannter Befehl: \"" + command + "\"!"); @@ -1303,6 +1314,7 @@ 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("admin?", &CRSM::getAdmin, Clonk | IRC | Management, User, "Fragt den aktuellen Rundenadmin ab."); + addCommand("afkadmin", &CRSM::afkAdmin, Clonk | IRC | Management, User, "Gibt den Rundenadmin frei, wenn er nicht in den nächsten " + QString::number(Config.Hosting.AfkAdminTime) + "s reagiert."); addCommand("ingameadmin", &CRSM::ingameadmin, IRC | Management, Admin, "Legt den Ingame-Rundenadmin fest.", ""); addCommand("noadmin", &CRSM::noadmin, Clonk | IRC | Management, Admin, "Entzieht dem (IRC-)Rundenadmin seine Rechte, damit jemand anders Rundenadmin sein kann."); @@ -1590,6 +1602,18 @@ void CRSM::enableAutoHosting() } } +void CRSM::afkAdminTimeout() +{ + Session.IRC.Admin.clear(); + Session.Clonk.Admin.clear(); + writeToServer("Der Rundenadmin war zu lange AFK und wurde freigegeben.\n"); + if(Session.IRC.UseIngameChat) + { + connection->sendCommand(IrcCommand::createMessage(Config.IRC.IngameChannel, "Der Rundenadmin war zu lange AFK und wurde freigegeben.\n")); + } + Session.AfkAdmin = false; +} + ClientInfo &CRSM::getClientInfo(const QString &pcName, int cuid, const QString &user) { if(!Session.Clonk.Clients.contains(pcName)) @@ -1615,6 +1639,7 @@ void CRSM::applyConfig() args << "/config:" + Config.Clonk.Server.Config; args << Config.Clonk.Server.Arguments.split(" "); Config.Auto.Volatile.Clonk.Directory = QFileInfo(Config.Clonk.Server.Executable).absoluteDir().absolutePath() + QDir::separator(); + afkAdminTimer.setInterval(Config.Hosting.AfkAdminTime * 1000); Config.CRSM.ListFolder = QDir(Config.CRSM.ListFolder).absolutePath() + QDir::separator(); @@ -1718,6 +1743,25 @@ void CRSM::writeFiles(bool writeSession, bool writeNoConfig) } } +void CRSM::checkActivity(ClientInfo &client) +{ + if(client.antiFloodList.isEmpty()) + { + client.antiFloodList.append(QDateTime::currentDateTime()); + } + else + { + client.antiFloodList.last() = QDateTime::currentDateTime(); + } + + if(Session.AfkAdmin) + { + respond(client, "Da du reagiert hast, kannst du den Rundenadmin beibehalten.\n"); + afkAdminTimer.stop(); + Session.AfkAdmin = false; + } +} + CMD_FUNCTION_IMPL(help) bool longHelp = (args == "long"); if(args.isEmpty() || longHelp) @@ -1844,6 +1888,36 @@ CMD_FUNCTION_IMPL(admin) return Success; } +CMD_FUNCTION_IMPL(afkAdmin) + if(Session.IRC.Admin.empty() && Session.Clonk.Admin.empty()) + { + respond(client, "Es gibt noch keinen Rundenadmin.\n"); + } + else if((!Session.IRC.Admin.empty() && !Session.IRC.Admin.antiFloodList.isEmpty() && Session.IRC.Admin.antiFloodList[0].secsTo(QDateTime::currentDateTime()) < Config.Hosting.AfkAdminPreAfkTime) || (!Session.Clonk.Admin.empty() && !Session.Clonk.Admin.antiFloodList.isEmpty() && Session.Clonk.Admin.antiFloodList[0].secsTo(QDateTime::currentDateTime()) < Config.Hosting.AfkAdminPreAfkTime)) + { + respond(client, "Der Rundenadmin war gerade aktiv.\n"); + } + else + { + Session.AfkAdmin = true; + afkAdminTimer.start(); + if(client.interface != Clonk || Session.Clonk.Admin.empty()) + { + respond(client, "Der Rundenadmin wird nach weiteren " + QString::number(Config.Hosting.AfkAdminTime) + "s Inaktivität freigegeben.\n"); + } + writeToServer("/alert\n"); + if(!Session.Clonk.Admin.empty()) + { + writeToServer(Session.Clonk.Admin.nick + "! Wenn du dich nicht in den nächsten " + QString::number(Config.Hosting.AfkAdminTime) + "s meldest, wird der Rundenadmin freigegeben.\n"); + } + if(!Session.IRC.Admin.empty()) + { + respond(Session.IRC.Admin, Session.IRC.Admin.nick + "! Wenn du dich nicht in den nächsten " + QString::number(Config.Hosting.AfkAdminTime) + "s meldest, wird der Rundenadmin freigegeben.\n"); + } + } + return Success; +} + CMD_FUNCTION_IMPL(host) if(hostingIsErrorDeactivated) { diff --git a/src/crsm.hpp b/src/crsm.hpp index 0466245..0fd17be 100644 --- a/src/crsm.hpp +++ b/src/crsm.hpp @@ -138,6 +138,7 @@ private slots: void updateNextAutoScens(); void reconnectIrc(); void enableAutoHosting(); + void afkAdminTimeout(); private: CRSMConfig Config; @@ -147,6 +148,7 @@ private: Boolean League = false; enum {None = -1, Lobby = 0, Loading = 1, Running = 2} State = None; Boolean UserWish = false; + Boolean AfkAdmin = false; Integer CountDown = -1; ScenarioSettings Scenario; @@ -224,6 +226,7 @@ private: QTcpServer managementServer; QMap managementConnections; QTimer gameRegisterFailTimer; + QTimer afkAdminTimer; bool ok = false; bool hostingIsErrorDeactivated = false; @@ -284,12 +287,14 @@ private: CmdResult callCommand(const CmdFunctionRef& func, const QString& args, const ClientInfo& client, UserType userType); void writeFiles(bool writeSession = false, bool writeNoConfig = false); + void checkActivity(ClientInfo& client); CMD_FUNCTION(help); CMD_FUNCTION(passToClonk); CMD_FUNCTION(passToClonkOnOff); CMD_FUNCTION(passToClonkNumeric); CMD_FUNCTION(passToClonkNumericOrEmpty); + CMD_FUNCTION(afkAdmin); CMD_FUNCTION(admin); CMD_FUNCTION(getAdmin); CMD_FUNCTION(host); @@ -345,6 +350,7 @@ private: CMD_FUNCTION(packsScenariosDelete); CMD_FUNCTION(packsScenariosList); + IRC_CHECK_CALLBACK(ircSetAdmin); IRC_CHECK_CALLBACK(ircModCmd); IRC_CHECK_CALLBACK(ircSayQuery); -- cgit v1.2.3-54-g00ecf