#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "CmdFunctionRef.hpp" #include "ProcessManager.hpp" #include "CRSMConfig.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 Config.Auto.Volatile.Clonk.Directory + "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) { (void)requester; (void)status; (void)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 ScenarioSettings { public: QString name; bool league = false; bool randomLeague = false; ClientInfo wishClient; ScenarioSettings(const QString& name, bool league = false) : name(name), league(league) {} ScenarioSettings(const QString& name, const ClientInfo& client, bool league = false) : name(name), league(league), wishClient(client) {} }; class CRSM : public QObject { private: enum IrcModOperations { ModCheck, ModInfo, SkipScen, ClearUserList, SkipCurrentScen, Autohost, NoAutohost, ModHelp, Kill, IO, CheckOnly, NewAlias, AliasWishes, IngameChat }; enum RespondType { Normal, Notice, Private, PrivateNotice }; Q_OBJECT public: explicit CRSM(QObject *parent = 0); ~CRSM(); void start(); bool isOk(); signals: private slots: void readServerOutput(); void readInput(); void nextScen(); void printAdditionalHelp(); void readLog(); void scenarioFinished(); void ircMessageReceived(IrcMessage* message); void greet(QString pcName); void newManagementConnection(); void newManagementData(); void managementConnectionDisconnected(); void updateNextAutoScens(); private: CRSMConfig Config; struct CRSMSession { bool League = false; enum {None = -1, Lobby = 0, Loading = 1, Running = 2} State = None; bool UserWish = false; int CountDown = -1; QString ScenarioName = ""; struct { ClientInfo Admin; QMap Clients; QMap LeaveAdmins; } Clonk; struct { ClientInfo Admin; bool UseIngameChat = false; } IRC; void clear() { *this = CRSMSession(); } } Session; QList userlist; QList autolist; QList nextAutoScens; QStringList args; QStringList ircModChecks; QStringList ircMods; QMap>> ircStatusFifos; QMap>> ircModFifos; QMap>> ircModFifosOld; QString aliasWishEditor = ""; QString currentAliasWish = ""; int current; QTextStream *qout; QTextStream *qin; bool finish; IrcConnection *connection = 0; bool autoHost = true; QSignalMapper greetMapper; QFile *logfile; QTextStream logstream; QTextCodec *codec; QStringList ircModIOList; QString writtenToServer; QMap cmds; ProcessManager* processManager = nullptr; QTcpServer managementServer; QMap managementConnections; bool ok = false; void startScen(const ScenarioSettings& scen, QStringList); void readConfig(); void readScenarios(); void listC4Folders(); void cleanUp(); QString scenPath(QString scenName); QString listScenarios(QString commandArgs); QString printQueue(); void ircCheckModCmd(const QString &nick, CmdFunctionRef func, QString arg = ""); QString skipScen(); bool skipCurrent(); void writeToServer(const QString& message); void writeConfig(); QString addAliasWish(const QString& param); void informModsAboutAliasWish(); void editAliasWishes(); void editAliasWishes(const QString &message); void stopAliasWishEditing(); QString ircActivateIngameChat(bool activated = true); QStringList listC4Folder(const QString &path); void ircSetIngameChannelTopic(); 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); QFile outputBuffer; void out(const QString& text); void replayOutputBuffer(QTcpSocket *socket, bool clear = true); bool scenAllowed(const ScenarioSettings& scen, const ClientInfo& client, UserType userType); void kick(const QString& pcName, const QString& reason = ""); void prepareAndConnectIrc(); ClientInfo& getClientInfo(const QString& pcName, int cuid, const QString& user); void exit(); 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); CMD_FUNCTION(set); CMD_FUNCTION(join); CMD_FUNCTION(leave); CMD_FUNCTION(exit); CMD_FUNCTION(exitDetach); CMD_FUNCTION(exitUpdate); CMD_FUNCTION(exitAfter); CMD_FUNCTION(reload); CMD_FUNCTION(saveConfig); CMD_FUNCTION(reconnectIrc); IRC_CHECK_CALLBACK(ircSetAdmin); IRC_CHECK_CALLBACK(ircModCmd); };