From de57bc38217c09a0ae4a143f631896652368ecc3 Mon Sep 17 00:00:00 2001 From: Dark1-dev Date: Wed, 1 Mar 2023 21:32:53 +0600 Subject: Add files via upload --- src/Core/CoreObject/coreobject.cpp | 5 ++ src/Core/CoreObject/coreobject.h | 30 ++++++++++ src/Core/CoreObject/serverinfostructure.h | 31 ++++++++++ src/Core/GameInfo/gameinfostructure.h | 24 ++++++++ src/Core/GameInfo/loadsupportedgames.cpp | 97 +++++++++++++++++++++++++++++++ src/Core/GameInfo/loadsupportedgames.h | 16 +++++ src/Core/core.cpp | 15 +++++ src/Core/core.h | 43 ++++++++++++++ src/Core/corerun.cpp | 75 ++++++++++++++++++++++++ src/Core/version.h | 43 ++++++++++++++ 10 files changed, 379 insertions(+) create mode 100644 src/Core/CoreObject/coreobject.cpp create mode 100644 src/Core/CoreObject/coreobject.h create mode 100644 src/Core/CoreObject/serverinfostructure.h create mode 100644 src/Core/GameInfo/gameinfostructure.h create mode 100644 src/Core/GameInfo/loadsupportedgames.cpp create mode 100644 src/Core/GameInfo/loadsupportedgames.h create mode 100644 src/Core/core.cpp create mode 100644 src/Core/core.h create mode 100644 src/Core/corerun.cpp create mode 100644 src/Core/version.h (limited to 'src/Core') diff --git a/src/Core/CoreObject/coreobject.cpp b/src/Core/CoreObject/coreobject.cpp new file mode 100644 index 0000000..11d1ab6 --- /dev/null +++ b/src/Core/CoreObject/coreobject.cpp @@ -0,0 +1,5 @@ +#include "coreobject.h" + +CoreObject::CoreObject() +{ +} diff --git a/src/Core/CoreObject/coreobject.h b/src/Core/CoreObject/coreobject.h new file mode 100644 index 0000000..91bd33b --- /dev/null +++ b/src/Core/CoreObject/coreobject.h @@ -0,0 +1,30 @@ +#ifndef COREOBJECT_H +#define COREOBJECT_H + +#include "Core/CoreObject/serverinfostructure.h" +#include "Core/GameInfo/gameinfostructure.h" +#include "Logger/logger.h" +#include "Settings/settingstructure.h" + +class CoreObject +{ +public: + CoreObject(); + + // struct with internal and external settings + SettingStructure Settings; + + // list of game details: gamename, cipher + QHash SupportedGames; + + // logging functions + Logger Log; + + // server address list acquired through third party masterservers + QList PendingServers; + + // generate our session/identification string, to prevent self-syncing + QString masterserverIdentity; // msid value +}; + +#endif // COREOBJECT_H diff --git a/src/Core/CoreObject/serverinfostructure.h b/src/Core/CoreObject/serverinfostructure.h new file mode 100644 index 0000000..4f86adb --- /dev/null +++ b/src/Core/CoreObject/serverinfostructure.h @@ -0,0 +1,31 @@ +#ifndef SERVERINFOSTRUCTURE_H +#define SERVERINFOSTRUCTURE_H + +#include +#include + +struct ServerInfo +{ + // server address + QHostAddress ip; + + // server port + unsigned short port = 0; + + // gamename + QString gamename = ""; + + // date that the serverinfo was added or last updated + qint64 time = QDateTime::currentSecsSinceEpoch(); +}; + +// compare operator +inline bool operator== (const ServerInfo serverInfo1, const ServerInfo serverInfo2) +{ + // compare address, port and gamename. ignore time. + return ( serverInfo1.ip.isEqual(serverInfo2.ip) and + serverInfo1.port == serverInfo2.port and + serverInfo1.gamename == serverInfo2.gamename ); +} + +#endif // SERVERINFOSTRUCTURE_H diff --git a/src/Core/GameInfo/gameinfostructure.h b/src/Core/GameInfo/gameinfostructure.h new file mode 100644 index 0000000..b73e9ef --- /dev/null +++ b/src/Core/GameInfo/gameinfostructure.h @@ -0,0 +1,24 @@ +#ifndef STRUCTGAMEINFO_H +#define STRUCTGAMEINFO_H + +#include + +struct GameInfo +{ + // gamename is the unique identifier + QString gamename; + + // 6-byte GameSpy identifier + QString cipher; + + // game label + QString label; + + // default port + unsigned short port = 0; + + // known protocol + QString protocol; +}; + +#endif // STRUCTGAMEINFO_H diff --git a/src/Core/GameInfo/loadsupportedgames.cpp b/src/Core/GameInfo/loadsupportedgames.cpp new file mode 100644 index 0000000..9a73947 --- /dev/null +++ b/src/Core/GameInfo/loadsupportedgames.cpp @@ -0,0 +1,97 @@ +#include "loadsupportedgames.h" + +QHash loadSupportedGames (const QString &applicationPath) +{ + // return hash + QHash supportedGames; + + // supported games file path (following README structure) + const QString supportPath = applicationPath + "/" + _supportedPath; + + // determine if file exists + if ( ! QFile(supportPath).exists() ) + { + // no game info file exists + logPrimitive() << "No games file found at " << supportPath << endl + << "Please provide the correct file . " << endl; + return supportedGames; + } + + // load config file + QFile supportedFile(supportPath); + if ( ! supportedFile.open(QIODevice::ReadOnly) ) + { + // error occurred. report and quit. + logPrimitive() << "Unable to open the game file. Is the file open or in use?" << endl; + return supportedGames; + } + + // stats + int total = 0; + + // load as json object + QJsonDocument supportedJsonData(QJsonDocument::fromJson(supportedFile.readAll())); + + /* Optimisation for web interface: add games to the database. + * + * If database/json data do not match, replace database table + * with json data. This should only occur during database creation + * or when manual changes were made to the json file (which is rare). + */ + bool dbInsert = supportedJsonData.array().count() != getNumGames(0).value("numTotal", 0); + QSqlQuery q; + if (dbInsert) + { + // no game info file exists + logPrimitive() << "Game info mismatch in database. Reloading json data. (" + << supportedJsonData.array().count() << "/" + << getNumGames(0).value("numTotal", 0) << ")" << endl; + + // void existing data + q.prepare("DELETE FROM gameinfo"); + if ( ! q.exec() ) + reportQuery(q); + } + + for (int i = 0; i < supportedJsonData.array().count(); i++) + { + // get the game object + QJsonObject thisGame = supportedJsonData.array().at(i).toObject(); + + GameInfo gameInfo; + gameInfo.gamename = thisGame.value("gamename").toString(""); + gameInfo.cipher = thisGame.value("cipher").toString(""); + gameInfo.port = static_cast(thisGame.value("port").toDouble(0)); + gameInfo.label = thisGame.value("label").toString(""); + + // insert in db if needed + if (dbInsert) + { + QString insertString = "INSERT INTO gameinfo (gamename, label) " + "VALUES (:gamename, :label)"; + + q.prepare(insertString); + q.bindValue(":gamename", gameInfo.gamename ); + q.bindValue(":label", gameInfo.label); + + if ( ! q.exec() ) + reportQuery(q); + } + + // add to list + supportedGames.insert(gameInfo.gamename, gameInfo); + total++; + } + + // no games found? report this! + if (total <= 0) + { + // no game info exists + logPrimitive() << "No game info found in file at " << supportPath << endl + << "Please provide the correct file . " << endl; + return supportedGames; + } + + // all games parsed. done. + return supportedGames; +} diff --git a/src/Core/GameInfo/loadsupportedgames.h b/src/Core/GameInfo/loadsupportedgames.h new file mode 100644 index 0000000..333dd0b --- /dev/null +++ b/src/Core/GameInfo/loadsupportedgames.h @@ -0,0 +1,16 @@ +#ifndef LOADSUPPORTEDGAMES_H +#define LOADSUPPORTEDGAMES_H + +#include +#include +#include +#include +#include "Database/Common/commonactions.h" +#include "gameinfostructure.h" + +// load supported games from json file + +const QString _supportedPath = "../data/SupportedGames.json"; +QHash loadSupportedGames (const QString &applicationPath); + +#endif // LOADSUPPORTEDGAMES_H diff --git a/src/Core/core.cpp b/src/Core/core.cpp new file mode 100644 index 0000000..04c7e53 --- /dev/null +++ b/src/Core/core.cpp @@ -0,0 +1,15 @@ +#include "core.h" + +Core::Core(QString applicationPath) +{ + _applicationPath = applicationPath; +} + +// TODO +void Core::shutdown() +{ + logPrimitive() << "[stop] quitting masterserver application" << endl; + + // end application + exit(0); +} diff --git a/src/Core/core.h b/src/Core/core.h new file mode 100644 index 0000000..bde3a04 --- /dev/null +++ b/src/Core/core.h @@ -0,0 +1,43 @@ +#ifndef CORE_H +#define CORE_H + +#include "Core/CoreObject/coreobject.h" +#include "Core/GameInfo/loadsupportedgames.h" +#include "Core/version.h" +#include "Database/databaseinterface.h" +#include "Settings/loadsettings.h" +#include "Maintenance/maintenance.h" +#include "Protocols/GameSpy0/securevalidate.h" +#include "UdpTasks/BeaconServer/beaconserver.h" +#include "UdpTasks/StatusChecker/statuschecker.h" +#include "TcpTasks/ListenServer/listenserver.h" +#include "TcpTasks/Updater/syncupdater.h" + +class Core : public QObject +{ + Q_OBJECT +public: + Core(QString applicationPath); + void run(); + void shutdown(); + +private: + // root path + QString _applicationPath = ""; + + // internal dataobject + QSharedPointer _coreObject = QSharedPointer(new CoreObject); + + // Networking services + QSharedPointer _udpBeaconServer = QSharedPointer(new BeaconServer(_coreObject)); + QSharedPointer _tcpListenServer = QSharedPointer(new ListenServer(_coreObject)); + + // Updaters + QSharedPointer _syncUpdater = QSharedPointer (new SyncUpdater (_coreObject)); + QSharedPointer _statusChecker = QSharedPointer(new StatusChecker(_coreObject)); + + // Maintenance + QSharedPointer _maintenance = QSharedPointer(new Maintenance(_coreObject)); +}; + +#endif // CORE_H diff --git a/src/Core/corerun.cpp b/src/Core/corerun.cpp new file mode 100644 index 0000000..c978026 --- /dev/null +++ b/src/Core/corerun.cpp @@ -0,0 +1,75 @@ +#include "core.h" + +void Core::run() +{ + // randomize + qsrand(static_cast(QDateTime::currentMSecsSinceEpoch())); + + // announce startup + logPrimitive() << "*** Starting 333networks Master Server v" << BUILD_VERSION << " ***" << endl; + + // can not set file paths + if (_applicationPath.length() <= 0) + this->shutdown(); + + // debug info (hardcoded disable for releases) + if ( false ) + logPrimitive() << "Using Qt " << qVersion() << endl; + + // set our own 12-byte identifier + _coreObject->masterserverIdentity = genChallengeString(12, true); + + // load config settings from file + _coreObject->Settings = loadSettings(_applicationPath); + if ( ! _coreObject->Settings.init ) + this->shutdown(); + + // initialise database + if ( ! initDatabase(_applicationPath) ) + this->shutdown(); + + // load game info from file and into database + _coreObject->SupportedGames = loadSupportedGames(_applicationPath); + if ( _coreObject->SupportedGames.count() <= 0 ) + this->shutdown(); + + // logger init + if ( ! _coreObject->Log.init(_applicationPath, _coreObject->Settings) ) + this->shutdown(); + + /* + * enter runmode + */ + + // udp beacon server + if ( ! _udpBeaconServer->listen() ) + this->shutdown(); + + // tcp listen server + if ( ! _tcpListenServer->listen() ) + this->shutdown(); + + /* + * advanced functionality + */ + + // maintenance and statistics + if ( _coreObject->Settings.MaintenanceSettings.doMaintenance ) + _maintenance->scheduleMaintenance(); + + // udp uplink broadcast every X minutes + if ( _coreObject->Settings.BeaconServerSettings.doUplink ) + _udpBeaconServer->uplink(); + + // syncing with other masterservers + if ( _coreObject->Settings.SyncerSettings.doSync ) + _syncUpdater->scheduleUpdater(); + + // server checker + if ( _coreObject->Settings.CheckerSettings.doCheck ) + _statusChecker->startTicker(); + + /* + * all services running + */ +} diff --git a/src/Core/version.h b/src/Core/version.h new file mode 100644 index 0000000..6dbc808 --- /dev/null +++ b/src/Core/version.h @@ -0,0 +1,43 @@ +#ifndef VERSION_H +#define VERSION_H + +#include + +/* + * Version and author information + * + * Only when you make (significant) modifications to the master server source + * code, you should edit these variables to reflect your changes. + * + * For example, + * if you limit functionality to only one game, you should change the variable + * BUILD_TYPE and SHORT_VER to something that reflects the change in function. + * + * In addition, if you have the actual interest to go through all this source + * code to end up here, consider sending Darkelarious (the original author) a + * postcard or (e)mail with your compliments. Or buy us a coffee. We like the + * appreciation. + */ + +// gamename for the 333networks-type MasterServer +#define TYPE_GAMENAME QString("333networks") + +// build type: type of software +#define BUILD_TYPE QString("MasterServer Qt5") + +// software version (of this particular type) +#define BUILD_VERSION QString("0.27") + +// short version (in query) -- Qt v0.n +#define SHORT_VER QString("Qt-" + BUILD_VERSION) + +// build time/date +#define BUILD_TIME QStringLiteral("%1 %2").arg(__DATE__).arg(__TIME__) + +// software author, contact +#define BUILD_AUTHOR QString("Darkelarious ") + +// minimum required database version +#define DATABASE_VERSION 0.27 + +#endif // VERSION_H -- cgit v1.2.3