Privatization rework ()

* Add clang-format

* Multiple privatization changes

"Participation handshake" this refers to the moment that the user's client sends the `askchaa` packet.

* Server::m_clients is now private. Get a copy with Server::getClients()
* Server::m_player_count is now private. Get a copy with Server::getPlayerCount() (Additional logic was added to handle the player count.)
* AOClient::m_joined is now private. Get a copy with AOClient::hasJoined()
* Added signal AOClient::joined(); will be emitted when the client first complete the participation handshake.
* Renamed Server::updatePlayerCount to Server::playerCountUpdated

* Privatized Server

* Made Server members private: m_characters, m_areas, m_area_names
* Added Server methods: getCharacters(), getAreas(), getAreaById(f_area_id), getAreaByName(f_area_name), getAreaNames(), getAreaName(f_area_id), getMusicList
* Added Server helper methods: getCharacterCount(), getAreaCount()
- This reduce code repetition of the following example: server->getCharacters().length(), server->getAreas().size()

* Solved other merge conflicts

* Added Server methods, various fixes

* Added Server methods: getCharacterById(f_chr_id)
* Various optimizations

* More Server privatization changes

* Made Server members private: db_manager, next_message_timer, can_send_ic_messages
* Renamed Server members:
  * next_message_timer -> m_message_floodguard_timer
  * can_send_ic_message -> m_can_send_ic_message
Added Server methods: getDatabaseManager, isMessageAllowed, startMessageFloodguard(f_duration)
Made Server methods private: allowMessage

* Added new fields to load for AreaData

* Added fields: `area_message` (default: empty string) and `send_area_message_on_join` (default: false)

* Added Server::clearAreaMessage

* Cleaned up headers include (AOPacket excluded)

* Removed most project file includes, moved to source file (cpp)
  * AOPacket was excluded because some methods modify the copy

* Fix compile error when using MingW compiler

* Appease clang by using proper or and putting it in parentheses
* Remove extra semicolon
This commit is contained in:
Leifa♥ 2022-04-25 21:54:15 +02:00 committed by Rosemary Witchaven
parent 2e7ad02bc3
commit b0555207d6
44 changed files with 2045 additions and 1675 deletions

21
.clang-format Normal file
View File

@ -0,0 +1,21 @@
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
BreakBeforeBraces: Custom
BreakConstructorInitializers: AfterColon
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterEnum: true
AfterFunction: true
AfterStruct: true
AfterExternBlock: true
BeforeElse: true
SplitEmptyFunction: false
ColumnLimit: 0
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: Always
FixNamespaceComments: false
IndentWidth: 4
PackConstructorInitializers: CurrentLine

View File

@ -15,21 +15,22 @@
// You should have received a copy of the GNU Affero General Public License // // You should have received a copy of the GNU Affero General Public License //
// along with this program. If not, see <https://www.gnu.org/licenses/>. // // along with this program. If not, see <https://www.gnu.org/licenses/>. //
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include <include/server.h>
#include <include/config_manager.h> #include <include/config_manager.h>
#include <include/server.h>
#include <cstdlib> #include <cstdlib>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
Server* server; Server *server;
void cleanup() { void cleanup()
{
server->deleteLater(); server->deleteLater();
} }
int main(int argc, char* argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName("akashi"); QCoreApplication::setApplicationName("akashi");

View File

@ -58,6 +58,7 @@ HEADERS += include/aoclient.h \
include/db_manager.h \ include/db_manager.h \
include/discord.h \ include/discord.h \
include/server.h \ include/server.h \
include/typedefs.h \
include/ws_client.h \ include/ws_client.h \
include/ws_proxy.h \ include/ws_proxy.h \
include/advertiser.h \ include/advertiser.h \

View File

@ -18,9 +18,8 @@
#ifndef ADVERTISER_H #ifndef ADVERTISER_H
#define ADVERTISER_H #define ADVERTISER_H
#include <QtNetwork>
#include <QObject> #include <QObject>
#include "include/config_manager.h" #include <QtNetwork>
/** /**
* @brief Represents the advertiser of the server. Sends current server information to masterserver. * @brief Represents the advertiser of the server. Sends current server information to masterserver.
@ -28,19 +27,19 @@
class Advertiser : public QObject class Advertiser : public QObject
{ {
Q_OBJECT Q_OBJECT
public:
public:
/** /**
* @brief Constructor for the HTTP_Advertiser class. * @brief Constructor for the HTTP_Advertiser class.
*/ */
explicit Advertiser(); explicit Advertiser();
/** /**
* @brief Deconstructor for the HTTP_Advertiser class. Yes, that's it. Can't say more about it. * @brief Deconstructor for the HTTP_Advertiser class. Yes, that's it. Can't say more about it.
*/ */
~Advertiser(); ~Advertiser();
public slots: public slots:
/** /**
* @brief Establishes a connection with masterserver to register or update the listing on the masterserver. * @brief Establishes a connection with masterserver to register or update the listing on the masterserver.
@ -63,12 +62,11 @@ public slots:
*/ */
void updateAdvertiserSettings(); void updateAdvertiserSettings();
private: private:
/** /**
* @brief Pointer to the network manager, necessary to execute POST requests to the masterserver. * @brief Pointer to the network manager, necessary to execute POST requests to the masterserver.
*/ */
QNetworkAccessManager* m_manager; QNetworkAccessManager *m_manager;
/** /**
* @brief Name of the server send to the masterserver. Changing this will change the display name in the serverlist * @brief Name of the server send to the masterserver. Changing this will change the display name in the serverlist

View File

@ -18,30 +18,32 @@
#ifndef AOCLIENT_H #ifndef AOCLIENT_H
#define AOCLIENT_H #define AOCLIENT_H
#include "include/aopacket.h"
#include "include/server.h"
#include "include/area_data.h"
#include "include/db_manager.h"
#include "include/music_manager.h"
#include <algorithm> #include <algorithm>
#include <QHostAddress>
#include <QTcpSocket>
#include <QDateTime> #include <QDateTime>
#include <QHostAddress>
#include <QRegularExpression> #include <QRegularExpression>
#include <QTcpSocket>
#include <QtGlobal> #include <QtGlobal>
#include <QTimer>
#if QT_VERSION > QT_VERSION_CHECK(5, 10, 0) #if QT_VERSION > QT_VERSION_CHECK(5, 10, 0)
#include <QRandomGenerator> #include <QRandomGenerator>
#endif #endif
#include "include/aopacket.h"
class AreaData;
class DBManager;
class MusicManager;
class Server; class Server;
/** /**
* @brief Represents a client connected to the server running Attorney Online 2 or one of its derivatives. * @brief Represents a client connected to the server running Attorney Online 2 or one of its derivatives.
*/ */
class AOClient : public QObject { class AOClient : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
/** /**
* @brief Creates an instance of the AOClient class. * @brief Creates an instance of the AOClient class.
@ -51,7 +53,7 @@ class AOClient : public QObject {
* @param user_id The user ID of the client. * @param user_id The user ID of the client.
* @param parent Qt-based parent, passed along to inherited constructor from QObject. * @param parent Qt-based parent, passed along to inherited constructor from QObject.
*/ */
AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent = nullptr, int user_id = 0, MusicManager* p_manager = nullptr);; AOClient(Server *p_server, QTcpSocket *p_socket, QObject *parent = nullptr, int user_id = 0, MusicManager *p_manager = nullptr);
/** /**
* @brief Destructor for the AOClient instance. * @brief Destructor for the AOClient instance.
@ -78,6 +80,13 @@ class AOClient : public QObject {
*/ */
QString getHwid() const; QString getHwid() const;
/**
* @brief Returns true if the client has completed the participation handshake. False otherwise.
*
* @return True if the client has completed the participation handshake. False otherwise.
*/
bool hasJoined() const;
/** /**
* @brief Calculates the client's IPID based on a hashed version of its IP. * @brief Calculates the client's IPID based on a hashed version of its IP.
*/ */
@ -92,7 +101,7 @@ class AOClient : public QObject {
* *
* @see #server * @see #server
*/ */
Server* getServer(); Server *getServer();
/** /**
* @brief The user ID of the client. * @brief The user ID of the client.
@ -197,7 +206,8 @@ class AOClient : public QObject {
* @note Though the version number and naming scheme looks vaguely semver-like, * @note Though the version number and naming scheme looks vaguely semver-like,
* do not be misled into thinking it is that. * do not be misled into thinking it is that.
*/ */
struct ClientVersion { struct ClientVersion
{
QString string; //!< The name of the client software, for example, `AO2`. QString string; //!< The name of the client software, for example, `AO2`.
int release = -1; //!< The 'release' part of the version number. In Attorney Online's case, this is fixed at `2`. int release = -1; //!< The 'release' part of the version number. In Attorney Online's case, this is fixed at `2`.
int major = -1; //!< The 'major' part of the version number. In Attorney Online's case, this increases when a new feature is introduced (generally). int major = -1; //!< The 'major' part of the version number. In Attorney Online's case, this increases when a new feature is introduced (generally).
@ -216,29 +226,27 @@ class AOClient : public QObject {
* *
* @showinitializer * @showinitializer
*/ */
QMap<QString, unsigned long long> ACLFlags { QMap<QString, unsigned long long> ACLFlags{
{"NONE", 0ULL }, {"NONE", 0ULL},
{"KICK", 1ULL << 0 }, {"KICK", 1ULL << 0},
{"BAN", 1ULL << 1 }, {"BAN", 1ULL << 1},
{"BGLOCK", 1ULL << 2 }, {"BGLOCK", 1ULL << 2},
{"MODIFY_USERS", 1ULL << 3 }, {"MODIFY_USERS", 1ULL << 3},
{"CM", 1ULL << 4 }, {"CM", 1ULL << 4},
{"GLOBAL_TIMER", 1ULL << 5 }, {"GLOBAL_TIMER", 1ULL << 5},
{"EVI_MOD", 1ULL << 6 }, {"EVI_MOD", 1ULL << 6},
{"MOTD", 1ULL << 7 }, {"MOTD", 1ULL << 7},
{"ANNOUNCE", 1ULL << 8 }, {"ANNOUNCE", 1ULL << 8},
{"MODCHAT", 1ULL << 9 }, {"MODCHAT", 1ULL << 9},
{"MUTE", 1ULL << 10}, {"MUTE", 1ULL << 10},
{"UNCM", 1ULL << 11}, {"UNCM", 1ULL << 11},
{"SAVETEST", 1ULL << 12}, {"SAVETEST", 1ULL << 12},
{"FORCE_CHARSELECT",1ULL << 13}, {"FORCE_CHARSELECT", 1ULL << 13},
{"BYPASS_LOCKS", 1ULL << 14}, {"BYPASS_LOCKS", 1ULL << 14},
{"IGNORE_BGLIST", 1ULL << 15}, {"IGNORE_BGLIST", 1ULL << 15},
{"SEND_NOTICE", 1ULL << 16}, {"SEND_NOTICE", 1ULL << 16},
{"JUKEBOX", 1ULL << 17}, {"JUKEBOX", 1ULL << 17},
{"SUPER", ~0ULL } {"SUPER", ~0ULL}};
};
/** /**
* @brief A list of 5 casing preferences (def, pro, judge, jury, steno) * @brief A list of 5 casing preferences (def, pro, judge, jury, steno)
@ -284,7 +292,7 @@ class AOClient : public QObject {
/** /**
* @brief Timer for tracking user interaction. Automatically restarted whenever a user interacts (i.e. sends any packet besides CH) * @brief Timer for tracking user interaction. Automatically restarted whenever a user interacts (i.e. sends any packet besides CH)
*/ */
QTimer* m_afk_timer; QTimer *m_afk_timer;
/** /**
* @brief The list of char IDs a charcursed player is allowed to switch to. * @brief The list of char IDs a charcursed player is allowed to switch to.
@ -344,21 +352,28 @@ class AOClient : public QObject {
*/ */
void onAfkTimeout(); void onAfkTimeout();
signals:
/**
* @brief This signal is emitted when the client has completed the participation handshake.
*/
void joined();
private: private:
/** /**
* @brief The TCP socket used to communicate with the client. * @brief The TCP socket used to communicate with the client.
*/ */
QTcpSocket* m_socket; QTcpSocket *m_socket;
/** /**
* @brief A pointer to the Server, used for updating server variables that depend on the client (e.g. amount of players in an area). * @brief A pointer to the Server, used for updating server variables that depend on the client (e.g. amount of players in an area).
*/ */
Server* server; Server *server;
/** /**
* @brief The type of area update, used for area update (ARUP) packets. * @brief The type of area update, used for area update (ARUP) packets.
*/ */
enum ARUPType { enum ARUPType
{
PLAYER_COUNT, //!< The packet contains player count updates. PLAYER_COUNT, //!< The packet contains player count updates.
STATUS, //!< The packet contains area status updates. STATUS, //!< The packet contains area status updates.
CM, //!< The packet contains updates about who's the CM of what area. CM, //!< The packet contains updates about who's the CM of what area.
@ -457,88 +472,87 @@ class AOClient : public QObject {
///@{ ///@{
/// A "default" packet handler, to be used for error checking and copying other packet handlers. /// A "default" packet handler, to be used for error checking and copying other packet handlers.
void pktDefault(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktDefault(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [hardware ID](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#hard-drive-id). /// Implements [hardware ID](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#hard-drive-id).
void pktHardwareId(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktHardwareId(AreaData *area, int argc, QStringList argv, AOPacket packet);
/** /**
* @brief Implements [feature list](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#feature-list) and * @brief Implements [feature list](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#feature-list) and
* [player count](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#player-count). * [player count](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#player-count).
*/ */
void pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktSoftwareId(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [resource counts](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#resource-counts). /// Implements [resource counts](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#resource-counts).
void pktBeginLoad(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktBeginLoad(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [character list](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#character-list). /// Implements [character list](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#character-list).
void pktRequestChars(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktRequestChars(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [music list](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#music-list). /// Implements [music list](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#music-list).
void pktRequestMusic(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktRequestMusic(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [the final loading confirmation](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#final-confirmation). /// Implements [the final loading confirmation](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#final-confirmation).
void pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktLoadingDone(AreaData *area, int argc, QStringList argv, AOPacket packet);
/** /**
* @brief Implements character passwording. This is not on the netcode documentation as of writing. * @brief Implements character passwording. This is not on the netcode documentation as of writing.
* *
* @todo Link packet details when it gets into the netcode documentation. * @todo Link packet details when it gets into the netcode documentation.
*/ */
void pktCharPassword(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktCharPassword(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [character selection](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#choose-character). /// Implements [character selection](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#choose-character).
void pktSelectChar(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktSelectChar(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [the in-character messaging hell](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#in-character-message). /// Implements [the in-character messaging hell](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#in-character-message).
void pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktIcChat(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [out-of-character messages](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#out-of-character-message). /// Implements [out-of-character messages](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#out-of-character-message).
void pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktOocChat(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [the keepalive packet](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#keep-alive). /// Implements [the keepalive packet](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#keep-alive).
void pktPing(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktPing(AreaData *area, int argc, QStringList argv, AOPacket packet);
/** /**
* @brief Implements [music](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#music) and * @brief Implements [music](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#music) and
* [area changing](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#switch-area). * [area changing](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#switch-area).
*/ */
void pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktChangeMusic(AreaData *area, int argc, QStringList argv, AOPacket packet);
/** /**
* @brief Implements [the witness testimony / cross examination / judge decision popups] * @brief Implements [the witness testimony / cross examination / judge decision popups]
* (https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#witness-testimonycross-examination-wtce). * (https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#witness-testimonycross-examination-wtce).
*/ */
void pktWtCe(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktWtCe(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [penalty bars](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#penalty-health-bars). /// Implements [penalty bars](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#penalty-health-bars).
void pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktHpBar(AreaData *area, int argc, QStringList argv, AOPacket packet);
/** /**
* @brief Implements WebSocket IP handling. This is not on the netcode documentation as of writing. * @brief Implements WebSocket IP handling. This is not on the netcode documentation as of writing.
* *
* @todo Link packet details when it gets into the netcode documentation. * @todo Link packet details when it gets into the netcode documentation.
*/ */
void pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktWebSocketIp(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [moderator calling](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#call-mod). /// Implements [moderator calling](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#call-mod).
void pktModCall(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktModCall(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [adding evidence](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#add). /// Implements [adding evidence](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#add).
void pktAddEvidence(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktAddEvidence(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [removing evidence](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#remove). /// Implements [removing evidence](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#remove).
void pktRemoveEvidence(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktRemoveEvidence(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [editing evidence](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#edit). /// Implements [editing evidence](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#edit).
void pktEditEvidence(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktEditEvidence(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [updating casing preferences](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#case-preferences-update). /// Implements [updating casing preferences](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#case-preferences-update).
void pktSetCase(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktSetCase(AreaData *area, int argc, QStringList argv, AOPacket packet);
/// Implements [announcing a case](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#case-alert). /// Implements [announcing a case](https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#case-alert).
void pktAnnounceCase(AreaData* area, int argc, QStringList argv, AOPacket packet); void pktAnnounceCase(AreaData *area, int argc, QStringList argv, AOPacket packet);
///@} ///@}
@ -552,14 +566,14 @@ class AOClient : public QObject {
* *
* @param area The current client's area. * @param area The current client's area.
*/ */
void sendEvidenceList(AreaData* area); void sendEvidenceList(AreaData *area);
/** /**
* @brief Updates the evidence list in the area for the client. * @brief Updates the evidence list in the area for the client.
* *
* @param area The client's area. * @param area The client's area.
*/ */
void updateEvidenceList(AreaData* area); void updateEvidenceList(AreaData *area);
/** /**
* @brief Attempts to validate that hellish abomination that Attorney Online 2 calls an in-character packet. * @brief Attempts to validate that hellish abomination that Attorney Online 2 calls an in-character packet.
@ -588,7 +602,7 @@ class AOClient : public QObject {
* *
* @return True if the client can modify the evidence, false if not. * @return True if the client can modify the evidence, false if not.
*/ */
bool checkEvidenceAccess(AreaData* area); bool checkEvidenceAccess(AreaData *area);
///@} ///@}
@ -644,10 +658,11 @@ class AOClient : public QObject {
///@} ///@}
/// Describes a packet's interpretation details. /// Describes a packet's interpretation details.
struct PacketInfo { struct PacketInfo
{
unsigned long long acl_mask; //!< The permissions necessary for the packet. unsigned long long acl_mask; //!< The permissions necessary for the packet.
int minArgs; //!< The minimum arguments needed for the packet to be interpreted correctly / make sense. int minArgs; //!< The minimum arguments needed for the packet to be interpreted correctly / make sense.
void (AOClient::*action)(AreaData*, int, QStringList, AOPacket); void (AOClient::*action)(AreaData *, int, QStringList, AOPacket);
}; };
/** /**
@ -670,28 +685,28 @@ class AOClient : public QObject {
* @tparam PacketInfo The details of the packet. * @tparam PacketInfo The details of the packet.
* See @ref PacketInfo "the type's documentation" for more details. * See @ref PacketInfo "the type's documentation" for more details.
*/ */
const QMap<QString, PacketInfo> packets { const QMap<QString, PacketInfo> packets{
{"HI", {ACLFlags.value("NONE"), 1, &AOClient::pktHardwareId }}, {"HI", {ACLFlags.value("NONE"), 1, &AOClient::pktHardwareId}},
{"ID", {ACLFlags.value("NONE"), 2, &AOClient::pktSoftwareId }}, {"ID", {ACLFlags.value("NONE"), 2, &AOClient::pktSoftwareId}},
{"askchaa", {ACLFlags.value("NONE"), 0, &AOClient::pktBeginLoad }}, {"askchaa", {ACLFlags.value("NONE"), 0, &AOClient::pktBeginLoad}},
{"RC", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestChars }}, {"RC", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestChars}},
{"RM", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestMusic }}, {"RM", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestMusic}},
{"RD", {ACLFlags.value("NONE"), 0, &AOClient::pktLoadingDone }}, {"RD", {ACLFlags.value("NONE"), 0, &AOClient::pktLoadingDone}},
{"PW", {ACLFlags.value("NONE"), 1, &AOClient::pktCharPassword }}, {"PW", {ACLFlags.value("NONE"), 1, &AOClient::pktCharPassword}},
{"CC", {ACLFlags.value("NONE"), 3, &AOClient::pktSelectChar }}, {"CC", {ACLFlags.value("NONE"), 3, &AOClient::pktSelectChar}},
{"MS", {ACLFlags.value("NONE"), 15, &AOClient::pktIcChat }}, {"MS", {ACLFlags.value("NONE"), 15, &AOClient::pktIcChat}},
{"CT", {ACLFlags.value("NONE"), 2, &AOClient::pktOocChat }}, {"CT", {ACLFlags.value("NONE"), 2, &AOClient::pktOocChat}},
{"CH", {ACLFlags.value("NONE"), 1, &AOClient::pktPing }}, {"CH", {ACLFlags.value("NONE"), 1, &AOClient::pktPing}},
{"MC", {ACLFlags.value("NONE"), 2, &AOClient::pktChangeMusic }}, {"MC", {ACLFlags.value("NONE"), 2, &AOClient::pktChangeMusic}},
{"RT", {ACLFlags.value("NONE"), 1, &AOClient::pktWtCe }}, {"RT", {ACLFlags.value("NONE"), 1, &AOClient::pktWtCe}},
{"HP", {ACLFlags.value("NONE"), 2, &AOClient::pktHpBar }}, {"HP", {ACLFlags.value("NONE"), 2, &AOClient::pktHpBar}},
{"WSIP", {ACLFlags.value("NONE"), 1, &AOClient::pktWebSocketIp }}, {"WSIP", {ACLFlags.value("NONE"), 1, &AOClient::pktWebSocketIp}},
{"ZZ", {ACLFlags.value("NONE"), 0, &AOClient::pktModCall }}, {"ZZ", {ACLFlags.value("NONE"), 0, &AOClient::pktModCall}},
{"PE", {ACLFlags.value("NONE"), 3, &AOClient::pktAddEvidence }}, {"PE", {ACLFlags.value("NONE"), 3, &AOClient::pktAddEvidence}},
{"DE", {ACLFlags.value("NONE"), 1, &AOClient::pktRemoveEvidence }}, {"DE", {ACLFlags.value("NONE"), 1, &AOClient::pktRemoveEvidence}},
{"EE", {ACLFlags.value("NONE"), 4, &AOClient::pktEditEvidence }}, {"EE", {ACLFlags.value("NONE"), 4, &AOClient::pktEditEvidence}},
{"SETCASE", {ACLFlags.value("NONE"), 7, &AOClient::pktSetCase }}, {"SETCASE", {ACLFlags.value("NONE"), 7, &AOClient::pktSetCase}},
{"CASEA", {ACLFlags.value("NONE"), 6, &AOClient::pktAnnounceCase }}, {"CASEA", {ACLFlags.value("NONE"), 6, &AOClient::pktAnnounceCase}},
}; };
/** /**
@ -1178,7 +1193,6 @@ class AOClient : public QObject {
*/ */
void cmdBans(int argc, QStringList argv); void cmdBans(int argc, QStringList argv);
/** /**
* @brief Toggle whether or not in-character messages purely consisting of spaces are allowed. * @brief Toggle whether or not in-character messages purely consisting of spaces are allowed.
* *
@ -1766,7 +1780,6 @@ class AOClient : public QObject {
*/ */
void cmdAddStatement(int argc, QStringList argv); void cmdAddStatement(int argc, QStringList argv);
/** /**
* @brief Sends a list of the testimony to OOC of the requesting client * @brief Sends a list of the testimony to OOC of the requesting client
* *
@ -2026,7 +2039,6 @@ class AOClient : public QObject {
*/ */
void sendNotice(QString f_notice, bool f_global = false); void sendNotice(QString f_notice, bool f_global = false);
/** /**
* @brief Checks if a testimony contains '<' or '>'. * @brief Checks if a testimony contains '<' or '>'.
* *
@ -2034,7 +2046,7 @@ class AOClient : public QObject {
* *
* @return True if it contains '<' or '>' symbols, otherwise false. * @return True if it contains '<' or '>' symbols, otherwise false.
*/ */
bool checkTestimonySymbols(const QString& message); bool checkTestimonySymbols(const QString &message);
///@} ///@}
/** /**
@ -2048,7 +2060,8 @@ class AOClient : public QObject {
/** /**
* @brief Describes a command's details. * @brief Describes a command's details.
*/ */
struct CommandInfo { struct CommandInfo
{
unsigned long long acl_mask; //!< The permissions necessary to be able to run the command. @see ACLFlags. unsigned long long acl_mask; //!< The permissions necessary to be able to run the command. @see ACLFlags.
int minArgs; //!< The minimum mandatory arguments needed for the command to function. int minArgs; //!< The minimum mandatory arguments needed for the command to function.
void (AOClient::*action)(int, QStringList); void (AOClient::*action)(int, QStringList);
@ -2073,7 +2086,7 @@ class AOClient : public QObject {
* @tparam CommandInfo The details of the command. * @tparam CommandInfo The details of the command.
* See @ref CommandInfo "the type's documentation" for more details. * See @ref CommandInfo "the type's documentation" for more details.
*/ */
const QMap<QString, CommandInfo> commands { const QMap<QString, CommandInfo> commands{
{"login", {ACLFlags.value("NONE"), 0, &AOClient::cmdLogin}}, {"login", {ACLFlags.value("NONE"), 0, &AOClient::cmdLogin}},
{"getareas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}}, {"getareas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}},
{"gas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}}, {"gas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}},
@ -2198,8 +2211,8 @@ class AOClient : public QObject {
{"updateban", {ACLFlags.value("BAN"), 3, &AOClient::cmdUpdateBan}}, {"updateban", {ACLFlags.value("BAN"), 3, &AOClient::cmdUpdateBan}},
{"update_ban", {ACLFlags.value("BAN"), 3, &AOClient::cmdUpdateBan}}, {"update_ban", {ACLFlags.value("BAN"), 3, &AOClient::cmdUpdateBan}},
{"changepass", {ACLFlags.value("NONE"), 1, &AOClient::cmdChangePassword}}, {"changepass", {ACLFlags.value("NONE"), 1, &AOClient::cmdChangePassword}},
{"ignorebglist", {ACLFlags.value("IGNORE_BGLIST"),0, &AOClient::cmdIgnoreBgList}}, {"ignorebglist", {ACLFlags.value("IGNORE_BGLIST"), 0, &AOClient::cmdIgnoreBgList}},
{"ignore_bglist", {ACLFlags.value("IGNORE_BGLIST"),0, &AOClient::cmdIgnoreBgList}}, {"ignore_bglist", {ACLFlags.value("IGNORE_BGLIST"), 0, &AOClient::cmdIgnoreBgList}},
{"notice", {ACLFlags.value("SEND_NOTICE"), 1, &AOClient::cmdNotice}}, {"notice", {ACLFlags.value("SEND_NOTICE"), 1, &AOClient::cmdNotice}},
{"noticeg", {ACLFlags.value("SEND_NOTICE"), 1, &AOClient::cmdNoticeGlobal}}, {"noticeg", {ACLFlags.value("SEND_NOTICE"), 1, &AOClient::cmdNoticeGlobal}},
{"togglejukebox", {ACLFlags.value("None"), 0, &AOClient::cmdToggleJukebox}}, {"togglejukebox", {ACLFlags.value("None"), 0, &AOClient::cmdToggleJukebox}},
@ -2212,8 +2225,7 @@ class AOClient : public QObject {
{"addcategory", {ACLFlags.value("CM"), 1, &AOClient::cmdAddCategory}}, {"addcategory", {ACLFlags.value("CM"), 1, &AOClient::cmdAddCategory}},
{"removeentry", {ACLFlags.value("CM"), 1, &AOClient::cmdRemoveCategorySong}}, {"removeentry", {ACLFlags.value("CM"), 1, &AOClient::cmdRemoveCategorySong}},
{"toggleroot", {ACLFlags.value("CM"), 0, &AOClient::cmdToggleRootlist}}, {"toggleroot", {ACLFlags.value("CM"), 0, &AOClient::cmdToggleRootlist}},
{"clearcustom", {ACLFlags.value("CM"), 0, &AOClient::cmdClearCustom}} {"clearcustom", {ACLFlags.value("CM"), 0, &AOClient::cmdClearCustom}}};
};
/** /**
* @brief Filled with part of a packet if said packet could not be read fully from the client's socket. * @brief Filled with part of a packet if said packet could not be read fully from the client's socket.
@ -2264,7 +2276,7 @@ class AOClient : public QObject {
/** /**
* @brief Pointer to the servers music manager instance. * @brief Pointer to the servers music manager instance.
*/ */
MusicManager* m_music_manager; MusicManager *m_music_manager;
/** /**
* @brief A helper function to add recorded packets to an area's judgelog. * @brief A helper function to add recorded packets to an area's judgelog.
@ -2275,7 +2287,7 @@ class AOClient : public QObject {
* *
* @param action String containing the info that is being recorded. * @param action String containing the info that is being recorded.
*/ */
void updateJudgeLog(AreaData* area, AOClient* client, QString action); void updateJudgeLog(AreaData *area, AOClient *client, QString action);
/** /**
* @brief A helper function for decoding AO encoding from a QString. * @brief A helper function for decoding AO encoding from a QString.
@ -2301,47 +2313,47 @@ class AOClient : public QObject {
/** /**
* @brief Signal connected to universal logger. Sends IC chat usage to the logger. * @brief Signal connected to universal logger. Sends IC chat usage to the logger.
*/ */
void logIC(const QString& f_charName, const QString& f_oocName, const QString& f_ipid, void logIC(const QString &f_charName, const QString &f_oocName, const QString &f_ipid,
const QString& f_areaName, const QString &f_message); const QString &f_areaName, const QString &f_message);
/** /**
* @brief Signal connected to universal logger. Sends OOC chat usage to the logger. * @brief Signal connected to universal logger. Sends OOC chat usage to the logger.
*/ */
void logOOC(const QString& f_charName, const QString& f_oocName, const QString& f_ipid, void logOOC(const QString &f_charName, const QString &f_oocName, const QString &f_ipid,
const QString& f_areaName, const QString& f_message); const QString &f_areaName, const QString &f_message);
/** /**
* @brief Signal connected to universal logger. Sends login attempt to the logger. * @brief Signal connected to universal logger. Sends login attempt to the logger.
*/ */
void logLogin(const QString& f_charName, const QString& f_oocName, const QString& f_moderatorName, void logLogin(const QString &f_charName, const QString &f_oocName, const QString &f_moderatorName,
const QString& f_ipid, const QString &f_areaName, const bool& f_success); const QString &f_ipid, const QString &f_areaName, const bool &f_success);
/** /**
* @brief Signal connected to universal logger. Sends command usage to the logger. * @brief Signal connected to universal logger. Sends command usage to the logger.
*/ */
void logCMD(const QString& f_charName, const QString &f_ipid, const QString& f_oocName, const QString f_command, void logCMD(const QString &f_charName, const QString &f_ipid, const QString &f_oocName, const QString f_command,
const QStringList f_args, const QString f_areaName); const QStringList f_args, const QString f_areaName);
/** /**
* @brief Signal connected to universal logger. Sends player kick information to the logger. * @brief Signal connected to universal logger. Sends player kick information to the logger.
*/ */
void logKick(const QString& f_moderator, const QString& f_targetIPID, const QString& f_reason); void logKick(const QString &f_moderator, const QString &f_targetIPID, const QString &f_reason);
/** /**
* @brief Signal connected to universal logger. Sends ban information to the logger. * @brief Signal connected to universal logger. Sends ban information to the logger.
*/ */
void logBan(const QString& f_moderator, const QString& f_targetIPID, const QString &f_duration, const QString& f_reason); void logBan(const QString &f_moderator, const QString &f_targetIPID, const QString &f_duration, const QString &f_reason);
/** /**
* @brief Signal connected to universal logger. Sends modcall information to the logger, triggering a write of the buffer * @brief Signal connected to universal logger. Sends modcall information to the logger, triggering a write of the buffer
* when modcall logging is used. * when modcall logging is used.
*/ */
void logModcall(const QString& f_charName, const QString &f_ipid, const QString& f_oocName, const QString& f_areaName); void logModcall(const QString &f_charName, const QString &f_ipid, const QString &f_oocName, const QString &f_areaName);
/** /**
* @brief Signals the server that the client has disconnected and marks its userID as free again. * @brief Signals the server that the client has disconnected and marks its userID as free again.
*/ */
void clientSuccessfullyDisconnected(const int& f_user_id); void clientSuccessfullyDisconnected(const int &f_user_id);
}; };
#endif // AOCLIENT_H #endif // AOCLIENT_H

View File

@ -29,7 +29,8 @@
* @see https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md for a general explanation * @see https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md for a general explanation
* on Attorney Online 2's network protocol. * on Attorney Online 2's network protocol.
*/ */
class AOPacket { class AOPacket
{
public: public:
/** /**
* @brief Creates an AOPacket with the given header and contents. * @brief Creates an AOPacket with the given header and contents.

View File

@ -18,25 +18,27 @@
#ifndef AREA_DATA_H #ifndef AREA_DATA_H
#define AREA_DATA_H #define AREA_DATA_H
#include "aopacket.h"
#include "config_manager.h"
#include "music_manager.h"
#include <QMap>
#include <QString>
#include <QSettings>
#include <QDebug> #include <QDebug>
#include <QTimer>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QMap>
#include <QRandomGenerator> #include <QRandomGenerator>
#include <QSettings>
#include <QString>
#include <QTimer>
#include "include/aopacket.h"
class ConfigManager;
class Logger; class Logger;
class MusicManager;
/** /**
* @brief Represents an area on the server, a distinct "room" for people to chat in. * @brief Represents an area on the server, a distinct "room" for people to chat in.
*/ */
class AreaData : public QObject { class AreaData : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
/** /**
* @brief Constructor for the AreaData class. * @brief Constructor for the AreaData class.
@ -45,12 +47,13 @@ class AreaData : public QObject {
* and `YYYYYY` is the actual name of the area. * and `YYYYYY` is the actual name of the area.
* @param p_index The index of the area in the area list. * @param p_index The index of the area in the area list.
*/ */
AreaData(QString p_name, int p_index, MusicManager* p_music_manager); AreaData(QString p_name, int p_index, MusicManager *p_music_manager);
/** /**
* @brief The data for evidence in the area. * @brief The data for evidence in the area.
*/ */
struct Evidence { struct Evidence
{
QString name; //!< The name of the evidence, shown when hovered over clientside. QString name; //!< The name of the evidence, shown when hovered over clientside.
QString description; //!< The longer description of the evidence, when the user opens the evidence window. QString description; //!< The longer description of the evidence, when the user opens the evidence window.
QString image; //!< A path originating from `base/evidence/` that points to an image file. QString image; //!< A path originating from `base/evidence/` that points to an image file.
@ -62,7 +65,8 @@ class AreaData : public QObject {
* @details This is purely aesthetic, and serves no functional purpose from a gameplay perspective. * @details This is purely aesthetic, and serves no functional purpose from a gameplay perspective.
* It's only benefit is giving the users a rough idea as to what is going on in an area. * It's only benefit is giving the users a rough idea as to what is going on in an area.
*/ */
enum Status { enum Status
{
IDLE, //!< The area is currently not busy with anything, or the area is empty. IDLE, //!< The area is currently not busy with anything, or the area is empty.
RP, //!< There is some (non-Ace Attorney-related) roleplay going on in the area. RP, //!< There is some (non-Ace Attorney-related) roleplay going on in the area.
CASING, //!< An Ace Attorney or Danganronpa-styled case is currently being held in the area. CASING, //!< An Ace Attorney or Danganronpa-styled case is currently being held in the area.
@ -77,7 +81,8 @@ class AreaData : public QObject {
/** /**
* @brief Determines who may traverse and communicate in the area. * @brief Determines who may traverse and communicate in the area.
*/ */
enum LockStatus { enum LockStatus
{
FREE, FREE,
LOCKED, LOCKED,
SPECTATABLE SPECTATABLE
@ -110,7 +115,8 @@ class AreaData : public QObject {
/** /**
* @brief The level of "authorisation" needed to be able to modify, add, and remove evidence in the area. * @brief The level of "authorisation" needed to be able to modify, add, and remove evidence in the area.
*/ */
enum class EvidenceMod{ enum class EvidenceMod
{
FFA, FFA,
MOD, MOD,
CM, CM,
@ -144,7 +150,8 @@ class AreaData : public QObject {
/** /**
* @brief The five "states" the testimony recording system can have in an area. * @brief The five "states" the testimony recording system can have in an area.
*/ */
enum TestimonyRecording{ enum TestimonyRecording
{
STOPPED, STOPPED,
RECORDING, RECORDING,
UPDATE, UPDATE,
@ -190,7 +197,8 @@ class AreaData : public QObject {
* @brief Determines how the testimony progressed after advancement was called in a direction * @brief Determines how the testimony progressed after advancement was called in a direction
* (Either to next or previous statement). * (Either to next or previous statement).
*/ */
enum class TestimonyProgress { enum class TestimonyProgress
{
OK, //!< The expected statement was selected. OK, //!< The expected statement was selected.
LOOPED, //!< The "next" statement would have been beyond the testimony's limits, so the first one was selected. LOOPED, //!< The "next" statement would have been beyond the testimony's limits, so the first one was selected.
STAYED_AT_FIRST, //!< The "previous" statement would have been before the first, so the selection stayed at the first. STAYED_AT_FIRST, //!< The "previous" statement would have been before the first, so the selection stayed at the first.
@ -199,7 +207,8 @@ class AreaData : public QObject {
/** /**
* @brief Determines a side. Self-explanatory. * @brief Determines a side. Self-explanatory.
*/ */
enum class Side { enum class Side
{
DEFENCE, //!< Self-explanatory. DEFENCE, //!< Self-explanatory.
PROSECUTOR, //!< Self-explanatory. PROSECUTOR, //!< Self-explanatory.
}; };
@ -411,7 +420,7 @@ class AreaData : public QObject {
* *
* @param f_evi_r The evidence to append. * @param f_evi_r The evidence to append.
*/ */
void appendEvidence(const Evidence& f_evi_r); void appendEvidence(const Evidence &f_evi_r);
/** /**
* @brief Deletes a piece of evidence from the list of evidence. * @brief Deletes a piece of evidence from the list of evidence.
@ -426,7 +435,7 @@ class AreaData : public QObject {
* @param f_eviId The ID of the evidence to replace. * @param f_eviId The ID of the evidence to replace.
* @param f_newEvi_r The new piece of evidence that will replace the aforementioned one. * @param f_newEvi_r The new piece of evidence that will replace the aforementioned one.
*/ */
void replaceEvidence(int f_eviId, const Evidence& f_newEvi_r); void replaceEvidence(int f_eviId, const Evidence &f_newEvi_r);
/** /**
* @brief Returns the status of the area. * @brief Returns the status of the area.
@ -444,7 +453,7 @@ class AreaData : public QObject {
* *
* @see #map_statuses * @see #map_statuses
*/ */
bool changeStatus(const QString& f_newStatus_r); bool changeStatus(const QString &f_newStatus_r);
/** /**
* @brief Returns a copy of the list of invited clients. * @brief Returns a copy of the list of invited clients.
@ -546,7 +555,7 @@ class AreaData : public QObject {
* *
* @see #m_document * @see #m_document
*/ */
void changeDoc(const QString& f_newDoc_r); void changeDoc(const QString &f_newDoc_r);
/** /**
* @brief Returns the message of the area. * @brief Returns the message of the area.
@ -569,7 +578,12 @@ class AreaData : public QObject {
* *
* @param f_newMessage_r The new message. * @param f_newMessage_r The new message.
*/ */
void changeAreaMessage(const QString& f_newMessage_r); void changeAreaMessage(const QString &f_newMessage_r);
/**
* @brief Clear the area message in the area.
*/
void clearAreaMessage();
/** /**
* @brief Returns the value of the Confidence bar for the defence's side. * @brief Returns the value of the Confidence bar for the defence's side.
@ -632,7 +646,7 @@ class AreaData : public QObject {
* *
* @see #m_musicPlayedBy * @see #m_musicPlayedBy
*/ */
void setMusicPlayedBy(const QString& f_music_player); void setMusicPlayedBy(const QString &f_music_player);
/** /**
* @brief Changes the music being played in the area. * @brief Changes the music being played in the area.
@ -640,7 +654,7 @@ class AreaData : public QObject {
* @param f_source_r The showname of the client who initiated the music change. * @param f_source_r The showname of the client who initiated the music change.
* @param f_newSong_r The name of the new song that is going to be played in the area. * @param f_newSong_r The name of the new song that is going to be played in the area.
*/ */
void changeMusic(const QString& f_source_r, const QString& f_newSong_r); void changeMusic(const QString &f_source_r, const QString &f_newSong_r);
/** /**
* @brief Returns the evidence mod in the area. * @brief Returns the evidence mod in the area.
@ -666,7 +680,7 @@ class AreaData : public QObject {
* *
* @return True if the notecard didn't replace a previous one, false if it did. * @return True if the notecard didn't replace a previous one, false if it did.
*/ */
bool addNotecard(const QString& f_owner_r, const QString& f_notecard_r); bool addNotecard(const QString &f_owner_r, const QString &f_notecard_r);
/** /**
* @brief Returns the list of notecards recorded in the area. * @brief Returns the list of notecards recorded in the area.
@ -708,7 +722,7 @@ class AreaData : public QObject {
* *
* @note Unlike most other getters, this one returns a reference, as it is expected to be used frequently. * @note Unlike most other getters, this one returns a reference, as it is expected to be used frequently.
*/ */
const QVector<QStringList>& testimony() const; const QVector<QStringList> &testimony() const;
/** /**
* @brief Returns the index of the currently examined statement in the testimony. * @brief Returns the index of the currently examined statement in the testimony.
@ -722,7 +736,7 @@ class AreaData : public QObject {
* *
* @param f_newStatement_r The IC message packet to append to the testimony vector. * @param f_newStatement_r The IC message packet to append to the testimony vector.
*/ */
void recordStatement(const QStringList& f_newStatement_r); void recordStatement(const QStringList &f_newStatement_r);
/** /**
* @brief Adds a statement into the testimony to a given position. * @brief Adds a statement into the testimony to a given position.
@ -730,7 +744,7 @@ class AreaData : public QObject {
* @param f_position The index to insert the statement to. * @param f_position The index to insert the statement to.
* @param f_newStatement_r The IC message packet to insert. * @param f_newStatement_r The IC message packet to insert.
*/ */
void addStatement(int f_position, const QStringList& f_newStatement_r); void addStatement(int f_position, const QStringList &f_newStatement_r);
/** /**
* @brief Replaces an already existing statement in the testimony in a given position with a new one. * @brief Replaces an already existing statement in the testimony in a given position with a new one.
@ -738,7 +752,7 @@ class AreaData : public QObject {
* @param f_position The index of the statement to replace. * @param f_position The index of the statement to replace.
* @param f_newStatement_r The IC message packet to insert in the old one's stead. * @param f_newStatement_r The IC message packet to insert in the old one's stead.
*/ */
void replaceStatement(int f_position, const QStringList& f_newStatement_r); void replaceStatement(int f_position, const QStringList &f_newStatement_r);
/** /**
* @brief Removes a statement from the testimony at a given position, and moves the statement index one backward. * @brief Removes a statement from the testimony at a given position, and moves the statement index one backward.
@ -780,21 +794,21 @@ class AreaData : public QObject {
* *
* @param f_newLog_r The new line to append to the judgelog. * @param f_newLog_r The new line to append to the judgelog.
*/ */
void appendJudgelog(const QString& f_newLog_r); void appendJudgelog(const QString &f_newLog_r);
/** /**
* @brief Returns the last IC message sent in the area. * @brief Returns the last IC message sent in the area.
* *
* @return See short description. * @return See short description.
*/ */
const QStringList& lastICMessage() const; const QStringList &lastICMessage() const;
/** /**
* @brief Updates the last IC message sent in the area. * @brief Updates the last IC message sent in the area.
* *
* @param f_lastMessage_r The new last IC message. * @param f_lastMessage_r The new last IC message.
*/ */
void updateLastICMessage(const QStringList& f_lastMessage_r); void updateLastICMessage(const QStringList &f_lastMessage_r);
/** /**
* @brief Returns whether ~~non-interrupting~~ immediate messages are forced in the area. * @brief Returns whether ~~non-interrupting~~ immediate messages are forced in the area.
@ -856,7 +870,7 @@ class AreaData : public QObject {
*/ */
QVector<int> joinedIDs() const; QVector<int> joinedIDs() const;
public slots: public slots:
/** /**
* @brief Plays a random song from the jukebox. Plays the same if only one is left. * @brief Plays a random song from the jukebox. Plays the same if only one is left.
@ -891,11 +905,11 @@ public slots:
*/ */
void userJoinedArea(int f_area_index, int f_user_id); void userJoinedArea(int f_area_index, int f_user_id);
private: private:
/** /**
* @brief The list of timers available in the area. * @brief The list of timers available in the area.
*/ */
QList<QTimer*> m_timers; QList<QTimer *> m_timers;
/** /**
* @brief The user-facing and internal name of the area. * @brief The user-facing and internal name of the area.
@ -910,7 +924,7 @@ private:
/** /**
* @brief Pointer to the global music manager. * @brief Pointer to the global music manager.
*/ */
MusicManager* m_music_manager; MusicManager *m_music_manager;
/** /**
* @brief A list of the character IDs of all characters taken. * @brief A list of the character IDs of all characters taken.
@ -1036,7 +1050,7 @@ private:
/** /**
* @brief A pointer to a Logger, used to send requests to log data. * @brief A pointer to a Logger, used to send requests to log data.
*/ */
Logger* m_logger; Logger *m_logger;
/** /**
* @brief The evidence mod of the area. * @brief The evidence mod of the area.
@ -1061,7 +1075,6 @@ private:
*/ */
TestimonyRecording m_testimonyRecording; TestimonyRecording m_testimonyRecording;
QVector<QStringList> m_testimony; //!< Vector of all statements saved. Index 0 is always the title of the testimony. QVector<QStringList> m_testimony; //!< Vector of all statements saved. Index 0 is always the title of the testimony.
int m_statement; //!< Keeps track of the currently played statement. int m_statement; //!< Keeps track of the currently played statement.
@ -1077,7 +1090,6 @@ private:
*/ */
QStringList m_lastICMessage; QStringList m_lastICMessage;
/** /**
* @brief Whether or not to force immediate text processing in this area. * @brief Whether or not to force immediate text processing in this area.
*/ */
@ -1118,7 +1130,7 @@ private:
* @details While this may be considered bad design, I do not care. * @details While this may be considered bad design, I do not care.
* It triggers a direct broadcast of the MC packet in the area. * It triggers a direct broadcast of the MC packet in the area.
*/ */
QTimer* m_jukebox_timer; QTimer *m_jukebox_timer;
/** /**
* @brief Wether or not the jukebox is enabled in this area. * @brief Wether or not the jukebox is enabled in this area.

View File

@ -20,29 +20,29 @@
#define CONFIG_VERSION 1 #define CONFIG_VERSION 1
#include "data_types.h"
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QElapsedTimer>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QHostAddress>
#include <QMetaEnum>
#include <QSettings> #include <QSettings>
#include <QUrl> #include <QUrl>
#include <QMetaEnum>
#include <QElapsedTimer>
#include <QHostAddress>
//JSON loading requirements // JSON loading requirements
#include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray>
typedef QMap<QString,QPair<QString,int>> MusicList; #include "include/data_types.h"
#include "include/typedefs.h"
/** /**
* @brief The config file handler class. * @brief The config file handler class.
*/ */
class ConfigManager { class ConfigManager
{
public: public:
/** /**
@ -99,7 +99,7 @@ class ConfigManager {
* *
* @return See short description. * @return See short description.
*/ */
static QSettings* areaData(); static QSettings *areaData();
/** /**
* @brief Returns a sanitized QStringList of the areas. * @brief Returns a sanitized QStringList of the areas.
@ -451,7 +451,8 @@ class ConfigManager {
* @brief A struct that contains the help information for a command. * @brief A struct that contains the help information for a command.
* It's split in the syntax and the explanation text. * It's split in the syntax and the explanation text.
*/ */
struct help { struct help
{
QString usage; QString usage;
QString text; QString text;
}; };
@ -482,8 +483,7 @@ class ConfigManager {
*/ */
static void reloadSettings(); static void reloadSettings();
private:
private:
/** /**
* @brief Checks if a file exists and is valid. * @brief Checks if a file exists and is valid.
* *
@ -491,7 +491,7 @@ private:
* *
* @return True if the file exists and is valid, false otherwise. * @return True if the file exists and is valid, false otherwise.
*/ */
static bool fileExists(const QFileInfo& file); static bool fileExists(const QFileInfo &file);
/** /**
* @brief Checks if a directory exists and is valid. * @brief Checks if a directory exists and is valid.
@ -500,12 +500,13 @@ private:
* *
* @return True if the directory exists and is valid, false otherwise. * @return True if the directory exists and is valid, false otherwise.
*/ */
static bool dirExists(const QFileInfo& dir); static bool dirExists(const QFileInfo &dir);
/** /**
* @brief A struct for storing QStringLists loaded from command configuration files. * @brief A struct for storing QStringLists loaded from command configuration files.
*/ */
struct CommandSettings { struct CommandSettings
{
QStringList magic_8ball; //!< Contains answers for /8ball, found in config/text/8ball.txt QStringList magic_8ball; //!< Contains answers for /8ball, found in config/text/8ball.txt
QStringList praises; //!< Contains command praises, found in config/text/praises.txt QStringList praises; //!< Contains command praises, found in config/text/praises.txt
QStringList reprimands; //!< Contains command reprimands, found in config/text/reprimands.txt QStringList reprimands; //!< Contains command reprimands, found in config/text/reprimands.txt
@ -516,47 +517,47 @@ private:
/** /**
* @brief Contains the settings required for various commands. * @brief Contains the settings required for various commands.
*/ */
static CommandSettings* m_commands; static CommandSettings *m_commands;
/** /**
* @brief Stores all server configuration values. * @brief Stores all server configuration values.
*/ */
static QSettings* m_settings; static QSettings *m_settings;
/** /**
* @brief Stores all discord webhook configuration values. * @brief Stores all discord webhook configuration values.
*/ */
static QSettings* m_discord; static QSettings *m_discord;
/** /**
* @brief Stores all of the area valus. * @brief Stores all of the area valus.
*/ */
static QSettings* m_areas; static QSettings *m_areas;
/** /**
* @brief Stores all adjustable logstrings. * @brief Stores all adjustable logstrings.
*/ */
static QSettings* m_logtext; static QSettings *m_logtext;
/** /**
* @brief Pointer to QElapsedTimer to track the uptime of the server. * @brief Pointer to QElapsedTimer to track the uptime of the server.
*/ */
static QElapsedTimer* m_uptimeTimer; static QElapsedTimer *m_uptimeTimer;
/** /**
* @brief Contains the musiclist with time durations. * @brief Contains the musiclist with time durations.
*/ */
static MusicList* m_musicList; static MusicList *m_musicList;
/** /**
* @brief Contains an ordered list for the musiclist. * @brief Contains an ordered list for the musiclist.
*/ */
static QStringList* m_ordered_list; static QStringList *m_ordered_list;
/** /**
* @brief QHash containing the help information for all commands registered to the server. * @brief QHash containing the help information for all commands registered to the server.
*/ */
static QHash<QString,help>* m_commands_help; static QHash<QString, help> *m_commands_help;
/** /**
* @brief Returns a stringlist with the contents of a .txt file from config/text/. * @brief Returns a stringlist with the contents of a .txt file from config/text/.
@ -566,6 +567,4 @@ private:
static QStringList loadConfigFile(const QString filename); static QStringList loadConfigFile(const QString filename);
}; };
#endif // CONFIG_MANAGER_H #endif // CONFIG_MANAGER_H

View File

@ -19,6 +19,7 @@
#define DATA_TYPES_H #define DATA_TYPES_H
#include <QDebug> #include <QDebug>
/** /**
* @brief A class for handling several custom data types. * @brief A class for handling several custom data types.
*/ */
@ -26,11 +27,12 @@ class DataTypes
{ {
Q_GADGET Q_GADGET
public: public:
/** /**
* @brief Custom type for authorization types. * @brief Custom type for authorization types.
*/ */
enum class AuthType { enum class AuthType
{
SIMPLE, SIMPLE,
ADVANCED ADVANCED
}; };
@ -39,7 +41,8 @@ public:
/** /**
* @brief Custom type for logging types. * @brief Custom type for logging types.
*/ */
enum class LogType { enum class LogType
{
MODCALL, MODCALL,
FULL, FULL,
FULLAREA FULLAREA
@ -47,13 +50,15 @@ public:
Q_ENUM(LogType) Q_ENUM(LogType)
}; };
template<typename T> template <typename T>
T toDataType(const QString& f_string){ T toDataType(const QString &f_string)
{
return QVariant(f_string).value<T>(); return QVariant(f_string).value<T>();
} }
template<typename T> template <typename T>
QString fromDataType(const T& f_t){ QString fromDataType(const T &f_t)
{
return QVariant::fromValue(f_t).toString(); return QVariant::fromValue(f_t).toString();
} }

View File

@ -21,13 +21,13 @@
#define DB_VERSION 1 #define DB_VERSION 1
#include <QDateTime> #include <QDateTime>
#include <QFileInfo>
#include <QHostAddress> #include <QHostAddress>
#include <QMessageAuthenticationCode> #include <QMessageAuthenticationCode>
#include <QSqlDatabase> #include <QSqlDatabase>
#include <QSqlDriver> #include <QSqlDriver>
#include <QSqlError> #include <QSqlError>
#include <QSqlQuery> #include <QSqlQuery>
#include <QFileInfo>
/** /**
* @brief A class used to handle database interaction. * @brief A class used to handle database interaction.
@ -39,9 +39,11 @@
* differently than the average user. * differently than the average user.
* This comes in two forms, when the user's client is banned, and when the user is a moderator. * This comes in two forms, when the user's client is banned, and when the user is a moderator.
*/ */
class DBManager : public QObject { class DBManager : public QObject
{
Q_OBJECT Q_OBJECT
public:
public:
/** /**
* @brief Constructor for the DBManager class. * @brief Constructor for the DBManager class.
* *
@ -95,7 +97,8 @@ public:
/** /**
* @brief Details about a ban. * @brief Details about a ban.
*/ */
struct BanInfo { struct BanInfo
{
QString ipid; //!< The banned user's IPID. QString ipid; //!< The banned user's IPID.
QHostAddress ip; //!< The banned user's IP. QHostAddress ip; //!< The banned user's IP.
QString hdid; //!< The banned user's hardware ID. QString hdid; //!< The banned user's hardware ID.
@ -250,7 +253,7 @@ public:
*/ */
bool updatePassword(QString username, QString password); bool updatePassword(QString username, QString password);
private: private:
/** /**
* @brief The name of the database connection driver. * @brief The name of the database connection driver.
*/ */

View File

@ -18,17 +18,19 @@
#ifndef DISCORD_H #ifndef DISCORD_H
#define DISCORD_H #define DISCORD_H
#include <QtNetwork>
#include <QCoreApplication> #include <QCoreApplication>
#include "config_manager.h" #include <QtNetwork>
class ConfigManager;
/** /**
* @brief A class for handling all Discord webhook requests. * @brief A class for handling all Discord webhook requests.
*/ */
class Discord : public QObject { class Discord : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
/** /**
* @brief Constructor for the Discord object * @brief Constructor for the Discord object
* *
@ -37,7 +39,7 @@ public:
* @param f_webhook_sendfile Whether or not to send a file containing area logs with the webhook POST request. * @param f_webhook_sendfile Whether or not to send a file containing area logs with the webhook POST request.
* @param parent Qt-based parent, passed along to inherited constructor from QObject. * @param parent Qt-based parent, passed along to inherited constructor from QObject.
*/ */
Discord(QObject* parent = nullptr); Discord(QObject *parent = nullptr);
/** /**
* @brief Deconstructor for the Discord class. * @brief Deconstructor for the Discord class.
@ -56,8 +58,7 @@ public:
*/ */
void stopUptimeTimer(); void stopUptimeTimer();
public slots:
public slots:
/** /**
* @brief Handles a modcall webhook request. * @brief Handles a modcall webhook request.
* *
@ -66,7 +67,7 @@ public slots:
* @param f_reason The reason for the modcall. * @param f_reason The reason for the modcall.
* @param f_buffer The area's log buffer. * @param f_buffer The area's log buffer.
*/ */
void onModcallWebhookRequested(const QString& f_name, const QString& f_area, const QString& f_reason, const QQueue<QString>& f_buffer); void onModcallWebhookRequested(const QString &f_name, const QString &f_area, const QString &f_reason, const QQueue<QString> &f_buffer);
/** /**
* @brief Handles a ban webhook request. * @brief Handles a ban webhook request.
@ -76,18 +77,18 @@ public slots:
* @param f_duration The date the ban expires. * @param f_duration The date the ban expires.
* @param f_reason The reason of the ban. * @param f_reason The reason of the ban.
*/ */
void onBanWebhookRequested(const QString& f_ipid, const QString& f_moderator, const QString& f_duration, const QString& f_reason, const int& f_banID); void onBanWebhookRequested(const QString &f_ipid, const QString &f_moderator, const QString &f_duration, const QString &f_reason, const int &f_banID);
/** /**
* @brief Handles a uptime webhook request. * @brief Handles a uptime webhook request.
*/ */
void onUptimeWebhookRequested(); void onUptimeWebhookRequested();
private: private:
/** /**
* @brief The QNetworkAccessManager for webhooks. * @brief The QNetworkAccessManager for webhooks.
*/ */
QNetworkAccessManager* m_nam; QNetworkAccessManager *m_nam;
/** /**
* @brief The QNetworkRequest for webhooks. * @brief The QNetworkRequest for webhooks.
@ -97,7 +98,7 @@ private:
/** /**
* @brief Timer to post a message that the server is still alive. * @brief Timer to post a message that the server is still alive.
*/ */
QTimer* m_uptimePostTimer; QTimer *m_uptimePostTimer;
/** /**
* @brief Constructs a new JSON document for modcalls. * @brief Constructs a new JSON document for modcalls.
@ -108,7 +109,7 @@ private:
* *
* @return A JSON document for the modcall. * @return A JSON document for the modcall.
*/ */
QJsonDocument constructModcallJson(const QString& f_name, const QString& f_area, const QString& f_reason) const; QJsonDocument constructModcallJson(const QString &f_name, const QString &f_area, const QString &f_reason) const;
/** /**
* @brief Constructs a new QHttpMultiPart document for log files. * @brief Constructs a new QHttpMultiPart document for log files.
@ -117,29 +118,29 @@ private:
* *
* @return A QHttpMultiPart containing the log file. * @return A QHttpMultiPart containing the log file.
*/ */
QHttpMultiPart* constructLogMultipart(const QQueue<QString>& f_buffer) const; QHttpMultiPart *constructLogMultipart(const QQueue<QString> &f_buffer) const;
private slots: private slots:
/** /**
* @brief Handles a network reply from a webhook POST request. * @brief Handles a network reply from a webhook POST request.
* *
* @param f_reply Pointer to the QNetworkReply created by the webhook POST request. * @param f_reply Pointer to the QNetworkReply created by the webhook POST request.
*/ */
void onReplyFinished(QNetworkReply* f_reply); void onReplyFinished(QNetworkReply *f_reply);
/** /**
* @brief Sends a webhook POST request with the given JSON document. * @brief Sends a webhook POST request with the given JSON document.
* *
* @param f_json The JSON document to send. * @param f_json The JSON document to send.
*/ */
void postJsonWebhook(const QJsonDocument& f_json); void postJsonWebhook(const QJsonDocument &f_json);
/** /**
* @brief Sends a webhook POST request with the given QHttpMultiPart. * @brief Sends a webhook POST request with the given QHttpMultiPart.
* *
* @param f_multipart The QHttpMultiPart to send. * @param f_multipart The QHttpMultiPart to send.
*/ */
void postMultipartWebhook(QHttpMultiPart& f_multipart); void postMultipartWebhook(QHttpMultiPart &f_multipart);
/** /**
* @brief Constructs a new JSON document for bans. * @brief Constructs a new JSON document for bans.
@ -151,15 +152,14 @@ private slots:
* *
* @return A JSON document for the ban. * @return A JSON document for the ban.
*/ */
QJsonDocument constructBanJson(const QString& f_ipid, const QString& f_moderator, const QString& f_duration, const QString& f_reason, const int& f_banID); QJsonDocument constructBanJson(const QString &f_ipid, const QString &f_moderator, const QString &f_duration, const QString &f_reason, const int &f_banID);
/** /**
* @brief Constructs a new JSON document for the server alive message. * @brief Constructs a new JSON document for the server alive message.
* @param f_timeExpired formatted uptime as a string. * @param f_timeExpired formatted uptime as a string.
* *
* @return A JSON document for the alive notification. * @return A JSON document for the alive notification.
*/ */
QJsonDocument constructUptimeJson(const QString& f_timeExpired); QJsonDocument constructUptimeJson(const QString &f_timeExpired);
}; };
#endif // DISCORD_H #endif // DISCORD_H

View File

@ -18,13 +18,13 @@
#ifndef U_LOGGER_H #ifndef U_LOGGER_H
#define U_LOGGER_H #define U_LOGGER_H
#include <QObject>
#include <QMap>
#include <QQueue>
#include <QDateTime>
#include "include/config_manager.h" #include "include/config_manager.h"
#include "include/logger/writer_full.h" #include "include/logger/writer_full.h"
#include "include/logger/writer_modcall.h" #include "include/logger/writer_modcall.h"
#include <QDateTime>
#include <QMap>
#include <QObject>
#include <QQueue>
/** /**
* @brief The Universal Logger class to provide a common place to handle, store and write logs to file. * @brief The Universal Logger class to provide a common place to handle, store and write logs to file.
@ -32,12 +32,13 @@
class ULogger : public QObject class ULogger : public QObject
{ {
Q_OBJECT Q_OBJECT
public:
public:
/** /**
* @brief Constructor for the universal logger. Determines which writer is initially created. * @brief Constructor for the universal logger. Determines which writer is initially created.
* @param Pointer to the Server. * @param Pointer to the Server.
*/ */
ULogger(QObject* parent = nullptr); ULogger(QObject *parent = nullptr);
/** /**
* @brief Deconstructor of the universal logger. Deletes its writer before deconstruction. * @brief Deconstructor of the universal logger. Deletes its writer before deconstruction.
@ -50,65 +51,64 @@ public:
*/ */
QQueue<QString> buffer(const QString &f_areaName); QQueue<QString> buffer(const QString &f_areaName);
public slots: public slots:
/** /**
* @brief Adds an IC log entry to the area buffer and writes it to the respective log format. * @brief Adds an IC log entry to the area buffer and writes it to the respective log format.
*/ */
void logIC(const QString& f_char_name, const QString& f_ooc_name, const QString& f_ipid, void logIC(const QString &f_char_name, const QString &f_ooc_name, const QString &f_ipid,
const QString& f_area_name, const QString &f_message); const QString &f_area_name, const QString &f_message);
/** /**
* @brief Adds an OOC log entry to the area buffer and writes it to the respective log format. * @brief Adds an OOC log entry to the area buffer and writes it to the respective log format.
*/ */
void logOOC(const QString& f_char_Name, const QString& f_ooc_name, const QString& f_ipid, void logOOC(const QString &f_char_Name, const QString &f_ooc_name, const QString &f_ipid,
const QString& f_area_name, const QString& f_message); const QString &f_area_name, const QString &f_message);
/** /**
* @brief Adds an login attempt to the area buffer and writes it to the respective log format. * @brief Adds an login attempt to the area buffer and writes it to the respective log format.
*/ */
void logLogin(const QString& f_char_name, const QString& f_ooc_name, const QString& f_moderator_name, void logLogin(const QString &f_char_name, const QString &f_ooc_name, const QString &f_moderator_name,
const QString& f_ipid, const QString &f_area_name, const bool& f_success); const QString &f_ipid, const QString &f_area_name, const bool &f_success);
/** /**
* @brief Adds a command usage to the area buffer and writes it to the respective log format. * @brief Adds a command usage to the area buffer and writes it to the respective log format.
*/ */
void logCMD(const QString& f_char_name, const QString &f_ipid, const QString& f_ooc_name, const QString& f_command, void logCMD(const QString &f_char_name, const QString &f_ipid, const QString &f_ooc_name, const QString &f_command,
const QStringList& f_args, const QString& f_area_name); const QStringList &f_args, const QString &f_area_name);
/** /**
* @brief Adds a player kick to the area buffer and writes it to the respective log format. * @brief Adds a player kick to the area buffer and writes it to the respective log format.
*/ */
void logKick(const QString& f_moderator, const QString& f_target_ipid); void logKick(const QString &f_moderator, const QString &f_target_ipid);
/** /**
* @brief Adds a player ban to the area buffer and writes it to the respective log format. * @brief Adds a player ban to the area buffer and writes it to the respective log format.
*/ */
void logBan(const QString& f_moderator, const QString& f_target_ipid, const QString &f_duration); void logBan(const QString &f_moderator, const QString &f_target_ipid, const QString &f_duration);
/** /**
* @brief Adds a modcall event to the area buffer, also triggers modcall writing. * @brief Adds a modcall event to the area buffer, also triggers modcall writing.
*/ */
void logModcall(const QString& f_char_name, const QString &f_ipid, const QString& f_ooc_name, const QString& f_area_name); void logModcall(const QString &f_char_name, const QString &f_ipid, const QString &f_ooc_name, const QString &f_area_name);
/** /**
* @brief Logs any connection attempt to the server, wether sucessful or not. * @brief Logs any connection attempt to the server, wether sucessful or not.
*/ */
void logConnectionAttempt(const QString& f_ip_address, const QString& f_ipid, const QString& f_hwid); void logConnectionAttempt(const QString &f_ip_address, const QString &f_ipid, const QString &f_hwid);
/** /**
* @brief Loads template strings for the logger. * @brief Loads template strings for the logger.
*/ */
void loadLogtext(); void loadLogtext();
private: private:
/** /**
* @brief Updates the area buffer with a new entry, moving old ones if the buffer exceesed the maximum size. * @brief Updates the area buffer with a new entry, moving old ones if the buffer exceesed the maximum size.
* @param Name of the area which buffer is modified. * @param Name of the area which buffer is modified.
* @param Formatted QString to be added into the buffer. * @param Formatted QString to be added into the buffer.
*/ */
void updateAreaBuffer(const QString& f_areaName, const QString& f_log_entry); void updateAreaBuffer(const QString &f_areaName, const QString &f_log_entry);
/** /**
* @brief QMap of all available area buffers. * @brief QMap of all available area buffers.
@ -120,12 +120,12 @@ private:
/** /**
* @brief Pointer to modcall writer. Handles QQueue delogging into area specific file. * @brief Pointer to modcall writer. Handles QQueue delogging into area specific file.
*/ */
WriterModcall* writerModcall; WriterModcall *writerModcall;
/** /**
* @brief Pointer to full writer. Handles single messages in one file. * @brief Pointer to full writer. Handles single messages in one file.
*/ */
WriterFull* writerFull; WriterFull *writerFull;
/** /**
* @brief Table that contains template strings for text-based logger format. * @brief Table that contains template strings for text-based logger format.
@ -133,7 +133,7 @@ private:
* This has the problem of lacking defaults that work for all when the file is missing. * This has the problem of lacking defaults that work for all when the file is missing.
* This QMap contains all default values and overwrites them on logger construction. * This QMap contains all default values and overwrites them on logger construction.
*/ */
QHash<QString,QString>m_logtext { QHash<QString, QString> m_logtext{
{"ic", "[%1][%5][IC][%2(%3)][%4]%6"}, {"ic", "[%1][%5][IC][%2(%3)][%4]%6"},
{"ooc", "[%1][%5][OOC][%2(%3)][%4]%6"}, {"ooc", "[%1][%5][OOC][%2(%3)][%4]%6"},
{"login", "[%1][LOGIN][%2][%3][%4(%5)]"}, {"login", "[%1][LOGIN][%2][%3][%4(%5)]"},
@ -144,8 +144,7 @@ private:
{"kick", "[%1][%2][KICK][%3]"}, {"kick", "[%1][%2][KICK][%3]"},
{"ban", "[%1][%2][BAN][%3][%4]"}, {"ban", "[%1][%2][BAN][%3][%4]"},
{"modcall", "[%1][%2][MODCALL][%5][%3(%4)]"}, {"modcall", "[%1][%2][MODCALL][%5][%3(%4)]"},
{"connect", "[%1][CONNECT][%2][%3][%4]"} {"connect", "[%1][CONNECT][%2][%3][%4]"}};
};
}; };
#endif //U_LOGGER_H #endif // U_LOGGER_H

View File

@ -17,10 +17,10 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#ifndef WRITER_FULL_H #ifndef WRITER_FULL_H
#define WRITER_FULL_H #define WRITER_FULL_H
#include <QObject>
#include <QFile>
#include <QDir>
#include <QDateTime> #include <QDateTime>
#include <QDir>
#include <QFile>
#include <QObject>
#include <QTextStream> #include <QTextStream>
/** /**
@ -29,13 +29,15 @@
class WriterFull : public QObject class WriterFull : public QObject
{ {
Q_OBJECT Q_OBJECT
public:
public:
/** /**
* @brief Constructor for full logwriter * @brief Constructor for full logwriter
* *
* @param QObject pointer to the parent object. * @param QObject pointer to the parent object.
*/ */
WriterFull(QObject* parent = nullptr);; WriterFull(QObject *parent = nullptr);
;
/** /**
* @brief Deconstructor for full logwriter. * @brief Deconstructor for full logwriter.
@ -57,7 +59,7 @@ public:
*/ */
void flush(const QString f_entry, const QString f_area_name); void flush(const QString f_entry, const QString f_area_name);
private: private:
/** /**
* @brief Filename of the logfile used. This will always be the time the server starts up. * @brief Filename of the logfile used. This will always be the time the server starts up.
*/ */
@ -69,4 +71,4 @@ private:
QDir l_dir; QDir l_dir;
}; };
#endif //WRITER_FULL_H #endif // WRITER_FULL_H

View File

@ -17,13 +17,12 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#ifndef WRITER_MODCALL_H #ifndef WRITER_MODCALL_H
#define WRITER_MODCALL_H #define WRITER_MODCALL_H
#include <QObject>
#include <QFile>
#include <QDir>
#include <QDateTime> #include <QDateTime>
#include <QTextStream> #include <QDir>
#include <QFile>
#include <QObject>
#include <QQueue> #include <QQueue>
#include <QTextStream>
/** /**
* @brief A class to handle file interaction when writing the modcall buffer. * @brief A class to handle file interaction when writing the modcall buffer.
@ -31,13 +30,15 @@
class WriterModcall : public QObject class WriterModcall : public QObject
{ {
Q_OBJECT Q_OBJECT
public:
public:
/** /**
* @brief Constructor for modcall logwriter * @brief Constructor for modcall logwriter
* *
* @param QObject pointer to the parent object. * @param QObject pointer to the parent object.
*/ */
WriterModcall(QObject* parent = nullptr);; WriterModcall(QObject *parent = nullptr);
;
/** /**
* @brief Deconstructor for modcall logwriter. * @brief Deconstructor for modcall logwriter.
@ -53,7 +54,7 @@ public:
*/ */
void flush(const QString f_area_name, QQueue<QString> f_buffer); void flush(const QString f_area_name, QQueue<QString> f_buffer);
private: private:
/** /**
* @brief Filename of the logfile used. * @brief Filename of the logfile used.
*/ */
@ -65,4 +66,4 @@ private:
QDir l_dir; QDir l_dir;
}; };
#endif //WRITER_MODCALL_H #endif // WRITER_MODCALL_H

View File

@ -18,26 +18,27 @@
#ifndef MUSIC_MANAGER_H #ifndef MUSIC_MANAGER_H
#define MUSIC_MANAGER_H #define MUSIC_MANAGER_H
#include <QObject>
#include <QMap>
#include <QHash> #include <QHash>
#include <QMap>
#include <QObject>
#include <QPair> #include <QPair>
#include <include/config_manager.h> #include "include/aopacket.h"
#include <include/aopacket.h> #include "include/typedefs.h"
class ConfigManager;
class MusicManager : public QObject class MusicManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public:
public:
/** /**
* @brief Constructor for the server-wide musiclist manager. * @brief Constructor for the server-wide musiclist manager.
* *
* @param Copy of the server musiclist generated by ConfigManager::musiclist(); * @param Copy of the server musiclist generated by ConfigManager::musiclist();
*/ */
MusicManager(QObject* parent = nullptr, QStringList f_root_ordered = {}, QStringList f_cdns = {"cdn.discord.com"}, MusicManager(QStringList f_root_ordered, QStringList f_cdns, QMap<QString, QPair<QString, int>> f_root_list, QObject *parent = nullptr);
QMap<QString, QPair<QString, int> > f_root_list = ConfigManager::musiclist());
/** /**
* @brief Destructor for the server-wide musiclist manager. * @brief Destructor for the server-wide musiclist manager.
@ -146,7 +147,7 @@ public:
*/ */
bool isCustom(int f_area_id, QString f_song_name); bool isCustom(int f_area_id, QString f_song_name);
public slots: public slots:
/** /**
* @brief Updates the root musiclist and CDN list. * @brief Updates the root musiclist and CDN list.
@ -158,7 +159,7 @@ public slots:
*/ */
void userJoinedArea(int f_area_index, int f_user_id); void userJoinedArea(int f_area_index, int f_user_id);
signals: signals:
/** /**
* @brief Sends the FM packet with the musiclist of the area when a client enters. * @brief Sends the FM packet with the musiclist of the area when a client enters.
@ -178,12 +179,11 @@ signals:
*/ */
void sendAreaFMPacket(AOPacket f_packet, int f_area_index); void sendAreaFMPacket(AOPacket f_packet, int f_area_index);
private: private:
/** /**
* @brief Contains all custom lists of all areas in the server. * @brief Contains all custom lists of all areas in the server.
*/ */
QHash<int,MusicList>* m_custom_lists; QHash<int, MusicList> *m_custom_lists;
/** /**
* @brief Server musiclist shared among all areas. * @brief Server musiclist shared among all areas.
@ -198,12 +198,12 @@ private:
/** /**
* @brief Contains all custom songs ordered in a per-area buffer. * @brief Contains all custom songs ordered in a per-area buffer.
*/ */
QMap<int,QStringList> m_customs_ordered; QMap<int, QStringList> m_customs_ordered;
/** /**
* @brief Wether the global musiclist is prepend and validation when adding custom music. * @brief Wether the global musiclist is prepend and validation when adding custom music.
*/ */
QHash<int,bool> m_global_enabled; QHash<int, bool> m_global_enabled;
/** /**
* @brief Contains all server approved content sources. * @brief Contains all server approved content sources.

View File

@ -18,35 +18,34 @@
#ifndef SERVER_H #ifndef SERVER_H
#define SERVER_H #define SERVER_H
#include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/ws_proxy.h"
#include "include/db_manager.h"
#include "include/discord.h"
#include "include/config_manager.h"
#include "include/advertiser.h"
#include "include/logger/u_logger.h"
#include "include/music_manager.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#include <QMap> #include <QMap>
#include <QSettings> #include <QSettings>
#include <QStack>
#include <QString> #include <QString>
#include <QTcpServer> #include <QTcpServer>
#include <QTcpSocket> #include <QTcpSocket>
#include <QTimer> #include <QTimer>
#include "include/aopacket.h"
class Advertiser;
class AOClient; class AOClient;
class DBManager;
class AreaData; class AreaData;
class ConfigManager;
class DBManager;
class Discord;
class MusicManager;
class ULogger;
class WSProxy;
/** /**
* @brief The class that represents the actual server as it is. * @brief The class that represents the actual server as it is.
*/ */
class Server : public QObject { class Server : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
@ -57,7 +56,7 @@ class Server : public QObject {
* @param p_ws_port The WebSocket port to listen for connections on. * @param p_ws_port The WebSocket port to listen for connections on.
* @param parent Qt-based parent, passed along to inherited constructor from QObject. * @param parent Qt-based parent, passed along to inherited constructor from QObject.
*/ */
Server(int p_port, int p_ws_port, QObject* parent = nullptr); Server(int p_port, int p_ws_port, QObject *parent = nullptr);
/** /**
* @brief Destructor for the Server class. * @brief Destructor for the Server class.
@ -79,13 +78,21 @@ class Server : public QObject {
/** /**
* @brief Enum to specifc different targets to send altered packets to a specific usergroup. * @brief Enum to specifc different targets to send altered packets to a specific usergroup.
*/ */
enum class TARGET_TYPE { enum class TARGET_TYPE
{
AUTHENTICATED, AUTHENTICATED,
MODCHAT, MODCHAT,
ADVERT ADVERT
}; };
Q_ENUM(TARGET_TYPE) Q_ENUM(TARGET_TYPE)
/**
* @brief Returns a list of all clients currently in the server.
*
* @return A list of all clients currently in the server.
*/
QVector<AOClient *> getClients();
/** /**
* @brief Gets a pointer to a client by IPID. * @brief Gets a pointer to a client by IPID.
* *
@ -95,7 +102,7 @@ class Server : public QObject {
* *
* @see Server::getClientsByIpid() to get all clients ran by the same user. * @see Server::getClientsByIpid() to get all clients ran by the same user.
*/ */
AOClient* getClient(QString ipid); AOClient *getClient(QString ipid);
/** /**
* @brief Gets a list of pointers to all clients with the given IPID. * @brief Gets a list of pointers to all clients with the given IPID.
@ -104,7 +111,7 @@ class Server : public QObject {
* *
* @return A list of clients whose IPID match. List may be empty. * @return A list of clients whose IPID match. List may be empty.
*/ */
QList<AOClient*> getClientsByIpid(QString ipid); QList<AOClient *> getClientsByIpid(QString ipid);
/** /**
* @brief Gets a pointer to a client by user ID. * @brief Gets a pointer to a client by user ID.
@ -113,7 +120,37 @@ class Server : public QObject {
* *
* @return A pointer to the client if found, a nullpointer if not. * @return A pointer to the client if found, a nullpointer if not.
*/ */
AOClient* getClientByID(int id); AOClient *getClientByID(int id);
/**
* @brief Returns the overall player count in the server.
*
* @return The overall player count in the server.
*/
int getPlayerCount();
/**
* @brief Returns a list of the available characters on the server to use.
*
* @return A list of the available characters on the server to use.
*/
QStringList getCharacters();
/**
* @brief Returns the count of available characters on the server to use.
*
* @return The count of available characters on the server to use.
*/
int getCharacterCount();
/**
* @brief Get the available character by index.
*
* @param f_chr_id The index of the character.
*
* @return The character if it exist, otherwise an empty stirng.
*/
QString getCharacterById(int f_chr_id);
/** /**
* @brief Updates which characters are taken in the given area, and sends out an update packet to * @brief Updates which characters are taken in the given area, and sends out an update packet to
@ -121,7 +158,7 @@ class Server : public QObject {
* *
* @param area The area in which to update the list of characters. * @param area The area in which to update the list of characters.
*/ */
void updateCharsTaken(AreaData* area); void updateCharsTaken(AreaData *area);
/** /**
* @brief Sends a packet to all clients in a given area. * @brief Sends a packet to all clients in a given area.
@ -185,20 +222,229 @@ class Server : public QObject {
**/ **/
bool isIPBanned(QHostAddress f_remote_IP); bool isIPBanned(QHostAddress f_remote_IP);
/**
* @brief Returns the list of areas in the server.
*
* @return A list of areas.
*/
QVector<AreaData *> getAreas();
/**
* @brief Returns the number of areas in the server.
*/
int getAreaCount();
/**
* @brief Returns a pointer to the area associated with the index.
*
* @param f_area_id The index of the area.
*
* @return A pointer to the area or null.
*/
AreaData *getAreaById(int f_area_id);
/** /**
* @brief Getter for an area specific buffer from the logger. * @brief Getter for an area specific buffer from the logger.
*/ */
QQueue<QString> getAreaBuffer(const QString& f_areaName); QQueue<QString> getAreaBuffer(const QString &f_areaName);
/**
* @brief The names of the areas on the server.
*
* @return A list of names.
*/
QStringList getAreaNames();
/**
* @brief Returns the name of the area associated with the index.
*
* @param f_area_id The index of the area.
*
* @return The name of the area or empty.
*/
QString getAreaName(int f_area_id);
/**
* @brief Returns the available songs on the server.
*
* @return A list of songs.
*/
QStringList getMusicList();
/**
* @brief Returns the available backgrounds on the server.
*
* @return A list of backgrounds.
*/
QStringList getBackgrounds();
/**
* @brief Returns a pointer to a database manager.
*
* @return A pointer to database manager.
*/
DBManager *getDatabaseManager();
/**
* @brief The server-wide global timer.
*/
QTimer *timer;
QStringList getCursedCharsTaken(AOClient *client, QStringList chars_taken);
/**
* @brief Returns whatever a game message may be broadcasted or not.
*
* @return True if expired; false otherwise.
*/
bool isMessageAllowed();
/**
* @brief Starts a global timer that determines whatever a game message may be broadcasted or not.
*
* @param f_duration The duration of the message floodguard timer.
*/
void startMessageFloodguard(int f_duration);
/**
* @brief Attempts to parse a IPv6 mapped IPv4 to an IPv4.
*/
QHostAddress parseToIPv4(QHostAddress f_remote_ip);
public slots:
/**
* @brief Convenience class to call a reload of available configuraiton elements.
*/
void reloadSettings();
/**
* @brief Handles a new connection.
*
* @details The function creates an AOClient to represent the user, assigns a user ID to them, and
* checks if the client is banned.
*/
void clientConnected();
/**
* @brief Method to construct and reconstruct Discord Webhook Integration.
*
* @details Constructs or rebuilds Discord Object during server startup and configuration reload.
*/
void handleDiscordIntegration();
/**
* @brief Marks a userID as free and ads it back to the available client id queue.
*/
void markIDFree(const int &f_user_id);
signals:
/**
* @brief Sends the server name and description, emitted by /reload.
*
* @param p_name The server name.
* @param p_desc The server description.
*/
void reloadRequest(QString p_name, QString p_desc);
/**
* @brief This signal is emitted whenever the current player count has changed.
*
* @param f_current_player The player count at the time the signal was emitted.
*/
void playerCountUpdated(int f_current_players);
/**
* @brief Triggers a partial update of the modern advertiser as some information, such as ports
* can't be updated while the server is running.
*/
void updateHTTPConfiguration();
/**
* @brief Sends a modcall webhook request, emitted by AOClient::pktModcall.
*
* @param f_name The character or OOC name of the client who sent the modcall.
* @param f_area The name of the area the modcall was sent from.
* @param f_reason The reason the client specified for the modcall.
* @param f_buffer The area's log buffer.
*/
void modcallWebhookRequest(const QString &f_name, const QString &f_area, const QString &f_reason, const QQueue<QString> &f_buffer);
/**
* @brief Sends a ban webhook request, emitted by AOClient::cmdBan
* @param f_ipid The IPID of the banned client.
* @param f_moderator The moderator who issued the ban.
* @param f_duration The duration of the ban in a human readable format.
* @param f_reason The reason for the ban.
* @param f_banID The ID of the issued ban.
*/
void banWebhookRequest(const QString &f_ipid, const QString &f_moderator, const QString &f_duration, const QString &f_reason, const int &f_banID);
/**
* @brief Signal connected to universal logger. Logs a client connection attempt.
* @param f_ip_address The IP Address of the incoming connection.
* @param f_ipid The IPID of the incoming connection.
* @param f_hdid The HDID of the incoming connection.
*/
void logConnectionAttempt(const QString &f_ip_address, const QString &f_ipid, const QString &f_hwid);
private:
/**
* @brief The proxy used for WebSocket connections.
*
* @see WSProxy and WSClient for an explanation as to why this is a thing.
*/
WSProxy *proxy;
/**
* @brief Listens for incoming TCP connections.
*/
QTcpServer *server;
/**
* @brief Handles Discord webhooks.
*/
Discord *discord;
/**
* @brief Handles HTTP server advertising.
*/
Advertiser *ms3_Advertiser;
/**
* @brief Advertises the server in a regular intervall.
*/
QTimer *AdvertiserTimer;
/**
* @brief Handles the universal log framework.
*/
ULogger *logger;
/**
* @brief Handles all musiclists.
*/
MusicManager *music_manager;
/**
* @brief The port through which the server will accept TCP connections.
*/
int port;
/**
* @brief The port through which the server will accept WebSocket connections.
*/
int ws_port;
/** /**
* @brief The collection of all currently connected clients. * @brief The collection of all currently connected clients.
*/ */
QVector<AOClient*> m_clients; QVector<AOClient *> m_clients;
/** /**
* @brief Collection of all clients with their userID as key. * @brief Collection of all clients with their userID as key.
*/ */
QHash<int,AOClient*> m_clients_ids; QHash<int, AOClient *> m_clients_ids;
/** /**
* @brief Stack of all available IDs for clients. When this is empty the server * @brief Stack of all available IDs for clients. When this is empty the server
@ -219,7 +465,7 @@ class Server : public QObject {
/** /**
* @brief The areas on the server. * @brief The areas on the server.
*/ */
QVector<AreaData*> m_areas; QVector<AreaData *> m_areas;
/** /**
* @brief The names of the areas on the server. * @brief The names of the areas on the server.
@ -247,169 +493,43 @@ class Server : public QObject {
*/ */
QStringList m_ipban_list; QStringList m_ipban_list;
/**
* @brief The database manager on the server, used to store users' bans and authorisation details.
*/
DBManager* db_manager;
/**
* @brief The server-wide global timer.
*/
QTimer* timer;
QStringList getCursedCharsTaken(AOClient* client, QStringList chars_taken);
/** /**
* @brief Timer until the next IC message can be sent. * @brief Timer until the next IC message can be sent.
*/ */
QTimer next_message_timer; QTimer *m_message_floodguard_timer;
/**
* @brief Attempts to parse a IPv6 mapped IPv4 to an IPv4.
*/
QHostAddress parseToIPv4(QHostAddress f_remote_ip);
/** /**
* @brief If false, IC messages will be rejected. * @brief If false, IC messages will be rejected.
*/ */
bool can_send_ic_messages = true; bool m_can_send_ic_messages = true;
public slots:
/** /**
* @brief Convenience class to call a reload of available configuraiton elements. * @brief The database manager on the server, used to store users' bans and authorisation details.
*/ */
void reloadSettings(); DBManager *db_manager;
/**
* @brief Handles a new connection.
*
* @details The function creates an AOClient to represent the user, assigns a user ID to them, and
* checks if the client is banned.
*/
void clientConnected();
/**
* @brief Sets #can_send_messages to true.
*
* @details Called whenever #next_message_timer reaches 0.
*/
void allowMessage();
/**
* @brief Method to construct and reconstruct Discord Webhook Integration.
*
* @details Constructs or rebuilds Discord Object during server startup and configuration reload.
*/
void handleDiscordIntegration();
/**
* @brief Marks a userID as free and ads it back to the available client id queue.
*/
void markIDFree(const int& f_user_id);
signals:
/**
* @brief Sends the server name and description, emitted by /reload.
*
* @param p_name The server name.
* @param p_desc The server description.
*/
void reloadRequest(QString p_name, QString p_desc);
/**
* @brief Updates the playercount in the modern advertiser.
*/
void updatePlayerCount(int f_current_players);
/**
* @brief Triggers a partial update of the modern advertiser as some information, such as ports
* can't be updated while the server is running.
*/
void updateHTTPConfiguration();
/**
* @brief Sends a modcall webhook request, emitted by AOClient::pktModcall.
*
* @param f_name The character or OOC name of the client who sent the modcall.
* @param f_area The name of the area the modcall was sent from.
* @param f_reason The reason the client specified for the modcall.
* @param f_buffer The area's log buffer.
*/
void modcallWebhookRequest(const QString& f_name, const QString& f_area, const QString& f_reason, const QQueue<QString>& f_buffer);
/**
* @brief Sends a ban webhook request, emitted by AOClient::cmdBan
* @param f_ipid The IPID of the banned client.
* @param f_moderator The moderator who issued the ban.
* @param f_duration The duration of the ban in a human readable format.
* @param f_reason The reason for the ban.
* @param f_banID The ID of the issued ban.
*/
void banWebhookRequest(const QString& f_ipid, const QString& f_moderator, const QString& f_duration, const QString& f_reason, const int& f_banID);
/**
* @brief Signal connected to universal logger. Logs a client connection attempt.
* @param f_ip_address The IP Address of the incoming connection.
* @param f_ipid The IPID of the incoming connection.
* @param f_hdid The HDID of the incoming connection.
*/
void logConnectionAttempt(const QString& f_ip_address, const QString& f_ipid, const QString& f_hwid);
private:
/** /**
* @brief Connects new AOClient to logger and disconnect handling. * @brief Connects new AOClient to logger and disconnect handling.
**/ **/
void hookupAOClient(AOClient* client); void hookupAOClient(AOClient *client);
private slots:
/**
* @brief Increase the current player count by one.
*/
void increasePlayerCount();
/** /**
* @brief The proxy used for WebSocket connections. * @brief Decrease the current player count based on the client id provided.
* *
* @see WSProxy and WSClient for an explanation as to why this is a thing. * @param f_client_id The client id of the client to check.
*/ */
WSProxy* proxy; void decreasePlayerCount();
/** /**
* @brief Listens for incoming TCP connections. * @brief Allow game messages to be broadcasted.
*/ */
QTcpServer* server; void allowMessage();
/**
* @brief Handles Discord webhooks.
*/
Discord* discord;
/**
* @brief Handles HTTP server advertising.
*/
Advertiser* ms3_Advertiser;
/**
* @brief Advertises the server in a regular intervall.
*/
QTimer* AdvertiserTimer;
/**
* @brief Handles the universal log framework.
*/
ULogger* logger;
/**
* @brief Handles all musiclists.
*/
MusicManager* music_manager;
/**
* @brief The port through which the server will accept TCP connections.
*/
int port;
/**
* @brief The port through which the server will accept WebSocket connections.
*/
int ws_port;
}; };
#endif // SERVER_H #endif // SERVER_H

7
core/include/typedefs.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <QMap>
#include <QPair>
#include <QString>
typedef QMap<QString, QPair<QString, int>> MusicList;

View File

@ -19,9 +19,9 @@
#define WS_CLIENT_H #define WS_CLIENT_H
#include <QObject> #include <QObject>
#include <QtWebSockets/QtWebSockets>
#include <QTcpSocket>
#include <QString> #include <QString>
#include <QTcpSocket>
#include <QtWebSockets/QtWebSockets>
/** /**
* @brief Represents a WebSocket client (generally WebAO) connected to the server. * @brief Represents a WebSocket client (generally WebAO) connected to the server.
@ -31,9 +31,11 @@
* *
* This class is a very thin layer -- see WSProxy for the actual mechanics of this WebSocket-to-TCP proxy solution. * This class is a very thin layer -- see WSProxy for the actual mechanics of this WebSocket-to-TCP proxy solution.
*/ */
class WSClient : public QObject { class WSClient : public QObject
{
Q_OBJECT Q_OBJECT
public:
public:
/** /**
* @brief Creates an instance of the WSClient class. * @brief Creates an instance of the WSClient class.
* *
@ -44,7 +46,7 @@ public:
* @pre This class will not connect up the ports to each other in any way. Unless some setup is done, this class * @pre This class will not connect up the ports to each other in any way. Unless some setup is done, this class
* by default will never be prompted to read and/or write from/to either of the sockets. * by default will never be prompted to read and/or write from/to either of the sockets.
*/ */
WSClient(QTcpSocket* p_tcp_socket, QWebSocket* p_web_socket, QObject* parent = nullptr); WSClient(QTcpSocket *p_tcp_socket, QWebSocket *p_web_socket, QObject *parent = nullptr);
/** /**
* @brief Destructor for the WSClient class. * @brief Destructor for the WSClient class.
@ -52,7 +54,7 @@ public:
* @details Marks the TCP and WebSocket for later deletion. * @details Marks the TCP and WebSocket for later deletion.
*/ */
~WSClient(); ~WSClient();
public slots: public slots:
/** /**
* @brief A slot that can be signalled when #tcp_socket has data ready for reading. * @brief A slot that can be signalled when #tcp_socket has data ready for reading.
* Will read all data in the socket. * Will read all data in the socket.
@ -92,17 +94,16 @@ public slots:
*/ */
void onTcpConnect(); void onTcpConnect();
private:
private:
/** /**
* @brief The local TCP socket used as a proxy to connect with the server. * @brief The local TCP socket used as a proxy to connect with the server.
*/ */
QTcpSocket* tcp_socket; QTcpSocket *tcp_socket;
/** /**
* @brief The WebSocket representing an incoming connection. * @brief The WebSocket representing an incoming connection.
*/ */
QWebSocket* web_socket; QWebSocket *web_socket;
/** /**
* @brief Stores partial packets in case they don't all come through the TCP socket at once * @brief Stores partial packets in case they don't all come through the TCP socket at once

View File

@ -18,19 +18,21 @@
#ifndef WS_PROXY_H #ifndef WS_PROXY_H
#define WS_PROXY_H #define WS_PROXY_H
#include "include/ws_client.h" #include <QHostAddress>
#include <QMap> #include <QMap>
#include <QTcpSocket> #include <QTcpSocket>
#include <QtWebSockets/QtWebSockets> #include <QtWebSockets/QtWebSockets>
#include <QHostAddress>
class WSClient;
/** /**
* @brief Handles WebSocket connections by redirecting data sent through them through a local TCP connection * @brief Handles WebSocket connections by redirecting data sent through them through a local TCP connection
* for common handling. * for common handling.
*/ */
class WSProxy : public QObject { class WSProxy : public QObject
{
Q_OBJECT Q_OBJECT
public: public:
/** /**
* @brief Creates a WSProxy instance. * @brief Creates a WSProxy instance.
@ -40,7 +42,7 @@ class WSProxy : public QObject {
* @param p_ws_port The WebSocket port. Should the same that is opened for WebSockets connections. * @param p_ws_port The WebSocket port. Should the same that is opened for WebSockets connections.
* @param parent Qt-based parent, passed along to inherited constructor from QObject. * @param parent Qt-based parent, passed along to inherited constructor from QObject.
*/ */
WSProxy(int p_local_port, int p_ws_port, QObject* parent); WSProxy(int p_local_port, int p_ws_port, QObject *parent);
/** /**
* @brief Destructor for the WSProxy class. * @brief Destructor for the WSProxy class.
@ -54,7 +56,7 @@ class WSProxy : public QObject {
*/ */
void start(); void start();
public slots: public slots:
/** /**
* @brief Sets up the proxy process to the newly connected WebSocket. * @brief Sets up the proxy process to the newly connected WebSocket.
* *
@ -66,12 +68,12 @@ public slots:
/** /**
* @brief The WebSocket server listening to incoming WebSocket connections. * @brief The WebSocket server listening to incoming WebSocket connections.
*/ */
QWebSocketServer* server; QWebSocketServer *server;
/** /**
* @brief Every client connected through WebSocket. * @brief Every client connected through WebSocket.
*/ */
QVector<WSClient*> clients; QVector<WSClient *> clients;
/** /**
* @brief The TCP port that the WebSocket connections will be redirected through. * @brief The TCP port that the WebSocket connections will be redirected through.

View File

@ -17,13 +17,14 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/advertiser.h" #include "include/advertiser.h"
#include "include/config_manager.h"
Advertiser::Advertiser() Advertiser::Advertiser()
{ {
m_manager = new QNetworkAccessManager(); m_manager = new QNetworkAccessManager();
connect(m_manager, &QNetworkAccessManager::finished, connect(m_manager, &QNetworkAccessManager::finished,
this, &Advertiser::msRequestFinished); this, &Advertiser::msRequestFinished);
m_name = ConfigManager::serverName(); m_name = ConfigManager::serverName();
m_hostname = ConfigManager::advertiserHostname(); m_hostname = ConfigManager::advertiserHostname();
m_description = ConfigManager::serverDescription(); m_description = ConfigManager::serverDescription();
@ -73,7 +74,6 @@ void Advertiser::msAdvertiseServer()
if (m_debug) if (m_debug)
qWarning().noquote() << "Unable to advertise. Masterserver URL '" + m_masterserver.toString() + "' is not valid."; qWarning().noquote() << "Unable to advertise. Masterserver URL '" + m_masterserver.toString() + "' is not valid.";
return; return;
} }
void Advertiser::msRequestFinished(QNetworkReply *f_reply) void Advertiser::msRequestFinished(QNetworkReply *f_reply)
@ -110,5 +110,3 @@ void Advertiser::updateAdvertiserSettings()
m_masterserver = ConfigManager::advertiserIP(); m_masterserver = ConfigManager::advertiserIP();
m_debug = ConfigManager::advertiserDebug(); m_debug = ConfigManager::advertiserDebug();
} }

View File

@ -17,6 +17,12 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/db_manager.h"
#include "include/server.h"
void AOClient::clientData() void AOClient::clientData()
{ {
if (last_read + m_socket->bytesAvailable() > 30720) { // Client can send a max of 30KB to the server over two sequential reads if (last_read + m_socket->bytesAvailable() > 30720) { // Client can send a max of 30KB to the server over two sequential reads
@ -53,19 +59,18 @@ void AOClient::clientDisconnected()
qDebug() << remote_ip.toString() << "disconnected"; qDebug() << remote_ip.toString() << "disconnected";
#endif #endif
if (m_joined) { if (m_joined) {
server->m_player_count--; server->getAreaById(m_current_area)->clientLeftArea(server->getCharID(m_current_char), m_id);
emit server->updatePlayerCount(server->m_player_count);
server->m_areas[m_current_area]->clientLeftArea(server->getCharID(m_current_char), m_id);
arup(ARUPType::PLAYER_COUNT, true); arup(ARUPType::PLAYER_COUNT, true);
} }
if (m_current_char != "") { if (m_current_char != "") {
server->updateCharsTaken(server->m_areas[m_current_area]); server->updateCharsTaken(server->getAreaById(m_current_area));
} }
bool l_updateLocks = false; bool l_updateLocks = false;
for (AreaData* l_area : qAsConst(server->m_areas)) { const QVector<AreaData *> l_areas = server->getAreas();
for (AreaData *l_area : l_areas) {
l_updateLocks = l_updateLocks || l_area->removeOwner(m_id); l_updateLocks = l_updateLocks || l_area->removeOwner(m_id);
} }
@ -81,7 +86,7 @@ void AOClient::handlePacket(AOPacket packet)
#ifdef NET_DEBUG #ifdef NET_DEBUG
qDebug() << "Received packet:" << packet.header << ":" << packet.contents << "args length:" << packet.contents.length(); qDebug() << "Received packet:" << packet.header << ":" << packet.contents << "args length:" << packet.contents.length();
#endif #endif
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
PacketInfo l_info = packets.value(packet.header, {false, 0, &AOClient::pktDefault}); PacketInfo l_info = packets.value(packet.header, {false, 0, &AOClient::pktDefault});
if (packet.contents.join("").size() > 16384) { if (packet.contents.join("").size() > 16384) {
@ -112,59 +117,59 @@ void AOClient::handlePacket(AOPacket packet)
void AOClient::changeArea(int new_area) void AOClient::changeArea(int new_area)
{ {
if (m_current_area == new_area) { if (m_current_area == new_area) {
sendServerMessage("You are already in area " + server->m_area_names[m_current_area]); sendServerMessage("You are already in area " + server->getAreaName(m_current_area));
return; return;
} }
if (server->m_areas[new_area]->lockStatus() == AreaData::LockStatus::LOCKED && !server->m_areas[new_area]->invited().contains(m_id) && !checkAuth(ACLFlags.value("BYPASS_LOCKS"))) { if (server->getAreaById(new_area)->lockStatus() == AreaData::LockStatus::LOCKED && !server->getAreaById(new_area)->invited().contains(m_id) && !checkAuth(ACLFlags.value("BYPASS_LOCKS"))) {
sendServerMessage("Area " + server->m_area_names[new_area] + " is locked."); sendServerMessage("Area " + server->getAreaName(new_area) + " is locked.");
return; return;
} }
if (m_current_char != "") { if (m_current_char != "") {
server->m_areas[m_current_area]->changeCharacter(server->getCharID(m_current_char), -1); server->getAreaById(m_current_area)->changeCharacter(server->getCharID(m_current_char), -1);
server->updateCharsTaken(server->m_areas[m_current_area]); server->updateCharsTaken(server->getAreaById(m_current_area));
} }
server->m_areas[m_current_area]->clientLeftArea(m_char_id, m_id); server->getAreaById(m_current_area)->clientLeftArea(m_char_id, m_id);
bool l_character_taken = false; bool l_character_taken = false;
if (server->m_areas[new_area]->charactersTaken().contains(server->getCharID(m_current_char))) { if (server->getAreaById(new_area)->charactersTaken().contains(server->getCharID(m_current_char))) {
m_current_char = ""; m_current_char = "";
m_char_id = -1; m_char_id = -1;
l_character_taken = true; l_character_taken = true;
} }
server->m_areas[new_area]->clientJoinedArea(m_char_id, m_id); server->getAreaById(new_area)->clientJoinedArea(m_char_id, m_id);
m_current_area = new_area; m_current_area = new_area;
arup(ARUPType::PLAYER_COUNT, true); arup(ARUPType::PLAYER_COUNT, true);
sendEvidenceList(server->m_areas[new_area]); sendEvidenceList(server->getAreaById(new_area));
sendPacket("HP", {"1", QString::number(server->m_areas[new_area]->defHP())}); sendPacket("HP", {"1", QString::number(server->getAreaById(new_area)->defHP())});
sendPacket("HP", {"2", QString::number(server->m_areas[new_area]->proHP())}); sendPacket("HP", {"2", QString::number(server->getAreaById(new_area)->proHP())});
sendPacket("BN", {server->m_areas[new_area]->background()}); sendPacket("BN", {server->getAreaById(new_area)->background()});
if (l_character_taken) { if (l_character_taken) {
sendPacket("DONE"); sendPacket("DONE");
} }
const QList<QTimer*> l_timers = server->m_areas[m_current_area]->timers(); const QList<QTimer *> l_timers = server->getAreaById(m_current_area)->timers();
for (QTimer* l_timer : l_timers) { for (QTimer *l_timer : l_timers) {
int l_timer_id = server->m_areas[m_current_area]->timers().indexOf(l_timer) + 1; int l_timer_id = server->getAreaById(m_current_area)->timers().indexOf(l_timer) + 1;
if (l_timer->isActive()) { if (l_timer->isActive()) {
sendPacket("TI", {QString::number(l_timer_id), "2"}); sendPacket("TI", {QString::number(l_timer_id), "2"});
sendPacket("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(l_timer->remainingTime())))}); sendPacket("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0, 0).msecsTo(QTime(0, 0).addMSecs(l_timer->remainingTime())))});
} }
else { else {
sendPacket("TI", {QString::number(l_timer_id), "3"}); sendPacket("TI", {QString::number(l_timer_id), "3"});
} }
} }
sendServerMessage("You moved to area " + server->m_area_names[m_current_area]); sendServerMessage("You moved to area " + server->getAreaName(m_current_area));
if (server->m_areas[m_current_area]->sendAreaMessageOnJoin()) if (server->getAreaById(m_current_area)->sendAreaMessageOnJoin())
sendServerMessage(server->m_areas[m_current_area]->areaMessage()); sendServerMessage(server->getAreaById(m_current_area)->areaMessage());
if (server->m_areas[m_current_area]->lockStatus() == AreaData::LockStatus::SPECTATABLE) if (server->getAreaById(m_current_area)->lockStatus() == AreaData::LockStatus::SPECTATABLE)
sendServerMessage("Area " + server->m_area_names[m_current_area] + " is spectate-only; to chat IC you will need to be invited by the CM."); sendServerMessage("Area " + server->getAreaName(m_current_area) + " is spectate-only; to chat IC you will need to be invited by the CM.");
} }
bool AOClient::changeCharacter(int char_id) bool AOClient::changeCharacter(int char_id)
{ {
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if(char_id >= server->m_characters.length()) if (char_id >= server->getCharacterCount())
return false; return false;
if (m_is_charcursed && !m_charcurse_list.contains(char_id)) { if (m_is_charcursed && !m_charcurse_list.contains(char_id)) {
@ -178,7 +183,7 @@ bool AOClient::changeCharacter(int char_id)
} }
if (l_successfulChange == true) { if (l_successfulChange == true) {
QString l_char_selected = server->m_characters[char_id]; QString l_char_selected = server->getCharacterById(char_id);
m_current_char = l_char_selected; m_current_char = l_char_selected;
m_pos = ""; m_pos = "";
server->updateCharsTaken(l_area); server->updateCharsTaken(l_area);
@ -217,37 +222,43 @@ void AOClient::arup(ARUPType type, bool broadcast)
{ {
QStringList l_arup_data; QStringList l_arup_data;
l_arup_data.append(QString::number(type)); l_arup_data.append(QString::number(type));
for (AreaData* l_area : qAsConst(server->m_areas)) { const QVector<AreaData *> l_areas = server->getAreas();
switch(type) { for (AreaData *l_area : l_areas) {
case ARUPType::PLAYER_COUNT: { switch (type) {
case ARUPType::PLAYER_COUNT:
{
l_arup_data.append(QString::number(l_area->playerCount())); l_arup_data.append(QString::number(l_area->playerCount()));
break; break;
} }
case ARUPType::STATUS: { case ARUPType::STATUS:
{
QString l_area_status = QVariant::fromValue(l_area->status()).toString().replace("_", "-"); // LOOKING_FOR_PLAYERS to LOOKING-FOR-PLAYERS QString l_area_status = QVariant::fromValue(l_area->status()).toString().replace("_", "-"); // LOOKING_FOR_PLAYERS to LOOKING-FOR-PLAYERS
l_arup_data.append(l_area_status); l_arup_data.append(l_area_status);
break; break;
} }
case ARUPType::CM: { case ARUPType::CM:
{
if (l_area->owners().isEmpty()) if (l_area->owners().isEmpty())
l_arup_data.append("FREE"); l_arup_data.append("FREE");
else { else {
QStringList l_area_owners; QStringList l_area_owners;
const QList<int> l_owner_ids = l_area->owners(); const QList<int> l_owner_ids = l_area->owners();
for (int l_owner_id : l_owner_ids) { for (int l_owner_id : l_owner_ids) {
AOClient* l_owner = server->getClientByID(l_owner_id); AOClient *l_owner = server->getClientByID(l_owner_id);
l_area_owners.append("[" + QString::number(l_owner->m_id) + "] " + l_owner->m_current_char); l_area_owners.append("[" + QString::number(l_owner->m_id) + "] " + l_owner->m_current_char);
} }
l_arup_data.append(l_area_owners.join(", ")); l_arup_data.append(l_area_owners.join(", "));
} }
break; break;
} }
case ARUPType::LOCKED: { case ARUPType::LOCKED:
{
QString l_lock_status = QVariant::fromValue(l_area->lockStatus()).toString(); QString l_lock_status = QVariant::fromValue(l_area->lockStatus()).toString();
l_arup_data.append(l_lock_status); l_arup_data.append(l_lock_status);
break; break;
} }
default: { default:
{
return; return;
} }
} }
@ -258,7 +269,8 @@ void AOClient::arup(ARUPType type, bool broadcast)
sendPacket("ARUP", l_arup_data); sendPacket("ARUP", l_arup_data);
} }
void AOClient::fullArup() { void AOClient::fullArup()
{
arup(ARUPType::PLAYER_COUNT, false); arup(ARUPType::PLAYER_COUNT, false);
arup(ARUPType::STATUS, false); arup(ARUPType::STATUS, false);
arup(ARUPType::CM, false); arup(ARUPType::CM, false);
@ -326,7 +338,7 @@ bool AOClient::checkAuth(unsigned long long acl_mask)
#endif #endif
if (acl_mask != ACLFlags.value("NONE")) { if (acl_mask != ACLFlags.value("NONE")) {
if (acl_mask == ACLFlags.value("CM")) { if (acl_mask == ACLFlags.value("CM")) {
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->owners().contains(m_id)) if (l_area->owners().contains(m_id))
return true; return true;
} }
@ -338,7 +350,7 @@ bool AOClient::checkAuth(unsigned long long acl_mask)
return m_authenticated; return m_authenticated;
break; break;
case DataTypes::AuthType::ADVANCED: case DataTypes::AuthType::ADVANCED:
unsigned long long l_user_acl = server->db_manager->getACL(m_moderator_name); unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
return (l_user_acl & acl_mask) != 0; return (l_user_acl & acl_mask) != 0;
break; break;
} }
@ -346,7 +358,6 @@ bool AOClient::checkAuth(unsigned long long acl_mask)
return true; return true;
} }
QString AOClient::getIpid() const QString AOClient::getIpid() const
{ {
return m_ipid; return m_ipid;
@ -357,7 +368,12 @@ QString AOClient::getHwid() const
return m_hwid; return m_hwid;
} }
Server* AOClient::getServer() { return server; } bool AOClient::hasJoined() const
{
return m_joined;
}
Server *AOClient::getServer() { return server; }
void AOClient::onAfkTimeout() void AOClient::onAfkTimeout()
{ {
@ -366,8 +382,8 @@ void AOClient::onAfkTimeout()
m_is_afk = true; m_is_afk = true;
} }
AOClient::AOClient(Server *p_server, QTcpSocket *p_socket, QObject *parent, int user_id, MusicManager *p_manager) AOClient::AOClient(Server *p_server, QTcpSocket *p_socket, QObject *parent, int user_id, MusicManager *p_manager) :
: QObject(parent), QObject(parent),
m_id(user_id), m_id(user_id),
m_remote_ip(p_socket->peerAddress()), m_remote_ip(p_socket->peerAddress()),
m_password(""), m_password(""),
@ -382,10 +398,10 @@ AOClient::AOClient(Server *p_server, QTcpSocket *p_socket, QObject *parent, int
{ {
m_afk_timer = new QTimer; m_afk_timer = new QTimer;
m_afk_timer->setSingleShot(true); m_afk_timer->setSingleShot(true);
connect(m_afk_timer, &QTimer::timeout, connect(m_afk_timer, &QTimer::timeout, this, &AOClient::onAfkTimeout);
this, &AOClient::onAfkTimeout);
} }
AOClient::~AOClient() { AOClient::~AOClient()
{
m_socket->deleteLater(); m_socket->deleteLater();
} }

View File

@ -18,9 +18,12 @@
#include <algorithm> #include <algorithm>
#include "include/aopacket.h"
#include "include/area_data.h" #include "include/area_data.h"
#include "include/config_manager.h"
#include "include/music_manager.h"
AreaData::AreaData(QString p_name, int p_index, MusicManager* p_music_manager = nullptr) : AreaData::AreaData(QString p_name, int p_index, MusicManager *p_music_manager = nullptr) :
m_index(p_index), m_index(p_index),
m_music_manager(p_music_manager), m_music_manager(p_music_manager),
m_playerCount(0), m_playerCount(0),
@ -38,7 +41,7 @@ AreaData::AreaData(QString p_name, int p_index, MusicManager* p_music_manager =
QStringList name_split = p_name.split(":"); QStringList name_split = p_name.split(":");
name_split.removeFirst(); name_split.removeFirst();
m_name = name_split.join(":"); m_name = name_split.join(":");
QSettings* areas_ini = ConfigManager::areaData(); QSettings *areas_ini = ConfigManager::areaData();
areas_ini->setIniCodec("UTF-8"); areas_ini->setIniCodec("UTF-8");
areas_ini->beginGroup(p_name); areas_ini->beginGroup(p_name);
m_background = areas_ini->value("background", "gs4").toString(); m_background = areas_ini->value("background", "gs4").toString();
@ -46,20 +49,22 @@ AreaData::AreaData(QString p_name, int p_index, MusicManager* p_music_manager =
m_iniswapAllowed = areas_ini->value("iniswap_allowed", "true").toBool(); m_iniswapAllowed = areas_ini->value("iniswap_allowed", "true").toBool();
m_bgLocked = areas_ini->value("bg_locked", "false").toBool(); m_bgLocked = areas_ini->value("bg_locked", "false").toBool();
m_eviMod = QVariant(areas_ini->value("evidence_mod", "FFA").toString().toUpper()).value<EvidenceMod>(); m_eviMod = QVariant(areas_ini->value("evidence_mod", "FFA").toString().toUpper()).value<EvidenceMod>();
m_blankpostingAllowed = areas_ini->value("blankposting_allowed","true").toBool(); m_blankpostingAllowed = areas_ini->value("blankposting_allowed", "true").toBool();
m_area_message = areas_ini->value("area_message").toString();
m_send_area_message = areas_ini->value("send_area_message_on_join", false).toBool();
m_forceImmediate = areas_ini->value("force_immediate", "false").toBool(); m_forceImmediate = areas_ini->value("force_immediate", "false").toBool();
m_toggleMusic = areas_ini->value("toggle_music", "true").toBool(); m_toggleMusic = areas_ini->value("toggle_music", "true").toBool();
m_shownameAllowed = areas_ini->value("shownames_allowed", "true").toBool(); m_shownameAllowed = areas_ini->value("shownames_allowed", "true").toBool();
m_ignoreBgList = areas_ini->value("ignore_bglist", "false").toBool(); m_ignoreBgList = areas_ini->value("ignore_bglist", "false").toBool();
m_jukebox = areas_ini->value("jukebox_enabled", "false").toBool(); m_jukebox = areas_ini->value("jukebox_enabled", "false").toBool();
areas_ini->endGroup(); areas_ini->endGroup();
QTimer* timer1 = new QTimer(); QTimer *timer1 = new QTimer();
m_timers.append(timer1); m_timers.append(timer1);
QTimer* timer2 = new QTimer(); QTimer *timer2 = new QTimer();
m_timers.append(timer2); m_timers.append(timer2);
QTimer* timer3 = new QTimer(); QTimer *timer3 = new QTimer();
m_timers.append(timer3); m_timers.append(timer3);
QTimer* timer4 = new QTimer(); QTimer *timer4 = new QTimer();
m_timers.append(timer4); m_timers.append(timer4);
m_jukebox_timer = new QTimer(); m_jukebox_timer = new QTimer();
connect(m_jukebox_timer, &QTimer::timeout, connect(m_jukebox_timer, &QTimer::timeout,
@ -67,13 +72,13 @@ AreaData::AreaData(QString p_name, int p_index, MusicManager* p_music_manager =
} }
const QMap<QString, AreaData::Status> AreaData::map_statuses = { const QMap<QString, AreaData::Status> AreaData::map_statuses = {
{"idle", AreaData::Status::IDLE }, {"idle", AreaData::Status::IDLE},
{"rp", AreaData::Status::RP }, {"rp", AreaData::Status::RP},
{"casing", AreaData::Status::CASING }, {"casing", AreaData::Status::CASING},
{"lfp", AreaData::Status::LOOKING_FOR_PLAYERS }, {"lfp", AreaData::Status::LOOKING_FOR_PLAYERS},
{"looking-for-players", AreaData::Status::LOOKING_FOR_PLAYERS }, {"looking-for-players", AreaData::Status::LOOKING_FOR_PLAYERS},
{"recess", AreaData::Status::RECESS }, {"recess", AreaData::Status::RECESS},
{"gaming", AreaData::Status::GAMING }, {"gaming", AreaData::Status::GAMING},
}; };
void AreaData::clientLeftArea(int f_charId, int f_userId) void AreaData::clientLeftArea(int f_charId, int f_userId)
@ -95,9 +100,9 @@ void AreaData::clientJoinedArea(int f_charId, int f_userId)
} }
m_joined_ids.append(f_userId); m_joined_ids.append(f_userId);
emit userJoinedArea(m_index, f_userId); emit userJoinedArea(m_index, f_userId);
//The name will never be shown as we are using a spectator ID. Still nice for people who network sniff. // The name will never be shown as we are using a spectator ID. Still nice for people who network sniff.
//We auto-loop this so you'll never sit in silence unless wanted. // We auto-loop this so you'll never sit in silence unless wanted.
emit sendAreaPacketClient(AOPacket("MC",{m_currentMusic, QString::number(-1), ConfigManager::serverName(), QString::number(1)}), f_userId); emit sendAreaPacketClient(AOPacket("MC", {m_currentMusic, QString::number(-1), ConfigManager::serverName(), QString::number(1)}), f_userId);
} }
QList<int> AreaData::owners() const QList<int> AreaData::owners() const
@ -238,7 +243,7 @@ QList<AreaData::Evidence> AreaData::evidence() const
void AreaData::swapEvidence(int f_eviId1, int f_eviId2) void AreaData::swapEvidence(int f_eviId1, int f_eviId2)
{ {
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
//swapItemsAt does not exist in Qt older than 5.13 // swapItemsAt does not exist in Qt older than 5.13
m_evidence.swap(f_eviId1, f_eviId2); m_evidence.swap(f_eviId1, f_eviId2);
#else #else
m_evidence.swapItemsAt(f_eviId1, f_eviId2); m_evidence.swapItemsAt(f_eviId1, f_eviId2);
@ -323,7 +328,7 @@ void AreaData::toggleImmediate()
m_forceImmediate = !m_forceImmediate; m_forceImmediate = !m_forceImmediate;
} }
const QStringList& AreaData::lastICMessage() const const QStringList &AreaData::lastICMessage() const
{ {
return m_lastICMessage; return m_lastICMessage;
} }
@ -391,7 +396,7 @@ QPair<QStringList, AreaData::TestimonyProgress> AreaData::jumpToStatement(int f_
} }
} }
const QVector<QStringList>& AreaData::testimony() const const QVector<QStringList> &AreaData::testimony() const
{ {
return m_testimony; return m_testimony;
} }
@ -438,7 +443,7 @@ QString AreaData::musicPlayerBy() const
return m_musicPlayedBy; return m_musicPlayedBy;
} }
void AreaData::setMusicPlayedBy(const QString& f_music_player) void AreaData::setMusicPlayedBy(const QString &f_music_player)
{ {
m_musicPlayedBy = f_music_player; m_musicPlayedBy = f_music_player;
} }
@ -468,7 +473,8 @@ void AreaData::changeHP(AreaData::Side f_side, int f_newHP)
{ {
if (f_side == Side::DEFENCE) { if (f_side == Side::DEFENCE) {
m_defHP = std::min(std::max(0, f_newHP), 10); m_defHP = std::min(std::max(0, f_newHP), 10);
} else if(f_side == Side::PROSECUTOR) { }
else if (f_side == Side::PROSECUTOR) {
m_proHP = std::min(std::max(0, f_newHP), 10); m_proHP = std::min(std::max(0, f_newHP), 10);
} }
} }
@ -490,7 +496,7 @@ void AreaData::changeDoc(const QString &f_newDoc_r)
QString AreaData::areaMessage() const QString AreaData::areaMessage() const
{ {
return m_area_message; return m_area_message.isEmpty() ? "No area message set." : m_area_message;
} }
bool AreaData::sendAreaMessageOnJoin() const bool AreaData::sendAreaMessageOnJoin() const
@ -498,14 +504,16 @@ bool AreaData::sendAreaMessageOnJoin() const
return m_send_area_message; return m_send_area_message;
} }
void AreaData::changeAreaMessage(const QString& f_newMessage_r) void AreaData::changeAreaMessage(const QString &f_newMessage_r)
{ {
if(f_newMessage_r.isEmpty())
m_area_message = "No area message set.";
else
m_area_message = f_newMessage_r; m_area_message = f_newMessage_r;
} }
void AreaData::clearAreaMessage()
{
changeAreaMessage(QString{});
}
bool AreaData::bgLocked() const bool AreaData::bgLocked() const
{ {
return m_bgLocked; return m_bgLocked;
@ -567,14 +575,14 @@ void AreaData::toggleJukebox()
QString AreaData::addJukeboxSong(QString f_song) QString AreaData::addJukeboxSong(QString f_song)
{ {
if(!m_jukebox_queue.contains(f_song)) { if (!m_jukebox_queue.contains(f_song)) {
//Retrieve song information. // Retrieve song information.
QPair<QString,float> l_song = m_music_manager->songInformation(f_song, index()); QPair<QString, float> l_song = m_music_manager->songInformation(f_song, index());
if (l_song.second > 0) { if (l_song.second > 0) {
if (m_jukebox_queue.size() == 0) { if (m_jukebox_queue.size() == 0) {
emit sendAreaPacket(AOPacket("MC",{l_song.first,QString::number(-1)}), index()); emit sendAreaPacket(AOPacket("MC", {l_song.first, QString::number(-1)}), index());
m_jukebox_timer->start(l_song.second * 1000); m_jukebox_timer->start(l_song.second * 1000);
setCurrentMusic(f_song); setCurrentMusic(f_song);
setMusicPlayedBy("Jukebox"); setMusicPlayedBy("Jukebox");
@ -597,18 +605,18 @@ QVector<int> AreaData::joinedIDs() const
void AreaData::switchJukeboxSong() void AreaData::switchJukeboxSong()
{ {
QString l_song_name; QString l_song_name;
if(m_jukebox_queue.size() == 1) { if (m_jukebox_queue.size() == 1) {
l_song_name = m_jukebox_queue[0]; l_song_name = m_jukebox_queue[0];
QPair<QString,float> l_song = m_music_manager->songInformation(l_song_name, index()); QPair<QString, float> l_song = m_music_manager->songInformation(l_song_name, index());
emit sendAreaPacket(AOPacket("MC",{l_song.first,"-1"}), m_index); emit sendAreaPacket(AOPacket("MC", {l_song.first, "-1"}), m_index);
m_jukebox_timer->start(l_song.second * 1000); m_jukebox_timer->start(l_song.second * 1000);
} }
else { else {
int l_random_index = QRandomGenerator::system()->bounded(m_jukebox_queue.size() -1); int l_random_index = QRandomGenerator::system()->bounded(m_jukebox_queue.size() - 1);
l_song_name = m_jukebox_queue[l_random_index]; l_song_name = m_jukebox_queue[l_random_index];
QPair<QString,float> l_song = m_music_manager->songInformation(l_song_name, index()); QPair<QString, float> l_song = m_music_manager->songInformation(l_song_name, index());
emit sendAreaPacket(AOPacket("MC",{l_song.first,"-1"}), m_index); emit sendAreaPacket(AOPacket("MC", {l_song.first, "-1"}), m_index);
m_jukebox_timer->start(l_song.second * 1000); m_jukebox_timer->start(l_song.second * 1000);
m_jukebox_queue.remove(l_random_index); m_jukebox_queue.remove(l_random_index);

View File

@ -17,14 +17,18 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/server.h"
// This file is for commands under the area category in aoclient.h // This file is for commands under the area category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
void AOClient::cmdCM(int argc, QStringList argv) void AOClient::cmdCM(int argc, QStringList argv)
{ {
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->isProtected()) { if (l_area->isProtected()) {
sendServerMessage("This area is protected, you may not become CM."); sendServerMessage("This area is protected, you may not become CM.");
return; return;
@ -39,7 +43,7 @@ void AOClient::cmdCM(int argc, QStringList argv)
} }
else if (argc == 1) { // we are CM, and we want to make ID argv[0] also CM else if (argc == 1) { // we are CM, and we want to make ID argv[0] also CM
bool ok; bool ok;
AOClient* l_owner_candidate = server->getClientByID(argv[0].toInt(&ok)); AOClient *l_owner_candidate = server->getClientByID(argv[0].toInt(&ok));
if (!ok) { if (!ok) {
sendServerMessage("That doesn't look like a valid ID."); sendServerMessage("That doesn't look like a valid ID.");
return; return;
@ -63,7 +67,7 @@ void AOClient::cmdCM(int argc, QStringList argv)
void AOClient::cmdUnCM(int argc, QStringList argv) void AOClient::cmdUnCM(int argc, QStringList argv)
{ {
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
int l_uid; int l_uid;
if (l_area->owners().isEmpty()) { if (l_area->owners().isEmpty()) {
@ -85,7 +89,7 @@ void AOClient::cmdUnCM(int argc, QStringList argv)
sendServerMessage("That user is not CMed."); sendServerMessage("That user is not CMed.");
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
return; return;
@ -108,7 +112,7 @@ void AOClient::cmdInvite(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
bool ok; bool ok;
int l_invited_id = argv[0].toInt(&ok); int l_invited_id = argv[0].toInt(&ok);
if (!ok) { if (!ok) {
@ -116,7 +120,7 @@ void AOClient::cmdInvite(int argc, QStringList argv)
return; return;
} }
AOClient* target_client = server->getClientByID(l_invited_id); AOClient *target_client = server->getClientByID(l_invited_id);
if (target_client == nullptr) { if (target_client == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
return; return;
@ -133,7 +137,7 @@ void AOClient::cmdUnInvite(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
bool ok; bool ok;
int l_uninvited_id = argv[0].toInt(&ok); int l_uninvited_id = argv[0].toInt(&ok);
if (!ok) { if (!ok) {
@ -141,7 +145,7 @@ void AOClient::cmdUnInvite(int argc, QStringList argv)
return; return;
} }
AOClient* target_client = server->getClientByID(l_uninvited_id); AOClient *target_client = server->getClientByID(l_uninvited_id);
if (target_client == nullptr) { if (target_client == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
return; return;
@ -163,16 +167,17 @@ void AOClient::cmdLock(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* area = server->m_areas[m_current_area]; AreaData *area = server->getAreaById(m_current_area);
if (area->lockStatus() == AreaData::LockStatus::LOCKED) { if (area->lockStatus() == AreaData::LockStatus::LOCKED) {
sendServerMessage("This area is already locked."); sendServerMessage("This area is already locked.");
return; return;
} }
sendServerMessageArea("This area is now locked."); sendServerMessageArea("This area is now locked.");
area->lock(); area->lock();
for (AOClient* client : qAsConst(server->m_clients)) { // qAsConst here avoids detaching the container const QVector<AOClient *> l_clients = server->getClients();
if (client->m_current_area == m_current_area && client->m_joined) { for (AOClient *l_client : l_clients) {
area->invite(client->m_id); if (l_client->m_current_area == m_current_area && l_client->hasJoined()) {
area->invite(l_client->m_id);
} }
} }
arup(ARUPType::LOCKED, true); arup(ARUPType::LOCKED, true);
@ -183,16 +188,17 @@ void AOClient::cmdSpectatable(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->lockStatus() == AreaData::LockStatus::SPECTATABLE) { if (l_area->lockStatus() == AreaData::LockStatus::SPECTATABLE) {
sendServerMessage("This area is already in spectate mode."); sendServerMessage("This area is already in spectate mode.");
return; return;
} }
sendServerMessageArea("This area is now spectatable."); sendServerMessageArea("This area is now spectatable.");
l_area->spectatable(); l_area->spectatable();
for (AOClient* client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
if (client->m_current_area == m_current_area && client->m_joined) { for (AOClient *l_client : l_clients) {
l_area->invite(client->m_id); if (l_client->m_current_area == m_current_area && l_client->hasJoined()) {
l_area->invite(l_client->m_id);
} }
} }
arup(ARUPType::LOCKED, true); arup(ARUPType::LOCKED, true);
@ -203,7 +209,7 @@ void AOClient::cmdUnLock(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->lockStatus() == AreaData::LockStatus::FREE) { if (l_area->lockStatus() == AreaData::LockStatus::FREE) {
sendServerMessage("This area is not locked."); sendServerMessage("This area is not locked.");
return; return;
@ -219,9 +225,9 @@ void AOClient::cmdGetAreas(int argc, QStringList argv)
Q_UNUSED(argv); Q_UNUSED(argv);
QStringList l_entries; QStringList l_entries;
l_entries.append("\n== Currently Online: " + QString::number(server->m_player_count)+ " =="); l_entries.append("\n== Currently Online: " + QString::number(server->getPlayerCount()) + " ==");
for (int i = 0; i < server->m_area_names.length(); i++) { for (int i = 0; i < server->getAreaCount(); i++) {
if (server->m_areas.value(i)->playerCount() > 0) { if (server->getAreaById(i)->playerCount() > 0) {
QStringList l_cur_area_lines = buildAreaList(i); QStringList l_cur_area_lines = buildAreaList(i);
l_entries.append(l_cur_area_lines); l_entries.append(l_cur_area_lines);
} }
@ -244,7 +250,7 @@ void AOClient::cmdArea(int argc, QStringList argv)
bool ok; bool ok;
int l_new_area = argv[0].toInt(&ok); int l_new_area = argv[0].toInt(&ok);
if (!ok || l_new_area >= server->m_areas.size() || l_new_area < 0) { if (!ok || l_new_area >= server->getAreaCount() || l_new_area < 0) {
sendServerMessage("That does not look like a valid area ID."); sendServerMessage("That does not look like a valid area ID.");
return; return;
} }
@ -255,7 +261,7 @@ void AOClient::cmdAreaKick(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
bool ok; bool ok;
int l_idx = argv[0].toInt(&ok); int l_idx = argv[0].toInt(&ok);
@ -263,11 +269,11 @@ void AOClient::cmdAreaKick(int argc, QStringList argv)
sendServerMessage("That does not look like a valid ID."); sendServerMessage("That does not look like a valid ID.");
return; return;
} }
if (server->m_areas[m_current_area]->owners().contains(l_idx)) { if (server->getAreaById(m_current_area)->owners().contains(l_idx)) {
sendServerMessage("You cannot kick another CM!"); sendServerMessage("You cannot kick another CM!");
return; return;
} }
AOClient* l_client_to_kick = server->getClientByID(l_idx); AOClient *l_client_to_kick = server->getClientByID(l_idx);
if (l_client_to_kick == nullptr) { if (l_client_to_kick == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
return; return;
@ -287,9 +293,9 @@ void AOClient::cmdSetBackground(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
QString f_background = argv.join(" "); QString f_background = argv.join(" ");
AreaData* area = server->m_areas[m_current_area]; AreaData *area = server->getAreaById(m_current_area);
if (m_authenticated || !area->bgLocked()) { if (m_authenticated || !area->bgLocked()) {
if (server->m_backgrounds.contains(f_background, Qt::CaseInsensitive) || area->ignoreBgList() == true) { if (server->getBackgrounds().contains(f_background, Qt::CaseInsensitive) || area->ignoreBgList() == true) {
area->setBackground(f_background); area->setBackground(f_background);
server->broadcast(AOPacket("BN", {f_background}), m_current_area); server->broadcast(AOPacket("BN", {f_background}), m_current_area);
sendServerMessageArea(m_current_char + " changed the background to " + f_background); sendServerMessageArea(m_current_char + " changed the background to " + f_background);
@ -308,7 +314,7 @@ void AOClient::cmdBgLock(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->bgLocked() == false) { if (l_area->bgLocked() == false) {
l_area->toggleBgLock(); l_area->toggleBgLock();
@ -322,7 +328,7 @@ void AOClient::cmdBgUnlock(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->bgLocked() == true) { if (l_area->bgLocked() == true) {
l_area->toggleBgLock(); l_area->toggleBgLock();
@ -335,13 +341,14 @@ void AOClient::cmdStatus(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
QString l_arg = argv[0].toLower(); QString l_arg = argv[0].toLower();
if (l_area->changeStatus(l_arg)) { if (l_area->changeStatus(l_arg)) {
arup(ARUPType::STATUS, true); arup(ARUPType::STATUS, true);
server->broadcast(AOPacket("CT", {ConfigManager::serverName(), m_current_char + " changed status to " + l_arg.toUpper(), "1"}), m_current_area); server->broadcast(AOPacket("CT", {ConfigManager::serverName(), m_current_char + " changed status to " + l_arg.toUpper(), "1"}), m_current_area);
} else { }
else {
const QStringList keys = AreaData::map_statuses.keys(); const QStringList keys = AreaData::map_statuses.keys();
sendServerMessage("That does not look like a valid status. Valid statuses are " + keys.join(", ")); sendServerMessage("That does not look like a valid status. Valid statuses are " + keys.join(", "));
} }
@ -352,18 +359,18 @@ void AOClient::cmdJudgeLog(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->judgelog().isEmpty()) { if (l_area->judgelog().isEmpty()) {
sendServerMessage("There have been no judge actions in this area."); sendServerMessage("There have been no judge actions in this area.");
return; return;
} }
QString l_message = l_area->judgelog().join("\n"); QString l_message = l_area->judgelog().join("\n");
//Judgelog contains an IPID, so we shouldn't send that unless the caller has appropriate permissions // Judgelog contains an IPID, so we shouldn't send that unless the caller has appropriate permissions
if (checkAuth(ACLFlags.value("KICK")) == 1 || checkAuth(ACLFlags.value("BAN")) == 1) { if (checkAuth(ACLFlags.value("KICK")) == 1 || checkAuth(ACLFlags.value("BAN")) == 1) {
sendServerMessage(l_message); sendServerMessage(l_message);
} }
else { else {
QString filteredmessage = l_message.remove(QRegularExpression("[(].*[)]")); //Filter out anything between two parentheses. This should only ever be the IPID QString filteredmessage = l_message.remove(QRegularExpression("[(].*[)]")); // Filter out anything between two parentheses. This should only ever be the IPID
sendServerMessage(filteredmessage); sendServerMessage(filteredmessage);
} }
} }
@ -373,7 +380,7 @@ void AOClient::cmdIgnoreBgList(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->toggleIgnoreBgList(); l_area->toggleIgnoreBgList();
QString l_state = l_area->ignoreBgList() ? "ignored." : "enforced."; QString l_state = l_area->ignoreBgList() ? "ignored." : "enforced.";
sendServerMessage("BG list in this area is now " + l_state); sendServerMessage("BG list in this area is now " + l_state);
@ -381,7 +388,7 @@ void AOClient::cmdIgnoreBgList(int argc, QStringList argv)
void AOClient::cmdAreaMessage(int argc, QStringList argv) void AOClient::cmdAreaMessage(int argc, QStringList argv)
{ {
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (argc == 0) { if (argc == 0) {
sendServerMessage(l_area->areaMessage()); sendServerMessage(l_area->areaMessage());
return; return;
@ -398,10 +405,10 @@ void AOClient::cmdToggleAreaMessageOnJoin(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->toggleAreaMessageJoin(); l_area->toggleAreaMessageJoin();
QString l_state = l_area->sendAreaMessageOnJoin() ? "enabled." : "disabled."; QString l_state = l_area->sendAreaMessageOnJoin() ? "enabled." : "disabled.";
sendServerMessage("Sending message on area join is now " +l_state); sendServerMessage("Sending message on area join is now " + l_state);
} }
void AOClient::cmdClearAreaMessage(int argc, QStringList argv) void AOClient::cmdClearAreaMessage(int argc, QStringList argv)
@ -409,8 +416,8 @@ void AOClient::cmdClearAreaMessage(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->changeAreaMessage(QString{}); l_area->clearAreaMessage();
if (l_area->sendAreaMessageOnJoin()) //Turn off the automatic sending. if (l_area->sendAreaMessageOnJoin()) // Turn off the automatic sending.
cmdToggleAreaMessageOnJoin(0,QStringList{}); //Dummy values. cmdToggleAreaMessageOnJoin(0, QStringList{}); // Dummy values.
} }

View File

@ -17,6 +17,10 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/config_manager.h"
#include "include/db_manager.h"
#include "include/server.h"
// This file is for commands under the authentication category in aoclient.h // This file is for commands under the authentication category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
@ -86,7 +90,7 @@ void AOClient::cmdSetRootPass(int argc, QStringList argv)
#endif #endif
QString l_salt = QStringLiteral("%1").arg(l_salt_number, 16, 16, QLatin1Char('0')); QString l_salt = QStringLiteral("%1").arg(l_salt_number, 16, 16, QLatin1Char('0'));
server->db_manager->createUser("root", l_salt, argv[0], ACLFlags.value("SUPER")); server->getDatabaseManager()->createUser("root", l_salt, argv[0], ACLFlags.value("SUPER"));
} }
void AOClient::cmdAddUser(int argc, QStringList argv) void AOClient::cmdAddUser(int argc, QStringList argv)
@ -107,7 +111,7 @@ void AOClient::cmdAddUser(int argc, QStringList argv)
#endif #endif
QString l_salt = QStringLiteral("%1").arg(l_salt_number, 16, 16, QLatin1Char('0')); QString l_salt = QStringLiteral("%1").arg(l_salt_number, 16, 16, QLatin1Char('0'));
if (server->db_manager->createUser(argv[0], l_salt, argv[1], ACLFlags.value("NONE"))) if (server->getDatabaseManager()->createUser(argv[0], l_salt, argv[1], ACLFlags.value("NONE")))
sendServerMessage("Created user " + argv[0] + ".\nUse /addperm to modify their permissions."); sendServerMessage("Created user " + argv[0] + ".\nUse /addperm to modify their permissions.");
else else
sendServerMessage("Unable to create user " + argv[0] + ".\nDoes a user with that name already exist?"); sendServerMessage("Unable to create user " + argv[0] + ".\nDoes a user with that name already exist?");
@ -117,7 +121,7 @@ void AOClient::cmdRemoveUser(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
if (server->db_manager->deleteUser(argv[0])) if (server->getDatabaseManager()->deleteUser(argv[0]))
sendServerMessage("Successfully removed user " + argv[0] + "."); sendServerMessage("Successfully removed user " + argv[0] + ".");
else else
sendServerMessage("Unable to remove user " + argv[0] + ".\nDoes it exist?"); sendServerMessage("Unable to remove user " + argv[0] + ".\nDoes it exist?");
@ -125,19 +129,21 @@ void AOClient::cmdRemoveUser(int argc, QStringList argv)
void AOClient::cmdListPerms(int argc, QStringList argv) void AOClient::cmdListPerms(int argc, QStringList argv)
{ {
unsigned long long l_user_acl = server->db_manager->getACL(m_moderator_name); unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
QStringList l_message; QStringList l_message;
const QStringList l_keys = ACLFlags.keys(); const QStringList l_keys = ACLFlags.keys();
if (argc == 0) { if (argc == 0) {
// Just print out all permissions available to the user. // Just print out all permissions available to the user.
l_message.append("You have been given the following permissions:"); l_message.append("You have been given the following permissions:");
for (const QString &l_perm : l_keys) { for (const QString &l_perm : l_keys) {
if (l_perm == "NONE"); // don't need to list this one if (l_perm == "NONE")
; // don't need to list this one
else if (l_perm == "SUPER") { else if (l_perm == "SUPER") {
if (l_user_acl == ACLFlags.value("SUPER")) // This has to be checked separately, because SUPER & anything will always be truthy if (l_user_acl == ACLFlags.value("SUPER")) // This has to be checked separately, because SUPER & anything will always be truthy
l_message.append("SUPER (Be careful! This grants the user all permissions.)"); l_message.append("SUPER (Be careful! This grants the user all permissions.)");
} }
else if ((ACLFlags.value(l_perm) & l_user_acl) == 0); // user doesn't have this permission, don't print it else if ((ACLFlags.value(l_perm) & l_user_acl) == 0)
; // user doesn't have this permission, don't print it
else else
l_message.append(l_perm); l_message.append(l_perm);
} }
@ -149,7 +155,7 @@ void AOClient::cmdListPerms(int argc, QStringList argv)
} }
l_message.append("User " + argv[0] + " has the following permissions:"); l_message.append("User " + argv[0] + " has the following permissions:");
unsigned long long l_acl = server->db_manager->getACL(argv[0]); unsigned long long l_acl = server->getDatabaseManager()->getACL(argv[0]);
if (l_acl == 0) { if (l_acl == 0) {
sendServerMessage("This user either doesn't exist, or has no permissions set."); sendServerMessage("This user either doesn't exist, or has no permissions set.");
return; return;
@ -168,7 +174,7 @@ void AOClient::cmdAddPerms(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
unsigned long long l_user_acl = server->db_manager->getACL(m_moderator_name); unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
argv[1] = argv[1].toUpper(); argv[1] = argv[1].toUpper();
const QStringList l_keys = ACLFlags.keys(); const QStringList l_keys = ACLFlags.keys();
@ -191,7 +197,7 @@ void AOClient::cmdAddPerms(int argc, QStringList argv)
unsigned long long l_newperm = ACLFlags.value(argv[1]); unsigned long long l_newperm = ACLFlags.value(argv[1]);
if ((l_newperm & l_user_acl) != 0) { if ((l_newperm & l_user_acl) != 0) {
if (server->db_manager->updateACL(argv[0], l_newperm, true)) if (server->getDatabaseManager()->updateACL(argv[0], l_newperm, true))
sendServerMessage("Successfully added permission " + argv[1] + " to user " + argv[0]); sendServerMessage("Successfully added permission " + argv[1] + " to user " + argv[0]);
else else
sendServerMessage(argv[0] + " wasn't found!"); sendServerMessage(argv[0] + " wasn't found!");
@ -205,7 +211,7 @@ void AOClient::cmdRemovePerms(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
unsigned long long l_user_acl = server->db_manager->getACL(m_moderator_name); unsigned long long l_user_acl = server->getDatabaseManager()->getACL(m_moderator_name);
argv[1] = argv[1].toUpper(); argv[1] = argv[1].toUpper();
const QStringList l_keys = ACLFlags.keys(); const QStringList l_keys = ACLFlags.keys();
@ -234,7 +240,7 @@ void AOClient::cmdRemovePerms(int argc, QStringList argv)
unsigned long long l_newperm = ACLFlags.value(argv[1]); unsigned long long l_newperm = ACLFlags.value(argv[1]);
if ((l_newperm & l_user_acl) != 0) { if ((l_newperm & l_user_acl) != 0) {
if (server->db_manager->updateACL(argv[0], l_newperm, false)) if (server->getDatabaseManager()->updateACL(argv[0], l_newperm, false))
sendServerMessage("Successfully removed permission " + argv[1] + " from user " + argv[0]); sendServerMessage("Successfully removed permission " + argv[1] + " from user " + argv[0]);
else else
sendServerMessage(argv[0] + " wasn't found!"); sendServerMessage(argv[0] + " wasn't found!");
@ -249,7 +255,7 @@ void AOClient::cmdListUsers(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
QStringList l_users = server->db_manager->getUsers(); QStringList l_users = server->getDatabaseManager()->getUsers();
sendServerMessage("All users:\n" + l_users.join("\n")); sendServerMessage("All users:\n" + l_users.join("\n"));
} }
@ -291,7 +297,7 @@ void AOClient::cmdChangePassword(int argc, QStringList argv)
return; return;
} }
if (server->db_manager->updatePassword(l_username, l_password)) { if (server->getDatabaseManager()->updatePassword(l_username, l_password)) {
sendServerMessage("Successfully changed password."); sendServerMessage("Successfully changed password.");
} }
else { else {

View File

@ -17,13 +17,18 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/server.h"
// This file is for commands under the casing category in aoclient.h // This file is for commands under the casing category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
void AOClient::cmdDoc(int argc, QStringList argv) void AOClient::cmdDoc(int argc, QStringList argv)
{ {
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (argc == 0) { if (argc == 0) {
sendServerMessage("Document: " + l_area->document()); sendServerMessage("Document: " + l_area->document());
} }
@ -39,7 +44,7 @@ void AOClient::cmdClearDoc(int argc, QStringList argv)
Q_UNUSED(argv); Q_UNUSED(argv);
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->changeDoc("No document."); l_area->changeDoc("No document.");
sendServerMessageArea(l_sender_name + " cleared the document."); sendServerMessageArea(l_sender_name + " cleared the document.");
} }
@ -48,7 +53,7 @@ void AOClient::cmdEvidenceMod(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
argv[0] = argv[0].toLower(); argv[0] = argv[0].toLower();
if (argv[0] == "cm") if (argv[0] == "cm")
l_area->setEviMod(AreaData::EvidenceMod::CM); l_area->setEviMod(AreaData::EvidenceMod::CM);
@ -72,8 +77,8 @@ void AOClient::cmdEvidence_Swap(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
int l_ev_size = l_area->evidence().size() -1; int l_ev_size = l_area->evidence().size() - 1;
if (l_ev_size < 0) { if (l_ev_size < 0) {
sendServerMessage("No evidence in area."); sendServerMessage("No evidence in area.");
@ -106,7 +111,7 @@ void AOClient::cmdTestify(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING) { if (l_area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING) {
sendServerMessage("Testimony recording is already in progress. Please stop it before starting a new one."); sendServerMessage("Testimony recording is already in progress. Please stop it before starting a new one.");
} }
@ -122,11 +127,10 @@ void AOClient::cmdExamine(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->testimony().size() -1 > 0) if (l_area->testimony().size() - 1 > 0) {
{
l_area->restartTestimony(); l_area->restartTestimony();
server->broadcast(AOPacket("RT",{"testimony2"}), m_current_area); server->broadcast(AOPacket("RT", {"testimony2"}), m_current_area);
server->broadcast(AOPacket("MS", {l_area->testimony()[0]}), m_current_area); server->broadcast(AOPacket("MS", {l_area->testimony()[0]}), m_current_area);
return; return;
} }
@ -141,18 +145,17 @@ void AOClient::cmdTestimony(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->testimony().size() -1 < 1) { if (l_area->testimony().size() - 1 < 1) {
sendServerMessage("Unable to display empty testimony."); sendServerMessage("Unable to display empty testimony.");
return; return;
} }
QString l_ooc_message; QString l_ooc_message;
for (int i = 1; i <= l_area->testimony().size() -1; i++) for (int i = 1; i <= l_area->testimony().size() - 1; i++) {
{
QStringList l_packet = l_area->testimony().at(i); QStringList l_packet = l_area->testimony().at(i);
QString l_ic_message = l_packet[4]; QString l_ic_message = l_packet[4];
l_ooc_message.append( "[" + QString::number(i) + "]" + l_ic_message + "\n"); l_ooc_message.append("[" + QString::number(i) + "]" + l_ic_message + "\n");
} }
sendServerMessage(l_ooc_message); sendServerMessage(l_ooc_message);
} }
@ -162,7 +165,7 @@ void AOClient::cmdDeleteStatement(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
int l_c_statement = l_area->statement(); int l_c_statement = l_area->statement();
if (l_area->testimony().size() - 1 == 0) { if (l_area->testimony().size() - 1 == 0) {
sendServerMessage("Unable to delete statement. No statements saved in this area."); sendServerMessage("Unable to delete statement. No statements saved in this area.");
@ -178,7 +181,7 @@ void AOClient::cmdUpdateStatement(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
server->m_areas[m_current_area]->setTestimonyRecording(AreaData::TestimonyRecording::UPDATE); server->getAreaById(m_current_area)->setTestimonyRecording(AreaData::TestimonyRecording::UPDATE);
sendServerMessage("The next IC-Message will replace the last displayed replay message."); sendServerMessage("The next IC-Message will replace the last displayed replay message.");
} }
@ -187,9 +190,9 @@ void AOClient::cmdPauseTestimony(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->setTestimonyRecording(AreaData::TestimonyRecording::STOPPED); l_area->setTestimonyRecording(AreaData::TestimonyRecording::STOPPED);
server->broadcast(AOPacket("RT",{"testimony1", "1"}), m_current_area); server->broadcast(AOPacket("RT", {"testimony1", "1"}), m_current_area);
sendServerMessage("Testimony has been stopped."); sendServerMessage("Testimony has been stopped.");
} }
@ -198,8 +201,8 @@ void AOClient::cmdAddStatement(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
if (server->m_areas[m_current_area]->statement() < ConfigManager::maxStatements()) { if (server->getAreaById(m_current_area)->statement() < ConfigManager::maxStatements()) {
server->m_areas[m_current_area]->setTestimonyRecording(AreaData::TestimonyRecording::ADD); server->getAreaById(m_current_area)->setTestimonyRecording(AreaData::TestimonyRecording::ADD);
sendServerMessage("The next IC-Message will be inserted into the testimony."); sendServerMessage("The next IC-Message will be inserted into the testimony.");
} }
else else
@ -218,8 +221,8 @@ void AOClient::cmdSaveTestimony(int argc, QStringList argv)
l_permission_found = true; l_permission_found = true;
if (l_permission_found) { if (l_permission_found) {
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (l_area->testimony().size() -1 <= 0) { if (l_area->testimony().size() - 1 <= 0) {
sendServerMessage("Can't save an empty testimony."); sendServerMessage("Can't save an empty testimony.");
return; return;
} }
@ -229,7 +232,7 @@ void AOClient::cmdSaveTestimony(int argc, QStringList argv)
l_dir_testimony.mkpath("."); l_dir_testimony.mkpath(".");
} }
QString l_testimony_name = argv[0].trimmed().toLower().replace("..",""); // :) QString l_testimony_name = argv[0].trimmed().toLower().replace("..", ""); // :)
QFile l_file("storage/testimony/" + l_testimony_name + ".txt"); QFile l_file("storage/testimony/" + l_testimony_name + ".txt");
if (l_file.exists()) { if (l_file.exists()) {
sendServerMessage("Unable to save testimony. Testimony name already exists."); sendServerMessage("Unable to save testimony. Testimony name already exists.");
@ -238,9 +241,8 @@ void AOClient::cmdSaveTestimony(int argc, QStringList argv)
QTextStream l_out(&l_file); QTextStream l_out(&l_file);
l_out.setCodec("UTF-8"); l_out.setCodec("UTF-8");
if(l_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) { if (l_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
for (int i = 0; i <= l_area->testimony().size() -1; i++) for (int i = 0; i <= l_area->testimony().size() - 1; i++) {
{
l_out << l_area->testimony().at(i).join("#") << "\n"; l_out << l_area->testimony().at(i).join("#") << "\n";
} }
sendServerMessage("Testimony saved. To load it use /loadtestimony " + l_testimony_name); sendServerMessage("Testimony saved. To load it use /loadtestimony " + l_testimony_name);
@ -257,14 +259,14 @@ void AOClient::cmdLoadTestimony(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
QDir l_dir_testimony("storage/testimony"); QDir l_dir_testimony("storage/testimony");
if (!l_dir_testimony.exists()) { if (!l_dir_testimony.exists()) {
sendServerMessage("Unable to load testimonies. Testimony storage not found."); sendServerMessage("Unable to load testimonies. Testimony storage not found.");
return; return;
} }
QString l_testimony_name = argv[0].trimmed().toLower().replace("..",""); // :) QString l_testimony_name = argv[0].trimmed().toLower().replace("..", ""); // :)
QFile l_file("storage/testimony/" + l_testimony_name + ".txt"); QFile l_file("storage/testimony/" + l_testimony_name + ".txt");
if (!l_file.exists()) { if (!l_file.exists()) {
sendServerMessage("Unable to load testimony. Testimony name not found."); sendServerMessage("Unable to load testimony. Testimony name not found.");

View File

@ -17,6 +17,11 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/server.h"
// This file is for functions used by various commands, defined in the command helper function category in aoclient.h // This file is for functions used by various commands, defined in the command helper function category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
@ -32,8 +37,8 @@ void AOClient::cmdDefault(int argc, QStringList argv)
QStringList AOClient::buildAreaList(int area_idx) QStringList AOClient::buildAreaList(int area_idx)
{ {
QStringList entries; QStringList entries;
QString area_name = server->m_area_names[area_idx]; QString area_name = server->getAreaName(area_idx);
AreaData* area = server->m_areas[area_idx]; AreaData *area = server->getAreaById(area_idx);
entries.append("=== " + area_name + " ==="); entries.append("=== " + area_name + " ===");
switch (area->lockStatus()) { switch (area->lockStatus()) {
case AreaData::LockStatus::LOCKED: case AreaData::LockStatus::LOCKED:
@ -47,18 +52,19 @@ QStringList AOClient::buildAreaList(int area_idx)
break; break;
} }
entries.append("[" + QString::number(area->playerCount()) + " users][" + QVariant::fromValue(area->status()).toString().replace("_", "-") + "]"); entries.append("[" + QString::number(area->playerCount()) + " users][" + QVariant::fromValue(area->status()).toString().replace("_", "-") + "]");
for (AOClient* client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
if (client->m_current_area == area_idx && client->m_joined) { for (AOClient *l_client : l_clients) {
QString char_entry = "[" + QString::number(client->m_id) + "] " + client->m_current_char; if (l_client->m_current_area == area_idx && l_client->hasJoined()) {
if (client->m_current_char == "") QString char_entry = "[" + QString::number(l_client->m_id) + "] " + l_client->m_current_char;
if (l_client->m_current_char == "")
char_entry += "Spectator"; char_entry += "Spectator";
if (client->m_showname != "") if (l_client->m_showname != "")
char_entry += " (" + client->m_showname + ")"; char_entry += " (" + l_client->m_showname + ")";
if (area->owners().contains(client->m_id)) if (area->owners().contains(l_client->m_id))
char_entry.insert(0, "[CM] "); char_entry.insert(0, "[CM] ");
if (m_authenticated) if (m_authenticated)
char_entry += " (" + client->getIpid() + "): " + client->m_ooc_name; char_entry += " (" + l_client->getIpid() + "): " + l_client->m_ooc_name;
if (client->m_is_afk) if (l_client->m_is_afk)
char_entry += " [AFK]"; char_entry += " [AFK]";
entries.append(char_entry); entries.append(char_entry);
} }
@ -100,8 +106,8 @@ void AOClient::diceThrower(int argc, QStringList argv, bool p_roll)
QString AOClient::getAreaTimer(int area_idx, int timer_idx) QString AOClient::getAreaTimer(int area_idx, int timer_idx)
{ {
AreaData* l_area = server->m_areas[area_idx]; AreaData *l_area = server->getAreaById(area_idx);
QTimer* l_timer; QTimer *l_timer;
QString l_timer_name = (timer_idx == 0) ? "Global timer" : "Timer " + QString::number(timer_idx); QString l_timer_name = (timer_idx == 0) ? "Global timer" : "Timer " + QString::number(timer_idx);
if (timer_idx == 0) if (timer_idx == 0)
@ -112,7 +118,7 @@ QString AOClient::getAreaTimer(int area_idx, int timer_idx)
return "Invalid timer ID."; return "Invalid timer ID.";
if (l_timer->isActive()) { if (l_timer->isActive()) {
QTime l_current_time = QTime(0,0).addMSecs(l_timer->remainingTime()); QTime l_current_time = QTime(0, 0).addMSecs(l_timer->remainingTime());
return l_timer_name + " is at " + l_current_time.toString("hh:mm:ss.zzz"); return l_timer_name + " is at " + l_current_time.toString("hh:mm:ss.zzz");
} }

View File

@ -17,6 +17,10 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/server.h"
// This file is for commands under the messaging category in aoclient.h // This file is for commands under the messaging category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
@ -25,7 +29,7 @@ void AOClient::cmdPos(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
changePosition(argv[0]); changePosition(argv[0]);
updateEvidenceList(server->m_areas[m_current_area]); updateEvidenceList(server->getAreaById(m_current_area));
} }
void AOClient::cmdForcePos(int argc, QStringList argv) void AOClient::cmdForcePos(int argc, QStringList argv)
@ -33,7 +37,7 @@ void AOClient::cmdForcePos(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
bool ok; bool ok;
QList<AOClient*> l_targets; QList<AOClient *> l_targets;
int l_target_id = argv[1].toInt(&ok); int l_target_id = argv[1].toInt(&ok);
int l_forced_clients = 0; int l_forced_clients = 0;
if (!ok && argv[1] != "*") { if (!ok && argv[1] != "*") {
@ -41,7 +45,7 @@ void AOClient::cmdForcePos(int argc, QStringList argv)
return; return;
} }
else if (ok) { else if (ok) {
AOClient* l_target_client = server->getClientByID(l_target_id); AOClient *l_target_client = server->getClientByID(l_target_id);
if (l_target_client != nullptr) if (l_target_client != nullptr)
l_targets.append(l_target_client); l_targets.append(l_target_client);
else { else {
@ -51,12 +55,13 @@ void AOClient::cmdForcePos(int argc, QStringList argv)
} }
else if (argv[1] == "*") { // force all clients in the area else if (argv[1] == "*") { // force all clients in the area
for (AOClient* client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
if (client->m_current_area == m_current_area) for (AOClient *l_client : l_clients) {
l_targets.append(client); if (l_client->m_current_area == m_current_area)
l_targets.append(l_client);
} }
} }
for (AOClient* l_target : l_targets) { for (AOClient *l_target : l_targets) {
l_target->sendServerMessage("Position forcibly changed by CM."); l_target->sendServerMessage("Position forcibly changed by CM.");
l_target->changePosition(argv[0]); l_target->changePosition(argv[0]);
l_forced_clients++; l_forced_clients++;
@ -69,7 +74,7 @@ void AOClient::cmdG(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
QString l_sender_area = server->m_area_names.value(m_current_area); QString l_sender_area = server->getAreaName(m_current_area);
QString l_sender_message = argv.join(" "); QString l_sender_message = argv.join(" ");
//Slightly better readability //Slightly better readability
AOPacket l_mod_packet = AOPacket("CT", {"[G][" + m_ipid + "][" + l_sender_area + "]" + l_sender_name, l_sender_message}); AOPacket l_mod_packet = AOPacket("CT", {"[G][" + m_ipid + "][" + l_sender_area + "]" + l_sender_name, l_sender_message});
@ -82,9 +87,9 @@ void AOClient::cmdNeed(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
QString l_sender_area = server->m_area_names.value(m_current_area); QString l_sender_area = server->getAreaName(m_current_area);
QString l_sender_message = argv.join(" "); QString l_sender_message = argv.join(" ");
server->broadcast(AOPacket("CT",{"=== Advert ===\n[" + l_sender_area + "] needs " + l_sender_message+ "."}),Server::TARGET_TYPE::ADVERT); server->broadcast(AOPacket("CT", {"=== Advert ===\n[" + l_sender_area + "] needs " + l_sender_message + "."}), Server::TARGET_TYPE::ADVERT);
} }
void AOClient::cmdSwitch(int argc, QStringList argv) void AOClient::cmdSwitch(int argc, QStringList argv)
@ -109,11 +114,11 @@ void AOClient::cmdRandomChar(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
int l_selected_char_id; int l_selected_char_id;
bool l_taken = true; bool l_taken = true;
while (l_taken) { while (l_taken) {
l_selected_char_id = genRand(0, server->m_characters.size() - 1); l_selected_char_id = genRand(0, server->getCharacterCount() - 1);
if (!l_area->charactersTaken().contains(l_selected_char_id)) { if (!l_area->charactersTaken().contains(l_selected_char_id)) {
l_taken = false; l_taken = false;
} }
@ -143,7 +148,7 @@ void AOClient::cmdPM(int argc, QStringList argv)
sendServerMessage("That does not look like a valid ID."); sendServerMessage("That does not look like a valid ID.");
return; return;
} }
AOClient* l_target_client = server->getClientByID(l_target_id); AOClient *l_target_client = server->getClientByID(l_target_id);
if (l_target_client == nullptr) { if (l_target_client == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
return; return;
@ -154,7 +159,7 @@ void AOClient::cmdPM(int argc, QStringList argv)
} }
QString l_message = argv.join(" "); //...which means it will not end up as part of the message QString l_message = argv.join(" "); //...which means it will not end up as part of the message
l_target_client->sendServerMessage("Message from " + m_ooc_name + " (" + QString::number(m_id) + "): " + l_message); l_target_client->sendServerMessage("Message from " + m_ooc_name + " (" + QString::number(m_id) + "): " + l_message);
sendServerMessage("PM sent to " + QString::number(l_target_id) +". Message: " + l_message); sendServerMessage("PM sent to " + QString::number(l_target_id) + ". Message: " + l_message);
} }
void AOClient::cmdAnnounce(int argc, QStringList argv) void AOClient::cmdAnnounce(int argc, QStringList argv)
@ -178,9 +183,9 @@ void AOClient::cmdGM(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
QString l_sender_area = server->m_area_names.value(m_current_area); QString l_sender_area = server->getAreaName(m_current_area);
QString l_sender_message = argv.join(" "); QString l_sender_message = argv.join(" ");
server->broadcast(AOPacket("CT", {"[G][" + l_sender_area + "]" + "["+ l_sender_name+"][M]", l_sender_message}),Server::TARGET_TYPE::MODCHAT); server->broadcast(AOPacket("CT", {"[G][" + l_sender_area + "]" + "[" + l_sender_name + "][M]", l_sender_message}), Server::TARGET_TYPE::MODCHAT);
} }
void AOClient::cmdLM(int argc, QStringList argv) void AOClient::cmdLM(int argc, QStringList argv)
@ -189,7 +194,7 @@ void AOClient::cmdLM(int argc, QStringList argv)
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
QString l_sender_message = argv.join(" "); QString l_sender_message = argv.join(" ");
server->broadcast(AOPacket("CT", {"["+ l_sender_name +"][M]", l_sender_message}), m_current_area); server->broadcast(AOPacket("CT", {"[" + l_sender_name + "][M]", l_sender_message}), m_current_area);
} }
void AOClient::cmdGimp(int argc, QStringList argv) void AOClient::cmdGimp(int argc, QStringList argv)
@ -203,7 +208,7 @@ void AOClient::cmdGimp(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -230,7 +235,7 @@ void AOClient::cmdUnGimp(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -257,7 +262,7 @@ void AOClient::cmdDisemvowel(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -284,7 +289,7 @@ void AOClient::cmdUnDisemvowel(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -311,7 +316,7 @@ void AOClient::cmdShake(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -338,7 +343,7 @@ void AOClient::cmdUnShake(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -392,7 +397,7 @@ void AOClient::cmdCharCurse(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -424,14 +429,14 @@ void AOClient::cmdCharCurse(int argc, QStringList argv)
l_target->m_is_charcursed = true; l_target->m_is_charcursed = true;
//Kick back to char select screen // Kick back to char select screen
if (!l_target->m_charcurse_list.contains(server->getCharID(l_target->m_current_char))) { if (!l_target->m_charcurse_list.contains(server->getCharID(l_target->m_current_char))) {
l_target->changeCharacter(-1); l_target->changeCharacter(-1);
server->updateCharsTaken(server->m_areas.value(m_current_area)); server->updateCharsTaken(server->getAreaById(m_current_area));
l_target->sendPacket("DONE"); l_target->sendPacket("DONE");
} }
else { else {
server->updateCharsTaken(server->m_areas.value(m_current_area)); server->updateCharsTaken(server->getAreaById(m_current_area));
} }
l_target->sendServerMessage("You have been charcursed!"); l_target->sendServerMessage("You have been charcursed!");
@ -449,7 +454,7 @@ void AOClient::cmdUnCharCurse(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -462,7 +467,7 @@ void AOClient::cmdUnCharCurse(int argc, QStringList argv)
} }
l_target->m_is_charcursed = false; l_target->m_is_charcursed = false;
l_target->m_charcurse_list.clear(); l_target->m_charcurse_list.clear();
server->updateCharsTaken(server->m_areas.value(m_current_area)); server->updateCharsTaken(server->getAreaById(m_current_area));
sendServerMessage("Uncharcursed player."); sendServerMessage("Uncharcursed player.");
l_target->sendServerMessage("You were uncharcursed."); l_target->sendServerMessage("You were uncharcursed.");
} }
@ -486,7 +491,7 @@ void AOClient::cmdCharSelect(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_target_id); AOClient *l_target = server->getClientByID(l_target_id);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("Unable to locate client with ID " + QString::number(l_target_id) + "."); sendServerMessage("Unable to locate client with ID " + QString::number(l_target_id) + ".");
@ -496,7 +501,6 @@ void AOClient::cmdCharSelect(int argc, QStringList argv)
l_target->changeCharacter(-1); l_target->changeCharacter(-1);
l_target->sendPacket("DONE"); l_target->sendPacket("DONE");
sendServerMessage("Client has been forced into character select!"); sendServerMessage("Client has been forced into character select!");
} }
} }
@ -511,7 +515,7 @@ void AOClient::cmdA(int argc, QStringList argv)
return; return;
} }
AreaData* l_area = server->m_areas[l_area_id]; AreaData *l_area = server->getAreaById(l_area_id);
if (!l_area->owners().contains(m_id)) { if (!l_area->owners().contains(m_id)) {
sendServerMessage("You are not CM in that area."); sendServerMessage("You are not CM in that area.");
return; return;
@ -527,12 +531,12 @@ void AOClient::cmdS(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
int l_all_areas = server->m_areas.size() - 1; int l_all_areas = server->getAreaCount() - 1;
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
QString l_ooc_message = argv.join(" "); QString l_ooc_message = argv.join(" ");
for (int i = 0; i <= l_all_areas; i++) { for (int i = 0; i <= l_all_areas; i++) {
if (server->m_areas[i]->owners().contains(m_id)) if (server->getAreaById(i)->owners().contains(m_id))
server->broadcast(AOPacket("CT", {"[CM]" + l_sender_name, l_ooc_message}), i); server->broadcast(AOPacket("CT", {"[CM]" + l_sender_name, l_ooc_message}), i);
} }
} }

View File

@ -17,6 +17,11 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/db_manager.h"
#include "include/server.h"
// This file is for commands under the moderation category in aoclient.h // This file is for commands under the moderation category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
@ -57,12 +62,12 @@ void AOClient::cmdBan(int argc, QStringList argv)
break; break;
} }
const QList<AOClient*> l_targets = server->getClientsByIpid(l_ban.ipid); const QList<AOClient *> l_targets = server->getClientsByIpid(l_ban.ipid);
for (AOClient* client : l_targets) { for (AOClient *l_client : l_targets) {
if (!l_ban_logged) { if (!l_ban_logged) {
l_ban.ip = client->m_remote_ip; l_ban.ip = l_client->m_remote_ip;
l_ban.hdid = client->m_hwid; l_ban.hdid = l_client->m_hwid;
server->db_manager->addBan(l_ban); server->getDatabaseManager()->addBan(l_ban);
sendServerMessage("Banned user with ipid " + l_ban.ipid + " for reason: " + l_ban.reason); sendServerMessage("Banned user with ipid " + l_ban.ipid + " for reason: " + l_ban.reason);
l_ban_logged = true; l_ban_logged = true;
} }
@ -73,12 +78,12 @@ void AOClient::cmdBan(int argc, QStringList argv)
else { else {
l_ban_duration = "The heat death of the universe."; l_ban_duration = "The heat death of the universe.";
} }
int l_ban_id = server->db_manager->getBanID(l_ban.ip); int l_ban_id = server->getDatabaseManager()->getBanID(l_ban.ip);
client->sendPacket("KB", {l_ban.reason + "\nID: " + QString::number(l_ban_id) + "\nUntil: " + l_ban_duration}); l_client->sendPacket("KB", {l_ban.reason + "\nID: " + QString::number(l_ban_id) + "\nUntil: " + l_ban_duration});
client->m_socket->close(); l_client->m_socket->close();
l_kick_counter++; l_kick_counter++;
emit logBan(l_ban.moderator,l_ban.ipid,l_ban_duration,l_ban.reason); emit logBan(l_ban.moderator, l_ban.ipid, l_ban_duration, l_ban.reason);
if (ConfigManager::discordBanWebhookEnabled()) if (ConfigManager::discordBanWebhookEnabled())
emit server->banWebhookRequest(l_ban.ipid, l_ban.moderator, l_ban_duration, l_ban.reason, l_ban_id); emit server->banWebhookRequest(l_ban.ipid, l_ban.moderator, l_ban_duration, l_ban.reason, l_ban_id);
} }
@ -88,7 +93,7 @@ void AOClient::cmdBan(int argc, QStringList argv)
// We're banning someone not connected. // We're banning someone not connected.
if (!l_ban_logged) { if (!l_ban_logged) {
server->db_manager->addBan(l_ban); server->getDatabaseManager()->addBan(l_ban);
sendServerMessage("Banned " + l_ban.ipid + " for reason: " + l_ban.reason); sendServerMessage("Banned " + l_ban.ipid + " for reason: " + l_ban.reason);
} }
} }
@ -105,15 +110,15 @@ void AOClient::cmdKick(int argc, QStringList argv)
} }
} }
const QList<AOClient*> l_targets = server->getClientsByIpid(l_target_ipid); const QList<AOClient *> l_targets = server->getClientsByIpid(l_target_ipid);
for (AOClient* client : l_targets) { for (AOClient *l_client : l_targets) {
client->sendPacket("KK", {l_reason}); l_client->sendPacket("KK", {l_reason});
client->m_socket->close(); l_client->m_socket->close();
l_kick_counter++; l_kick_counter++;
} }
if (l_kick_counter > 0) { if (l_kick_counter > 0) {
if (ConfigManager::authType() == DataTypes::AuthType::ADVANCED){ if (ConfigManager::authType() == DataTypes::AuthType::ADVANCED) {
emit logKick(m_moderator_name, l_target_ipid, l_reason); emit logKick(m_moderator_name, l_target_ipid, l_reason);
} }
else { else {
@ -132,7 +137,8 @@ void AOClient::cmdMods(int argc, QStringList argv)
QStringList l_entries; QStringList l_entries;
int l_online_count = 0; int l_online_count = 0;
for (AOClient* l_client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
for (AOClient *l_client : l_clients) {
if (l_client->m_authenticated) { if (l_client->m_authenticated) {
l_entries << "---"; l_entries << "---";
if (ConfigManager::authType() != DataTypes::AuthType::SIMPLE) if (ConfigManager::authType() != DataTypes::AuthType::SIMPLE)
@ -157,7 +163,7 @@ void AOClient::cmdCommands(int argc, QStringList argv)
QStringList l_entries; QStringList l_entries;
l_entries << "Allowed commands:"; l_entries << "Allowed commands:";
QMap<QString, CommandInfo>::const_iterator i; QMap<QString, CommandInfo>::const_iterator i;
for (i = commands.constBegin(); i!= commands.constEnd(); ++i) { for (i = commands.constBegin(); i != commands.constEnd(); ++i) {
CommandInfo info = i.value(); CommandInfo info = i.value();
if (checkAuth(info.acl_mask)) { // if we are allowed to use this command if (checkAuth(info.acl_mask)) { // if we are allowed to use this command
l_entries << "/" + i.key(); l_entries << "/" + i.key();
@ -168,7 +174,7 @@ void AOClient::cmdCommands(int argc, QStringList argv)
void AOClient::cmdHelp(int argc, QStringList argv) void AOClient::cmdHelp(int argc, QStringList argv)
{ {
if(argc > 1) { if (argc > 1) {
sendServerMessage("Too many arguments. Please only use the command name."); sendServerMessage("Too many arguments. Please only use the command name.");
return; return;
} }
@ -178,7 +184,7 @@ void AOClient::cmdHelp(int argc, QStringList argv)
if (l_command_info.usage.isEmpty() || l_command_info.text.isEmpty()) // my picoseconds :( if (l_command_info.usage.isEmpty() || l_command_info.text.isEmpty()) // my picoseconds :(
sendServerMessage("Unable to find the command " + l_command_name + "."); sendServerMessage("Unable to find the command " + l_command_name + ".");
else else
sendServerMessage("==Help==\n" +l_command_info.usage + "\n" + l_command_info.text); sendServerMessage("==Help==\n" + l_command_info.usage + "\n" + l_command_info.text);
} }
void AOClient::cmdMOTD(int argc, QStringList argv) void AOClient::cmdMOTD(int argc, QStringList argv)
@ -206,7 +212,7 @@ void AOClient::cmdBans(int argc, QStringList argv)
QStringList l_recent_bans; QStringList l_recent_bans;
l_recent_bans << "Last 5 bans:"; l_recent_bans << "Last 5 bans:";
l_recent_bans << "-----"; l_recent_bans << "-----";
const QList<DBManager::BanInfo> l_bans_list = server->db_manager->getRecentBans(); const QList<DBManager::BanInfo> l_bans_list = server->getDatabaseManager()->getRecentBans();
for (const DBManager::BanInfo &l_ban : l_bans_list) { for (const DBManager::BanInfo &l_ban : l_bans_list) {
QString l_banned_until; QString l_banned_until;
if (l_ban.duration == -2) if (l_ban.duration == -2)
@ -235,7 +241,7 @@ void AOClient::cmdUnBan(int argc, QStringList argv)
sendServerMessage("Invalid ban ID."); sendServerMessage("Invalid ban ID.");
return; return;
} }
else if (server->db_manager->invalidateBan(l_target_ban)) else if (server->getDatabaseManager()->invalidateBan(l_target_ban))
sendServerMessage("Successfully invalidated ban " + argv[0] + "."); sendServerMessage("Successfully invalidated ban " + argv[0] + ".");
else else
sendServerMessage("Couldn't invalidate ban " + argv[0] + ", are you sure it exists?"); sendServerMessage("Couldn't invalidate ban " + argv[0] + ", are you sure it exists?");
@ -260,7 +266,7 @@ void AOClient::cmdMute(int argc, QStringList argv)
return; return;
} }
AOClient* target = server->getClientByID(l_uid); AOClient *target = server->getClientByID(l_uid);
if (target == nullptr) { if (target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -287,7 +293,7 @@ void AOClient::cmdUnMute(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -314,7 +320,7 @@ void AOClient::cmdOocMute(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -341,7 +347,7 @@ void AOClient::cmdOocUnMute(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -368,7 +374,7 @@ void AOClient::cmdBlockWtce(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -395,7 +401,7 @@ void AOClient::cmdUnBlockWtce(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -417,7 +423,7 @@ void AOClient::cmdAllowBlankposting(int argc, QStringList argv)
Q_UNUSED(argv); Q_UNUSED(argv);
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->toggleBlankposting(); l_area->toggleBlankposting();
if (l_area->blankpostingAllowed() == false) { if (l_area->blankpostingAllowed() == false) {
sendServerMessageArea(l_sender_name + " has set blankposting in the area to forbidden."); sendServerMessageArea(l_sender_name + " has set blankposting in the area to forbidden.");
@ -449,7 +455,7 @@ void AOClient::cmdBanInfo(int argc, QStringList argv)
return; return;
} }
QString l_id = argv[0]; QString l_id = argv[0];
const QList<DBManager::BanInfo> l_bans = server->db_manager->getBanInfo(l_lookup_type, l_id); const QList<DBManager::BanInfo> l_bans = server->getDatabaseManager()->getBanInfo(l_lookup_type, l_id);
for (const DBManager::BanInfo &l_ban : l_bans) { for (const DBManager::BanInfo &l_ban : l_bans) {
QString l_banned_until; QString l_banned_until;
if (l_ban.duration == -2) if (l_ban.duration == -2)
@ -473,7 +479,7 @@ void AOClient::cmdReload(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
//Todo: Make this a signal when splitting AOClient and Server. // Todo: Make this a signal when splitting AOClient and Server.
server->reloadSettings(); server->reloadSettings();
sendServerMessage("Reloaded configurations"); sendServerMessage("Reloaded configurations");
} }
@ -483,7 +489,7 @@ void AOClient::cmdForceImmediate(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->toggleImmediate(); l_area->toggleImmediate();
QString l_state = l_area->forceImmediate() ? "on." : "off."; QString l_state = l_area->forceImmediate() ? "on." : "off.";
sendServerMessage("Forced immediate text processing in this area is now " + l_state); sendServerMessage("Forced immediate text processing in this area is now " + l_state);
@ -494,7 +500,7 @@ void AOClient::cmdAllowIniswap(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->toggleIniswap(); l_area->toggleIniswap();
QString state = l_area->iniswapAllowed() ? "allowed." : "disallowed."; QString state = l_area->iniswapAllowed() ? "allowed." : "disallowed.";
sendServerMessage("Iniswapping in this area is now " + state); sendServerMessage("Iniswapping in this area is now " + state);
@ -504,7 +510,7 @@ void AOClient::cmdPermitSaving(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AOClient* l_client = server->getClientByID(argv[0].toInt()); AOClient *l_client = server->getClientByID(argv[0].toInt());
if (l_client == nullptr) { if (l_client == nullptr) {
sendServerMessage("Invalid ID."); sendServerMessage("Invalid ID.");
return; return;
@ -530,7 +536,7 @@ void AOClient::cmdKickUid(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
return; return;
@ -560,7 +566,6 @@ void AOClient::cmdUpdateBan(int argc, QStringList argv)
return; return;
} }
l_updated_info = QVariant(l_duration_seconds); l_updated_info = QVariant(l_duration_seconds);
} }
else if (argv[1] == "reason") { else if (argv[1] == "reason") {
QString l_args_str = argv[2]; QString l_args_str = argv[2];
@ -574,7 +579,7 @@ void AOClient::cmdUpdateBan(int argc, QStringList argv)
sendServerMessage("Invalid update type."); sendServerMessage("Invalid update type.");
return; return;
} }
if (!server->db_manager->updateBan(l_ban_id, argv[1], l_updated_info)) { if (!server->getDatabaseManager()->updateBan(l_ban_id, argv[1], l_updated_info)) {
sendServerMessage("There was an error updating the ban. Please confirm the ban ID is valid."); sendServerMessage("There was an error updating the ban. Please confirm the ban ID is valid.");
return; return;
} }
@ -599,8 +604,8 @@ void AOClient::cmdClearCM(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas.value(m_current_area); AreaData *l_area = server->getAreaById(m_current_area);
foreach (int l_client_id,l_area->owners()) { foreach (int l_client_id, l_area->owners()) {
l_area->removeOwner(l_client_id); l_area->removeOwner(l_client_id);
} }
arup(ARUPType::CM, true); arup(ARUPType::CM, true);

View File

@ -16,6 +16,12 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // // along with this program. If not, see <https://www.gnu.org/licenses/>. //
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/music_manager.h"
#include "include/server.h"
// This file is for commands under the music category in aoclient.h // This file is for commands under the music category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
@ -27,7 +33,7 @@ void AOClient::cmdPlay(int argc, QStringList argv)
sendServerMessage("You are blocked from changing the music."); sendServerMessage("You are blocked from changing the music.");
return; return;
} }
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
QString l_song = argv.join(" "); QString l_song = argv.join(" ");
if (m_showname.isEmpty()) { if (m_showname.isEmpty()) {
l_area->changeMusic(m_current_char, l_song); l_area->changeMusic(m_current_char, l_song);
@ -44,7 +50,7 @@ void AOClient::cmdCurrentMusic(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (!l_area->currentMusic().isEmpty() && !l_area->currentMusic().contains("~stop.mp3")) // dummy track for stopping music if (!l_area->currentMusic().isEmpty() && !l_area->currentMusic().contains("~stop.mp3")) // dummy track for stopping music
sendServerMessage("The current song is " + l_area->currentMusic() + " played by " + l_area->musicPlayerBy()); sendServerMessage("The current song is " + l_area->currentMusic() + " played by " + l_area->musicPlayerBy());
else else
@ -62,7 +68,7 @@ void AOClient::cmdBlockDj(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -89,7 +95,7 @@ void AOClient::cmdUnBlockDj(int argc, QStringList argv)
return; return;
} }
AOClient* l_target = server->getClientByID(l_uid); AOClient *l_target = server->getClientByID(l_uid);
if (l_target == nullptr) { if (l_target == nullptr) {
sendServerMessage("No client with that ID found."); sendServerMessage("No client with that ID found.");
@ -110,7 +116,7 @@ void AOClient::cmdToggleMusic(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
l_area->toggleMusic(); l_area->toggleMusic();
QString l_state = l_area->isMusicAllowed() ? "allowed." : "disallowed."; QString l_state = l_area->isMusicAllowed() ? "allowed." : "disallowed.";
sendServerMessage("Music in this area is now " + l_state); sendServerMessage("Music in this area is now " + l_state);
@ -122,7 +128,7 @@ void AOClient::cmdToggleJukebox(int argc, QStringList argv)
Q_UNUSED(argv); Q_UNUSED(argv);
if (checkAuth(ACLFlags.value("CM")) | checkAuth(ACLFlags.value("Jukebox"))) { if (checkAuth(ACLFlags.value("CM")) | checkAuth(ACLFlags.value("Jukebox"))) {
AreaData* l_area = server->m_areas.value(m_current_area); AreaData *l_area = server->getAreaById(m_current_area);
l_area->toggleJukebox(); l_area->toggleJukebox();
QString l_state = l_area->isjukeboxEnabled() ? "enabled." : "disabled."; QString l_state = l_area->isjukeboxEnabled() ? "enabled." : "disabled.";
sendServerMessageArea("The jukebox in this area has been " + l_state); sendServerMessageArea("The jukebox in this area has been " + l_state);
@ -136,11 +142,11 @@ void AOClient::cmdAddSong(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
//This needs some explanation. // This needs some explanation.
//Akashi has no concept of argument count,so any space is interpreted as a new element // Akashi has no concept of argument count,so any space is interpreted as a new element
//in the QStringList. This works fine until someone enters something with a space. // in the QStringList. This works fine until someone enters something with a space.
//Since we can't preencode those elements, we join all as a string and use a delimiter // Since we can't preencode those elements, we join all as a string and use a delimiter
//that does not exist in file and URL paths. I decided on the ol' reliable ','. // that does not exist in file and URL paths. I decided on the ol' reliable ','.
QString l_argv_string = argv.join(" "); QString l_argv_string = argv.join(" ");
QStringList l_argv = l_argv_string.split(","); QStringList l_argv = l_argv_string.split(",");

View File

@ -17,6 +17,11 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/server.h"
// This file is for commands under the roleplay category in aoclient.h // This file is for commands under the roleplay category in aoclient.h
// Be sure to register the command in the header before adding it here! // Be sure to register the command in the header before adding it here!
@ -26,8 +31,8 @@ void AOClient::cmdFlip(int argc, QStringList argv)
Q_UNUSED(argv); Q_UNUSED(argv);
QString l_sender_name = m_ooc_name; QString l_sender_name = m_ooc_name;
QStringList l_faces = {"heads","tails"}; QStringList l_faces = {"heads", "tails"};
QString l_face = l_faces[AOClient::genRand(0,1)]; QString l_face = l_faces[AOClient::genRand(0, 1)];
sendServerMessageArea(l_sender_name + " flipped a coin and got " + l_face + "."); sendServerMessageArea(l_sender_name + " flipped a coin and got " + l_face + ".");
} }
@ -43,7 +48,7 @@ void AOClient::cmdRollP(int argc, QStringList argv)
void AOClient::cmdTimer(int argc, QStringList argv) void AOClient::cmdTimer(int argc, QStringList argv)
{ {
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
// Called without arguments // Called without arguments
// Shows a brief of all timers // Shows a brief of all timers
@ -77,7 +82,7 @@ void AOClient::cmdTimer(int argc, QStringList argv)
// Select the proper timer // Select the proper timer
// Check against permissions if global timer is selected // Check against permissions if global timer is selected
QTimer* l_requested_timer; QTimer *l_requested_timer;
if (l_timer_id == 0) { if (l_timer_id == 0) {
if (!checkAuth(ACLFlags.value("GLOBAL_TIMER"))) { if (!checkAuth(ACLFlags.value("GLOBAL_TIMER"))) {
sendServerMessage("You are not authorized to alter the global timer."); sendServerMessage("You are not authorized to alter the global timer.");
@ -96,10 +101,10 @@ void AOClient::cmdTimer(int argc, QStringList argv)
// argument is a valid time // argument is a valid time
QTime l_requested_time = QTime::fromString(argv[1], "hh:mm:ss"); QTime l_requested_time = QTime::fromString(argv[1], "hh:mm:ss");
if (l_requested_time.isValid()) { if (l_requested_time.isValid()) {
l_requested_timer->setInterval(QTime(0,0).msecsTo(l_requested_time)); l_requested_timer->setInterval(QTime(0, 0).msecsTo(l_requested_time));
l_requested_timer->start(); l_requested_timer->start();
sendServerMessage("Set timer " + QString::number(l_timer_id) + " to " + argv[1] + "."); sendServerMessage("Set timer " + QString::number(l_timer_id) + " to " + argv[1] + ".");
AOPacket l_update_timer("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0,0).msecsTo(l_requested_time))}); AOPacket l_update_timer("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0, 0).msecsTo(l_requested_time))});
l_is_global ? server->broadcast(l_show_timer) : server->broadcast(l_show_timer, m_current_area); // Show the timer l_is_global ? server->broadcast(l_show_timer) : server->broadcast(l_show_timer, m_current_area); // Show the timer
l_is_global ? server->broadcast(l_update_timer) : server->broadcast(l_update_timer, m_current_area); l_is_global ? server->broadcast(l_update_timer) : server->broadcast(l_update_timer, m_current_area);
return; return;
@ -109,7 +114,7 @@ void AOClient::cmdTimer(int argc, QStringList argv)
if (argv[1] == "start") { if (argv[1] == "start") {
l_requested_timer->start(); l_requested_timer->start();
sendServerMessage("Started timer " + QString::number(l_timer_id) + "."); sendServerMessage("Started timer " + QString::number(l_timer_id) + ".");
AOPacket l_update_timer("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(l_requested_timer->remainingTime())))}); AOPacket l_update_timer("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0, 0).msecsTo(QTime(0, 0).addMSecs(l_requested_timer->remainingTime())))});
l_is_global ? server->broadcast(l_show_timer) : server->broadcast(l_show_timer, m_current_area); l_is_global ? server->broadcast(l_show_timer) : server->broadcast(l_show_timer, m_current_area);
l_is_global ? server->broadcast(l_update_timer) : server->broadcast(l_update_timer, m_current_area); l_is_global ? server->broadcast(l_update_timer) : server->broadcast(l_update_timer, m_current_area);
} }
@ -117,7 +122,7 @@ void AOClient::cmdTimer(int argc, QStringList argv)
l_requested_timer->setInterval(l_requested_timer->remainingTime()); l_requested_timer->setInterval(l_requested_timer->remainingTime());
l_requested_timer->stop(); l_requested_timer->stop();
sendServerMessage("Stopped timer " + QString::number(l_timer_id) + "."); sendServerMessage("Stopped timer " + QString::number(l_timer_id) + ".");
AOPacket l_update_timer("TI", {QString::number(l_timer_id), "1", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(l_requested_timer->interval())))}); AOPacket l_update_timer("TI", {QString::number(l_timer_id), "1", QString::number(QTime(0, 0).msecsTo(QTime(0, 0).addMSecs(l_requested_timer->interval())))});
l_is_global ? server->broadcast(l_update_timer) : server->broadcast(l_update_timer, m_current_area); l_is_global ? server->broadcast(l_update_timer) : server->broadcast(l_update_timer, m_current_area);
} }
else if (argv[1] == "hide" || argv[1] == "unset") { else if (argv[1] == "hide" || argv[1] == "unset") {
@ -134,7 +139,7 @@ void AOClient::cmdNoteCard(int argc, QStringList argv)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
QString l_notecard = argv.join(" "); QString l_notecard = argv.join(" ");
l_area->addNotecard(m_current_char, l_notecard); l_area->addNotecard(m_current_char, l_notecard);
sendServerMessageArea(m_current_char + " wrote a note card."); sendServerMessageArea(m_current_char + " wrote a note card.");
@ -145,7 +150,7 @@ void AOClient::cmdNoteCardClear(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
if (!l_area->addNotecard(m_current_char, QString())) { if (!l_area->addNotecard(m_current_char, QString())) {
sendServerMessageArea(m_current_char + " erased their note card."); sendServerMessageArea(m_current_char + " erased their note card.");
} }
@ -156,7 +161,7 @@ void AOClient::cmdNoteCardReveal(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
AreaData* l_area = server->m_areas[m_current_area]; AreaData *l_area = server->getAreaById(m_current_area);
const QStringList l_notecards = l_area->getNotecards(); const QStringList l_notecards = l_area->getNotecards();
if (l_notecards.isEmpty()) { if (l_notecards.isEmpty()) {
@ -192,7 +197,8 @@ void AOClient::cmdSubTheme(int argc, QStringList argv)
Q_UNUSED(argc); Q_UNUSED(argc);
QString l_subtheme = argv.join(" "); QString l_subtheme = argv.join(" ");
for (AOClient* l_client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
for (AOClient *l_client : l_clients) {
if (l_client->m_current_area == m_current_area) if (l_client->m_current_area == m_current_area)
l_client->sendPacket("ST", {l_subtheme, "1"}); l_client->sendPacket("ST", {l_subtheme, "1"});
} }

View File

@ -19,15 +19,15 @@
#include <include/config_manager.h> #include <include/config_manager.h>
QSettings* ConfigManager::m_settings = new QSettings("config/config.ini", QSettings::IniFormat); QSettings *ConfigManager::m_settings = new QSettings("config/config.ini", QSettings::IniFormat);
QSettings* ConfigManager::m_discord = new QSettings("config/discord.ini", QSettings::IniFormat); QSettings *ConfigManager::m_discord = new QSettings("config/discord.ini", QSettings::IniFormat);
QSettings* ConfigManager::m_areas = new QSettings("config/areas.ini", QSettings::IniFormat); QSettings *ConfigManager::m_areas = new QSettings("config/areas.ini", QSettings::IniFormat);
QSettings* ConfigManager::m_logtext = new QSettings("config/text/logtext.ini", QSettings::IniFormat); QSettings *ConfigManager::m_logtext = new QSettings("config/text/logtext.ini", QSettings::IniFormat);
ConfigManager::CommandSettings* ConfigManager::m_commands = new CommandSettings(); ConfigManager::CommandSettings *ConfigManager::m_commands = new CommandSettings();
QElapsedTimer* ConfigManager::m_uptimeTimer = new QElapsedTimer; QElapsedTimer *ConfigManager::m_uptimeTimer = new QElapsedTimer;
MusicList* ConfigManager::m_musicList = new MusicList; MusicList *ConfigManager::m_musicList = new MusicList;
QHash<QString,ConfigManager::help>* ConfigManager::m_commands_help = new QHash<QString,ConfigManager::help>; QHash<QString, ConfigManager::help> *ConfigManager::m_commands_help = new QHash<QString, ConfigManager::help>;
QStringList* ConfigManager::m_ordered_list = new QStringList; QStringList *ConfigManager::m_ordered_list = new QStringList;
bool ConfigManager::verifyServerConfig() bool ConfigManager::verifyServerConfig()
{ {
@ -43,7 +43,7 @@ bool ConfigManager::verifyServerConfig()
// Verify config files // Verify config files
QStringList l_config_files{"config/config.ini", "config/areas.ini", "config/backgrounds.txt", "config/characters.txt", "config/music.json", QStringList l_config_files{"config/config.ini", "config/areas.ini", "config/backgrounds.txt", "config/characters.txt", "config/music.json",
"config/discord.ini", "config/text/8ball.txt", "config/text/gimp.txt", "config/text/praise.txt", "config/discord.ini", "config/text/8ball.txt", "config/text/gimp.txt", "config/text/praise.txt",
"config/text/reprimands.txt","config/text/commandhelp.json","config/text/cdns.txt"}; "config/text/reprimands.txt", "config/text/commandhelp.json", "config/text/cdns.txt"};
for (const QString &l_file : l_config_files) { for (const QString &l_file : l_config_files) {
if (!fileExists(QFileInfo(l_file))) { if (!fileExists(QFileInfo(l_file))) {
qCritical() << l_file + " does not exist!"; qCritical() << l_file + " does not exist!";
@ -94,6 +94,8 @@ bool ConfigManager::verifyServerConfig()
m_commands->reprimands = (loadConfigFile("reprimands")); m_commands->reprimands = (loadConfigFile("reprimands"));
m_commands->gimps = (loadConfigFile("gimp")); m_commands->gimps = (loadConfigFile("gimp"));
m_commands->cdns = (loadConfigFile("cdns")); m_commands->cdns = (loadConfigFile("cdns"));
if (m_commands->cdns.isEmpty())
m_commands->cdns = QStringList{"cdn.discord.com"};
m_uptimeTimer->start(); m_uptimeTimer->start();
@ -102,7 +104,7 @@ bool ConfigManager::verifyServerConfig()
QString ConfigManager::bindIP() QString ConfigManager::bindIP()
{ {
return m_settings->value("Options/bind_ip","all").toString(); return m_settings->value("Options/bind_ip", "all").toString();
} }
QStringList ConfigManager::charlist() QStringList ConfigManager::charlist()
@ -138,22 +140,22 @@ MusicList ConfigManager::musiclist()
QJsonParseError l_error; QJsonParseError l_error;
QJsonDocument l_music_list_json = QJsonDocument::fromJson(l_music_json.readAll(), &l_error); QJsonDocument l_music_list_json = QJsonDocument::fromJson(l_music_json.readAll(), &l_error);
if (!(l_error.error == QJsonParseError::NoError)) { //Non-Terminating error. if (!(l_error.error == QJsonParseError::NoError)) { // Non-Terminating error.
qWarning() << "Unable to load musiclist. The following error was encounted : " + l_error.errorString(); qWarning() << "Unable to load musiclist. The following error was encounted : " + l_error.errorString();
return QMap<QString,QPair<QString,int>>{}; //Server can still run without music. return QMap<QString, QPair<QString, int>>{}; // Server can still run without music.
} }
// Akashi expects the musiclist to be contained in a JSON array, even if its only a single category. // Akashi expects the musiclist to be contained in a JSON array, even if its only a single category.
QJsonArray l_Json_root_array = l_music_list_json.array(); QJsonArray l_Json_root_array = l_music_list_json.array();
QJsonObject l_child_obj; QJsonObject l_child_obj;
QJsonArray l_child_array; QJsonArray l_child_array;
for (int i = 0; i <= l_Json_root_array.size() -1; i++){ //Iterate trough entire JSON file to assemble musiclist for (int i = 0; i <= l_Json_root_array.size() - 1; i++) { // Iterate trough entire JSON file to assemble musiclist
l_child_obj = l_Json_root_array.at(i).toObject(); l_child_obj = l_Json_root_array.at(i).toObject();
//Technically not a requirement, but neat for organisation. // Technically not a requirement, but neat for organisation.
QString l_category_name = l_child_obj["category"].toString(); QString l_category_name = l_child_obj["category"].toString();
if (!l_category_name.isEmpty()) { if (!l_category_name.isEmpty()) {
m_musicList->insert(l_category_name,{l_category_name,0}); m_musicList->insert(l_category_name, {l_category_name, 0});
m_ordered_list->append(l_category_name); m_ordered_list->append(l_category_name);
} }
else { else {
@ -161,7 +163,7 @@ MusicList ConfigManager::musiclist()
} }
l_child_array = l_child_obj["songs"].toArray(); l_child_array = l_child_obj["songs"].toArray();
for (int i = 0; i <= l_child_array.size() -1; i++){ // Inner for loop because a category can contain multiple songs. for (int i = 0; i <= l_child_array.size() - 1; i++) { // Inner for loop because a category can contain multiple songs.
QJsonObject l_song_obj = l_child_array.at(i).toObject(); QJsonObject l_song_obj = l_child_array.at(i).toObject();
QString l_song_name = l_song_obj["name"].toString(); QString l_song_name = l_song_obj["name"].toString();
QString l_real_name = l_song_obj["realname"].toString(); QString l_real_name = l_song_obj["realname"].toString();
@ -169,7 +171,7 @@ MusicList ConfigManager::musiclist()
l_real_name = l_song_name; l_real_name = l_song_name;
} }
int l_song_duration = l_song_obj["length"].toVariant().toInt(); int l_song_duration = l_song_obj["length"].toVariant().toInt();
m_musicList->insert(l_song_name,{l_real_name,l_song_duration}); m_musicList->insert(l_song_name, {l_real_name, l_song_duration});
m_ordered_list->append(l_song_name); m_ordered_list->append(l_song_name);
} }
} }
@ -190,7 +192,7 @@ void ConfigManager::loadCommandHelp()
QJsonParseError l_error; QJsonParseError l_error;
QJsonDocument l_help_list_json = QJsonDocument::fromJson(l_help_json.readAll(), &l_error); QJsonDocument l_help_list_json = QJsonDocument::fromJson(l_help_json.readAll(), &l_error);
if (!(l_error.error == QJsonParseError::NoError)) { //Non-Terminating error. if (!(l_error.error == QJsonParseError::NoError)) { // Non-Terminating error.
qWarning() << "Unable to load help information. The following error occurred: " + l_error.errorString(); qWarning() << "Unable to load help information. The following error occurred: " + l_error.errorString();
} }
@ -198,7 +200,7 @@ void ConfigManager::loadCommandHelp()
QJsonArray l_Json_root_array = l_help_list_json.array(); QJsonArray l_Json_root_array = l_help_list_json.array();
QJsonObject l_child_obj; QJsonObject l_child_obj;
for (int i = 0; i <= l_Json_root_array.size() -1; i++){ for (int i = 0; i <= l_Json_root_array.size() - 1; i++) {
l_child_obj = l_Json_root_array.at(i).toObject(); l_child_obj = l_Json_root_array.at(i).toObject();
QString l_name = l_child_obj["name"].toString(); QString l_name = l_child_obj["name"].toString();
QString l_usage = l_child_obj["usage"].toString(); QString l_usage = l_child_obj["usage"].toString();
@ -209,12 +211,12 @@ void ConfigManager::loadCommandHelp()
l_help_information.usage = l_usage; l_help_information.usage = l_usage;
l_help_information.text = l_text; l_help_information.text = l_text;
m_commands_help->insert(l_name,l_help_information); m_commands_help->insert(l_name, l_help_information);
} }
} }
} }
QSettings* ConfigManager::areaData() QSettings *ConfigManager::areaData()
{ {
return m_areas; return m_areas;
} }
@ -222,7 +224,7 @@ QSettings* ConfigManager::areaData()
QStringList ConfigManager::sanitizedAreaNames() QStringList ConfigManager::sanitizedAreaNames()
{ {
QStringList l_area_names = m_areas->childGroups(); // invisibly does a lexicographical sort, because Qt is great like that QStringList l_area_names = m_areas->childGroups(); // invisibly does a lexicographical sort, because Qt is great like that
std::sort(l_area_names.begin(), l_area_names.end(), [] (const QString &a, const QString &b) {return a.split(":")[0].toInt() < b.split(":")[0].toInt();}); std::sort(l_area_names.begin(), l_area_names.end(), [](const QString &a, const QString &b) { return a.split(":")[0].toInt() < b.split(":")[0].toInt(); });
QStringList l_sanitized_area_names; QStringList l_sanitized_area_names;
for (const QString &areaName : qAsConst(l_area_names)) { for (const QString &areaName : qAsConst(l_area_names)) {
QStringList l_nameSplit = areaName.split(":"); QStringList l_nameSplit = areaName.split(":");
@ -452,13 +454,13 @@ QString ConfigManager::discordBanWebhookUrl()
bool ConfigManager::discordUptimeEnabled() bool ConfigManager::discordUptimeEnabled()
{ {
return m_discord->value("Discord/webhook_uptime_enabled","false").toBool(); return m_discord->value("Discord/webhook_uptime_enabled", "false").toBool();
} }
int ConfigManager::discordUptimeTime() int ConfigManager::discordUptimeTime()
{ {
bool ok; bool ok;
int l_aliveTime = m_discord->value("Discord/webhook_uptime_time","60").toInt(&ok); int l_aliveTime = m_discord->value("Discord/webhook_uptime_time", "60").toInt(&ok);
if (!ok) { if (!ok) {
qWarning("alive_time is not an int"); qWarning("alive_time is not an int");
l_aliveTime = 60; l_aliveTime = 60;
@ -532,7 +534,7 @@ bool ConfigManager::passwordCanContainUsername()
QString ConfigManager::LogText(QString f_logtype) QString ConfigManager::LogText(QString f_logtype)
{ {
return m_logtext->value("LogConfiguration/" + f_logtype,"").toString(); return m_logtext->value("LogConfiguration/" + f_logtype, "").toString();
} }
int ConfigManager::afkTimeout() int ConfigManager::afkTimeout()
@ -578,23 +580,23 @@ QStringList ConfigManager::cdnList()
bool ConfigManager::advertiseServer() bool ConfigManager::advertiseServer()
{ {
return m_settings->value("Advertiser/advertise","true").toBool(); return m_settings->value("Advertiser/advertise", "true").toBool();
} }
bool ConfigManager::advertiserDebug() bool ConfigManager::advertiserDebug()
{ {
return m_settings->value("Advertiser/debug","true").toBool(); return m_settings->value("Advertiser/debug", "true").toBool();
} }
QUrl ConfigManager::advertiserIP() QUrl ConfigManager::advertiserIP()
{ {
qDebug() << m_settings->value("Advertiser/ms_ip","").toUrl(); qDebug() << m_settings->value("Advertiser/ms_ip", "").toUrl();
return m_settings->value("Advertiser/ms_ip","").toUrl(); return m_settings->value("Advertiser/ms_ip", "").toUrl();
} }
QString ConfigManager::advertiserHostname() QString ConfigManager::advertiserHostname()
{ {
return m_settings->value("Advertiser/hostname","").toString(); return m_settings->value("Advertiser/hostname", "").toString();
} }
qint64 ConfigManager::uptime() qint64 ConfigManager::uptime()

View File

@ -26,8 +26,8 @@ DBManager::DBManager() :
qWarning().noquote() << tr("Database Info: Database not found. Attempting to create new database."); qWarning().noquote() << tr("Database Info: Database not found. Attempting to create new database.");
} }
else { else {
//We should only check if a file is readable/writeable when it actually exists. // We should only check if a file is readable/writeable when it actually exists.
if(!db_info.isReadable() || !db_info.isWritable()) if (!db_info.isReadable() || !db_info.isWritable())
qCritical() << tr("Database Error: Missing permissions. Check if \"%1\" is writable.").arg(db_filename); qCritical() << tr("Database Error: Missing permissions. Check if \"%1\" is writable.").arg(db_filename);
} }
@ -59,9 +59,11 @@ QPair<bool, QString> DBManager::isIPBanned(QString ipid)
long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch();
if (ban_time + duration > current_time) if (ban_time + duration > current_time)
return {true, reason}; return {true, reason};
else return {false, nullptr}; else
return {false, nullptr};
} }
else return {false, nullptr}; else
return {false, nullptr};
} }
QPair<bool, QString> DBManager::isHDIDBanned(QString hdid) QPair<bool, QString> DBManager::isHDIDBanned(QString hdid)
@ -79,9 +81,11 @@ QPair<bool, QString> DBManager::isHDIDBanned(QString hdid)
long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch();
if (ban_time + duration > current_time) if (ban_time + duration > current_time)
return {true, reason}; return {true, reason};
else return {false, nullptr}; else
return {false, nullptr};
} }
else return {false, nullptr}; else
return {false, nullptr};
} }
int DBManager::getBanID(QString hdid) int DBManager::getBanID(QString hdid)
@ -98,7 +102,6 @@ int DBManager::getBanID(QString hdid)
} }
} }
int DBManager::getBanID(QHostAddress ip) int DBManager::getBanID(QHostAddress ip)
{ {
QSqlQuery query; QSqlQuery query;
@ -199,7 +202,7 @@ bool DBManager::createUser(QString username, QString salt, QString password, uns
bool DBManager::deleteUser(QString username) bool DBManager::deleteUser(QString username)
{ {
if (username == "root") { if (username == "root") {
//To prevent lockout scenarios where an admin may accidentally delete root. // To prevent lockout scenarios where an admin may accidentally delete root.
return false; return false;
} }
@ -209,9 +212,9 @@ bool DBManager::deleteUser(QString username)
username_exists.addBindValue(username); username_exists.addBindValue(username);
username_exists.exec(); username_exists.exec();
username_exists.first(); username_exists.first();
//If EXISTS can't find a record, it returns 0. // If EXISTS can't find a record, it returns 0.
if (username_exists.value(0).toInt() == 0) if (username_exists.value(0).toInt() == 0)
//We were unable to locate an entry with this name. // We were unable to locate an entry with this name.
return false; return false;
} }
{ {
@ -405,7 +408,7 @@ void DBManager::updateDB(int current_version)
QSqlQuery("ALTER TABLE bans ADD COLUMN MODERATOR TEXT"); QSqlQuery("ALTER TABLE bans ADD COLUMN MODERATOR TEXT");
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case 1: case 1:
QSqlQuery ("PRAGMA user_version = " + QString::number(DB_VERSION)); QSqlQuery("PRAGMA user_version = " + QString::number(DB_VERSION));
break; break;
} }
} }

View File

@ -17,7 +17,9 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/discord.h" #include "include/discord.h"
Discord::Discord(QObject* parent) : #include "include/config_manager.h"
Discord::Discord(QObject *parent) :
QObject(parent) QObject(parent)
{ {
m_nam = new QNetworkAccessManager(); m_nam = new QNetworkAccessManager();
@ -44,7 +46,7 @@ void Discord::onModcallWebhookRequested(const QString &f_name, const QString &f_
void Discord::onBanWebhookRequested(const QString &f_ipid, const QString &f_moderator, const QString &f_duration, const QString &f_reason, const int &f_banID) void Discord::onBanWebhookRequested(const QString &f_ipid, const QString &f_moderator, const QString &f_duration, const QString &f_reason, const int &f_banID)
{ {
m_request.setUrl(QUrl(ConfigManager::discordBanWebhookUrl())); m_request.setUrl(QUrl(ConfigManager::discordBanWebhookUrl()));
QJsonDocument l_json = constructBanJson(f_ipid,f_moderator, f_duration, f_reason, f_banID); QJsonDocument l_json = constructBanJson(f_ipid, f_moderator, f_duration, f_reason, f_banID);
postJsonWebhook(l_json); postJsonWebhook(l_json);
} }
@ -65,18 +67,16 @@ QJsonDocument Discord::constructModcallJson(const QString &f_name, const QString
{ {
QJsonObject l_json; QJsonObject l_json;
QJsonArray l_array; QJsonArray l_array;
QJsonObject l_object { QJsonObject l_object{
{"color", ConfigManager::discordWebhookColor()}, {"color", ConfigManager::discordWebhookColor()},
{"title", f_name + " filed a modcall in " + f_area}, {"title", f_name + " filed a modcall in " + f_area},
{"description", f_reason} {"description", f_reason}};
};
l_array.append(l_object); l_array.append(l_object);
if (!ConfigManager::discordModcallWebhookContent().isEmpty()) if (!ConfigManager::discordModcallWebhookContent().isEmpty())
l_json["content"] = ConfigManager::discordModcallWebhookContent(); l_json["content"] = ConfigManager::discordModcallWebhookContent();
l_json["embeds"] = l_array; l_json["embeds"] = l_array;
return QJsonDocument(l_json); return QJsonDocument(l_json);
} }
@ -84,35 +84,33 @@ QJsonDocument Discord::constructBanJson(const QString &f_ipid, const QString &f_
{ {
QJsonObject l_json; QJsonObject l_json;
QJsonArray l_array; QJsonArray l_array;
QJsonObject l_object { QJsonObject l_object{
{"color", ConfigManager::discordWebhookColor()}, {"color", ConfigManager::discordWebhookColor()},
{"title", "Ban issued by " + f_moderator}, {"title", "Ban issued by " + f_moderator},
{"description", "Client IPID : " + f_ipid + "\nBan ID: " + QString::number(f_banID) + "\nBan reason : " + f_reason +"\nBanned until : " +f_duration} {"description", "Client IPID : " + f_ipid + "\nBan ID: " + QString::number(f_banID) + "\nBan reason : " + f_reason + "\nBanned until : " + f_duration}};
};
l_array.append(l_object); l_array.append(l_object);
l_json["embeds"] = l_array; l_json["embeds"] = l_array;
return QJsonDocument(l_json); return QJsonDocument(l_json);
} }
QJsonDocument Discord::constructUptimeJson(const QString& f_timeExpired) QJsonDocument Discord::constructUptimeJson(const QString &f_timeExpired)
{ {
QJsonObject l_json; QJsonObject l_json;
QJsonArray l_array; QJsonArray l_array;
QJsonObject l_object { QJsonObject l_object{
{"color", ConfigManager::discordWebhookColor()}, {"color", ConfigManager::discordWebhookColor()},
{"title", "Your server is online!"}, {"title", "Your server is online!"},
{"description", "Your server has been online for " + f_timeExpired} {"description", "Your server has been online for " + f_timeExpired}};
};
l_array.append(l_object); l_array.append(l_object);
l_json["embeds"] = l_array; l_json["embeds"] = l_array;
return QJsonDocument(l_json); return QJsonDocument(l_json);
} }
QHttpMultiPart* Discord::constructLogMultipart(const QQueue<QString> &f_buffer) const QHttpMultiPart *Discord::constructLogMultipart(const QQueue<QString> &f_buffer) const
{ {
QHttpMultiPart* l_multipart = new QHttpMultiPart(); QHttpMultiPart *l_multipart = new QHttpMultiPart();
QHttpPart l_file; QHttpPart l_file;
l_file.setRawHeader(QByteArray("Content-Disposition"), QByteArray("form-data; name=\"file\"; filename=\"log.txt\"")); l_file.setRawHeader(QByteArray("Content-Disposition"), QByteArray("form-data; name=\"file\"; filename=\"log.txt\""));
l_file.setRawHeader(QByteArray("Content-Type"), QByteArray("plain/text")); l_file.setRawHeader(QByteArray("Content-Type"), QByteArray("plain/text"));
@ -143,7 +141,7 @@ void Discord::postMultipartWebhook(QHttpMultiPart &f_multipart)
return; return;
} }
m_request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + f_multipart.boundary()); m_request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + f_multipart.boundary());
QNetworkReply* l_reply = m_nam->post(m_request, &f_multipart); QNetworkReply *l_reply = m_nam->post(m_request, &f_multipart);
f_multipart.setParent(l_reply); f_multipart.setParent(l_reply);
} }

View File

@ -17,15 +17,15 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/logger/u_logger.h" #include "include/logger/u_logger.h"
ULogger::ULogger(QObject* parent) : ULogger::ULogger(QObject *parent) :
QObject(parent) QObject(parent)
{ {
switch (ConfigManager::loggingType()) { switch (ConfigManager::loggingType()) {
case DataTypes::LogType::MODCALL : case DataTypes::LogType::MODCALL:
writerModcall = new WriterModcall; writerModcall = new WriterModcall;
break; break;
case DataTypes::LogType::FULL : case DataTypes::LogType::FULL:
case DataTypes::LogType::FULLAREA : case DataTypes::LogType::FULLAREA:
writerFull = new WriterFull; writerFull = new WriterFull;
break; break;
} }
@ -35,35 +35,35 @@ ULogger::ULogger(QObject* parent) :
ULogger::~ULogger() ULogger::~ULogger()
{ {
switch (ConfigManager::loggingType()) { switch (ConfigManager::loggingType()) {
case DataTypes::LogType::MODCALL : case DataTypes::LogType::MODCALL:
writerModcall->deleteLater(); writerModcall->deleteLater();
break; break;
case DataTypes::LogType::FULL : case DataTypes::LogType::FULL:
case DataTypes::LogType::FULLAREA : case DataTypes::LogType::FULLAREA:
writerFull->deleteLater(); writerFull->deleteLater();
break; break;
} }
} }
void ULogger::logIC(const QString& f_char_name, const QString& f_ooc_name, const QString& f_ipid, void ULogger::logIC(const QString &f_char_name, const QString &f_ooc_name, const QString &f_ipid,
const QString& f_area_name, const QString& f_message) const QString &f_area_name, const QString &f_message)
{ {
QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss"); QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss");
QString l_logEntry = QString(m_logtext.value("ic") + "\n").arg(l_time, f_char_name, f_ooc_name, f_ipid, f_area_name, f_message); QString l_logEntry = QString(m_logtext.value("ic") + "\n").arg(l_time, f_char_name, f_ooc_name, f_ipid, f_area_name, f_message);
updateAreaBuffer(f_area_name,l_logEntry); updateAreaBuffer(f_area_name, l_logEntry);
} }
void ULogger::logOOC(const QString& f_char_name, const QString& f_ooc_name, const QString& f_ipid, void ULogger::logOOC(const QString &f_char_name, const QString &f_ooc_name, const QString &f_ipid,
const QString& f_area_name, const QString& f_message) const QString &f_area_name, const QString &f_message)
{ {
QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss"); QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss");
QString l_logEntry = QString(m_logtext.value("ooc") + "\n") QString l_logEntry = QString(m_logtext.value("ooc") + "\n")
.arg(l_time, f_char_name, f_ooc_name, f_ipid, f_area_name, f_message); .arg(l_time, f_char_name, f_ooc_name, f_ipid, f_area_name, f_message);
updateAreaBuffer(f_area_name,l_logEntry); updateAreaBuffer(f_area_name, l_logEntry);
} }
void ULogger::logLogin(const QString& f_char_name, const QString& f_ooc_name, const QString& f_moderator_name, void ULogger::logLogin(const QString &f_char_name, const QString &f_ooc_name, const QString &f_moderator_name,
const QString& f_ipid, const QString& f_area_name, const bool &f_success) const QString &f_ipid, const QString &f_area_name, const bool &f_success)
{ {
QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss"); QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss");
QString l_success = f_success ? "SUCCESS][" + f_moderator_name : "FAILED][" + f_moderator_name; QString l_success = f_success ? "SUCCESS][" + f_moderator_name : "FAILED][" + f_moderator_name;
@ -72,8 +72,8 @@ void ULogger::logLogin(const QString& f_char_name, const QString& f_ooc_name, co
updateAreaBuffer(f_area_name, l_logEntry); updateAreaBuffer(f_area_name, l_logEntry);
} }
void ULogger::logCMD(const QString& f_char_name,const QString& f_ipid, const QString& f_ooc_name, const QString& f_command, void ULogger::logCMD(const QString &f_char_name, const QString &f_ipid, const QString &f_ooc_name, const QString &f_command,
const QStringList& f_args, const QString& f_area_name) const QStringList &f_args, const QString &f_area_name)
{ {
QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss"); QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss");
QString l_logEntry; QString l_logEntry;
@ -95,15 +95,15 @@ void ULogger::logCMD(const QString& f_char_name,const QString& f_ipid, const QSt
l_logEntry = QString(m_logtext.value("cmd") + "\n") l_logEntry = QString(m_logtext.value("cmd") + "\n")
.arg(l_time, f_area_name, f_char_name, f_ooc_name, f_command, f_args.join(" "), f_ipid); .arg(l_time, f_area_name, f_char_name, f_ooc_name, f_command, f_args.join(" "), f_ipid);
} }
updateAreaBuffer(f_area_name,l_logEntry); updateAreaBuffer(f_area_name, l_logEntry);
} }
void ULogger::logKick(const QString& f_moderator, const QString& f_target_ipid) void ULogger::logKick(const QString &f_moderator, const QString &f_target_ipid)
{ {
QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss"); QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss");
QString l_logEntry = QString(m_logtext.value("kick") + "\n") QString l_logEntry = QString(m_logtext.value("kick") + "\n")
.arg(l_time, f_moderator, f_target_ipid); .arg(l_time, f_moderator, f_target_ipid);
updateAreaBuffer("SERVER",l_logEntry); updateAreaBuffer("SERVER", l_logEntry);
} }
void ULogger::logBan(const QString &f_moderator, const QString &f_target_ipid, const QString &f_duration) void ULogger::logBan(const QString &f_moderator, const QString &f_target_ipid, const QString &f_duration)
@ -111,7 +111,7 @@ void ULogger::logBan(const QString &f_moderator, const QString &f_target_ipid, c
QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss"); QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss");
QString l_logEntry = QString(m_logtext.value("ban") + "\n") QString l_logEntry = QString(m_logtext.value("ban") + "\n")
.arg(l_time, f_moderator, f_target_ipid, f_duration); .arg(l_time, f_moderator, f_target_ipid, f_duration);
updateAreaBuffer("SERVER",l_logEntry); updateAreaBuffer("SERVER", l_logEntry);
} }
void ULogger::logModcall(const QString &f_char_name, const QString &f_ipid, const QString &f_ooc_name, const QString &f_area_name) void ULogger::logModcall(const QString &f_char_name, const QString &f_ipid, const QString &f_ooc_name, const QString &f_area_name)
@ -126,18 +126,18 @@ void ULogger::logModcall(const QString &f_char_name, const QString &f_ipid, cons
} }
} }
void ULogger::logConnectionAttempt(const QString& f_ip_address, const QString& f_ipid, const QString& f_hwid) void ULogger::logConnectionAttempt(const QString &f_ip_address, const QString &f_ipid, const QString &f_hwid)
{ {
QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss"); QString l_time = QDateTime::currentDateTime().toString("ddd MMMM d yyyy | hh:mm:ss");
QString l_logEntry = QString(m_logtext.value("connect") + "\n") QString l_logEntry = QString(m_logtext.value("connect") + "\n")
.arg(l_time, f_ip_address, f_ipid, f_hwid); .arg(l_time, f_ip_address, f_ipid, f_hwid);
updateAreaBuffer("SERVER",l_logEntry); updateAreaBuffer("SERVER", l_logEntry);
} }
void ULogger::loadLogtext() void ULogger::loadLogtext()
{ {
//All of this to prevent one single clazy warning from appearing. // All of this to prevent one single clazy warning from appearing.
for (auto iterator = m_logtext.keyBegin(), end = m_logtext.keyEnd(); iterator != end; ++iterator){ for (auto iterator = m_logtext.keyBegin(), end = m_logtext.keyEnd(); iterator != end; ++iterator) {
QString l_tempstring = ConfigManager::LogText(iterator.operator*()); QString l_tempstring = ConfigManager::LogText(iterator.operator*());
if (!l_tempstring.isEmpty()) { if (!l_tempstring.isEmpty()) {
m_logtext[iterator.operator*()] = l_tempstring; m_logtext[iterator.operator*()] = l_tempstring;
@ -145,9 +145,9 @@ void ULogger::loadLogtext()
} }
} }
void ULogger::updateAreaBuffer(const QString& f_area_name, const QString& f_log_entry) void ULogger::updateAreaBuffer(const QString &f_area_name, const QString &f_log_entry)
{ {
QQueue<QString>l_buffer = m_bufferMap.value(f_area_name); QQueue<QString> l_buffer = m_bufferMap.value(f_area_name);
if (l_buffer.length() <= ConfigManager::logBuffer()) { if (l_buffer.length() <= ConfigManager::logBuffer()) {
l_buffer.enqueue(f_log_entry); l_buffer.enqueue(f_log_entry);
@ -158,7 +158,7 @@ void ULogger::updateAreaBuffer(const QString& f_area_name, const QString& f_log_
} }
m_bufferMap.insert(f_area_name, l_buffer); m_bufferMap.insert(f_area_name, l_buffer);
if (ConfigManager::loggingType() == DataTypes::LogType::FULL){ if (ConfigManager::loggingType() == DataTypes::LogType::FULL) {
writerFull->flush(f_log_entry); writerFull->flush(f_log_entry);
} }
if (ConfigManager::loggingType() == DataTypes::LogType::FULLAREA) { if (ConfigManager::loggingType() == DataTypes::LogType::FULLAREA) {
@ -166,7 +166,7 @@ void ULogger::updateAreaBuffer(const QString& f_area_name, const QString& f_log_
} }
} }
QQueue<QString> ULogger::buffer(const QString& f_area_name) QQueue<QString> ULogger::buffer(const QString &f_area_name)
{ {
return m_bufferMap.value(f_area_name); return m_bufferMap.value(f_area_name);
} }

View File

@ -17,7 +17,7 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/logger/writer_full.h" #include "include/logger/writer_full.h"
WriterFull::WriterFull(QObject* parent) : WriterFull::WriterFull(QObject *parent) :
QObject(parent) QObject(parent)
{ {
l_dir.setPath("logs/"); l_dir.setPath("logs/");
@ -47,4 +47,3 @@ void WriterFull::flush(const QString f_entry, const QString f_area_name)
} }
l_logfile.close(); l_logfile.close();
}; };

View File

@ -17,7 +17,7 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/logger/writer_modcall.h" #include "include/logger/writer_modcall.h"
WriterModcall::WriterModcall(QObject* parent) : WriterModcall::WriterModcall(QObject *parent) :
QObject(parent) QObject(parent)
{ {
l_dir.setPath("logs/"); l_dir.setPath("logs/");
@ -43,5 +43,4 @@ void WriterModcall::flush(const QString f_area_name, QQueue<QString> f_buffer)
} }
l_logfile.close(); l_logfile.close();
}; };

View File

@ -1,11 +1,14 @@
#include "include/music_manager.h" #include "include/music_manager.h"
MusicManager::MusicManager(QObject *parent, QStringList f_root_ordered, QStringList f_cdns, QMap<QString, QPair<QString, int>> f_root_list) : #include "include/aopacket.h"
#include "include/config_manager.h"
MusicManager::MusicManager(QStringList f_root_ordered, QStringList f_cdns, QMap<QString, QPair<QString, int>> f_root_list, QObject *parent) :
QObject(parent), QObject(parent),
m_root_list(f_root_list), m_root_list(f_root_list),
m_root_ordered(f_root_ordered) m_root_ordered(f_root_ordered)
{ {
m_custom_lists = new QHash<int,QMap<QString,QPair<QString,int>>>; m_custom_lists = new QHash<int, QMap<QString, QPair<QString, int>>>;
if (!f_cdns.isEmpty()) { if (!f_cdns.isEmpty()) {
m_cdns = f_cdns; m_cdns = f_cdns;
} }
@ -13,7 +16,6 @@ MusicManager::MusicManager(QObject *parent, QStringList f_root_ordered, QStringL
MusicManager::~MusicManager() MusicManager::~MusicManager()
{ {
} }
QStringList MusicManager::musiclist(int f_area_id) QStringList MusicManager::musiclist(int f_area_id)
@ -33,28 +35,27 @@ QStringList MusicManager::rootMusiclist()
bool MusicManager::registerArea(int f_area_id) bool MusicManager::registerArea(int f_area_id)
{ {
if(m_custom_lists->contains(f_area_id)) { if (m_custom_lists->contains(f_area_id)) {
//This area is already registered. We can't add it. // This area is already registered. We can't add it.
return false; return false;
} }
m_custom_lists->insert(f_area_id,{}); m_custom_lists->insert(f_area_id, {});
m_global_enabled.insert(f_area_id,true); m_global_enabled.insert(f_area_id, true);
return true; return true;
} }
bool MusicManager::validateSong(QString f_song_name, QStringList f_approved_cdns) bool MusicManager::validateSong(QString f_song_name, QStringList f_approved_cdns)
{ {
QStringList l_extensions = {".opus", ".ogg", ".mp3", ".wav" }; QStringList l_extensions = {".opus", ".ogg", ".mp3", ".wav"};
bool l_cdn_approved = false; bool l_cdn_approved = false;
//Check if URL formatted. // Check if URL formatted.
if (f_song_name.contains("/")) { if (f_song_name.contains("/")) {
//Only allow HTTPS/HTTP sources. // Only allow HTTPS/HTTP sources.
if (f_song_name.startsWith("https://") || f_song_name.startsWith("http://")) { if (f_song_name.startsWith("https://") || f_song_name.startsWith("http://")) {
for (const QString &l_cdn : qAsConst(f_approved_cdns)) { for (const QString &l_cdn : qAsConst(f_approved_cdns)) {
//Iterate trough all available CDNs to find an approved match // Iterate trough all available CDNs to find an approved match
if (f_song_name.startsWith("https://" + l_cdn + "/", Qt::CaseInsensitive) if (f_song_name.startsWith("https://" + l_cdn + "/", Qt::CaseInsensitive) || f_song_name.startsWith("http://" + l_cdn + "/", Qt::CaseInsensitive)) {
|| f_song_name.startsWith("http://" + l_cdn + "/", Qt::CaseInsensitive)) {
l_cdn_approved = true; l_cdn_approved = true;
break; break;
} }
@ -68,9 +69,10 @@ bool MusicManager::validateSong(QString f_song_name, QStringList f_approved_cdns
} }
} }
bool l_suffix_found = false;; bool l_suffix_found = false;
;
for (const QString &suffix : qAsConst(l_extensions)) { for (const QString &suffix : qAsConst(l_extensions)) {
if (f_song_name.endsWith(suffix)){ if (f_song_name.endsWith(suffix)) {
l_suffix_found = true; l_suffix_found = true;
break; break;
} }
@ -85,7 +87,7 @@ bool MusicManager::validateSong(QString f_song_name, QStringList f_approved_cdns
bool MusicManager::addCustomSong(QString f_song_name, QString f_real_name, int f_duration, int f_area_id) bool MusicManager::addCustomSong(QString f_song_name, QString f_real_name, int f_duration, int f_area_id)
{ {
//Validate if simple name. // Validate if simple name.
QString l_song_name = f_song_name; QString l_song_name = f_song_name;
if (f_song_name.split(".").size() == 1) { if (f_song_name.split(".").size() == 1) {
l_song_name = l_song_name + ".opus"; l_song_name = l_song_name + ".opus";
@ -109,16 +111,16 @@ bool MusicManager::addCustomSong(QString f_song_name, QString f_real_name, int f
return false; return false;
} }
if (m_customs_ordered.value(f_area_id).contains(l_song_name)){ if (m_customs_ordered.value(f_area_id).contains(l_song_name)) {
return false; return false;
} }
// There should be a way to directly insert into the QMap. Too bad! // There should be a way to directly insert into the QMap. Too bad!
MusicList l_custom_list = m_custom_lists->value(f_area_id); MusicList l_custom_list = m_custom_lists->value(f_area_id);
l_custom_list.insert(l_song_name,{l_real_name,f_duration}); l_custom_list.insert(l_song_name, {l_real_name, f_duration});
m_custom_lists->insert(f_area_id,l_custom_list); m_custom_lists->insert(f_area_id, l_custom_list);
m_customs_ordered.insert(f_area_id,(QStringList {m_customs_ordered.value(f_area_id)} << l_song_name)); m_customs_ordered.insert(f_area_id, (QStringList{m_customs_ordered.value(f_area_id)} << l_song_name));
emit sendAreaFMPacket(AOPacket("FM",musiclist(f_area_id)), f_area_id); emit sendAreaFMPacket(AOPacket("FM", musiclist(f_area_id)), f_area_id);
return true; return true;
} }
@ -142,28 +144,28 @@ bool MusicManager::addCustomCategory(QString f_category_name, int f_area_id)
return false; return false;
} }
QMap<QString,QPair<QString,int>> l_custom_list = m_custom_lists->value(f_area_id); QMap<QString, QPair<QString, int>> l_custom_list = m_custom_lists->value(f_area_id);
l_custom_list.insert(l_category_name,{l_category_name,0}); l_custom_list.insert(l_category_name, {l_category_name, 0});
m_custom_lists->insert(f_area_id,l_custom_list); m_custom_lists->insert(f_area_id, l_custom_list);
m_customs_ordered.insert(f_area_id,(QStringList {m_customs_ordered.value(f_area_id)} << l_category_name)); m_customs_ordered.insert(f_area_id, (QStringList{m_customs_ordered.value(f_area_id)} << l_category_name));
emit sendAreaFMPacket(AOPacket("FM",musiclist(f_area_id)), f_area_id); emit sendAreaFMPacket(AOPacket("FM", musiclist(f_area_id)), f_area_id);
return true; return true;
} }
bool MusicManager::removeCategorySong(QString f_songcategory_name, int f_area_id) bool MusicManager::removeCategorySong(QString f_songcategory_name, int f_area_id)
{ {
if (!m_root_list.contains(f_songcategory_name)){ if (!m_root_list.contains(f_songcategory_name)) {
MusicList l_custom_list = m_custom_lists->value(f_area_id); MusicList l_custom_list = m_custom_lists->value(f_area_id);
if (l_custom_list.contains(f_songcategory_name)) { if (l_custom_list.contains(f_songcategory_name)) {
l_custom_list.remove(f_songcategory_name); l_custom_list.remove(f_songcategory_name);
m_custom_lists->insert(f_area_id,l_custom_list); m_custom_lists->insert(f_area_id, l_custom_list);
//Updating the list alias too. // Updating the list alias too.
QStringList l_customs_ordered = m_customs_ordered.value(f_area_id); QStringList l_customs_ordered = m_customs_ordered.value(f_area_id);
l_customs_ordered.removeAll(f_songcategory_name); l_customs_ordered.removeAll(f_songcategory_name);
m_customs_ordered.insert(f_area_id, l_customs_ordered); m_customs_ordered.insert(f_area_id, l_customs_ordered);
emit sendAreaFMPacket(AOPacket("FM",musiclist(f_area_id)), f_area_id); emit sendAreaFMPacket(AOPacket("FM", musiclist(f_area_id)), f_area_id);
return true; return true;
} // Fallthrough } // Fallthrough
} }
@ -176,7 +178,7 @@ bool MusicManager::toggleRootEnabled(int f_area_id)
if (m_global_enabled.value(f_area_id)) { if (m_global_enabled.value(f_area_id)) {
sanitiseCustomList(f_area_id); sanitiseCustomList(f_area_id);
} }
emit sendAreaFMPacket(AOPacket("FM",musiclist(f_area_id)), f_area_id); emit sendAreaFMPacket(AOPacket("FM", musiclist(f_area_id)), f_area_id);
return m_global_enabled.value(f_area_id); return m_global_enabled.value(f_area_id);
} }
@ -185,8 +187,8 @@ void MusicManager::sanitiseCustomList(int f_area_id)
MusicList l_sanitised_list; MusicList l_sanitised_list;
QStringList l_sanitised_ordered = m_customs_ordered.value(f_area_id); QStringList l_sanitised_ordered = m_customs_ordered.value(f_area_id);
for (auto iterator = m_custom_lists->value(f_area_id).keyBegin(), for (auto iterator = m_custom_lists->value(f_area_id).keyBegin(),
end = m_custom_lists->value(f_area_id).keyEnd(); iterator != end; ++iterator) end = m_custom_lists->value(f_area_id).keyEnd();
{ iterator != end; ++iterator) {
QString l_key = iterator.operator*(); QString l_key = iterator.operator*();
if (!m_root_list.contains(l_key)) { if (!m_root_list.contains(l_key)) {
l_sanitised_list.insert(l_key, m_custom_lists->value(f_area_id).value(l_key)); l_sanitised_list.insert(l_key, m_custom_lists->value(f_area_id).value(l_key));
@ -194,7 +196,6 @@ void MusicManager::sanitiseCustomList(int f_area_id)
else { else {
l_sanitised_ordered.removeAll(l_key); l_sanitised_ordered.removeAll(l_key);
} }
} }
m_custom_lists->insert(f_area_id, l_sanitised_list); m_custom_lists->insert(f_area_id, l_sanitised_list);
m_customs_ordered.insert(f_area_id, l_sanitised_ordered); m_customs_ordered.insert(f_area_id, l_sanitised_ordered);
@ -203,7 +204,7 @@ void MusicManager::sanitiseCustomList(int f_area_id)
void MusicManager::clearCustomList(int f_area_id) void MusicManager::clearCustomList(int f_area_id)
{ {
m_custom_lists->remove(f_area_id); m_custom_lists->remove(f_area_id);
m_custom_lists->insert(f_area_id,{}); m_custom_lists->insert(f_area_id, {});
m_customs_ordered.remove(f_area_id); m_customs_ordered.remove(f_area_id);
m_customs_ordered.insert(f_area_id, {}); m_customs_ordered.insert(f_area_id, {});
} }

View File

@ -17,7 +17,16 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
void AOClient::pktDefault(AreaData* area, int argc, QStringList argv, AOPacket packet) #include <QQueue>
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/db_manager.h"
#include "include/music_manager.h"
#include "include/server.h"
void AOClient::pktDefault(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -29,7 +38,7 @@ void AOClient::pktDefault(AreaData* area, int argc, QStringList argv, AOPacket p
#endif #endif
} }
void AOClient::pktHardwareId(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktHardwareId(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -37,16 +46,16 @@ void AOClient::pktHardwareId(AreaData* area, int argc, QStringList argv, AOPacke
m_hwid = argv[0]; m_hwid = argv[0];
emit server->logConnectionAttempt(m_remote_ip.toString(), m_ipid, m_hwid); emit server->logConnectionAttempt(m_remote_ip.toString(), m_ipid, m_hwid);
auto l_ban = server->db_manager->isHDIDBanned(m_hwid); auto l_ban = server->getDatabaseManager()->isHDIDBanned(m_hwid);
if (l_ban.first) { if (l_ban.first) {
sendPacket("BD", {l_ban.second + "\nBan ID: " + QString::number(server->db_manager->getBanID(m_hwid))}); sendPacket("BD", {l_ban.second + "\nBan ID: " + QString::number(server->getDatabaseManager()->getBanID(m_hwid))});
m_socket->close(); m_socket->close();
return; return;
} }
sendPacket("ID", {QString::number(m_id), "akashi", QCoreApplication::applicationVersion()}); sendPacket("ID", {QString::number(m_id), "akashi", QCoreApplication::applicationVersion()});
} }
void AOClient::pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktSoftwareId(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -61,9 +70,7 @@ void AOClient::pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacke
"deskmod", "evidence", "cccc_ic_support", "deskmod", "evidence", "cccc_ic_support",
"arup", "casing_alerts", "modcall_reason", "arup", "casing_alerts", "modcall_reason",
"looping_sfx", "additive", "effects", "looping_sfx", "additive", "effects",
"y_offset", "expanded_desk_mods", "auth_packet" "y_offset", "expanded_desk_mods", "auth_packet"};
};
m_version.string = argv[1]; m_version.string = argv[1];
QRegularExpression rx("\\b(\\d+)\\.(\\d+)\\.(\\d+)\\b"); // matches X.X.X (e.g. 2.9.0, 2.4.10, etc.) QRegularExpression rx("\\b(\\d+)\\.(\\d+)\\.(\\d+)\\b"); // matches X.X.X (e.g. 2.9.0, 2.4.10, etc.)
@ -74,7 +81,7 @@ void AOClient::pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacke
m_version.minor = l_match.captured(3).toInt(); m_version.minor = l_match.captured(3).toInt();
} }
sendPacket("PN", {QString::number(server->m_player_count), QString::number(ConfigManager::maxPlayers()), ConfigManager::serverDescription()}); sendPacket("PN", {QString::number(server->getPlayerCount()), QString::number(ConfigManager::maxPlayers()), ConfigManager::serverDescription()});
sendPacket("FL", l_feature_list); sendPacket("FL", l_feature_list);
if (ConfigManager::assetUrl().isValid()) { if (ConfigManager::assetUrl().isValid()) {
@ -83,7 +90,7 @@ void AOClient::pktSoftwareId(AreaData* area, int argc, QStringList argv, AOPacke
} }
} }
void AOClient::pktBeginLoad(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktBeginLoad(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -93,30 +100,30 @@ void AOClient::pktBeginLoad(AreaData* area, int argc, QStringList argv, AOPacket
// Evidence isn't loaded during this part anymore // Evidence isn't loaded during this part anymore
// As a result, we can always send "0" for evidence length // As a result, we can always send "0" for evidence length
// Client only cares about what it gets from LE // Client only cares about what it gets from LE
sendPacket("SI", {QString::number(server->m_characters.length()), "0", QString::number(server->m_area_names.length() + server->m_music_list.length())}); sendPacket("SI", {QString::number(server->getCharacterCount()), "0", QString::number(server->getAreaCount() + server->getMusicList().length())});
} }
void AOClient::pktRequestChars(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktRequestChars(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
Q_UNUSED(packet); Q_UNUSED(packet);
sendPacket("SC", server->m_characters); sendPacket("SC", server->getCharacters());
} }
void AOClient::pktRequestMusic(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktRequestMusic(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
Q_UNUSED(packet); Q_UNUSED(packet);
sendPacket("SM", server->m_area_names + server->m_music_list); sendPacket("SM", server->getAreaNames() + server->getMusicList());
} }
void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktLoadingDone(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
@ -132,14 +139,13 @@ void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPack
return; return;
} }
server->m_player_count++;
m_joined = true; m_joined = true;
server->updateCharsTaken(area); server->updateCharsTaken(area);
sendEvidenceList(area); sendEvidenceList(area);
sendPacket("HP", {"1", QString::number(area->defHP())}); sendPacket("HP", {"1", QString::number(area->defHP())});
sendPacket("HP", {"2", QString::number(area->proHP())}); sendPacket("HP", {"2", QString::number(area->proHP())});
sendPacket("FA", server->m_area_names); sendPacket("FA", server->getAreaNames());
//Here lies OPPASS, the genius of FanatSors who send the modpass to everyone in plain text. // Here lies OPPASS, the genius of FanatSors who send the modpass to everyone in plain text.
sendPacket("DONE"); sendPacket("DONE");
sendPacket("BN", {area->background()}); sendPacket("BN", {area->background()});
@ -148,28 +154,28 @@ void AOClient::pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPack
fullArup(); // Give client all the area data fullArup(); // Give client all the area data
if (server->timer->isActive()) { if (server->timer->isActive()) {
sendPacket("TI", {"0", "2"}); sendPacket("TI", {"0", "2"});
sendPacket("TI", {"0", "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(server->timer->remainingTime())))}); sendPacket("TI", {"0", "0", QString::number(QTime(0, 0).msecsTo(QTime(0, 0).addMSecs(server->timer->remainingTime())))});
} }
else { else {
sendPacket("TI", {"0", "3"}); sendPacket("TI", {"0", "3"});
} }
const QList<QTimer*> l_timers = area->timers(); const QList<QTimer *> l_timers = area->timers();
for (QTimer* l_timer : l_timers) { for (QTimer *l_timer : l_timers) {
int l_timer_id = area->timers().indexOf(l_timer) + 1; int l_timer_id = area->timers().indexOf(l_timer) + 1;
if (l_timer->isActive()) { if (l_timer->isActive()) {
sendPacket("TI", {QString::number(l_timer_id), "2"}); sendPacket("TI", {QString::number(l_timer_id), "2"});
sendPacket("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0,0).msecsTo(QTime(0,0).addMSecs(l_timer->remainingTime())))}); sendPacket("TI", {QString::number(l_timer_id), "0", QString::number(QTime(0, 0).msecsTo(QTime(0, 0).addMSecs(l_timer->remainingTime())))});
} }
else { else {
sendPacket("TI", {QString::number(l_timer_id), "3"}); sendPacket("TI", {QString::number(l_timer_id), "3"});
} }
} }
emit server->updatePlayerCount(server->m_player_count); emit joined();
area->clientJoinedArea(-1, m_id); area->clientJoinedArea(-1, m_id);
arup(ARUPType::PLAYER_COUNT, true); // Tell everyone there is a new player arup(ARUPType::PLAYER_COUNT, true); // Tell everyone there is a new player
} }
void AOClient::pktCharPassword(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktCharPassword(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -178,7 +184,7 @@ void AOClient::pktCharPassword(AreaData* area, int argc, QStringList argv, AOPac
m_password = argv[0]; m_password = argv[0];
} }
void AOClient::pktSelectChar(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktSelectChar(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -194,7 +200,7 @@ void AOClient::pktSelectChar(AreaData* area, int argc, QStringList argv, AOPacke
m_char_id = l_selected_char_id; m_char_id = l_selected_char_id;
} }
void AOClient::pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktIcChat(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
@ -204,7 +210,7 @@ void AOClient::pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket pa
return; return;
} }
if (!server->can_send_ic_messages) { if (!server->isMessageAllowed()) {
return; return;
} }
@ -216,14 +222,13 @@ void AOClient::pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket pa
validated_packet.contents[5] = m_pos; validated_packet.contents[5] = m_pos;
server->broadcast(validated_packet, m_current_area); server->broadcast(validated_packet, m_current_area);
emit logIC((m_current_char + " " + m_showname), m_ooc_name, m_ipid,server->m_areas[m_current_area]->name(), m_last_message); emit logIC((m_current_char + " " + m_showname), m_ooc_name, m_ipid, server->getAreaById(m_current_area)->name(), m_last_message);
area->updateLastICMessage(validated_packet.contents); area->updateLastICMessage(validated_packet.contents);
server->can_send_ic_messages = false; server->startMessageFloodguard(ConfigManager::messageFloodguard());
server->next_message_timer.start(ConfigManager::messageFloodguard());
} }
void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktOocChat(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(packet); Q_UNUSED(packet);
@ -251,7 +256,7 @@ void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket p
if (l_message.length() == 0 || l_message.length() > ConfigManager::maxCharacters()) if (l_message.length() == 0 || l_message.length() > ConfigManager::maxCharacters())
return; return;
AOPacket final_packet("CT", {m_ooc_name, l_message, "0"}); AOPacket final_packet("CT", {m_ooc_name, l_message, "0"});
if(l_message.at(0) == '/') { if (l_message.at(0) == '/') {
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QStringList l_cmd_argv = l_message.split(" ", QString::SplitBehavior::SkipEmptyParts); QStringList l_cmd_argv = l_message.split(" ", QString::SplitBehavior::SkipEmptyParts);
#else #else
@ -263,7 +268,7 @@ void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket p
int l_cmd_argc = l_cmd_argv.length(); int l_cmd_argc = l_cmd_argv.length();
handleCommand(l_command, l_cmd_argc, l_cmd_argv); handleCommand(l_command, l_cmd_argc, l_cmd_argv);
emit logCMD((m_current_char + " " + m_showname), m_ipid, m_ooc_name, l_command, l_cmd_argv,server->m_areas[m_current_area]->name()); emit logCMD((m_current_char + " " + m_showname), m_ipid, m_ooc_name, l_command, l_cmd_argv, server->getAreaById(m_current_area)->name());
return; return;
} }
else { else {
@ -272,7 +277,7 @@ void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket p
emit logOOC((m_current_char + " " + m_showname), m_ooc_name, m_ipid, area->name(), l_message); emit logOOC((m_current_char + " " + m_showname), m_ooc_name, m_ipid, area->name(), l_message);
} }
void AOClient::pktPing(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktPing(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -285,7 +290,7 @@ void AOClient::pktPing(AreaData* area, int argc, QStringList argv, AOPacket pack
sendPacket("CHECK"); sendPacket("CHECK");
} }
void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktChangeMusic(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(packet); Q_UNUSED(packet);
@ -297,7 +302,7 @@ void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPack
// argument is a valid song // argument is a valid song
QString l_argument = argv[0]; QString l_argument = argv[0];
if (server->m_music_list.contains(l_argument) || m_music_manager->isCustom(m_current_area, l_argument) || l_argument == "~stop.mp3") { // ~stop.mp3 is a dummy track used by 2.9+ if (server->getMusicList().contains(l_argument) || m_music_manager->isCustom(m_current_area, l_argument) || l_argument == "~stop.mp3") { // ~stop.mp3 is a dummy track used by 2.9+
// We have a song here // We have a song here
if (m_is_dj_blocked) { if (m_is_dj_blocked) {
sendServerMessage("You are blocked from changing the music."); sendServerMessage("You are blocked from changing the music.");
@ -314,13 +319,13 @@ void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPack
l_effects = "0"; l_effects = "0";
QString l_final_song; QString l_final_song;
//As categories can be used to stop music we need to check if it has a dot for the extension. If not, we assume its a category. // As categories can be used to stop music we need to check if it has a dot for the extension. If not, we assume its a category.
if (!l_argument.contains(".")) if (!l_argument.contains("."))
l_final_song = "~stop.mp3"; l_final_song = "~stop.mp3";
else else
l_final_song = l_argument; l_final_song = l_argument;
//Jukebox intercepts the direct playing of messages. // Jukebox intercepts the direct playing of messages.
if (area->isjukeboxEnabled()) { if (area->isjukeboxEnabled()) {
QString l_jukebox_reply = area->addJukeboxSong(l_final_song); QString l_jukebox_reply = area->addJukeboxSong(l_final_song);
sendServerMessage(l_jukebox_reply); sendServerMessage(l_jukebox_reply);
@ -328,33 +333,33 @@ void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPack
} }
if (l_final_song != "~stop.mp3") { if (l_final_song != "~stop.mp3") {
//We might have an aliased song. We check for its real songname and send it to the clients. // We might have an aliased song. We check for its real songname and send it to the clients.
QPair<QString,float> l_song = m_music_manager->songInformation(l_final_song, m_current_area); QPair<QString, float> l_song = m_music_manager->songInformation(l_final_song, m_current_area);
l_final_song = l_song.first; l_final_song = l_song.first;
} }
AOPacket l_music_change("MC", {l_final_song, argv[1], m_showname, "1", "0", l_effects}); AOPacket l_music_change("MC", {l_final_song, argv[1], m_showname, "1", "0", l_effects});
server->broadcast(l_music_change, m_current_area); server->broadcast(l_music_change, m_current_area);
//Since we can't ensure a user has their showname set, we check if its empty to prevent // Since we can't ensure a user has their showname set, we check if its empty to prevent
//"played by ." in /currentmusic. //"played by ." in /currentmusic.
if (m_showname.isEmpty()) { if (m_showname.isEmpty()) {
area->changeMusic(m_current_char,l_final_song); area->changeMusic(m_current_char, l_final_song);
return; return;
} }
area->changeMusic(m_showname,l_final_song); area->changeMusic(m_showname, l_final_song);
return; return;
} }
for (int i = 0; i < server->m_area_names.length(); i++) { for (int i = 0; i < server->getAreaCount(); i++) {
QString l_area = server->m_area_names[i]; QString l_area = server->getAreaName(i);
if(l_area == l_argument) { if (l_area == l_argument) {
changeArea(i); changeArea(i);
break; break;
} }
} }
} }
void AOClient::pktWtCe(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktWtCe(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
@ -370,7 +375,7 @@ void AOClient::pktWtCe(AreaData* area, int argc, QStringList argv, AOPacket pack
updateJudgeLog(area, this, "WT/CE"); updateJudgeLog(area, this, "WT/CE");
} }
void AOClient::pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktHpBar(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(packet); Q_UNUSED(packet);
@ -394,7 +399,7 @@ void AOClient::pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket pac
updateJudgeLog(area, this, "updated the penalties"); updateJudgeLog(area, this, "updated the penalties");
} }
void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktWebSocketIp(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -413,7 +418,7 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack
l_remote_ip = server->parseToIPv4(l_remote_ip); l_remote_ip = server->parseToIPv4(l_remote_ip);
} }
if (server->isIPBanned(l_remote_ip)){ if (server->isIPBanned(l_remote_ip)) {
QString l_reason = "Your IP has been banned by a moderator."; QString l_reason = "Your IP has been banned by a moderator.";
AOPacket l_ban_reason("BD", {l_reason}); AOPacket l_ban_reason("BD", {l_reason});
m_socket->write(l_ban_reason.toUtf8()); m_socket->write(l_ban_reason.toUtf8());
@ -422,7 +427,7 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack
} }
calculateIpid(); calculateIpid();
auto l_ban = server->db_manager->isIPBanned(m_ipid); auto l_ban = server->getDatabaseManager()->isIPBanned(m_ipid);
if (l_ban.first) { if (l_ban.first) {
sendPacket("BD", {l_ban.second}); sendPacket("BD", {l_ban.second});
m_socket->close(); m_socket->close();
@ -430,7 +435,8 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack
} }
int l_multiclient_count = 0; int l_multiclient_count = 0;
for (AOClient* l_joined_client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
for (AOClient *l_joined_client : l_clients) {
if (m_remote_ip.isEqual(l_joined_client->m_remote_ip)) if (m_remote_ip.isEqual(l_joined_client->m_remote_ip))
l_multiclient_count++; l_multiclient_count++;
} }
@ -442,7 +448,7 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack
} }
} }
void AOClient::pktModCall(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktModCall(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(argv); Q_UNUSED(argv);
@ -460,18 +466,24 @@ void AOClient::pktModCall(AreaData* area, int argc, QStringList argv, AOPacket p
else else
l_modcallNotice.append("No reason given."); l_modcallNotice.append("No reason given.");
for (AOClient* client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
if (client->m_authenticated) { for (AOClient *l_client : l_clients) {
client->sendPacket(AOPacket("ZZ", {l_modcallNotice})); if (l_client->m_authenticated)
l_client->sendPacket(AOPacket("ZZ", {l_modcallNotice}));
} }
} emit logModcall((m_current_char + " " + m_showname), m_ipid, m_ooc_name, server->getAreaById(m_current_area)->name());
emit logModcall((m_current_char + " " + m_showname), m_ipid, m_ooc_name, server->m_areas[m_current_area]->name());
if (ConfigManager::discordModcallWebhookEnabled()) if (ConfigManager::discordModcallWebhookEnabled()) {
emit server->modcallWebhookRequest(l_name, l_areaName, packet.contents[0],server->getAreaBuffer(l_areaName)); QString l_name = m_ooc_name;
if (m_ooc_name.isEmpty())
l_name = m_current_char;
QString l_areaName = area->name();
emit server->modcallWebhookRequest(l_name, l_areaName, packet.contents[0], server->getAreaBuffer(l_areaName));
}
} }
void AOClient::pktAddEvidence(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktAddEvidence(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(packet); Q_UNUSED(packet);
@ -483,7 +495,7 @@ void AOClient::pktAddEvidence(AreaData* area, int argc, QStringList argv, AOPack
sendEvidenceList(area); sendEvidenceList(area);
} }
void AOClient::pktRemoveEvidence(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktRemoveEvidence(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(packet); Q_UNUSED(packet);
@ -498,7 +510,7 @@ void AOClient::pktRemoveEvidence(AreaData* area, int argc, QStringList argv, AOP
sendEvidenceList(area); sendEvidenceList(area);
} }
void AOClient::pktEditEvidence(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktEditEvidence(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(packet); Q_UNUSED(packet);
@ -514,14 +526,14 @@ void AOClient::pktEditEvidence(AreaData* area, int argc, QStringList argv, AOPac
sendEvidenceList(area); sendEvidenceList(area);
} }
void AOClient::pktSetCase(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktSetCase(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
Q_UNUSED(packet); Q_UNUSED(packet);
QList<bool> l_prefs_list; QList<bool> l_prefs_list;
for (int i = 2; i <=6; i++) { for (int i = 2; i <= 6; i++) {
bool is_int = false; bool is_int = false;
bool pref = argv[i].toInt(&is_int); bool pref = argv[i].toInt(&is_int);
if (!is_int) if (!is_int)
@ -531,7 +543,7 @@ void AOClient::pktSetCase(AreaData* area, int argc, QStringList argv, AOPacket p
m_casing_preferences = l_prefs_list; m_casing_preferences = l_prefs_list;
} }
void AOClient::pktAnnounceCase(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktAnnounceCase(AreaData *area, int argc, QStringList argv, AOPacket packet)
{ {
Q_UNUSED(area); Q_UNUSED(area);
Q_UNUSED(argc); Q_UNUSED(argc);
@ -540,7 +552,7 @@ void AOClient::pktAnnounceCase(AreaData* area, int argc, QStringList argv, AOPac
QString l_case_title = argv[0]; QString l_case_title = argv[0];
QStringList l_needed_roles; QStringList l_needed_roles;
QList<bool> l_needs_list; QList<bool> l_needs_list;
for (int i = 1; i <=5; i++) { for (int i = 1; i <= 5; i++) {
bool is_int = false; bool is_int = false;
bool need = argv[i].toInt(&is_int); bool need = argv[i].toInt(&is_int);
if (!is_int) if (!is_int)
@ -557,14 +569,15 @@ void AOClient::pktAnnounceCase(AreaData* area, int argc, QStringList argv, AOPac
QString l_message = "=== Case Announcement ===\r\n" + (m_ooc_name == "" ? m_current_char : m_ooc_name) + " needs " + l_needed_roles.join(", ") + " for " + (l_case_title == "" ? "a case" : l_case_title) + "!"; QString l_message = "=== Case Announcement ===\r\n" + (m_ooc_name == "" ? m_current_char : m_ooc_name) + " needs " + l_needed_roles.join(", ") + " for " + (l_case_title == "" ? "a case" : l_case_title) + "!";
QList<AOClient*> l_clients_to_alert; QList<AOClient *> l_clients_to_alert;
// here lies morton, RIP // here lies morton, RIP
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QSet<bool> l_needs_set(l_needs_list.begin(), l_needs_list.end()); QSet<bool> l_needs_set(l_needs_list.begin(), l_needs_list.end());
#else #else
QSet<bool> l_needs_set = l_needs_list.toSet(); QSet<bool> l_needs_set = l_needs_list.toSet();
#endif #endif
for (AOClient* l_client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
for (AOClient *l_client : l_clients) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QSet<bool> l_matches(l_client->m_casing_preferences.begin(), l_client->m_casing_preferences.end()); QSet<bool> l_matches(l_client->m_casing_preferences.begin(), l_client->m_casing_preferences.end());
l_matches.intersect(l_needs_set); l_matches.intersect(l_needs_set);
@ -575,7 +588,7 @@ void AOClient::pktAnnounceCase(AreaData* area, int argc, QStringList argv, AOPac
l_clients_to_alert.append(l_client); l_clients_to_alert.append(l_client);
} }
for (AOClient* l_client : l_clients_to_alert) { for (AOClient *l_client : l_clients_to_alert) {
l_client->sendPacket(AOPacket("CASEA", {l_message, argv[1], argv[2], argv[3], argv[4], argv[5], "1"})); l_client->sendPacket(AOPacket("CASEA", {l_message, argv[1], argv[2], argv[3], argv[4], argv[5], "1"}));
// you may be thinking, "hey wait a minute the network protocol documentation doesn't mention that last argument!" // you may be thinking, "hey wait a minute the network protocol documentation doesn't mention that last argument!"
// if you are in fact thinking that, you are correct! it is not in the documentation! // if you are in fact thinking that, you are correct! it is not in the documentation!
@ -584,15 +597,16 @@ void AOClient::pktAnnounceCase(AreaData* area, int argc, QStringList argv, AOPac
} }
} }
void AOClient::sendEvidenceList(AreaData* area) void AOClient::sendEvidenceList(AreaData *area)
{ {
for (AOClient* l_client : qAsConst(server->m_clients)) { const QVector<AOClient *> l_clients = server->getClients();
for (AOClient *l_client : l_clients) {
if (l_client->m_current_area == m_current_area) if (l_client->m_current_area == m_current_area)
l_client->updateEvidenceList(area); l_client->updateEvidenceList(area);
} }
} }
void AOClient::updateEvidenceList(AreaData* area) void AOClient::updateEvidenceList(AreaData *area)
{ {
QStringList l_evidence_list; QStringList l_evidence_list;
QString l_evidence_format("%1&%2&%3"); QString l_evidence_format("%1&%2&%3");
@ -633,7 +647,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
if (m_current_char == "" || !m_joined) if (m_current_char == "" || !m_joined)
// Spectators cannot use IC // Spectators cannot use IC
return l_invalid; return l_invalid;
AreaData* area = server->m_areas[m_current_area]; AreaData *area = server->getAreaById(m_current_area);
if (area->lockStatus() == AreaData::LockStatus::SPECTATABLE && !area->invited().contains(m_id) && !checkAuth(ACLFlags.value("BYPASS_LOCKS"))) if (area->lockStatus() == AreaData::LockStatus::SPECTATABLE && !area->invited().contains(m_id) && !checkAuth(ACLFlags.value("BYPASS_LOCKS")))
// Non-invited players cannot speak in spectatable areas // Non-invited players cannot speak in spectatable areas
return l_invalid; return l_invalid;
@ -645,7 +659,13 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
// desk modifier // desk modifier
QStringList allowed_desk_mods; QStringList allowed_desk_mods;
allowed_desk_mods << "chat" << "0" << "1" << "2" << "3" << "4" << "5"; allowed_desk_mods << "chat"
<< "0"
<< "1"
<< "2"
<< "3"
<< "4"
<< "5";
if (allowed_desk_mods.contains(l_incoming_args[0].toString())) { if (allowed_desk_mods.contains(l_incoming_args[0].toString())) {
l_args.append(l_incoming_args[0].toString()); l_args.append(l_incoming_args[0].toString());
} }
@ -660,7 +680,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
// Selected char is different from supplied folder name // Selected char is different from supplied folder name
// This means the user is INI-swapped // This means the user is INI-swapped
if (!area->iniswapAllowed()) { if (!area->iniswapAllowed()) {
if (!server->m_characters.contains(l_incoming_args[2].toString(), Qt::CaseInsensitive)) if (!server->getCharacters().contains(l_incoming_args[2].toString(), Qt::CaseInsensitive))
return l_invalid; return l_invalid;
} }
qDebug() << "INI swap detected from " << getIpid(); qDebug() << "INI swap detected from " << getIpid();
@ -679,9 +699,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
return l_invalid; return l_invalid;
QString l_incoming_msg = dezalgo(l_incoming_args[4].toString().trimmed()); QString l_incoming_msg = dezalgo(l_incoming_args[4].toString().trimmed());
if (!area->lastICMessage().isEmpty() if (!area->lastICMessage().isEmpty() && l_incoming_msg == area->lastICMessage()[4] && l_incoming_msg != "")
&& l_incoming_msg == area->lastICMessage()[4]
&& l_incoming_msg != "")
return l_invalid; return l_invalid;
if (l_incoming_msg == "" && area->blankpostingAllowed() == false) { if (l_incoming_msg == "" && area->blankpostingAllowed() == false) {
@ -713,7 +731,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
l_args.append(l_incoming_args[5].toString()); l_args.append(l_incoming_args[5].toString());
if (m_pos != l_incoming_args[5].toString()) { if (m_pos != l_incoming_args[5].toString()) {
m_pos = l_incoming_args[5].toString(); m_pos = l_incoming_args[5].toString();
updateEvidenceList(server->m_areas[m_current_area]); updateEvidenceList(server->getAreaById(m_current_area));
} }
// sfx name // sfx name
@ -815,10 +833,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
QString l_other_flip = "0"; QString l_other_flip = "0";
for (int l_client_id : area->joinedIDs()) { for (int l_client_id : area->joinedIDs()) {
AOClient* l_client = server->getClientByID(l_client_id); AOClient* l_client = server->getClientByID(l_client_id);
if (l_client->m_pairing_with == m_char_id if (l_client->m_pairing_with == m_char_id && l_other_charid != m_char_id && l_client->m_char_id == m_pairing_with && l_client->m_pos == m_pos) {
&& l_other_charid != m_char_id
&& l_client->m_char_id == m_pairing_with
&& l_client->m_pos == m_pos) {
l_other_name = l_client->m_current_iniswap; l_other_name = l_client->m_current_iniswap;
l_other_emote = l_client->m_emote; l_other_emote = l_client->m_emote;
l_other_offset = l_client->m_offset; l_other_offset = l_client->m_offset;
@ -893,7 +908,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
int l_additive = l_incoming_args[24].toInt(); int l_additive = l_incoming_args[24].toInt();
if (l_additive != 0 && l_additive != 1) if (l_additive != 0 && l_additive != 1)
return l_invalid; return l_invalid;
else if (area->lastICMessage().isEmpty()){ else if (area->lastICMessage().isEmpty()) {
l_additive = 0; l_additive = 0;
} }
else if (!(m_char_id == area->lastICMessage()[8].toInt())) { else if (!(m_char_id == area->lastICMessage()[8].toInt())) {
@ -908,7 +923,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
l_args.append(l_incoming_args[25].toString()); l_args.append(l_incoming_args[25].toString());
} }
//Testimony playback // Testimony playback
if (area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING || area->testimonyRecording() == AreaData::TestimonyRecording::ADD) { if (area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING || area->testimonyRecording() == AreaData::TestimonyRecording::ADD) {
if (l_args[5] != "wit") if (l_args[5] != "wit")
return AOPacket("MS", l_args); return AOPacket("MS", l_args);
@ -916,7 +931,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
if (area->statement() == -1) { if (area->statement() == -1) {
l_args[4] = "~~\\n-- " + l_args[4] + " --"; l_args[4] = "~~\\n-- " + l_args[4] + " --";
l_args[14] = "3"; l_args[14] = "3";
server->broadcast(AOPacket("RT",{"testimony1"}), m_current_area); server->broadcast(AOPacket("RT", {"testimony1"}), m_current_area);
} }
addStatement(l_args); addStatement(l_args);
} }
@ -928,7 +943,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
if (l_args[4] == ">") { if (l_args[4] == ">") {
m_pos = "wit"; m_pos = "wit";
auto l_statement = area->jumpToStatement(area->statement() +1); auto l_statement = area->jumpToStatement(area->statement() + 1);
l_args = l_statement.first; l_args = l_statement.first;
l_progress = l_statement.second; l_progress = l_statement.second;
@ -947,7 +962,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
} }
} }
QString l_decoded_message = decodeMessage(l_args[4]); //Get rid of that pesky encoding first. QString l_decoded_message = decodeMessage(l_args[4]); // Get rid of that pesky encoding first.
QRegularExpression jump("(?<arrow>>)(?<int>[0,1,2,3,4,5,6,7,8,9]+)"); QRegularExpression jump("(?<arrow>>)(?<int>[0,1,2,3,4,5,6,7,8,9]+)");
QRegularExpressionMatch match = jump.match(l_decoded_message); QRegularExpressionMatch match = jump.match(l_decoded_message);
if (match.hasMatch()) { if (match.hasMatch()) {
@ -956,8 +971,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
l_args = l_statement.first; l_args = l_statement.first;
l_progress = l_statement.second; l_progress = l_statement.second;
switch (l_progress) {
switch (l_progress){
case AreaData::TestimonyProgress::LOOPED: case AreaData::TestimonyProgress::LOOPED:
{ {
sendServerMessageArea("Last statement reached. Looping to first statement."); sendServerMessageArea("Last statement reached. Looping to first statement.");
@ -988,7 +1002,7 @@ QString AOClient::dezalgo(QString p_text)
bool AOClient::checkEvidenceAccess(AreaData *area) bool AOClient::checkEvidenceAccess(AreaData *area)
{ {
switch(area->eviMod()) { switch (area->eviMod()) {
case AreaData::EvidenceMod::FFA: case AreaData::EvidenceMod::FFA:
return true; return true;
case AreaData::EvidenceMod::CM: case AreaData::EvidenceMod::CM:
@ -1001,7 +1015,7 @@ bool AOClient::checkEvidenceAccess(AreaData *area)
} }
} }
void AOClient::updateJudgeLog(AreaData* area, AOClient* client, QString action) void AOClient::updateJudgeLog(AreaData *area, AOClient *client, QString action)
{ {
QString l_timestamp = QTime::currentTime().toString("hh:mm:ss"); QString l_timestamp = QTime::currentTime().toString("hh:mm:ss");
QString l_uid = QString::number(client->m_id); QString l_uid = QString::number(client->m_id);
@ -1034,8 +1048,8 @@ void AOClient::loginAttempt(QString message)
sendPacket("AUTH", {"0"}); // Client: "Login unsuccessful." sendPacket("AUTH", {"0"}); // Client: "Login unsuccessful."
sendServerMessage("Incorrect password."); sendServerMessage("Incorrect password.");
} }
emit logLogin((m_current_char + " " + m_showname), m_ooc_name,"Moderator", emit logLogin((m_current_char + " " + m_showname), m_ooc_name, "Moderator",
m_ipid, server->m_areas.value(m_current_area)->name(), m_authenticated); m_ipid, server->getAreaById(m_current_area)->name(), m_authenticated);
break; break;
case DataTypes::AuthType::ADVANCED: case DataTypes::AuthType::ADVANCED:
QStringList l_login = message.split(" "); QStringList l_login = message.split(" ");
@ -1047,7 +1061,7 @@ void AOClient::loginAttempt(QString message)
} }
QString username = l_login[0]; QString username = l_login[0];
QString password = l_login[1]; QString password = l_login[1];
if (server->db_manager->authenticate(username, password)) { if (server->getDatabaseManager()->authenticate(username, password)) {
m_moderator_name = username; m_moderator_name = username;
m_authenticated = true; m_authenticated = true;
sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button." sendPacket("AUTH", {"1"}); // Client: "You were granted the Disable Modcalls button."
@ -1060,11 +1074,10 @@ void AOClient::loginAttempt(QString message)
sendServerMessage("Incorrect password."); sendServerMessage("Incorrect password.");
} }
emit logLogin((m_current_char + " " + m_showname), m_ooc_name, username, m_ipid, emit logLogin((m_current_char + " " + m_showname), m_ooc_name, username, m_ipid,
server->m_areas.value(m_current_area)->name(), m_authenticated); server->getAreaById(m_current_area)->name(), m_authenticated);
break; break;
} }
sendServerMessage("Exiting login prompt."); sendServerMessage("Exiting login prompt.");
m_is_logging_in = false; m_is_logging_in = false;
return; return;
} }

View File

@ -17,28 +17,38 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/server.h" #include "include/server.h"
Server::Server(int p_port, int p_ws_port, QObject* parent) : #include "include/advertiser.h"
#include "include/aoclient.h"
#include "include/aopacket.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/db_manager.h"
#include "include/discord.h"
#include "include/logger/u_logger.h"
#include "include/music_manager.h"
#include "include/ws_proxy.h"
Server::Server(int p_port, int p_ws_port, QObject *parent) :
QObject(parent), QObject(parent),
m_player_count(0),
port(p_port), port(p_port),
ws_port(p_ws_port) ws_port(p_ws_port),
m_player_count(0)
{ {
server = new QTcpServer(this); server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()), this, SLOT(clientConnected())); connect(server, SIGNAL(newConnection()), this, SLOT(clientConnected()));
proxy = new WSProxy(port, ws_port, this); proxy = new WSProxy(port, ws_port, this);
if(ws_port != -1) if (ws_port != -1)
proxy->start(); proxy->start();
timer = new QTimer(); timer = new QTimer(this);
db_manager = new DBManager(); db_manager = new DBManager();
//We create it, even if its not used later on. // We create it, even if its not used later on.
discord = new Discord(this); discord = new Discord(this);
logger = new ULogger(this); logger = new ULogger(this);
connect(this, &Server::logConnectionAttempt, connect(this, &Server::logConnectionAttempt, logger, &ULogger::logConnectionAttempt);
logger, &ULogger::logConnectionAttempt);
} }
void Server::start() void Server::start()
@ -59,80 +69,78 @@ void Server::start()
qDebug() << "Server listening on" << port; qDebug() << "Server listening on" << port;
} }
//Checks if any Discord webhooks are enabled. // Checks if any Discord webhooks are enabled.
handleDiscordIntegration(); handleDiscordIntegration();
//Construct modern advertiser if enabled in config // Construct modern advertiser if enabled in config
if (ConfigManager::advertiseServer()) { if (ConfigManager::advertiseServer()) {
AdvertiserTimer = new QTimer(this); AdvertiserTimer = new QTimer(this);
ms3_Advertiser = new Advertiser(); ms3_Advertiser = new Advertiser();
connect(AdvertiserTimer, &QTimer::timeout, connect(AdvertiserTimer, &QTimer::timeout, ms3_Advertiser, &Advertiser::msAdvertiseServer);
ms3_Advertiser, &Advertiser::msAdvertiseServer); connect(this, &Server::playerCountUpdated, ms3_Advertiser, &Advertiser::updatePlayerCount);
connect(this, &Server::updatePlayerCount, connect(this, &Server::updateHTTPConfiguration, ms3_Advertiser, &Advertiser::updateAdvertiserSettings);
ms3_Advertiser, &Advertiser::updatePlayerCount); emit playerCountUpdated(m_player_count);
connect(this, &Server::updateHTTPConfiguration,
ms3_Advertiser, &Advertiser::updateAdvertiserSettings);
emit updatePlayerCount(m_player_count);
ms3_Advertiser->msAdvertiseServer(); ms3_Advertiser->msAdvertiseServer();
AdvertiserTimer->start(300000); AdvertiserTimer->start(300000);
} }
//Get characters from config file // Get characters from config file
m_characters = ConfigManager::charlist(); m_characters = ConfigManager::charlist();
//Get backgrounds from config file // Get backgrounds from config file
m_backgrounds = ConfigManager::backgrounds(); m_backgrounds = ConfigManager::backgrounds();
//Build our music manager. // Build our music manager.
ConfigManager::musiclist(); ConfigManager::musiclist();
music_manager = new MusicManager(this, ConfigManager::ordered_songs(), ConfigManager::cdnList()); music_manager = new MusicManager(ConfigManager::ordered_songs(), ConfigManager::cdnList(), ConfigManager::musiclist(), this);
connect(music_manager, &MusicManager::sendFMPacket, connect(music_manager, &MusicManager::sendFMPacket, this, &Server::unicast);
this, &Server::unicast); connect(music_manager, &MusicManager::sendAreaFMPacket, this, QOverload<AOPacket, int>::of(&Server::broadcast));
connect(music_manager, &MusicManager::sendAreaFMPacket,
this, QOverload<AOPacket,int>::of(&Server::broadcast));
//Get musiclist from config file // Get musiclist from config file
m_music_list = music_manager->rootMusiclist(); m_music_list = music_manager->rootMusiclist();
//Assembles the area list // Assembles the area list
m_area_names = ConfigManager::sanitizedAreaNames(); m_area_names = ConfigManager::sanitizedAreaNames();
QStringList raw_area_names = ConfigManager::rawAreaNames(); QStringList raw_area_names = ConfigManager::rawAreaNames();
for (int i = 0; i < raw_area_names.length(); i++) { for (int i = 0; i < raw_area_names.length(); i++) {
QString area_name = raw_area_names[i]; QString area_name = raw_area_names[i];
AreaData* l_area = new AreaData(area_name, i, music_manager); AreaData *l_area = new AreaData(area_name, i, music_manager);
m_areas.insert(i, l_area); m_areas.insert(i, l_area);
connect(l_area, &AreaData::sendAreaPacket, connect(l_area, &AreaData::sendAreaPacket, this, QOverload<AOPacket, int>::of(&Server::broadcast));
this, QOverload<AOPacket,int>::of(&Server::broadcast)); connect(l_area, &AreaData::sendAreaPacketClient, this, &Server::unicast);
connect(l_area, &AreaData::sendAreaPacketClient, connect(l_area, &AreaData::userJoinedArea, music_manager, &MusicManager::userJoinedArea);
this, &Server::unicast);
connect(l_area, &AreaData::userJoinedArea,
music_manager, &MusicManager::userJoinedArea);
music_manager->registerArea(i); music_manager->registerArea(i);
} }
//Loads the command help information. This is not stored inside the server. // Loads the command help information. This is not stored inside the server.
ConfigManager::loadCommandHelp(); ConfigManager::loadCommandHelp();
//Get IP bans // Get IP bans
m_ipban_list = ConfigManager::iprangeBans(); m_ipban_list = ConfigManager::iprangeBans();
//Rate-Limiter for IC-Chat // Rate-Limiter for IC-Chat
connect(&next_message_timer, &QTimer::timeout, this, &Server::allowMessage); m_message_floodguard_timer = new QTimer(this);
connect(m_message_floodguard_timer, &QTimer::timeout, this, &Server::allowMessage);
//Prepare player IDs and reference hash. // Prepare player IDs and reference hash.
for (int i = ConfigManager::maxPlayers() -1; i >= 0; i--){ for (int i = ConfigManager::maxPlayers() - 1; i >= 0; i--) {
m_available_ids.push(i); m_available_ids.push(i);
m_clients_ids.insert(i, nullptr); m_clients_ids.insert(i, nullptr);
} }
} }
QVector<AOClient *> Server::getClients()
{
return m_clients;
}
void Server::clientConnected() void Server::clientConnected()
{ {
QTcpSocket* socket = server->nextPendingConnection(); QTcpSocket *socket = server->nextPendingConnection();
//Too many players. Reject connection! // Too many players. Reject connection!
//This also enforces the maximum playercount. // This also enforces the maximum playercount.
if (m_available_ids.empty()) { if (m_available_ids.empty()) {
AOPacket disconnect_reason("BD", {"Maximum playercount has been reached."}); AOPacket disconnect_reason("BD", {"Maximum playercount has been reached."});
socket->write(disconnect_reason.toUtf8()); socket->write(disconnect_reason.toUtf8());
@ -143,7 +151,7 @@ void Server::clientConnected()
} }
int user_id = m_available_ids.pop(); int user_id = m_available_ids.pop();
AOClient* client = new AOClient(this, socket, this, user_id, music_manager); AOClient *client = new AOClient(this, socket, this, user_id, music_manager);
m_clients_ids.insert(user_id, client); m_clients_ids.insert(user_id, client);
int multiclient_count = 1; int multiclient_count = 1;
@ -151,7 +159,7 @@ void Server::clientConnected()
client->calculateIpid(); client->calculateIpid();
auto ban = db_manager->isIPBanned(client->getIpid()); auto ban = db_manager->isIPBanned(client->getIpid());
bool is_banned = ban.first; bool is_banned = ban.first;
for (AOClient* joined_client : qAsConst(m_clients)) { for (AOClient *joined_client : qAsConst(m_clients)) {
if (client->m_remote_ip.isEqual(joined_client->m_remote_ip)) if (client->m_remote_ip.isEqual(joined_client->m_remote_ip))
multiclient_count++; multiclient_count++;
} }
@ -177,7 +185,7 @@ void Server::clientConnected()
l_remote_ip = parseToIPv4(l_remote_ip); l_remote_ip = parseToIPv4(l_remote_ip);
} }
if (isIPBanned(l_remote_ip)){ if (isIPBanned(l_remote_ip)) {
QString l_reason = "Your IP has been banned by a moderator."; QString l_reason = "Your IP has been banned by a moderator.";
AOPacket l_ban_reason("BD", {l_reason}); AOPacket l_ban_reason("BD", {l_reason});
socket->write(l_ban_reason.toUtf8()); socket->write(l_ban_reason.toUtf8());
@ -188,9 +196,11 @@ void Server::clientConnected()
} }
m_clients.append(client); m_clients.append(client);
connect(socket, &QTcpSocket::disconnected, client, connect(socket, &QTcpSocket::disconnected, client, &AOClient::clientDisconnected);
&AOClient::clientDisconnected);
connect(socket, &QTcpSocket::disconnected, this, [=] { connect(socket, &QTcpSocket::disconnected, this, [=] {
if (client->hasJoined()) {
decreasePlayerCount();
}
m_clients.removeAll(client); m_clients.removeAll(client);
client->deleteLater(); client->deleteLater();
}); });
@ -206,7 +216,7 @@ void Server::clientConnected()
#endif #endif
} }
void Server::updateCharsTaken(AreaData* area) void Server::updateCharsTaken(AreaData *area)
{ {
QStringList chars_taken; QStringList chars_taken;
for (const QString &cur_char : qAsConst(m_characters)) { for (const QString &cur_char : qAsConst(m_characters)) {
@ -217,20 +227,20 @@ void Server::updateCharsTaken(AreaData* area)
AOPacket response_cc("CharsCheck", chars_taken); AOPacket response_cc("CharsCheck", chars_taken);
for (AOClient* client : qAsConst(m_clients)) { for (AOClient *l_client : qAsConst(m_clients)) {
if (client->m_current_area == area->index()){ if (l_client->m_current_area == area->index()) {
if (!client->m_is_charcursed) if (!l_client->m_is_charcursed)
client->sendPacket(response_cc); l_client->sendPacket(response_cc);
else { else {
QStringList chars_taken_cursed = getCursedCharsTaken(client, chars_taken); QStringList chars_taken_cursed = getCursedCharsTaken(l_client, chars_taken);
AOPacket response_cc_cursed("CharsCheck", chars_taken_cursed); AOPacket response_cc_cursed("CharsCheck", chars_taken_cursed);
client->sendPacket(response_cc_cursed); l_client->sendPacket(response_cc_cursed);
} }
} }
} }
} }
QStringList Server::getCursedCharsTaken(AOClient* client, QStringList chars_taken) QStringList Server::getCursedCharsTaken(AOClient *client, QStringList chars_taken)
{ {
QStringList chars_taken_cursed; QStringList chars_taken_cursed;
for (int i = 0; i < chars_taken.length(); i++) { for (int i = 0; i < chars_taken.length(); i++) {
@ -242,6 +252,17 @@ QStringList Server::getCursedCharsTaken(AOClient* client, QStringList chars_take
return chars_taken_cursed; return chars_taken_cursed;
} }
bool Server::isMessageAllowed()
{
return m_can_send_ic_messages;
}
void Server::startMessageFloodguard(int f_duration)
{
m_can_send_ic_messages = false;
m_message_floodguard_timer->start(f_duration);
}
QHostAddress Server::parseToIPv4(QHostAddress f_remote_ip) QHostAddress Server::parseToIPv4(QHostAddress f_remote_ip)
{ {
bool l_ok; bool l_ok;
@ -273,14 +294,14 @@ void Server::broadcast(AOPacket packet, int area_index)
void Server::broadcast(AOPacket packet) void Server::broadcast(AOPacket packet)
{ {
for (AOClient* client : qAsConst(m_clients)) { for (AOClient *l_client : qAsConst(m_clients)) {
client->sendPacket(packet); l_client->sendPacket(packet);
} }
} }
void Server::broadcast(AOPacket packet, TARGET_TYPE target) void Server::broadcast(AOPacket packet, TARGET_TYPE target)
{ {
for (AOClient* l_client : qAsConst(m_clients)) { for (AOClient *l_client : qAsConst(m_clients)) {
switch (target) { switch (target) {
case TARGET_TYPE::MODCHAT: case TARGET_TYPE::MODCHAT:
if (l_client->checkAuth(l_client->ACLFlags.value("MODCHAT"))) { if (l_client->checkAuth(l_client->ACLFlags.value("MODCHAT"))) {
@ -302,44 +323,70 @@ void Server::broadcast(AOPacket packet, AOPacket other_packet, TARGET_TYPE targe
{ {
switch (target) { switch (target) {
case TARGET_TYPE::AUTHENTICATED: case TARGET_TYPE::AUTHENTICATED:
for (AOClient* client : qAsConst(m_clients)){ for (AOClient *l_client : qAsConst(m_clients)) {
if (client->m_authenticated) { if (l_client->m_authenticated) {
client->sendPacket(other_packet); l_client->sendPacket(other_packet);
} }
else { else {
client->sendPacket(packet); l_client->sendPacket(packet);
} }
} }
default: default:
//Unimplemented, so not handled. // Unimplemented, so not handled.
break; break;
} }
} }
void Server::unicast(AOPacket f_packet, int f_client_id) void Server::unicast(AOPacket f_packet, int f_client_id)
{ {
AOClient* l_client = getClientByID(f_client_id); AOClient *l_client = getClientByID(f_client_id);
if (l_client != nullptr) { // This should never happen, but safety first. if (l_client != nullptr) { // This should never happen, but safety first.
l_client->sendPacket(f_packet); l_client->sendPacket(f_packet);
return; return;
} }
} }
QList<AOClient*> Server::getClientsByIpid(QString ipid) QList<AOClient *> Server::getClientsByIpid(QString ipid)
{ {
QList<AOClient*> return_clients; QList<AOClient *> return_clients;
for (AOClient* client : qAsConst(m_clients)) { for (AOClient *l_client : qAsConst(m_clients)) {
if (client->getIpid() == ipid) if (l_client->getIpid() == ipid)
return_clients.append(client); return_clients.append(l_client);
} }
return return_clients; return return_clients;
} }
AOClient* Server::getClientByID(int id) AOClient *Server::getClientByID(int id)
{ {
return m_clients_ids.value(id); return m_clients_ids.value(id);
} }
int Server::getPlayerCount()
{
return m_player_count;
}
QStringList Server::getCharacters()
{
return m_characters;
}
int Server::getCharacterCount()
{
return m_characters.length();
}
QString Server::getCharacterById(int f_chr_id)
{
QString l_chr;
if (f_chr_id >= 0 && f_chr_id < m_characters.length()) {
l_chr = m_characters.at(f_chr_id);
}
return l_chr;
}
int Server::getCharID(QString char_name) int Server::getCharID(QString char_name)
{ {
for (const QString &character : qAsConst(m_characters)) { for (const QString &character : qAsConst(m_characters)) {
@ -350,14 +397,66 @@ int Server::getCharID(QString char_name)
return -1; // character does not exist return -1; // character does not exist
} }
QVector<AreaData *> Server::getAreas()
{
return m_areas;
}
int Server::getAreaCount()
{
return m_areas.length();
}
AreaData *Server::getAreaById(int f_area_id)
{
AreaData *l_area = nullptr;
if (f_area_id >= 0 && f_area_id < m_areas.length()) {
l_area = m_areas.at(f_area_id);
}
return l_area;
}
QQueue<QString> Server::getAreaBuffer(const QString &f_areaName) QQueue<QString> Server::getAreaBuffer(const QString &f_areaName)
{ {
return logger->buffer(f_areaName); return logger->buffer(f_areaName);
} }
QStringList Server::getAreaNames()
{
return m_area_names;
}
QString Server::getAreaName(int f_area_id)
{
QString l_name;
if (f_area_id >= 0 && f_area_id < m_area_names.length()) {
l_name = m_area_names.at(f_area_id);
}
return l_name;
}
QStringList Server::getMusicList()
{
return m_music_list;
}
QStringList Server::getBackgrounds()
{
return m_backgrounds;
}
DBManager *Server::getDatabaseManager()
{
return db_manager;
}
void Server::allowMessage() void Server::allowMessage()
{ {
can_send_ic_messages = true; m_can_send_ic_messages = true;
} }
void Server::handleDiscordIntegration() void Server::handleDiscordIntegration()
@ -367,12 +466,10 @@ void Server::handleDiscordIntegration()
if (ConfigManager::discordWebhookEnabled()) { if (ConfigManager::discordWebhookEnabled()) {
if (ConfigManager::discordModcallWebhookEnabled()) if (ConfigManager::discordModcallWebhookEnabled())
connect(this, &Server::modcallWebhookRequest, connect(this, &Server::modcallWebhookRequest, discord, &Discord::onModcallWebhookRequested);
discord, &Discord::onModcallWebhookRequested);
if (ConfigManager::discordBanWebhookEnabled()) if (ConfigManager::discordBanWebhookEnabled())
connect(this, &Server::banWebhookRequest, connect(this, &Server::banWebhookRequest, discord, &Discord::onBanWebhookRequested);
discord, &Discord::onBanWebhookRequested);
if (ConfigManager::discordUptimeEnabled()) if (ConfigManager::discordUptimeEnabled())
discord->startUptimeTimer(); discord->startUptimeTimer();
@ -388,30 +485,34 @@ void Server::markIDFree(const int &f_user_id)
m_clients_ids.insert(f_user_id, nullptr); m_clients_ids.insert(f_user_id, nullptr);
} }
void Server::hookupAOClient(AOClient* client) void Server::hookupAOClient(AOClient *client)
{ {
connect(client, &AOClient::logIC, connect(client, &AOClient::joined, this, &Server::increasePlayerCount);
logger, &ULogger::logIC); connect(client, &AOClient::logIC, logger, &ULogger::logIC);
connect(client, &AOClient::logOOC, connect(client, &AOClient::logOOC, logger, &ULogger::logOOC);
logger, &ULogger::logOOC); connect(client, &AOClient::logLogin, logger, &ULogger::logLogin);
connect(client, &AOClient::logLogin, connect(client, &AOClient::logCMD, logger, &ULogger::logCMD);
logger, &ULogger::logLogin); connect(client, &AOClient::logBan, logger, &ULogger::logBan);
connect(client, &AOClient::logCMD, connect(client, &AOClient::logKick, logger, &ULogger::logKick);
logger, &ULogger::logCMD); connect(client, &AOClient::logModcall, logger, &ULogger::logModcall);
connect(client, &AOClient::logBan, }
logger, &ULogger::logBan);
connect(client, &AOClient::logKick, void Server::increasePlayerCount()
logger, &ULogger::logKick); {
connect(client, &AOClient::logModcall, m_player_count++;
logger, &ULogger::logModcall); emit playerCountUpdated(m_player_count);
connect(client, &AOClient::clientSuccessfullyDisconnected, }
this, &Server::markIDFree);
void Server::decreasePlayerCount()
{
m_player_count--;
emit playerCountUpdated(m_player_count);
} }
bool Server::isIPBanned(QHostAddress f_remote_IP) bool Server::isIPBanned(QHostAddress f_remote_IP)
{ {
bool l_match_found = false; bool l_match_found = false;
for(const QString &l_ipban : qAsConst(m_ipban_list)) { for (const QString &l_ipban : qAsConst(m_ipban_list)) {
if (f_remote_IP.isInSubnet(QHostAddress::parseSubnet(l_ipban))) { if (f_remote_IP.isInSubnet(QHostAddress::parseSubnet(l_ipban))) {
l_match_found = true; l_match_found = true;
break; break;
@ -422,8 +523,8 @@ bool Server::isIPBanned(QHostAddress f_remote_IP)
Server::~Server() Server::~Server()
{ {
for (AOClient* client : qAsConst(m_clients)) { for (AOClient *l_client : qAsConst(m_clients)) {
client->deleteLater(); l_client->deleteLater();
} }
server->deleteLater(); server->deleteLater();
proxy->deleteLater(); proxy->deleteLater();

View File

@ -17,12 +17,16 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/aoclient.h" #include "include/aoclient.h"
#include "include/area_data.h"
#include "include/config_manager.h"
#include "include/server.h"
void AOClient::addStatement(QStringList packet) void AOClient::addStatement(QStringList packet)
{ {
if (checkTestimonySymbols(packet[4])) { if (checkTestimonySymbols(packet[4])) {
return; return;
} }
AreaData* area = server->m_areas[m_current_area]; AreaData *area = server->getAreaById(m_current_area);
int c_statement = area->statement(); int c_statement = area->statement();
if (c_statement >= -1) { if (c_statement >= -1) {
if (area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING) { if (area->testimonyRecording() == AreaData::TestimonyRecording::RECORDING) {
@ -55,7 +59,7 @@ QStringList AOClient::updateStatement(QStringList packet)
if (checkTestimonySymbols(packet[4])) { if (checkTestimonySymbols(packet[4])) {
return packet; return packet;
} }
AreaData* area = server->m_areas[m_current_area]; AreaData *area = server->getAreaById(m_current_area);
int c_statement = area->statement(); int c_statement = area->statement();
area->setTestimonyRecording(AreaData::TestimonyRecording::PLAYBACK); area->setTestimonyRecording(AreaData::TestimonyRecording::PLAYBACK);
if (c_statement <= 0 || area->testimony()[c_statement].empty()) if (c_statement <= 0 || area->testimony()[c_statement].empty())
@ -71,11 +75,11 @@ QStringList AOClient::updateStatement(QStringList packet)
void AOClient::clearTestimony() void AOClient::clearTestimony()
{ {
AreaData* area = server->m_areas[m_current_area]; AreaData *area = server->getAreaById(m_current_area);
area->clearTestimony(); area->clearTestimony();
} }
bool AOClient::checkTestimonySymbols(const QString& message) bool AOClient::checkTestimonySymbols(const QString &message)
{ {
if (message.contains('>') || message.contains('<')) { if (message.contains('>') || message.contains('<')) {
sendServerMessage("Unable to add statements containing '>' or '<'."); sendServerMessage("Unable to add statements containing '>' or '<'.");

View File

@ -43,7 +43,7 @@ void WSClient::onTcpData()
// Workaround for WebAO bug needing every packet in its own message // Workaround for WebAO bug needing every packet in its own message
QStringList all_packets = QString::fromUtf8(tcp_message).split("%"); QStringList all_packets = QString::fromUtf8(tcp_message).split("%");
all_packets.removeLast(); // Remove empty space after final delimiter all_packets.removeLast(); // Remove empty space after final delimiter
for(const QString &packet : qAsConst(all_packets)) { for (const QString &packet : qAsConst(all_packets)) {
web_socket->sendTextMessage(packet + "%"); web_socket->sendTextMessage(packet + "%");
} }
} }
@ -65,15 +65,15 @@ void WSClient::onTcpConnect()
tcp_socket->flush(); tcp_socket->flush();
} }
WSClient::WSClient(QTcpSocket *p_tcp_socket, QWebSocket *p_web_socket, QObject *parent) WSClient::WSClient(QTcpSocket *p_tcp_socket, QWebSocket *p_web_socket, QObject *parent) :
: QObject(parent), QObject(parent),
tcp_socket(p_tcp_socket), tcp_socket(p_tcp_socket),
web_socket(p_web_socket) web_socket(p_web_socket)
{ {
bool l_is_local = web_socket->peerAddress() == QHostAddress::LocalHost | bool l_is_local = (web_socket->peerAddress() == QHostAddress::LocalHost) ||
web_socket->peerAddress() == QHostAddress::LocalHostIPv6; (web_socket->peerAddress() == QHostAddress::LocalHostIPv6);
//TLDR : We check if the header comes trough a proxy/tunnel running locally. // TLDR : We check if the header comes trough a proxy/tunnel running locally.
//This is to ensure nobody can send those headers from the web. // This is to ensure nobody can send those headers from the web.
QNetworkRequest l_request = web_socket->request(); QNetworkRequest l_request = web_socket->request();
if (l_request.hasRawHeader("x-forwarded-for") && l_is_local) { if (l_request.hasRawHeader("x-forwarded-for") && l_is_local) {
websocket_ip = l_request.rawHeader("x-forwarded-for"); websocket_ip = l_request.rawHeader("x-forwarded-for");

View File

@ -17,7 +17,9 @@
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
#include "include/ws_proxy.h" #include "include/ws_proxy.h"
WSProxy::WSProxy(int p_local_port, int p_ws_port, QObject* parent) : #include "include/ws_client.h"
WSProxy::WSProxy(int p_local_port, int p_ws_port, QObject *parent) :
QObject(parent), QObject(parent),
local_port(p_local_port), local_port(p_local_port),
ws_port(p_ws_port) ws_port(p_ws_port)
@ -30,18 +32,19 @@ WSProxy::WSProxy(int p_local_port, int p_ws_port, QObject* parent) :
void WSProxy::start() void WSProxy::start()
{ {
if(!server->listen(QHostAddress::Any, ws_port)) { if (!server->listen(QHostAddress::Any, ws_port)) {
qDebug() << "WebSocket proxy failed to start: " << server->errorString(); qDebug() << "WebSocket proxy failed to start: " << server->errorString();
} else { }
else {
qDebug() << "WebSocket proxy listening"; qDebug() << "WebSocket proxy listening";
} }
} }
void WSProxy::wsConnected() void WSProxy::wsConnected()
{ {
QWebSocket* new_ws = server->nextPendingConnection(); QWebSocket *new_ws = server->nextPendingConnection();
QTcpSocket* new_tcp = new QTcpSocket(this); QTcpSocket *new_tcp = new QTcpSocket(this);
WSClient* client = new WSClient(new_tcp, new_ws, this); WSClient *client = new WSClient(new_tcp, new_ws, this);
clients.append(client); clients.append(client);
connect(new_ws, &QWebSocket::textMessageReceived, client, &WSClient::onWsData); connect(new_ws, &QWebSocket::textMessageReceived, client, &WSClient::onWsData);

View File

@ -14,13 +14,13 @@ class Area : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
/** /**
* @brief An AreaData pointer to test with. * @brief An AreaData pointer to test with.
*/ */
AreaData* m_area; AreaData *m_area;
private slots: private slots:
/** /**
* @brief Initialises every tests with creating a new area with the title "Test Area", and the index of 0. * @brief Initialises every tests with creating a new area with the title "Test Area", and the index of 0.
*/ */
@ -78,14 +78,14 @@ void Area::clientJoinLeave()
{ {
{ {
// There must be exactly one client in the area, and it must have a charid of 5 and userid 0. // There must be exactly one client in the area, and it must have a charid of 5 and userid 0.
m_area->clientJoinedArea(5,0); m_area->clientJoinedArea(5, 0);
QCOMPARE(m_area->joinedIDs().size(), 1); QCOMPARE(m_area->joinedIDs().size(), 1);
QCOMPARE(m_area->charactersTaken().at(0), 5); QCOMPARE(m_area->charactersTaken().at(0), 5);
} }
{ {
// No clients must be left in the area. // No clients must be left in the area.
m_area->clientLeftArea(5,0); m_area->clientLeftArea(5, 0);
QCOMPARE(m_area->joinedIDs().size(), 0); QCOMPARE(m_area->joinedIDs().size(), 0);
} }
@ -143,7 +143,8 @@ void Area::changeHP()
if (AreaData::Side::DEFENCE == side) { if (AreaData::Side::DEFENCE == side) {
QCOMPARE(expectedHP, m_area->defHP()); QCOMPARE(expectedHP, m_area->defHP());
} else { }
else {
QCOMPARE(expectedHP, m_area->proHP()); QCOMPARE(expectedHP, m_area->proHP());
} }
} }
@ -152,7 +153,7 @@ void Area::changeCharacter()
{ {
{ {
// A client with a charid of 6 and userid 0 joins. There's only them in there. // A client with a charid of 6 and userid 0 joins. There's only them in there.
m_area->clientJoinedArea(6,0); m_area->clientJoinedArea(6, 0);
QCOMPARE(m_area->charactersTaken().size(), 1); QCOMPARE(m_area->charactersTaken().size(), 1);
QCOMPARE(m_area->charactersTaken().at(0), 6); QCOMPARE(m_area->charactersTaken().at(0), 6);
@ -211,8 +212,7 @@ void Area::testimony()
{ {
// Add all statements, and check that they're added. // Add all statements, and check that they're added.
for (const auto& l_statement : l_testimony) for (const auto &l_statement : l_testimony) {
{
m_area->recordStatement(l_statement); m_area->recordStatement(l_statement);
QCOMPARE(l_statement, m_area->testimony().at(m_area->statement() - 1)); QCOMPARE(l_statement, m_area->testimony().at(m_area->statement() - 1));
@ -223,7 +223,7 @@ void Area::testimony()
m_area->jumpToStatement(1); m_area->jumpToStatement(1);
for (int i = 1; i < l_testimony.size() - 1; i++) { for (int i = 1; i < l_testimony.size() - 1; i++) {
const auto& l_results = m_area->jumpToStatement(m_area->statement() + 1); const auto &l_results = m_area->jumpToStatement(m_area->statement() + 1);
QCOMPARE(l_results.first, l_testimony.at(i + 1)); QCOMPARE(l_results.first, l_testimony.at(i + 1));
QCOMPARE(l_results.second, AreaData::TestimonyProgress::OK); QCOMPARE(l_results.second, AreaData::TestimonyProgress::OK);
@ -231,14 +231,14 @@ void Area::testimony()
} }
{ {
// Next advancement loops the testimony. // Next advancement loops the testimony.
const auto& l_results = m_area->jumpToStatement(m_area->statement() + 1); const auto &l_results = m_area->jumpToStatement(m_area->statement() + 1);
QCOMPARE(l_results.first, l_testimony.at(1)); QCOMPARE(l_results.first, l_testimony.at(1));
QCOMPARE(l_results.second, AreaData::TestimonyProgress::LOOPED); QCOMPARE(l_results.second, AreaData::TestimonyProgress::LOOPED);
} }
{ {
// Going back makes the testimony stay at the first statement. // Going back makes the testimony stay at the first statement.
const auto& l_results = m_area->jumpToStatement(m_area->statement() - 1); const auto &l_results = m_area->jumpToStatement(m_area->statement() - 1);
QCOMPARE(l_results.first, l_testimony.at(1)); QCOMPARE(l_results.first, l_testimony.at(1));
QCOMPARE(l_results.second, AreaData::TestimonyProgress::STAYED_AT_FIRST); QCOMPARE(l_results.second, AreaData::TestimonyProgress::STAYED_AT_FIRST);

View File

@ -11,11 +11,11 @@ namespace unittests {
class MusicListManager : public QObject class MusicListManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public :
MusicManager* m_music_manager; public:
MusicManager *m_music_manager;
private slots: private slots:
/** /**
* @brief Initialises every tests with creating a new MusicManager with a small sample root list. * @brief Initialises every tests with creating a new MusicManager with a small sample root list.
*/ */
@ -70,56 +70,56 @@ private slots:
* @brief Tests the retrieval of the full musiclist for an area. * @brief Tests the retrieval of the full musiclist for an area.
*/ */
void musiclist(); void musiclist();
}; };
void MusicListManager::init() void MusicListManager::init()
{ {
QMap<QString,QPair<QString,int>> l_test_list; QMap<QString, QPair<QString, int>> l_test_list;
l_test_list.insert("==Music==",{"==Music==",0}); l_test_list.insert("==Music==", {"==Music==", 0});
l_test_list.insert("Announce The Truth (AJ).opus",{"Announce The Truth (AJ).opus",59}); l_test_list.insert("Announce The Truth (AJ).opus", {"Announce The Truth (AJ).opus", 59});
l_test_list.insert("Announce The Truth (JFA).opus",{"Announce The Truth (JFA).opus",98}); l_test_list.insert("Announce The Truth (JFA).opus", {"Announce The Truth (JFA).opus", 98});
QStringList l_list = {}; QStringList l_list = {};
l_list << "==Music==" << "Announce The Truth (AJ).opus" << "Announce The Truth (JFA).opus"; l_list << "==Music=="
<< "Announce The Truth (AJ).opus"
<< "Announce The Truth (JFA).opus";
m_music_manager = new MusicManager(nullptr, l_list ,{"my.cdn.com","your.cdn.com"}, l_test_list); m_music_manager = new MusicManager(l_list, {"my.cdn.com", "your.cdn.com"}, l_test_list, nullptr);
} }
void MusicListManager::registerArea() void MusicListManager::registerArea()
{ {
{ {
//We register a single area with the music manager of ID 0. // We register a single area with the music manager of ID 0.
//Creation should work as there are no other areas yet. // Creation should work as there are no other areas yet.
bool l_creation_success = m_music_manager->registerArea(0); bool l_creation_success = m_music_manager->registerArea(0);
QCOMPARE(l_creation_success,true); QCOMPARE(l_creation_success, true);
} }
{ {
//Someone tries to register the same area again! // Someone tries to register the same area again!
//This should fail as this area already exists. // This should fail as this area already exists.
bool l_creation_success = m_music_manager->registerArea(0); bool l_creation_success = m_music_manager->registerArea(0);
QCOMPARE(l_creation_success,false); QCOMPARE(l_creation_success, false);
} }
} }
void MusicListManager::toggleRootEnabled() void MusicListManager::toggleRootEnabled()
{ {
{ {
//We register an area of ID0 and toggle the inclusion of global list. // We register an area of ID0 and toggle the inclusion of global list.
m_music_manager->registerArea(0); m_music_manager->registerArea(0);
QCOMPARE(m_music_manager->toggleRootEnabled(0), false); QCOMPARE(m_music_manager->toggleRootEnabled(0), false);
} }
{ {
//We toggle it again. It should return true now. // We toggle it again. It should return true now.
//Since this is now true, we should have the root list with customs cleared. // Since this is now true, we should have the root list with customs cleared.
QCOMPARE(m_music_manager->toggleRootEnabled(0), true); QCOMPARE(m_music_manager->toggleRootEnabled(0), true);
} }
} }
void MusicListManager::validateSong_data() void MusicListManager::validateSong_data()
{ {
//Songname can also be the realname. // Songname can also be the realname.
QTest::addColumn<QString>("songname"); QTest::addColumn<QString>("songname");
QTest::addColumn<bool>("expectedResult"); QTest::addColumn<bool>("expectedResult");
@ -137,47 +137,47 @@ void MusicListManager::validateSong_data()
void MusicListManager::validateSong() void MusicListManager::validateSong()
{ {
QFETCH(QString,songname); QFETCH(QString, songname);
QFETCH(bool,expectedResult); QFETCH(bool, expectedResult);
bool l_result = m_music_manager->validateSong(songname, {"my.cdn.com","your.cdn.com"}); bool l_result = m_music_manager->validateSong(songname, {"my.cdn.com", "your.cdn.com"});
QCOMPARE(expectedResult,l_result); QCOMPARE(expectedResult, l_result);
} }
void MusicListManager::addCustomSong() void MusicListManager::addCustomSong()
{ {
{ {
//Dummy register. // Dummy register.
m_music_manager->registerArea(0); m_music_manager->registerArea(0);
//No custom songs, so musiclist = root_list.size() // No custom songs, so musiclist = root_list.size()
QCOMPARE(m_music_manager->musiclist(0).size(), 3); QCOMPARE(m_music_manager->musiclist(0).size(), 3);
} }
{ {
//Add a song that's valid. The musiclist is now root_list.size() + custom_list.size() // Add a song that's valid. The musiclist is now root_list.size() + custom_list.size()
m_music_manager->addCustomSong("mysong","mysong.opus",0,0); m_music_manager->addCustomSong("mysong", "mysong.opus", 0, 0);
QCOMPARE(m_music_manager->musiclist(0).size(), 4); QCOMPARE(m_music_manager->musiclist(0).size(), 4);
} }
{ {
//Add a song that's part of the root list. This should fail and not increase the size. // Add a song that's part of the root list. This should fail and not increase the size.
bool l_result = m_music_manager->addCustomSong("Announce The Truth (AJ)","Announce The Truth (AJ).opus",0,0); bool l_result = m_music_manager->addCustomSong("Announce The Truth (AJ)", "Announce The Truth (AJ).opus", 0, 0);
QCOMPARE(l_result,false); QCOMPARE(l_result, false);
QCOMPARE(m_music_manager->musiclist(0).size(), 4); QCOMPARE(m_music_manager->musiclist(0).size(), 4);
} }
{ {
//Disable the root list. Musiclist is now custom_list.size() // Disable the root list. Musiclist is now custom_list.size()
m_music_manager->toggleRootEnabled(0); m_music_manager->toggleRootEnabled(0);
QCOMPARE(m_music_manager->musiclist(0).size(), 1); QCOMPARE(m_music_manager->musiclist(0).size(), 1);
} }
{ {
//Add an item that is in the root list into the custom list. Size is still custom_list.size() // Add an item that is in the root list into the custom list. Size is still custom_list.size()
bool l_result = m_music_manager->addCustomSong("Announce The Truth (AJ)","Announce The Truth (AJ).opus",0,0); bool l_result = m_music_manager->addCustomSong("Announce The Truth (AJ)", "Announce The Truth (AJ).opus", 0, 0);
QCOMPARE(l_result,true); QCOMPARE(l_result, true);
QCOMPARE(m_music_manager->musiclist(0).size(), 2); QCOMPARE(m_music_manager->musiclist(0).size(), 2);
} }
{ {
bool l_result = m_music_manager->addCustomSong("Announce The Truth (AJ)2","https://my.cdn.com/mysong.opus",0,0); bool l_result = m_music_manager->addCustomSong("Announce The Truth (AJ)2", "https://my.cdn.com/mysong.opus", 0, 0);
QCOMPARE(l_result,true); QCOMPARE(l_result, true);
QCOMPARE(m_music_manager->musiclist(0).size(), 3); QCOMPARE(m_music_manager->musiclist(0).size(), 3);
} }
} }
@ -185,93 +185,91 @@ void MusicListManager::addCustomSong()
void MusicListManager::addCustomCategory() void MusicListManager::addCustomCategory()
{ {
{ {
//Dummy register. // Dummy register.
m_music_manager->registerArea(0); m_music_manager->registerArea(0);
//Add category to the custom list. Category marker are added manually. // Add category to the custom list. Category marker are added manually.
bool l_result = m_music_manager->addCustomCategory("Music2",0); bool l_result = m_music_manager->addCustomCategory("Music2", 0);
QCOMPARE(l_result,true); QCOMPARE(l_result, true);
QCOMPARE(m_music_manager->musiclist(0).size(), 4); QCOMPARE(m_music_manager->musiclist(0).size(), 4);
QCOMPARE(m_music_manager->musiclist(0).at(3), "==Music2=="); QCOMPARE(m_music_manager->musiclist(0).at(3), "==Music2==");
} }
{ {
//Add a category that already exists on root. This should fail and not increase the size of our list. // Add a category that already exists on root. This should fail and not increase the size of our list.
bool l_result = m_music_manager->addCustomCategory("Music",0); bool l_result = m_music_manager->addCustomCategory("Music", 0);
QCOMPARE(l_result, false); QCOMPARE(l_result, false);
QCOMPARE(m_music_manager->musiclist(0).size(), 4); QCOMPARE(m_music_manager->musiclist(0).size(), 4);
} }
{ {
//We disable the root list. We now insert the category again. // We disable the root list. We now insert the category again.
m_music_manager->toggleRootEnabled(0); m_music_manager->toggleRootEnabled(0);
bool l_result = m_music_manager->addCustomCategory("Music",0); bool l_result = m_music_manager->addCustomCategory("Music", 0);
QCOMPARE(l_result, true); QCOMPARE(l_result, true);
QCOMPARE(m_music_manager->musiclist(0).size(), 2); QCOMPARE(m_music_manager->musiclist(0).size(), 2);
QCOMPARE(m_music_manager->musiclist(0).at(1), "==Music=="); QCOMPARE(m_music_manager->musiclist(0).at(1), "==Music==");
} }
{ {
//Global now enabled. We add a song with three ===. // Global now enabled. We add a song with three ===.
m_music_manager->toggleRootEnabled(0); m_music_manager->toggleRootEnabled(0);
bool l_result = m_music_manager->addCustomCategory("===Music===",0); bool l_result = m_music_manager->addCustomCategory("===Music===", 0);
QCOMPARE(l_result, true); QCOMPARE(l_result, true);
QCOMPARE(m_music_manager->musiclist(0).size(), 5); QCOMPARE(m_music_manager->musiclist(0).size(), 5);
QCOMPARE(m_music_manager->musiclist(0).at(4), "===Music==="); QCOMPARE(m_music_manager->musiclist(0).at(4), "===Music===");
} }
} }
void MusicListManager::sanitiseCustomList() void MusicListManager::sanitiseCustomList()
{ {
//Prepare a dummy area with root list disabled.Insert both non-root and root elements. // Prepare a dummy area with root list disabled.Insert both non-root and root elements.
m_music_manager->registerArea(0); m_music_manager->registerArea(0);
m_music_manager->toggleRootEnabled(0); m_music_manager->toggleRootEnabled(0);
m_music_manager->addCustomCategory("Music",0); m_music_manager->addCustomCategory("Music", 0);
m_music_manager->addCustomCategory("Music2",0); m_music_manager->addCustomCategory("Music2", 0);
m_music_manager->addCustomSong("Announce The Truth (AJ)","Announce The Truth (AJ).opus",0,0); m_music_manager->addCustomSong("Announce The Truth (AJ)", "Announce The Truth (AJ).opus", 0, 0);
m_music_manager->addCustomSong("mysong","mysong.opus",0,0); m_music_manager->addCustomSong("mysong", "mysong.opus", 0, 0);
//We now only have custom elements. // We now only have custom elements.
QCOMPARE(m_music_manager->musiclist(0).size(), 4); QCOMPARE(m_music_manager->musiclist(0).size(), 4);
//We reenable the root list. Sanisation should only leave the non-root elements in the custom list. // We reenable the root list. Sanisation should only leave the non-root elements in the custom list.
m_music_manager->toggleRootEnabled(0); m_music_manager->toggleRootEnabled(0);
QCOMPARE(m_music_manager->musiclist(0).size(), 5); QCOMPARE(m_music_manager->musiclist(0).size(), 5);
QCOMPARE(m_music_manager->musiclist(0).at(3), "==Music2=="); QCOMPARE(m_music_manager->musiclist(0).at(3), "==Music2==");
QCOMPARE(m_music_manager->musiclist(0).at(4), "mysong.opus"); QCOMPARE(m_music_manager->musiclist(0).at(4), "mysong.opus");
} }
void MusicListManager::removeCategorySong() void MusicListManager::removeCategorySong()
{ {
{ {
//Prepare dummy area. Add both custom songs and categories. // Prepare dummy area. Add both custom songs and categories.
m_music_manager->registerArea(0); m_music_manager->registerArea(0);
m_music_manager->addCustomCategory("Music2",0); m_music_manager->addCustomCategory("Music2", 0);
m_music_manager->addCustomSong("mysong","mysong.opus",0,0); m_music_manager->addCustomSong("mysong", "mysong.opus", 0, 0);
m_music_manager->addCustomCategory("Music3",0); m_music_manager->addCustomCategory("Music3", 0);
m_music_manager->addCustomSong("mysong2","mysong.opus",0,0); m_music_manager->addCustomSong("mysong2", "mysong.opus", 0, 0);
QCOMPARE(m_music_manager->musiclist(0).size(), 7); QCOMPARE(m_music_manager->musiclist(0).size(), 7);
} }
{ {
//Delete a category that is not custom. This should fail. // Delete a category that is not custom. This should fail.
bool l_success = m_music_manager->removeCategorySong("==Music==",0); bool l_success = m_music_manager->removeCategorySong("==Music==", 0);
QCOMPARE(l_success, false); QCOMPARE(l_success, false);
QCOMPARE(m_music_manager->musiclist(0).size(), 7); QCOMPARE(m_music_manager->musiclist(0).size(), 7);
} }
{ {
//Correct category name, wrong format. // Correct category name, wrong format.
bool l_success = m_music_manager->removeCategorySong("Music2",0); bool l_success = m_music_manager->removeCategorySong("Music2", 0);
QCOMPARE(l_success, false); QCOMPARE(l_success, false);
QCOMPARE(m_music_manager->musiclist(0).size(), 7); QCOMPARE(m_music_manager->musiclist(0).size(), 7);
} }
{ {
//Correct category name. This should be removed. // Correct category name. This should be removed.
bool l_success = m_music_manager->removeCategorySong("==Music2==",0); bool l_success = m_music_manager->removeCategorySong("==Music2==", 0);
QCOMPARE(l_success, true); QCOMPARE(l_success, true);
QCOMPARE(m_music_manager->musiclist(0).size(), 6); QCOMPARE(m_music_manager->musiclist(0).size(), 6);
} }
{ {
//Correct song name. This should be removed. This needs to be with the extension. // Correct song name. This should be removed. This needs to be with the extension.
bool l_success = m_music_manager->removeCategorySong("mysong2.opus",0); bool l_success = m_music_manager->removeCategorySong("mysong2.opus", 0);
QCOMPARE(l_success, true); QCOMPARE(l_success, true);
QCOMPARE(m_music_manager->musiclist(0).size(), 5); QCOMPARE(m_music_manager->musiclist(0).size(), 5);
} }
@ -280,20 +278,20 @@ void MusicListManager::removeCategorySong()
void MusicListManager::songInformation() void MusicListManager::songInformation()
{ {
{ {
//Prepare dummy area. Add both custom songs and categories. // Prepare dummy area. Add both custom songs and categories.
m_music_manager->registerArea(0); m_music_manager->registerArea(0);
m_music_manager->addCustomCategory("Music2",0); m_music_manager->addCustomCategory("Music2", 0);
m_music_manager->addCustomSong("mysong","realmysong.opus",47,0); m_music_manager->addCustomSong("mysong", "realmysong.opus", 47, 0);
m_music_manager->addCustomCategory("Music3",0); m_music_manager->addCustomCategory("Music3", 0);
m_music_manager->addCustomSong("mysong2","mysong.opus",42,0); m_music_manager->addCustomSong("mysong2", "mysong.opus", 42, 0);
} }
{ {
QPair<QString,int> l_song_information = m_music_manager->songInformation("mysong.opus",0); QPair<QString, int> l_song_information = m_music_manager->songInformation("mysong.opus", 0);
QCOMPARE(l_song_information.first, "realmysong.opus"); QCOMPARE(l_song_information.first, "realmysong.opus");
QCOMPARE(l_song_information.second, 47); QCOMPARE(l_song_information.second, 47);
} }
{ {
QPair<QString,int> l_song_information = m_music_manager->songInformation("Announce The Truth (AJ).opus",0); QPair<QString, int> l_song_information = m_music_manager->songInformation("Announce The Truth (AJ).opus", 0);
QCOMPARE(l_song_information.first, "Announce The Truth (AJ).opus"); QCOMPARE(l_song_information.first, "Announce The Truth (AJ).opus");
QCOMPARE(l_song_information.second, 59); QCOMPARE(l_song_information.second, 59);
} }
@ -302,12 +300,12 @@ void MusicListManager::songInformation()
void MusicListManager::musiclist() void MusicListManager::musiclist()
{ {
{ {
//Prepare dummy area. Add both custom songs and categories. // Prepare dummy area. Add both custom songs and categories.
m_music_manager->registerArea(0); m_music_manager->registerArea(0);
m_music_manager->addCustomCategory("Music2",0); m_music_manager->addCustomCategory("Music2", 0);
m_music_manager->addCustomSong("mysong","realmysong.opus",47,0); m_music_manager->addCustomSong("mysong", "realmysong.opus", 47, 0);
m_music_manager->addCustomCategory("Music3",0); m_music_manager->addCustomCategory("Music3", 0);
m_music_manager->addCustomSong("mysong2","mysong.opus",42,0); m_music_manager->addCustomSong("mysong2", "mysong.opus", 42, 0);
} }
{ {
QCOMPARE(m_music_manager->musiclist(0).size(), 7); QCOMPARE(m_music_manager->musiclist(0).size(), 7);