summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ClonkInterface.cpp7
-rw-r--r--src/ClonkInterface.hpp18
-rw-r--r--src/CrServerManager.pro6
-rw-r--r--src/PatchedClonkControl.cpp56
-rw-r--r--src/PatchedClonkControl.hpp14
-rw-r--r--src/crsm.cpp76
-rw-r--r--src/crsm.hpp8
7 files changed, 135 insertions, 50 deletions
diff --git a/src/ClonkInterface.cpp b/src/ClonkInterface.cpp
index 8d6ab98..036b931 100644
--- a/src/ClonkInterface.cpp
+++ b/src/ClonkInterface.cpp
@@ -31,6 +31,13 @@ void ClonkOutputInterface::gameStarted() {}
void ClonkOutputInterface::masterserverError(const QString &msg) { Q_UNUSED(msg); }
+ClonkControlInterface::~ClonkControlInterface() {}
+
+void ClonkControlInterface::setController(ClonkControllerInterface *controller)
+{
+ this->controller = controller;
+}
+
ClonkParser::ClonkParser(CRSMSession &session) : Session(session)
{
diff --git a/src/ClonkInterface.hpp b/src/ClonkInterface.hpp
index 376acbe..a6961f3 100644
--- a/src/ClonkInterface.hpp
+++ b/src/ClonkInterface.hpp
@@ -4,15 +4,27 @@
#include "ClientInfo.hpp"
#include "CRSMSession.hpp"
+class ClonkControllerInterface {
+public:
+ virtual ~ClonkControllerInterface();
+
+ virtual void writeToServer(const QString& msg) = 0;
+};
+
class ClonkControlInterface {
- ClonkControlInterface() = delete;
- virtual ~ClonkControlInterface();
+protected:
+ ClonkControllerInterface* controller = nullptr;
+
public:
+ virtual ~ClonkControlInterface();
+
+ void setController(ClonkControllerInterface* controller);
+
virtual void serverMessage(const QString& msg, bool action = false) = 0;
virtual void setCountdown(unsigned int seconds) = 0;
virtual void abortCountdown() = 0;
virtual void setCommand(const QString& command) = 0; // split?
- virtual void kick(const ClientInfo& client) = 0;
+ virtual void kick(const ClientInfo& client, const QString& reason = "") = 0;
virtual void watchdog(const QString& id) = 0;
virtual void rawCommand(const QString& command) = 0;
virtual void alert() = 0; // specify client? (Clonk patch first)
diff --git a/src/CrServerManager.pro b/src/CrServerManager.pro
index d197acb..fbfd003 100644
--- a/src/CrServerManager.pro
+++ b/src/CrServerManager.pro
@@ -27,7 +27,8 @@ SOURCES += main.cpp \
CRSMLogging.cpp \
ClonkInterface.cpp \
PatchedClonkParser.cpp \
- CRSMSession.cpp
+ CRSMSession.cpp \
+ PatchedClonkControl.cpp
HEADERS += \
CmdFunctionRef.hpp \
@@ -44,7 +45,8 @@ HEADERS += \
ClientInterface.hpp \
ClonkInterface.hpp \
PatchedClonkParser.hpp \
- CRSMSession.hpp
+ CRSMSession.hpp \
+ PatchedClonkControl.hpp
equals(QT_ARCH, "x86_64"):linux-*: DEFINES += Q_OS_LINUX64
QMAKE_CXXFLAGS *= -std=c++11 -Wall -Wextra -Werror -Wunused
diff --git a/src/PatchedClonkControl.cpp b/src/PatchedClonkControl.cpp
index 47758d2..45b6d68 100644
--- a/src/PatchedClonkControl.cpp
+++ b/src/PatchedClonkControl.cpp
@@ -1,6 +1,62 @@
#include "PatchedClonkControl.hpp"
+#define CMD_SIGN "/"
+
PatchedClonkControl::PatchedClonkControl()
{
}
+
+void PatchedClonkControl::abortCountdown()
+{
+ rawCommand("stop");
+}
+
+void PatchedClonkControl::alert()
+{
+ rawCommand("alert");
+}
+
+void PatchedClonkControl::kick(const ClientInfo& client, const QString& reason)
+{
+ rawCommand("kick " + client.pcName + (reason.isEmpty() ? "" : " " + reason));
+}
+
+void PatchedClonkControl::rawCommand(const QString& command)
+{
+ controller->writeToServer(CMD_SIGN + command + "\n");
+}
+
+void PatchedClonkControl::serverMessage(const QString& msg, bool action)
+{
+ if(action)
+ {
+ rawCommand("me " + msg);
+ }
+ else
+ {
+ if(msg.startsWith(CMD_SIGN))
+ {
+ controller->writeToServer(" " + msg + "\n");
+ }
+ else
+ {
+ controller->writeToServer(msg + "\n");
+ }
+ }
+}
+
+void PatchedClonkControl::setCommand(const QString& command)
+{
+ rawCommand("set " + command);
+}
+
+void PatchedClonkControl::setCountdown(unsigned int countdown)
+{
+ rawCommand("start " + QString::number(countdown));
+}
+
+void PatchedClonkControl::watchdog(const QString& id)
+{
+ rawCommand("watchdog " + id);
+}
diff --git a/src/PatchedClonkControl.hpp b/src/PatchedClonkControl.hpp
index 2469178..8ec6cff 100644
--- a/src/PatchedClonkControl.hpp
+++ b/src/PatchedClonkControl.hpp
@@ -1,11 +1,17 @@
-#ifndef PATCHEDCLONKCONTROL_HPP
-#define PATCHEDCLONKCONTROL_HPP
+#pragma once
+#include "ClonkInterface.hpp"
class PatchedClonkControl : public ClonkControlInterface
{
public:
PatchedClonkControl();
+ void abortCountdown() override;
+ void alert() override;
+ void kick(const ClientInfo& client, const QString& reason = "") override;
+ void rawCommand(const QString& command) override;
+ void serverMessage(const QString& msg, bool action = false) override;
+ void setCommand(const QString& command) override;
+ void setCountdown(unsigned int countdown) override;
+ void watchdog(const QString& id) override;
};
-
-#endif // PATCHEDCLONKCONTROL_HPP \ No newline at end of file
diff --git a/src/crsm.cpp b/src/crsm.cpp
index 754e73c..86f3f70 100644
--- a/src/crsm.cpp
+++ b/src/crsm.cpp
@@ -14,6 +14,7 @@
CRSM::CRSM(QObject *parent) :
QObject(parent), Session(this), parser(Session)
{
+ control.setController(this);
parser.addTarget(this);
qsrand((uint)QDateTime::currentMSecsSinceEpoch());
@@ -62,7 +63,7 @@ CRSM::CRSM(QObject *parent) :
if(processManager->isRunning())
{
Session.read(Config.CRSM.SessionFile, false);
- writeToServer("Der Server Manager läuft wieder.\n");
+ control.serverMessage("Der Server Manager läuft wieder.");
if(Session.State == CRSMSession::Running)
{
watchdog();
@@ -258,7 +259,7 @@ void CRSM::clientMessage(ClientInfo& client, const QString& message, ClonkOutput
}
if(client.floodCheck(Config.Clonk.Chat.AntiFlood.Count, Config.Clonk.Chat.AntiFlood.Time, QDateTime(QDate::currentDate(), time)))
{
- kick(client.pcName, "Flooding! Maximal " + QString::number(Config.Clonk.Chat.AntiFlood.Count) + " Nachrichten in " + QString::number(Config.Clonk.Chat.AntiFlood.Time) + "s");
+ kick(client, "Flooding! Maximal " + QString::number(Config.Clonk.Chat.AntiFlood.Count) + " Nachrichten in " + QString::number(Config.Clonk.Chat.AntiFlood.Time) + "s");
}
else if(type == Sound)
{
@@ -302,7 +303,7 @@ void CRSM::clientConnected(const ClientInfo& client)
void CRSM::clientRemoved(const ClientInfo& client, const QString& reason)
{
- writeToServer(QString(client.nick +" ist ein L34V0R!\n"));
+ control.serverMessage(client.nick +" ist ein L34V0R!");
if(Session.IRC.UseIngameChat)
{
@@ -314,7 +315,7 @@ void CRSM::clientRemoved(const ClientInfo& client, const QString& reason)
Session.Clonk.LeaveAdmins.insert(client, QDateTime::currentDateTime());
afkAdminTimer.stop();
Session.AfkAdmin = false;
- writeToServer("Rundenadmin wurde freigegeben.\n");
+ control.serverMessage("Rundenadmin wurde freigegeben.");
Session.Clonk.Admin.clear();
}
@@ -326,7 +327,7 @@ void CRSM::clientRemoved(const ClientInfo& client, const QString& reason)
}
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");
+ control.setCountdown(Config.Clonk.Server.EmptyTimer);
}
}
@@ -340,7 +341,7 @@ void CRSM::gameStarted()
Stats.AddScenarioStart(Session.Scenario.wishClient, scenarioFileName(Session.Scenario.name));
if(!Session.League)
{
- writeToServer(QString("/set maxplayer 0\n"));
+ control.setCommand("maxplayer 0");
}
setSessionState(CRSMSession::Running);
watchdog();
@@ -547,7 +548,7 @@ void CRSM::ircMessageReceived(IrcMessage *message)
if(joinChannel == Config.IRC.IngameChannel && Session.IRC.UseIngameChat)
{
- writeToServer("[IRC] " + message->nick() + " hat den Channel betreten." + "\n");
+ control.serverMessage("[IRC] " + message->nick() + " hat den Channel betreten.");
}
else
ircCheckUserStatus(ClientInfo::ircClient(message->nick()), ClientInfo::ircClient(message->nick()), &CRSM::ircModCmd);
@@ -581,7 +582,7 @@ void CRSM::ircMessageReceived(IrcMessage *message)
QString leaveChannel = partMessage->channel();
if(leaveChannel == Config.IRC.IngameChannel && Session.IRC.UseIngameChat)
{
- writeToServer("[IRC] " + message->nick() + " hat den Channel verlassen." + "\n");
+ control.serverMessage("[IRC] " + message->nick() + " hat den Channel verlassen.");
}
}
else if(message->type() == IrcMessage::Mode)
@@ -626,13 +627,13 @@ void CRSM::greet(QString pcName)
return;
}
- writeToServer(QString("Hallo, " + info.nick + "!\n"));
+ control.serverMessage("Hallo, " + info.nick + "!");
if(Session.Clonk.LeaveAdmins.contains(info))
{
qint64 timeGone;
if((timeGone = Session.Clonk.LeaveAdmins.value(info).secsTo(QDateTime::currentDateTime())) < Config.Clonk.Chat.RegainAdminTime && (!Session.Clonk.Admin.empty() || !Session.IRC.Admin.empty()))
{
- writeToServer(info.nick + "! Der Rundenadmin wurde freigegeben, weil du das Spiel verlassen hast.\nDu hast noch " + QString::number(Config.Clonk.Chat.RegainAdminTime - timeGone) + "s Zeit um den Rundenadmin zurückzuholen.\n");
+ control.serverMessage(info.nick + "! Der Rundenadmin wurde freigegeben, weil du das Spiel verlassen hast.\nDu hast noch " + QString::number(Config.Clonk.Chat.RegainAdminTime - timeGone) + "s Zeit um den Rundenadmin zurückzuholen.");
}
else
{
@@ -696,13 +697,13 @@ void CRSM::newManagementData()
}
else
{
- writeToServer(data + "\n");
+ control.rawCommand(command);
}
}
else
{
const QString& msg = ClientInfo::managementClient(conn).toString(true) + " " + data + "\n";
- writeToServer(msg);
+ control.serverMessage(msg);
if(Session.IRC.UseIngameChat)
{
sendIrcMessage(msg, Config.IRC.IngameChannel, false, false);
@@ -1667,7 +1668,7 @@ void CRSM::respond(const ClientInfo &client, const QString &message, const Respo
switch(client.interface)
{
case Clonk:
- writeToServer(message);
+ control.serverMessage(message);
break;
case IRC:
foreach(const QString line, message.split('\n', QString::SkipEmptyParts))
@@ -1772,12 +1773,15 @@ void CRSM::replayOutputBuffer(QTcpSocket *socket, bool clear)
}
}
-void CRSM::announceInfo(const QString &info)
+void CRSM::announceInfo(const QString &info, bool useOutgameChannel)
{
out(info);
if(Config.IRC.Use)
{
- sendIrcMessage(info, Config.IRC.Channel, false, false);
+ if(useOutgameChannel)
+ {
+ sendIrcMessage(info, Config.IRC.Channel, false, false);
+ }
if(Config.IRC.UseIngameChat)
{
sendIrcMessage(info, Config.IRC.IngameChannel, false, false);
@@ -1820,9 +1824,9 @@ bool CRSM::scenAllowed(const ScenarioSettings &scen, const ClientInfo &client, U
return true;
}
-void CRSM::kick(const QString& pcName, const QString& reason)
+void CRSM::kick(const ClientInfo& client, const QString& reason)
{
- writeToServer("/kick " + pcName + (reason.isEmpty() ? QString("") : QString(" ") + reason) + "\n");
+ control.kick(client, reason);
}
void CRSM::prepareAndConnectIrc()
@@ -1867,11 +1871,7 @@ 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)
- {
- sendIrcMessage("Der Rundenadmin war zu lange AFK und wurde freigegeben.\n", Config.IRC.IngameChannel, false, false);
- }
+ announceInfo("Der Rundenadmin war zu lange AFK und wurde freigegeben.", false);
Session.AfkAdmin = false;
}
@@ -2272,11 +2272,11 @@ void CRSM::handleIrcMessage(const ClientInfo &client, QString message, const QSt
{
if(action)
{
- writeToServer("/me [IRC] " + client.nick + " " + message + "\n");
+ control.serverMessage("[IRC] " + client.nick + " " + message, true);
}
else
{
- writeToServer("[IRC]<" + client.nick + "> " + message + "\n");
+ control.serverMessage("[IRC]<" + client.nick + "> " + message);
}
}
else if(!action && !(command = getCommand(message)).isEmpty())
@@ -2305,7 +2305,7 @@ void CRSM::handleIrcMessage(const ClientInfo &client, QString message, const QSt
writeMessage = "[IRC]<" + client.nick + "> ";
}
writeMessage += message;
- writeToServer(writeMessage + "\n");
+ control.serverMessage(writeMessage);
handled = true;
}
}
@@ -2345,7 +2345,7 @@ void CRSM::watchdog()
{
watchDogTimer.start(Config.Clonk.Server.Watchdog.Timeout * 1000);
watchDogString = GetRandomString(20);
- writeToServer("/watchdog " + watchDogString + "\n");
+ control.watchdog(watchDogString);
}
else
{
@@ -2490,12 +2490,12 @@ CMD_FUNCTION_IMPL(help)
}
CMD_FUNCTION_IMPL(passToClonk)
- writeToServer('/' + cmd + ' ' + args + '\n');
+ control.rawCommand(cmd + ' ' + args);
return Success;
}
CMD_FUNCTION_IMPL(passToClonkGrouped)
- writeToServer('/' + cmd.split(' ').last() + ' ' + args + '\n');
+ control.rawCommand(cmd.split(' ').last() + ' ' + args);
return Success;
}
@@ -2573,10 +2573,10 @@ CMD_FUNCTION_IMPL(afkAdmin)
{
respond(client, "Der Rundenadmin wird nach weiteren " + QString::number(Config.Hosting.AfkAdminTime) + "s Inaktivität freigegeben.\n");
}
- writeToServer("/alert\n");
+ control.alert();
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");
+ control.serverMessage(Session.Clonk.Admin.nick + "! Wenn du dich nicht in den nächsten " + QString::number(Config.Hosting.AfkAdminTime) + "s meldest, wird der Rundenadmin freigegeben.");
}
if(!Session.IRC.Admin.empty())
{
@@ -2891,7 +2891,7 @@ CMD_FUNCTION_IMPL(passToClonkPcName)
respond(client, "Moderatoren können nur von anderen Moderatoren gekickt werden.\n");
return RightsFail;
}
- writeToServer("/" + cmd + " " + info.pcName + "\n");
+ control.rawCommand(cmd + " " + info.pcName);
return Success;
}
@@ -2925,13 +2925,13 @@ CMD_FUNCTION_IMPL(noadmin)
}
else
{
- static const QString msg("Rundenadmin wurde freigegeben.\n");
+ static const QString msg("Rundenadmin wurde freigegeben.");
Session.IRC.Admin.clear();
Session.Clonk.Admin.clear();
respond(client, msg);
if(client.interface == IRC)
{
- writeToServer(msg);
+ control.serverMessage(msg);
}
}
return Success;
@@ -2978,7 +2978,7 @@ CMD_FUNCTION_IMPL(passToClonkNumeric)
}
else
{
- writeToServer("/" + cmd + " " + QString::number(number) + "\n");
+ control.rawCommand(cmd + " " + QString::number(number));
return Success;
}
}
@@ -2986,7 +2986,7 @@ CMD_FUNCTION_IMPL(passToClonkNumeric)
CMD_FUNCTION_IMPL(passToClonkNumericOrEmpty)
if(args.isEmpty())
{
- writeToServer("/" + cmd + "\n");
+ control.rawCommand(cmd);
return Success;
}
else
@@ -3003,7 +3003,7 @@ CMD_FUNCTION_IMPL(passToClonkOnOff)
}
else
{
- writeToServer("/" + cmd + " " + args + "\n");
+ control.rawCommand(cmd + " " + args);
return Success;
}
}
@@ -3085,7 +3085,7 @@ CMD_FUNCTION_IMPL(exitDetach)
}
CMD_FUNCTION_IMPL(exitUpdate)
- writeToServer("Der Server Manager wird upgedatet. Befehle funktionieren temporär nicht.\n");
+ control.serverMessage("Der Server Manager wird upgedatet. Befehle funktionieren temporär nicht.");
return exitDetach(cmd, "Updating...", client, userType);
}
@@ -3150,7 +3150,7 @@ CMD_FUNCTION_IMPL(grouphelp)
}
CMD_FUNCTION_IMPL(setRaw)
- writeToServer("/set " + args + '\n');
+ control.setCommand(args);
return Success;
}
diff --git a/src/crsm.hpp b/src/crsm.hpp
index 87886c6..abae69a 100644
--- a/src/crsm.hpp
+++ b/src/crsm.hpp
@@ -29,6 +29,7 @@
#include "ClonkInterface.hpp"
#include "PatchedClonkParser.hpp"
+#include "PatchedClonkControl.hpp"
#define CONFIG_FILE_NAME "CrServerManager.conf"
#define SESSION_FILE_NAME "CrServerManager.session"
@@ -76,7 +77,7 @@ public:
QString value() { return Util::joinEscape({ConfigValueBase::getStringValue(config.name), ConfigValueBase::getStringValue(config.league), ConfigValueBase::getStringValue(config.wishClient)}, ':', '|'); }
};
-class CRSM : public QObject, public ClonkOutputInterface
+class CRSM : public QObject, public ClonkOutputInterface, public ClonkControllerInterface
{
friend CRSMSession::CRSMSession(CRSM *crsm);
private:
@@ -158,6 +159,7 @@ private:
CRSMLogging Log;
PatchedClonkParser parser;
+ PatchedClonkControl control;
QList<ScenarioSettings> userlist;
QList<ScenarioSettings> autolist;
@@ -246,11 +248,11 @@ private:
void out(const QString& text);
void replayOutputBuffer(QTcpSocket *socket, bool clear = true);
- void announceInfo(const QString& info);
+ void announceInfo(const QString& info, bool useOutgameChannel = true);
bool scenAllowed(const ScenarioSettings& scen, const ClientInfo& client, UserType userType);
- void kick(const QString& pcName, const QString& reason = "");
+ void kick(const ClientInfo& client, const QString& reason = "");
void prepareAndConnectIrc();