
Set a hard limit on 30KB that the server is willing to read, over two sequential reads. If the client sends more than 30KB combined, the server will disconnect the client.
2060 lines
72 KiB
C++
2060 lines
72 KiB
C++
//////////////////////////////////////////////////////////////////////////////////////
|
|
// akashi - a server for Attorney Online 2 //
|
|
// Copyright (C) 2020 scatterflower //
|
|
// //
|
|
// This program is free software: you can redistribute it and/or modify //
|
|
// it under the terms of the GNU Affero General Public License as //
|
|
// published by the Free Software Foundation, either version 3 of the //
|
|
// License, or (at your option) any later version. //
|
|
// //
|
|
// This program is distributed in the hope that it will be useful, //
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
|
// GNU Affero General Public License for more details. //
|
|
// //
|
|
// 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/>. //
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
#ifndef AOCLIENT_H
|
|
#define AOCLIENT_H
|
|
|
|
#include "include/aopacket.h"
|
|
#include "include/server.h"
|
|
#include "include/area_data.h"
|
|
#include "include/db_manager.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <QHostAddress>
|
|
#include <QTcpSocket>
|
|
#include <QDateTime>
|
|
#include <QRegularExpression>
|
|
#include <QtGlobal>
|
|
#if QT_VERSION > QT_VERSION_CHECK(5, 10, 0)
|
|
#include <QRandomGenerator>
|
|
#endif
|
|
|
|
class Server;
|
|
|
|
/**
|
|
* @brief Represents a client connected to the server running Attorney Online 2 or one of its derivatives.
|
|
*/
|
|
class AOClient : public QObject {
|
|
Q_OBJECT
|
|
public:
|
|
/**
|
|
* @brief Creates an instance of the AOClient class.
|
|
*
|
|
* @param p_server A pointer to the Server instance where the client is joining to.
|
|
* @param p_socket The socket associated with the AOClient.
|
|
* @param user_id The user ID of the client.
|
|
* @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)
|
|
: QObject(parent), id(user_id), remote_ip(p_socket->peerAddress()), password(""),
|
|
joined(false), current_area(0), current_char(""), socket(p_socket), server(p_server),
|
|
is_partial(false), last_wtce_time(0) {
|
|
afk_timer = new QTimer;
|
|
afk_timer->setSingleShot(true);
|
|
connect(afk_timer, SIGNAL(timeout()), this, SLOT(onAfkTimeout()));
|
|
};
|
|
|
|
/**
|
|
* @brief Destructor for the AOClient instance.
|
|
*
|
|
* @details Sets the socket to delete later.
|
|
*/
|
|
~AOClient();
|
|
|
|
/**
|
|
* @brief Getter for the client's IPID.
|
|
*
|
|
* @return The IPID.
|
|
*
|
|
* @see #ipid
|
|
*/
|
|
QString getIpid();
|
|
|
|
/**
|
|
* @brief Calculates the client's IPID based on a hashed version of its IP.
|
|
*/
|
|
void calculateIpid();
|
|
|
|
/**
|
|
* @brief Getter for the pointer to the server.
|
|
*
|
|
* @return See brief description.
|
|
*
|
|
* @note Unused. There isn't really a point to this existing, either.
|
|
*
|
|
* @see #server
|
|
*/
|
|
Server* getServer();
|
|
|
|
/**
|
|
* @brief The user ID of the client.
|
|
*/
|
|
int id;
|
|
|
|
/**
|
|
* @brief The IP address of the client.
|
|
*/
|
|
QHostAddress remote_ip;
|
|
|
|
/**
|
|
* @brief The stored character password for the client, used to be able to select passworded characters.
|
|
*/
|
|
QString password;
|
|
|
|
/**
|
|
* @brief True if the client is actually in the server.
|
|
*
|
|
* @details To explain: In AO, clients immediately establish connection to the server when the user clicks on the server's name in the server
|
|
* browser. Thus, as the user browses servers, they constantly connect and disconnect to and from servers.
|
|
*
|
|
* The purpose of this variable is to determine if the user isn't just doing that, but has actually double-clicked the server, and
|
|
* its client has sent the standard handshake packets, which does signify that the client intended to 'join' this server.
|
|
*/
|
|
bool joined;
|
|
|
|
/**
|
|
* @brief The ID of the area the client is currently in.
|
|
*/
|
|
int current_area;
|
|
|
|
/**
|
|
* @brief The internal name of the character the client is currently using.
|
|
*/
|
|
QString current_char;
|
|
|
|
/**
|
|
* @brief The internal name of the character the client is iniswapped to.
|
|
*
|
|
* @note This will be the same as current_char if the client is not iniswapped.
|
|
*/
|
|
QString current_iniswap;
|
|
|
|
/**
|
|
* @brief If true, the client is a logged-in moderator.
|
|
*/
|
|
bool authenticated = false;
|
|
|
|
/**
|
|
* @brief If using advanced authentication, this is the moderator name that the client has logged in with.
|
|
*/
|
|
QString moderator_name = "";
|
|
|
|
/**
|
|
* @brief The out-of-character name of the client, generally the nickname of the user themself.
|
|
*/
|
|
QString ooc_name = "";
|
|
|
|
/**
|
|
* @brief The custom showname of the client, used when "renaming" already existing characters in-character.
|
|
*/
|
|
QString showname = "";
|
|
|
|
/**
|
|
* @brief If true, the client is willing to receive global messages.
|
|
*
|
|
* @see AOClient::cmdG and AOClient::cmdToggleGlobal
|
|
*/
|
|
bool global_enabled = true;
|
|
|
|
/**
|
|
* @brief If true, the client may not use in-character chat.
|
|
*/
|
|
bool is_muted = false;
|
|
|
|
/**
|
|
* @brief If true, the client may not use out-of-character chat.
|
|
*/
|
|
bool is_ooc_muted = false;
|
|
|
|
/**
|
|
* @brief If true, the client may not use the music list.
|
|
*/
|
|
bool is_dj_blocked = false;
|
|
|
|
/**
|
|
* @brief If true, the client may not use the judge controls.
|
|
*/
|
|
bool is_wtce_blocked = false;
|
|
|
|
/**
|
|
* @brief Represents the client's client software, and its version.
|
|
*
|
|
* @note Though the version number and naming scheme looks vaguely semver-like,
|
|
* do not be misled into thinking it is that.
|
|
*/
|
|
struct ClientVersion {
|
|
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 major = -1; //!< The 'major' part of the version number. In Attorney Online's case, this increases when a new feature is introduced (generally).
|
|
int minor = -1; //!< The 'minor' part of the version number. In Attorney Online's case, this increases for bugfix releases (generally).
|
|
};
|
|
|
|
/**
|
|
* @brief The software and version of the client.
|
|
*
|
|
* @see The struct itself for more details.
|
|
*/
|
|
ClientVersion version;
|
|
|
|
/**
|
|
* @brief The authorisation bitflag, representing what permissions a client can have.
|
|
*
|
|
* @showinitializer
|
|
*/
|
|
QMap<QString, unsigned long long> ACLFlags {
|
|
{"NONE", 0ULL },
|
|
{"KICK", 1ULL << 0 },
|
|
{"BAN", 1ULL << 1 },
|
|
{"BGLOCK", 1ULL << 2 },
|
|
{"MODIFY_USERS", 1ULL << 3 },
|
|
{"CM", 1ULL << 4 },
|
|
{"GLOBAL_TIMER", 1ULL << 5 },
|
|
{"EVI_MOD", 1ULL << 6 },
|
|
{"MOTD", 1ULL << 7 },
|
|
{"ANNOUNCE", 1ULL << 8 },
|
|
{"MODCHAT", 1ULL << 9 },
|
|
{"MUTE", 1ULL << 10},
|
|
{"UNCM", 1ULL << 11},
|
|
{"SAVETEST", 1ULL << 12},
|
|
{"FORCE_CHARSELECT",1ULL << 13},
|
|
{"SUPER", ~0ULL }
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief A list of 5 casing preferences (def, pro, judge, jury, steno)
|
|
*/
|
|
QList<bool> casing_preferences = {false, false, false, false, false};
|
|
|
|
/**
|
|
* @brief If true, the client's in-character messages will have their word order randomised.
|
|
*/
|
|
bool is_shaken = false;
|
|
|
|
/**
|
|
* @brief If true, the client's in-character messages will have their vowels (English alphabet only) removed.
|
|
*/
|
|
bool is_disemvoweled = false;
|
|
|
|
/**
|
|
* @brief If true, the client's in-character messages will be overwritten by a randomly picked predetermined message.
|
|
*/
|
|
bool is_gimped = false;
|
|
|
|
/**
|
|
* @brief If true, the client will be marked as AFK in /getarea. Automatically applied when a configurable
|
|
* amount of time has passed since the last interaction, or manually applied by /afk.
|
|
*/
|
|
bool is_afk = false;
|
|
|
|
/**
|
|
* @brief If true, the client will not recieve PM messages.
|
|
*/
|
|
bool pm_mute = false;
|
|
|
|
/**
|
|
* @brief If true, the client will recieve advertisements.
|
|
*/
|
|
bool advert_enabled = true;
|
|
|
|
/**
|
|
* @brief If true, the client is restricted to only changing into certain characters.
|
|
*/
|
|
bool is_charcursed = false;
|
|
|
|
/**
|
|
* @brief Timer for tracking user interaction. Automatically restarted whenever a user interacts (i.e. sends any packet besides CH)
|
|
*/
|
|
QTimer* afk_timer;
|
|
|
|
/**
|
|
* @brief The list of char IDs a charcursed player is allowed to switch to.
|
|
*/
|
|
QList<int> charcurse_list;
|
|
|
|
/**
|
|
* @brief Temporary client permission if client is allowed to save a testimony to server storage.
|
|
*/
|
|
bool testimony_saving = false;
|
|
|
|
public slots:
|
|
/**
|
|
* @brief A slot for when the client disconnects from the server.
|
|
*/
|
|
void clientDisconnected();
|
|
|
|
/**
|
|
* @brief A slot for when the client sends data to the server.
|
|
*/
|
|
void clientData();
|
|
|
|
/**
|
|
* @brief A slot for sending a packet to the client.
|
|
*
|
|
* @param packet The packet to send.
|
|
*/
|
|
void sendPacket(AOPacket packet);
|
|
|
|
/**
|
|
* @overload
|
|
*/
|
|
void sendPacket(QString header, QStringList contents);
|
|
|
|
/**
|
|
* @overload
|
|
*/
|
|
void sendPacket(QString header);
|
|
|
|
/**
|
|
* @brief A slot for when the client's AFK timer runs out.
|
|
*/
|
|
void onAfkTimeout();
|
|
|
|
private:
|
|
/**
|
|
* @brief The TCP socket used to communicate with the client.
|
|
*/
|
|
QTcpSocket* 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).
|
|
*/
|
|
Server* server;
|
|
|
|
/**
|
|
* @brief The type of area update, used for area update (ARUP) packets.
|
|
*/
|
|
enum ARUPType {
|
|
PLAYER_COUNT, //!< The packet contains player count updates.
|
|
STATUS, //!< The packet contains area status updates.
|
|
CM, //!< The packet contains updates about who's the CM of what area.
|
|
LOCKED //!< The packet contains updates about what areas are locked.
|
|
};
|
|
|
|
/**
|
|
* @brief Handles an incoming packet, checking for authorisation and minimum argument count.
|
|
*
|
|
* @param packet The incoming packet.
|
|
*/
|
|
void handlePacket(AOPacket packet);
|
|
|
|
/**
|
|
* @brief Handles an incoming command, checking for authorisation and minimum argument count.
|
|
*
|
|
* @param command The incoming command.
|
|
* @param argc The amount of arguments the command was called with. Equivalent to `argv.size()`.
|
|
* @param argv The arguments the command was called with.
|
|
*/
|
|
void handleCommand(QString command, int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Changes the area the client is in.
|
|
*
|
|
* @param new_area The ID of the new area.
|
|
*/
|
|
void changeArea(int new_area);
|
|
|
|
/**
|
|
* @brief Changes the client's character.
|
|
*
|
|
* @param char_id The character ID of the client's new character.
|
|
*/
|
|
bool changeCharacter(int char_id);
|
|
|
|
/**
|
|
* @brief Changes the client's in-character position.
|
|
*
|
|
* @param new_pos The new position of the client.
|
|
*/
|
|
void changePosition(QString new_pos);
|
|
|
|
/**
|
|
* @brief Sends or announces an ARUP update.
|
|
*
|
|
* @param type The type of ARUP to send.
|
|
* @param broadcast If true, the update is sent out to all clients on the server. If false, it is only sent to this client.
|
|
*
|
|
* @see AOClient::ARUPType
|
|
*/
|
|
void arup(ARUPType type, bool broadcast);
|
|
|
|
/**
|
|
* @brief Sends all four types of ARUP to the client.
|
|
*/
|
|
void fullArup();
|
|
/**
|
|
* @brief Sends an out-of-character message originating from the server to the client.
|
|
*
|
|
* @param message The text of the message to send.
|
|
*/
|
|
void sendServerMessage(QString message);
|
|
|
|
/**
|
|
* @brief Like with AOClient::sendServerMessage(), but to every client in the client's area.
|
|
*
|
|
* @param message The text of the message to send.
|
|
*/
|
|
void sendServerMessageArea(QString message);
|
|
|
|
/**
|
|
* @brief Like with AOClient::sendServerMessage(), but to every client in the server.
|
|
*
|
|
* @param message The text of the message to send.
|
|
*/
|
|
void sendServerBroadcast(QString message);
|
|
|
|
/**
|
|
* @brief Checks if the client would be authorised to something based on its necessary permissions.
|
|
*
|
|
* @param acl_mask The permissions bitflag that the client's own permissions should be checked against.
|
|
*
|
|
* @return True if the client's permissions are high enough for `acl_mask`, or higher than it.
|
|
* False if the client is missing some permissions.
|
|
*/
|
|
bool checkAuth(unsigned long long acl_mask);
|
|
|
|
/**
|
|
* @name Packet headers
|
|
*
|
|
* @details These functions implement the AO2-style packet handling.
|
|
* As these should generally be the same across server software, I see no reason to document them specifically.
|
|
*
|
|
* You can check out the AO2 network protocol for explanations.
|
|
*
|
|
* All packet handling functions share the same parameters:
|
|
*
|
|
* @param area The area the client is in. Some packets make use of the client's current area.
|
|
* @param argc The amount of arguments in the packet, not counting the header. Same as `argv.size()`.
|
|
* @param argv The arguments in the packet, once again, not counting the header.
|
|
* @param packet The... arguments in the packet. Yes, exactly the same as `argv`, just packed into an AOPacket.
|
|
*
|
|
* @see https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md for the AO2 network protocol.
|
|
*/
|
|
///@{
|
|
|
|
/// 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);
|
|
|
|
/// 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);
|
|
|
|
/**
|
|
* @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).
|
|
*/
|
|
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).
|
|
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).
|
|
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).
|
|
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).
|
|
void pktLoadingDone(AreaData* area, int argc, QStringList argv, AOPacket packet);
|
|
|
|
/**
|
|
* @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.
|
|
*/
|
|
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).
|
|
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).
|
|
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).
|
|
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).
|
|
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
|
|
* [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);
|
|
|
|
|
|
/**
|
|
* @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).
|
|
*/
|
|
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).
|
|
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.
|
|
*
|
|
* @todo Link packet details when it gets into the netcode documentation.
|
|
*/
|
|
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).
|
|
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).
|
|
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).
|
|
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).
|
|
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).
|
|
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).
|
|
void pktAnnounceCase(AreaData* area, int argc, QStringList argv, AOPacket packet);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Packet helper functions
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Calls AOClient::updateEvidenceList() for every client in the current client's area.
|
|
*
|
|
* @param area The current client's area.
|
|
*/
|
|
void sendEvidenceList(AreaData* area);
|
|
|
|
/**
|
|
* @brief Updates the evidence list in the area for the client.
|
|
*
|
|
* @param area The client's area.
|
|
*/
|
|
void updateEvidenceList(AreaData* area);
|
|
|
|
/**
|
|
* @brief Attempts to validate that hellish abomination that Attorney Online 2 calls an in-character packet.
|
|
*
|
|
* @param packet The packet to validate.
|
|
*
|
|
* @return A validated version of the input packet if it is correct, or an `"INVALID"` packet if it is not.
|
|
*/
|
|
AOPacket validateIcPacket(AOPacket packet);
|
|
|
|
/**
|
|
* @brief Removes excessive combining characters from a text.
|
|
*
|
|
* @param p_text The text to clear of its excessive combining characters.
|
|
*
|
|
* @return See brief description.
|
|
*
|
|
* @see https://en.wikipedia.org/wiki/Zalgo_text
|
|
*/
|
|
QString dezalgo(QString p_text);
|
|
|
|
/**
|
|
* @brief Checks if the client can modify the evidence in the area.
|
|
*
|
|
* @param area The client's area.
|
|
*
|
|
* @return True if the client can modify the evidence, false if not.
|
|
*/
|
|
bool checkEvidenceAccess(AreaData* area);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Packet helper global variables
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief The client's character ID.
|
|
*
|
|
* @details A character ID is just the character's index in the server's character list.
|
|
*
|
|
* In general, the client assumes that this is a continuous block starting from 0.
|
|
*/
|
|
int char_id = -1;
|
|
|
|
/**
|
|
* @brief The character ID of the other character that the client wants to pair up with.
|
|
*
|
|
* @details Though this uses character ID, a client with *that* character ID must exist in the area for the pairing to work.
|
|
* Furthermore, the owner of that character ID must also do the reverse to this client, making their `pairing_with` equal
|
|
* to this client's character ID.
|
|
*/
|
|
int pairing_with = -1;
|
|
|
|
/**
|
|
* @brief The name of the emote last used by the client. No extension.
|
|
*
|
|
* @details This is used for pairing mainly, for the server to be able to craft a smooth-looking transition from one
|
|
* paired-up client talking to the next.
|
|
*/
|
|
QString emote = "";
|
|
|
|
/**
|
|
* @brief The amount the client was last offset by.
|
|
*
|
|
* @details This used to be just a plain number ranging from -100 to 100, but then Crystal mangled it by building some extra data into it.
|
|
* Cheers, love.
|
|
*/
|
|
QString offset = "";
|
|
|
|
/**
|
|
* @brief The last flipped state of the client.
|
|
*/
|
|
QString flipping = "";
|
|
|
|
/**
|
|
* @brief The last reported position of the client.
|
|
*/
|
|
QString pos = "";
|
|
|
|
///@}
|
|
|
|
/// Describes a packet's interpretation details.
|
|
struct PacketInfo {
|
|
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.
|
|
void (AOClient::*action)(AreaData*, int, QStringList, AOPacket);
|
|
};
|
|
|
|
/**
|
|
* @property PacketInfo::action
|
|
*
|
|
* @brief A function reference that contains what the packet actually does.
|
|
*
|
|
* @param AreaData This is always just a reference to the data of the area the sender client is in. Used by some packets.
|
|
* @param int When called, this parameter will be filled with the argument count.
|
|
* @param QStringList When called, this parameter will be filled the list of arguments.
|
|
* @param AOPacket This is a duplicated version of the QStringList above, containing the same data.
|
|
*/
|
|
|
|
/**
|
|
* @brief The list of packets that the server can interpret.
|
|
*
|
|
* @showinitializer
|
|
*
|
|
* @tparam QString The header of the packet that uniquely identifies it.
|
|
* @tparam PacketInfo The details of the packet.
|
|
* See @ref PacketInfo "the type's documentation" for more details.
|
|
*/
|
|
const QMap<QString, PacketInfo> packets {
|
|
{"HI", {ACLFlags.value("NONE"), 1, &AOClient::pktHardwareId }},
|
|
{"ID", {ACLFlags.value("NONE"), 2, &AOClient::pktSoftwareId }},
|
|
{"askchaa", {ACLFlags.value("NONE"), 0, &AOClient::pktBeginLoad }},
|
|
{"RC", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestChars }},
|
|
{"RM", {ACLFlags.value("NONE"), 0, &AOClient::pktRequestMusic }},
|
|
{"RD", {ACLFlags.value("NONE"), 0, &AOClient::pktLoadingDone }},
|
|
{"PW", {ACLFlags.value("NONE"), 1, &AOClient::pktCharPassword }},
|
|
{"CC", {ACLFlags.value("NONE"), 3, &AOClient::pktSelectChar }},
|
|
{"MS", {ACLFlags.value("NONE"), 15, &AOClient::pktIcChat }},
|
|
{"CT", {ACLFlags.value("NONE"), 2, &AOClient::pktOocChat }},
|
|
{"CH", {ACLFlags.value("NONE"), 1, &AOClient::pktPing }},
|
|
{"MC", {ACLFlags.value("NONE"), 2, &AOClient::pktChangeMusic }},
|
|
{"RT", {ACLFlags.value("NONE"), 1, &AOClient::pktWtCe }},
|
|
{"HP", {ACLFlags.value("NONE"), 2, &AOClient::pktHpBar }},
|
|
{"WSIP", {ACLFlags.value("NONE"), 1, &AOClient::pktWebSocketIp }},
|
|
{"ZZ", {ACLFlags.value("NONE"), 0, &AOClient::pktModCall }},
|
|
{"PE", {ACLFlags.value("NONE"), 3, &AOClient::pktAddEvidence }},
|
|
{"DE", {ACLFlags.value("NONE"), 1, &AOClient::pktRemoveEvidence }},
|
|
{"EE", {ACLFlags.value("NONE"), 4, &AOClient::pktEditEvidence }},
|
|
{"SETCASE", {ACLFlags.value("NONE"), 7, &AOClient::pktSetCase }},
|
|
{"CASEA", {ACLFlags.value("NONE"), 6, &AOClient::pktAnnounceCase }},
|
|
};
|
|
|
|
/**
|
|
* @name Authentication
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Logs the user in as a moderator.
|
|
*
|
|
* @details If the authorisation type is `"simple"`, then this command expects one argument, the **global moderator password**.
|
|
*
|
|
* If the authorisation type is `"advanced"`, then it requires two arguments, the **moderator's username** and the **matching password**.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdLogin(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Starts the authorisation type change from `"simple"` to `"advanced"`.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdChangeAuth(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sets the root user's password.
|
|
*
|
|
* @details Accepts a single argument that will be the **root user's password**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @pre AOClient::cmdChangeAuth()
|
|
*/
|
|
void cmdSetRootPass(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Adds a user to the moderators in `"advanced"` authorisation type.
|
|
*
|
|
* @details The first argument is the **user's name**, the second is their **password**.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdAddUser(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes a user from the moderators in `"advanced"` authorisation type.
|
|
*
|
|
* @details Takes the **targer user's name** as the argument.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdRemoveUser(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Lists the permission of a given user.
|
|
*
|
|
* @details If called without argument, lists the caller's permissions.
|
|
*
|
|
* If called with one argument, **a username**, lists that user's permissions.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdListPerms(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Adds permissions to a given user.
|
|
*
|
|
* @details The first argument is the **target user**, the second is the **permission** (in string form) to add to that user.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdAddPerms(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes permissions from a given user.
|
|
*
|
|
* @details The first argument is the **target user**, the second is the **permission** (in string form) to remove from that user.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdRemovePerms(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Lists all users in the server's database.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdListUsers(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Logs the caller out from their moderator user.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdLogout(int argc, QStringList argv);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Areas
|
|
*
|
|
* @brief All functions that detail the actions of commands,
|
|
* that are also related to area management.
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Promotes a client to CM status.
|
|
*
|
|
* @details If called without arguments, promotes the caller.
|
|
*
|
|
* If called with a **user ID** as an argument, and the caller is a CM, promotes the target client to CM status.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdCM(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes the CM status from the caller.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdUnCM(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Invites a client to the area.
|
|
*
|
|
* @details Needs a **user ID** as an argument.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AreaData::LOCKED and AreaData::SPECTATABLE for the benefits of being invited.
|
|
*/
|
|
void cmdInvite(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Uninvites a client to the area.
|
|
*
|
|
* @details Needs a **user ID** as an argument.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AreaData::LOCKED and AreaData::SPECTATABLE for the benefits of being invited.
|
|
*/
|
|
void cmdUnInvite(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Locks the area.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AreaData::LOCKED
|
|
*/
|
|
void cmdLock(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sets the area to spectatable.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AreaData::SPECTATABLE
|
|
*/
|
|
void cmdSpectatable(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Unlocks the area.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AreaData::FREE
|
|
*/
|
|
void cmdUnLock(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Lists all clients in all areas.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdGetAreas(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Lists all clients in the area the caller is in.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdGetArea(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Moves the caller to the area with the given ID.
|
|
*
|
|
* @details Takes an **area ID** as an argument.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdArea(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Kicks a client from the area, moving them back to the default area.
|
|
*
|
|
* @details Takes one argument, the **client's ID** to kick.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdAreaKick(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Changes the background of the current area.
|
|
*
|
|
* @details Takes the **background's internal name** (generally the background's directory's name for the clients) as the only argument.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdSetBackground(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Locks the background, preventing it from being changed.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdBgLock(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Unlocks the background, allowing it to be changed again.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdBgUnlock(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Changes the status of the current area.
|
|
*
|
|
* @details Takes a **status** as an argument. See AreaData::Status for permitted values.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdStatus(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends an out-of-character message with the judgelog of an area.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdJudgeLog(int argc, QStringList argv);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Moderation
|
|
*
|
|
* @brief All functions that detail the actions of commands,
|
|
* that are also related to the moderation and administration of the server.
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Lists all the commands that the caller client has the permissions to use.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdHelp(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Gets or sets the server's Message Of The Day.
|
|
*
|
|
* @details If called without arguments, gets the MOTD.
|
|
*
|
|
* If it has any number of arguments, it is set as the **MOTD**.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdMOTD(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Gives a very brief description of Akashi.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdAbout(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Lists the currently logged-in moderators on the server.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdMods(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Bans a client from the server, forcibly severing its connection to the server,
|
|
* and disallowing their return.
|
|
*
|
|
* @details The first argument is the **target's IPID**, the second is the **reason** why the client
|
|
* was banned, the third is the **duration**.
|
|
*
|
|
* Both the reason and the duration must be in quotation marks.
|
|
*
|
|
* The duration can be `"perma"`, meaning a forever ban, otherwise, it must be given in the format of `"YYyWWwDDdHHhMMmSSs"` to
|
|
* mean a YY years, WW weeks, DD days, HH hours, MM minutes and SS seconds long ban. Any of these may be left out, for example,
|
|
* `"1h30m"` for a 1.5 hour long ban.
|
|
*
|
|
* Besides banning, this command kicks all clients having the given IPID,
|
|
* thus a multiclienting user will have all their clients be kicked from the server.
|
|
*
|
|
* The target's hardware ID is also recorded in a ban, so users with dynamic IPs will not be able to
|
|
* cirvumvent the ban without also changing their hardware ID.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdBan(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes a ban from the database.
|
|
*
|
|
* @details Takes a single argument, the **ID** of the ban.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdUnBan(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Kicks a client from the server, forcibly severing its connection to the server.
|
|
*
|
|
* @details The first argument is the **target's IPID**, while the remaining arguments are the **reason**
|
|
* the client was kicked. Both arguments are mandatory.
|
|
*
|
|
* This command kicks all clients having the given IPID, thus a multiclienting user will have all
|
|
* their clients be kicked from the server.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdKick(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Mutes a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_muted
|
|
*/
|
|
void cmdMute(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes the muted status from a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_muted
|
|
*/
|
|
void cmdUnMute(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief OOC-mutes a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_ooc_muted
|
|
*/
|
|
void cmdOocMute(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes the OOC-muted status from a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_ooc_muted
|
|
*/
|
|
void cmdOocUnMute(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief WTCE-blocks a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_wtce_blocked
|
|
*/
|
|
void cmdBlockWtce(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes the WTCE-blocked status from a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_wtce_blocked
|
|
*/
|
|
void cmdUnBlockWtce(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Lists the last five bans made on the server.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdBans(int argc, QStringList argv);
|
|
|
|
|
|
/**
|
|
* @brief Toggle whether or not in-character messages purely consisting of spaces are allowed.
|
|
*
|
|
* @details Takes no arguments. Against all common sense this also allows you to disable blankposting.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdAllowBlankposting(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Looks up info on a ban.
|
|
*
|
|
* @details If it is called with **one argument**, that argument is the ban ID to look up.
|
|
*
|
|
* If it is called with **two arguments**, then the first argument is either a ban ID, an IPID,
|
|
* or an HDID, and the the second argument specifies the ID type.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdBanInfo(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Reloads all server configuration files.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdReload(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Toggles immediate text processing in the current area.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdForceImmediate(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Toggles whether iniswaps are allowed in the current area.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdAllowIniswap(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Grants a client the temporary permission to save a testimony.
|
|
*
|
|
* @details ClientID as the target of permission
|
|
*
|
|
* @iscommand
|
|
*
|
|
*/
|
|
void cmdPermitSaving(int argc, QStringList argv);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Roleplay
|
|
*
|
|
* @brief All functions that detail the actions of commands,
|
|
* that are also related to various kinds of roleplay actions in some way.
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Flips a coin, returning heads or tails.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdFlip(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Rolls dice and sends the results.
|
|
*
|
|
* @details The first argument is the **amount of faces** each die should have.
|
|
* The second argument is the **amount of dice** that should be rolled.
|
|
*
|
|
* Both arguments are optional.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AOClient::diceThrower
|
|
*/
|
|
void cmdRoll(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Rolls dice, but sends the results in private to the roller.
|
|
*
|
|
* @copydetails AOClient::cmdRoll
|
|
*/
|
|
void cmdRollP(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Gets or sets the global or one of the area-specific timers.
|
|
*
|
|
* @details If called without arguments, sends an out-of-character message listing the statuses of both
|
|
* the global timer and the area-specific timers.
|
|
*
|
|
* If called with **one argument**, and that argument is between `0` and `4` (inclusive on both ends),
|
|
* sends an out-of-character message about the status of the given timer, where `0` is the global timer,
|
|
* and the remaining numbers are the first, second, third and fourth timers in the current area.
|
|
*
|
|
* If called with **two arguments**, and the second argument is
|
|
* * in the format of `hh:mm:ss`, then it starts the given timer,
|
|
* with `hh` hours, `mm` minutes, and `ss` seconds on it, making it appear if needed.
|
|
* * `start`, it (re)starts the given timer, making it appear if needed.
|
|
* * `pause` or `stop`, it pauses the given timer.
|
|
* * `hide` or `unset`, it stops the timer and hides it.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdTimer(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Changes the subtheme of the clients in the current area.
|
|
*
|
|
* @details The only argument is the **name of the subtheme**. Reloading is always forced.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
|
|
void cmdSubTheme(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Writes a "note card" in the current area.
|
|
*
|
|
* @details The note card is not readable until all note cards in the area are revealed by a **CM**.
|
|
* A message will appear to all clients in the area indicating that a note card has been written.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdNoteCard(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Reveals all note cards in the current area.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdNoteCardReveal(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Erases the client's note card from the area's list of cards.
|
|
*
|
|
* @details A message will appear to all clients in the area indicating that a note card has been erased.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdNoteCardClear(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Randomly selects an answer from 8ball.txt to a question.
|
|
*
|
|
* @details The only argument is the question the client wants answered.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmd8Ball(int argc, QStringList argv);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Messaging
|
|
*
|
|
* @brief All functions that detail the actions of commands,
|
|
* that are also related to messages or the client's self-management in some way.
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Changes the client's position.
|
|
*
|
|
* @details The only argument is the **target position** to move the client to.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdPos(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Forces a client, or all clients in the area, to a specific position.
|
|
*
|
|
* @details The first argument is the **client's ID**, or `\*` if the client wants to force all
|
|
* clients in their area into the position.
|
|
* If a specific client ID is given, this command can reach across areas, i.e., the caller and target
|
|
* clients don't have to share areas.
|
|
*
|
|
* The second argument is the **position** to force the clients to.
|
|
* This is not checked for nonsense values.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdForcePos(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Switches to a different character based on character ID.
|
|
*
|
|
* @details The only argument is the **character's ID** that the client wants to switch to.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdSwitch(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Picks a new random character for the client.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdRandomChar(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends a global message (i.e., all clients in the server will be able to see it).
|
|
*
|
|
* @details The arguments are **the message** that the client wants to send.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdG(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Toggles whether the client will ignore @ref cmdG "global" messages or not.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdToggleGlobal(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends a direct message to another client on the server based on ID.
|
|
*
|
|
* @details Has two arguments, the first is **the target's ID** whom the client wants to send the message to,
|
|
* while the second is **the message** the client wants to send.
|
|
*
|
|
* The "second" part is technically everything that isn't the first argument.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdPM(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief A global message expressing that the client needs something (generally: players for something).
|
|
*
|
|
* @details The arguments are **the message** that the client wants to send.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdNeed(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends out a decorated global message, for announcements.
|
|
*
|
|
* @details The arguments are **the message** that the client wants to send.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AOClient::cmdG()
|
|
*/
|
|
void cmdAnnounce(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends a message in the server-wide, moderator only chat.
|
|
*
|
|
* @details The arguments are **the message** that the client wants to send.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdM(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends out a global message that is marked with an `[M]` to mean it is coming from a moderator.
|
|
*
|
|
* @details The arguments are **the message** that the client wants to send.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AOClient::cmdG()
|
|
*/
|
|
void cmdGM(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends out a local message that is marked with an `[M]` to mean it is coming from a moderator.
|
|
*
|
|
* @details The arguments are **the message** that the client wants to send.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AOClient::cmdLM()
|
|
*/
|
|
void cmdLM(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Replaces a target client's in-character messages with strings randomly selected from gimp.txt.
|
|
*
|
|
* @details The only argument is the **the target's ID** whom the client wants to gimp.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdGimp(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Allows a gimped client to speak normally.
|
|
*
|
|
* @details The only argument is **the target's ID** whom the client wants to ungimp.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdUnGimp(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes all vowels from a target client's in-character messages.
|
|
*
|
|
* @details The only argument is **the target's ID** whom the client wants to disemvowel.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdDisemvowel(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Allows a disemvoweled client to speak normally.
|
|
*
|
|
* @details The only argument is **the target's ID** whom the client wants to undisemvowel.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdUnDisemvowel(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Scrambles the words of a target client's in-character messages.
|
|
*
|
|
* @details The only argument is **the target's ID** whom the client wants to shake.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdShake(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Allows a shaken client to speak normally.
|
|
*
|
|
* @details The only argument is **the target's ID** whom the client wants to unshake.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdUnShake(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Toggles whether a client will recieve @ref cmdPM private messages or not.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdMutePM(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Toggles whether a client will recieve @ref cmdNeed "advertisement" messages.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdToggleAdverts(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Toggles whether this client is considered AFK.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdAfk(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Restricts a target client to a set of characters that they can switch from, blocking them from other characters.
|
|
*
|
|
* @details The first argument is the **target's ID** whom the client wants to charcurse.
|
|
*
|
|
* The second argument is one or more character names the client wants to restrict to, comma separated.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdCharCurse(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes the charcurse status from a client.
|
|
*
|
|
* @details The only argument is the **target's ID** whom the client wants to uncharcurse.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdUnCharCurse(int argc, QStringList argv);
|
|
void cmdCharSelect(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sends a message to an area that you a CM in.
|
|
*
|
|
* @details Usage: /a <area> <message>
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdA(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Send a message to all areas that you are a CM in.
|
|
*
|
|
* @details Usage: /s <message>
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdS(int argc, QStringList argv);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Casing
|
|
*
|
|
* @brief All functions that detail the actions of commands,
|
|
* that are related to casing.
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Sets the `/doc` to a custom text.
|
|
*
|
|
* @details The arguments are **the text** that the client wants to set the doc to.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdDoc(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sets the `/doc` to `"No document."`.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdClearDoc(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Changes the evidence mod in the area.
|
|
*
|
|
* @details The only argument is the **evidence mod** to change to.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see AreaData::EvidenceMod
|
|
*/
|
|
void cmdEvidenceMod(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Changes position of two pieces of evidence in the area.
|
|
*
|
|
* @details The two arguments are the indices of the evidence items you want to swap the position of.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see Area::Evidence_Swap
|
|
*
|
|
*/
|
|
void cmdEvidence_Swap(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Sets are to PLAYBACK mode
|
|
*
|
|
* @details Enables control over the stored testimony, prevent new messages to be added and
|
|
* allows people to navigate trough it using > and <.
|
|
*/
|
|
void cmdExamine(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Enables the testimony recording functionality.
|
|
*
|
|
* @details Any IC-Message send after this command is issues will be recorded by the testimony recorder.
|
|
*/
|
|
void cmdTestify(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Allows user to update the currently displayed IC-Message from the testimony replay.
|
|
*
|
|
* @details Using this command replaces the content of the current statement entirely. It does not append information.
|
|
*/
|
|
void cmdUpdateStatement(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Deletes a statement from the testimony.
|
|
*
|
|
* @details Using this deletes the entire entry in the QVector and resizes it appropriately to prevent empty record indices.
|
|
*/
|
|
void cmdDeleteStatement(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Pauses testimony playback.
|
|
*
|
|
* @details Disables the testimony playback controls.
|
|
*/
|
|
void cmdPauseTestimony(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Adds a statement to an existing testimony.
|
|
*
|
|
* @details Inserts new statement after the currently displayed recorded message. Increases the index by 1.
|
|
*
|
|
*/
|
|
void cmdAddStatement(int argc, QStringList argv);
|
|
|
|
|
|
/**
|
|
* @brief Sends a list of the testimony to OOC of the requesting client
|
|
*
|
|
* @details Retrieves all stored IC-Messages of the area and dumps them into OOC with some formatting.
|
|
*
|
|
*/
|
|
void cmdTestimony(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Saves a testimony recording to the servers storage.
|
|
*
|
|
* @details Saves a titled text file which contains the edited packets into a text file.
|
|
* The filename will always be lowercase.
|
|
*
|
|
*/
|
|
void cmdSaveTestimony(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Loads testimony for the testimony replay. Argument is the testimony name.
|
|
*
|
|
* @details Loads a titled text file which contains the edited packets to be loaded into the QVector.
|
|
* Validates the size of the testimony to ensure the entire testimony can be replayed.
|
|
* Testimony name will always be converted to lowercase.
|
|
*
|
|
*/
|
|
void cmdLoadTestimony(int argc, QStringList argv);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Music
|
|
*
|
|
* @brief All functions that detail the actions of commands,
|
|
* that are also related to music in some way.
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Plays music in the area.
|
|
*
|
|
* @details The arguments are **the song's filepath** originating from `base/sounds/music/`,
|
|
* or **the song's URL** if it's a stream.
|
|
*
|
|
* As described above, this command can be used to play songs by URL (for clients at and above version 2.9),
|
|
* but it can also be used to play songs locally available for the clients but not listed in the music list.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdPlay(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief DJ-blocks a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_dj_blocked
|
|
*/
|
|
void cmdBlockDj(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Removes the DJ-blocked status from a client.
|
|
*
|
|
* @details The only argument is the **target client's user ID**.
|
|
*
|
|
* @iscommand
|
|
*
|
|
* @see #is_dj_blocked
|
|
*/
|
|
void cmdUnBlockDj(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Returns the currently playing music in the area, and who played it.
|
|
*
|
|
* @details No arguments.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdCurrentMusic(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Toggles music playing in the current area.
|
|
*
|
|
* @details No arguments.
|
|
*/
|
|
void cmdToggleMusic(int argc, QStringList argv);
|
|
|
|
///@}
|
|
|
|
/**
|
|
* @name Command helper functions
|
|
*
|
|
* @brief A collection of functions of shared behaviour between command functions,
|
|
* allowing the abstraction of technical details in the command function definition,
|
|
* or the avoidance of repetition over multiple definitions.
|
|
*/
|
|
///@{
|
|
|
|
/**
|
|
* @brief Literally just an invalid default command. That's it.
|
|
*
|
|
* @note Can be used as a base for future commands.
|
|
*
|
|
* @iscommand
|
|
*/
|
|
void cmdDefault(int argc, QStringList argv);
|
|
|
|
/**
|
|
* @brief Returns a textual representation of the time left in an area's Timer.
|
|
*
|
|
* @param area_idx The ID of the area whose timer to grab.
|
|
* @param timer_idx The ID of the timer to grab
|
|
*
|
|
* @return A textual representation of the time left over on the Timer,
|
|
* or `"Timer is inactive"` if the timer wasn't started.
|
|
*/
|
|
QString getAreaTimer(int area_idx, int timer_idx);
|
|
|
|
/**
|
|
* @brief Generates a tsuserver3-style area list to be displayed to the user in the out-of-character chat.
|
|
*
|
|
* @details This list shows general details about the area the caller is currently in,
|
|
* like who is the owner, what players are in there, the status of the area, etc.
|
|
*
|
|
* @param area_idx The index of the area whose details should be generated.
|
|
*
|
|
* @return A QStringList of details about the given area, with every entry in the string list amounting to
|
|
* roughly a separate line.
|
|
*/
|
|
QStringList buildAreaList(int area_idx);
|
|
|
|
/**
|
|
* @brief Convenience function to generate a random integer number between the given minimum and maximum values.
|
|
*
|
|
* @param min The minimum possible value for the random integer, inclusive.
|
|
* @param max The maximum possible value for the random integer, exclusive.
|
|
*
|
|
* @warning `max` must be greater than `min`.
|
|
*
|
|
* @return A randomly generated integer within the bounds given.
|
|
*/
|
|
int genRand(int min, int max);
|
|
|
|
/**
|
|
* @brief A convenience function for rolling dice.
|
|
*
|
|
* @param argc The amount of arguments.
|
|
*
|
|
* @param argv Stringlist of the arguments given by the client.
|
|
*
|
|
* @param p_roll Bool to determine of a roll is private or not.
|
|
*/
|
|
void diceThrower(int argc, QStringList argv, bool p_roll);
|
|
|
|
/**
|
|
* @brief Interprets an expression of time into amount of seconds.
|
|
*
|
|
* @param input A string in the format of `"XXyXXwXXdXXhXXmXXs"`, where every `XX` is some integer.
|
|
* There is no limit on the length of the integers, the `XX` text is just a placeholder, and is not intended to
|
|
* indicate a limit of two digits maximum.
|
|
*
|
|
* The string gets interpreted as follows:
|
|
* * `XXy` is parsed into `XX` amount of years,
|
|
* * `XXw` is parsed into `XX` amount of weeks,
|
|
* * `XXd` is parsed into `XX` amount of days,
|
|
* * `XXh` is parsed into `XX` amount of hours,
|
|
* * `XXm` is parsed into `XX` amount of minutes, and
|
|
* * `XXs` is parsed into `XX` amount of seconds.
|
|
*
|
|
* Any of these may be left out, but the order must be kept (i.e., `"10s5y"` is a malformed text).
|
|
*
|
|
* @return The parsed text, converted into their respective durations, summed up, then converted into seconds.
|
|
*/
|
|
long long parseTime(QString input);
|
|
QString getReprimand(bool positive = false);
|
|
|
|
/**
|
|
* @brief Adds the last send IC-Message to QVector of the respective area.
|
|
*
|
|
* @details This one pulls double duty to both append IC-Messages to the QVector or insert them, depending on the current recorder enum.
|
|
*
|
|
* @param packet The MS-Packet being recorded with their color changed to green.
|
|
*/
|
|
void addStatement(QStringList packet);
|
|
|
|
/**
|
|
* @brief Clears QVector of the current area.
|
|
*
|
|
* @details It clears both its content and trims it back to size 0
|
|
*
|
|
*/
|
|
void clearTestimony();
|
|
|
|
/**
|
|
* @brief Updates the currently displayed IC-Message with the next one send
|
|
* @param packet The IC-Message that will overwrite the currently stored one.
|
|
* @return Returns the updated IC-Message to be send to the other users. It also changes the color to green.
|
|
*/
|
|
QStringList updateStatement(QStringList packet);
|
|
|
|
/**
|
|
* @brief Called when area enum is set to PLAYBACK. Sends the IC-Message stored at the current statement.
|
|
* @return IC-Message stored in the QVector.
|
|
*/
|
|
QStringList playTestimony();
|
|
///@}
|
|
|
|
/**
|
|
* @brief A helper variable that is used to direct the called of the `/changeAuth` command through the process
|
|
* of changing the authorisation method from simple to advanced.
|
|
*
|
|
* @see cmdChangeAuth and cmdSetRootPass
|
|
*/
|
|
bool change_auth_started = false;
|
|
|
|
/**
|
|
* @brief Describes a command's details.
|
|
*/
|
|
struct CommandInfo {
|
|
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.
|
|
void (AOClient::*action)(int, QStringList);
|
|
};
|
|
|
|
/**
|
|
* @property CommandInfo::action
|
|
*
|
|
* @brief A function reference that contains what the command actually does.
|
|
*
|
|
* @param int When called, this parameter will be filled with the argument count. @anchor commandArgc
|
|
* @param QStringList When called, this parameter will be filled the list of arguments. @anchor commandArgv
|
|
*/
|
|
|
|
/**
|
|
* @brief The list of commands available on the server.
|
|
*
|
|
* @details Generally called with the format of `/command parameters` in the out-of-character chat.
|
|
* @showinitializer
|
|
*
|
|
* @tparam QString The name of the command, without the leading slash.
|
|
* @tparam CommandInfo The details of the command.
|
|
* See @ref CommandInfo "the type's documentation" for more details.
|
|
*/
|
|
const QMap<QString, CommandInfo> commands {
|
|
{"login", {ACLFlags.value("NONE"), 1, &AOClient::cmdLogin}},
|
|
{"getareas", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetAreas}},
|
|
{"getarea", {ACLFlags.value("NONE"), 0, &AOClient::cmdGetArea}},
|
|
{"ban", {ACLFlags.value("BAN"), 2, &AOClient::cmdBan}},
|
|
{"kick", {ACLFlags.value("KICK"), 2, &AOClient::cmdKick}},
|
|
{"changeauth", {ACLFlags.value("SUPER"), 0, &AOClient::cmdChangeAuth}},
|
|
{"rootpass", {ACLFlags.value("SUPER"), 1, &AOClient::cmdSetRootPass}},
|
|
{"background", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
|
|
{"bg", {ACLFlags.value("NONE"), 1, &AOClient::cmdSetBackground}},
|
|
{"bglock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgLock}},
|
|
{"bgunlock", {ACLFlags.value("BGLOCK"), 0, &AOClient::cmdBgUnlock}},
|
|
{"adduser", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddUser}},
|
|
{"listperms", {ACLFlags.value("NONE"), 0, &AOClient::cmdListPerms}},
|
|
{"addperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdAddPerms}},
|
|
{"removeperm", {ACLFlags.value("MODIFY_USERS"), 2, &AOClient::cmdRemovePerms}},
|
|
{"listusers", {ACLFlags.value("MODIFY_USERS"), 0, &AOClient::cmdListUsers}},
|
|
{"logout", {ACLFlags.value("NONE"), 0, &AOClient::cmdLogout}},
|
|
{"pos", {ACLFlags.value("NONE"), 1, &AOClient::cmdPos}},
|
|
{"g", {ACLFlags.value("NONE"), 1, &AOClient::cmdG}},
|
|
{"need", {ACLFlags.value("NONE"), 1, &AOClient::cmdNeed}},
|
|
{"coinflip", {ACLFlags.value("NONE"), 0, &AOClient::cmdFlip}},
|
|
{"roll", {ACLFlags.value("NONE"), 0, &AOClient::cmdRoll}},
|
|
{"rollp", {ACLFlags.value("NONE"), 0, &AOClient::cmdRollP}},
|
|
{"doc", {ACLFlags.value("NONE"), 0, &AOClient::cmdDoc}},
|
|
{"cleardoc", {ACLFlags.value("NONE"), 0, &AOClient::cmdClearDoc}},
|
|
{"cm", {ACLFlags.value("NONE"), 0, &AOClient::cmdCM}},
|
|
{"uncm", {ACLFlags.value("CM"), 0, &AOClient::cmdUnCM}},
|
|
{"invite", {ACLFlags.value("CM"), 1, &AOClient::cmdInvite}},
|
|
{"uninvite", {ACLFlags.value("CM"), 1, &AOClient::cmdUnInvite}},
|
|
{"lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}},
|
|
{"area_lock", {ACLFlags.value("CM"), 0, &AOClient::cmdLock}},
|
|
{"spectatable", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}},
|
|
{"area_spectate", {ACLFlags.value("CM"), 0, &AOClient::cmdSpectatable}},
|
|
{"unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}},
|
|
{"area_unlock", {ACLFlags.value("CM"), 0, &AOClient::cmdUnLock}},
|
|
{"timer", {ACLFlags.value("CM"), 0, &AOClient::cmdTimer}},
|
|
{"area", {ACLFlags.value("NONE"), 1, &AOClient::cmdArea}},
|
|
{"play", {ACLFlags.value("CM"), 1, &AOClient::cmdPlay}},
|
|
{"areakick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}},
|
|
{"area_kick", {ACLFlags.value("CM"), 1, &AOClient::cmdAreaKick}},
|
|
{"randomchar", {ACLFlags.value("NONE"), 0, &AOClient::cmdRandomChar}},
|
|
{"switch", {ACLFlags.value("NONE"), 1, &AOClient::cmdSwitch}},
|
|
{"toggleglobal", {ACLFlags.value("NONE"), 0, &AOClient::cmdToggleGlobal}},
|
|
{"mods", {ACLFlags.value("NONE"), 0, &AOClient::cmdMods}},
|
|
{"help", {ACLFlags.value("NONE"), 0, &AOClient::cmdHelp}},
|
|
{"status", {ACLFlags.value("NONE"), 1, &AOClient::cmdStatus}},
|
|
{"forcepos", {ACLFlags.value("CM"), 2, &AOClient::cmdForcePos}},
|
|
{"currentmusic", {ACLFlags.value("NONE"), 0, &AOClient::cmdCurrentMusic}},
|
|
{"pm", {ACLFlags.value("NONE"), 2, &AOClient::cmdPM}},
|
|
{"evidence_mod", {ACLFlags.value("EVI_MOD"), 1, &AOClient::cmdEvidenceMod}},
|
|
{"motd", {ACLFlags.value("NONE"), 0, &AOClient::cmdMOTD}},
|
|
{"announce", {ACLFlags.value("ANNOUNCE"), 1, &AOClient::cmdAnnounce}},
|
|
{"m", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdM}},
|
|
{"gm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdGM}},
|
|
{"mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdMute}},
|
|
{"unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnMute}},
|
|
{"bans", {ACLFlags.value("BAN"), 0, &AOClient::cmdBans}},
|
|
{"unban", {ACLFlags.value("BAN"), 1, &AOClient::cmdUnBan}},
|
|
{"removeuser", {ACLFlags.value("MODIFY_USERS"), 1, &AOClient::cmdRemoveUser}},
|
|
{"subtheme", {ACLFlags.value("CM"), 1, &AOClient::cmdSubTheme}},
|
|
{"about", {ACLFlags.value("NONE"), 0, &AOClient::cmdAbout}},
|
|
{"evidence_swap", {ACLFlags.value("CM"), 2, &AOClient::cmdEvidence_Swap}},
|
|
{"notecard", {ACLFlags.value("NONE"), 1, &AOClient::cmdNoteCard}},
|
|
{"notecardreveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}},
|
|
{"notecard_reveal", {ACLFlags.value("CM"), 0, &AOClient::cmdNoteCardReveal}},
|
|
{"notecardclear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}},
|
|
{"notecard_clear", {ACLFlags.value("NONE"), 0, &AOClient::cmdNoteCardClear}},
|
|
{"8ball", {ACLFlags.value("NONE"), 1, &AOClient::cmd8Ball}},
|
|
{"lm", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdLM}},
|
|
{"judgelog", {ACLFlags.value("CM"), 0, &AOClient::cmdJudgeLog}},
|
|
{"allowblankposting", {ACLFlags.value("MODCHAT"), 0, &AOClient::cmdAllowBlankposting}},
|
|
{"allow_blankposting", {ACLFlags.value("MODCHAT"), 0, &AOClient::cmdAllowBlankposting}},
|
|
{"gimp", {ACLFlags.value("MUTE"), 1, &AOClient::cmdGimp}},
|
|
{"ungimp", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnGimp}},
|
|
{"baninfo", {ACLFlags.value("BAN"), 1, &AOClient::cmdBanInfo}},
|
|
{"testify", {ACLFlags.value("CM"), 0, &AOClient::cmdTestify}},
|
|
{"testimony", {ACLFlags.value("NONE"), 0, &AOClient::cmdTestimony}},
|
|
{"examine", {ACLFlags.value("CM"), 0, &AOClient::cmdExamine}},
|
|
{"pause", {ACLFlags.value("CM"), 0, &AOClient::cmdPauseTestimony}},
|
|
{"delete", {ACLFlags.value("CM"), 0, &AOClient::cmdDeleteStatement}},
|
|
{"update", {ACLFlags.value("CM"), 0, &AOClient::cmdUpdateStatement}},
|
|
{"add", {ACLFlags.value("CM"), 0, &AOClient::cmdAddStatement}},
|
|
{"reload", {ACLFlags.value("SUPER"), 0, &AOClient::cmdReload}},
|
|
{"disemvowel", {ACLFlags.value("MUTE"), 1, &AOClient::cmdDisemvowel}},
|
|
{"undisemvowel", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnDisemvowel}},
|
|
{"shake", {ACLFlags.value("MUTE"), 1, &AOClient::cmdShake}},
|
|
{"unshake", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnShake}},
|
|
{"forceimmediate", {ACLFlags.value("CM"), 0, &AOClient::cmdForceImmediate}},
|
|
{"force_noint_pres", {ACLFlags.value("CM"), 0, &AOClient::cmdForceImmediate}},
|
|
{"allowiniswap", {ACLFlags.value("CM"), 0, &AOClient::cmdAllowIniswap}},
|
|
{"allow_iniswap", {ACLFlags.value("CM"), 0, &AOClient::cmdAllowIniswap}},
|
|
{"afk", {ACLFlags.value("NONE"), 0, &AOClient::cmdAfk}},
|
|
{"savetestimony", {ACLFlags.value("NONE"), 1, &AOClient::cmdSaveTestimony}},
|
|
{"loadtestimony", {ACLFlags.value("CM"), 1, &AOClient::cmdLoadTestimony}},
|
|
{"permitsaving", {ACLFlags.value("MODCHAT"), 1, &AOClient::cmdPermitSaving}},
|
|
{"mutepm", {ACLFlags.value("NONE"), 0, &AOClient::cmdMutePM}},
|
|
{"toggleadverts", {ACLFlags.value("NONE"), 0, &AOClient::cmdToggleAdverts}},
|
|
{"oocmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocMute}},
|
|
{"ooc_mute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocMute}},
|
|
{"oocunmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocUnMute}},
|
|
{"ooc_unmute", {ACLFlags.value("MUTE"), 1, &AOClient::cmdOocUnMute}},
|
|
{"blockwtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockWtce}},
|
|
{"block_wtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockWtce}},
|
|
{"unblockwtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockWtce}},
|
|
{"unblock_wtce", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockWtce}},
|
|
{"blockdj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockDj}},
|
|
{"block_dj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdBlockDj}},
|
|
{"unblockdj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockDj}},
|
|
{"unblock_dj", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnBlockDj}},
|
|
{"charcurse", {ACLFlags.value("MUTE"), 1, &AOClient::cmdCharCurse}},
|
|
{"uncharcurse", {ACLFlags.value("MUTE"), 1, &AOClient::cmdUnCharCurse}},
|
|
{"charselect", {ACLFlags.value("NONE"), 0, &AOClient::cmdCharSelect}},
|
|
{"togglemusic", {ACLFlags.value("CM"), 0, &AOClient::cmdToggleMusic}},
|
|
{"a", {ACLFlags.value("NONE"), 2, &AOClient::cmdA}},
|
|
{"s", {ACLFlags.value("NONE"), 0, &AOClient::cmdS}}
|
|
};
|
|
|
|
/**
|
|
* @brief Filled with part of a packet if said packet could not be read fully from the client's socket.
|
|
*
|
|
* @details Per AO2's network protocol, a packet is finished with the character `%`.
|
|
*
|
|
* @see #is_partial
|
|
*/
|
|
QString partial_packet;
|
|
|
|
/**
|
|
* @brief True when the previous `readAll()` call from the client's socket returned an unfinished packet.
|
|
*
|
|
* @see #partial_packet
|
|
*/
|
|
bool is_partial;
|
|
|
|
/**
|
|
* @brief The hardware ID of the client.
|
|
*
|
|
* @details Generated based on the client's own supplied hardware ID.
|
|
* The client supplied hardware ID is generally a machine unique ID.
|
|
*/
|
|
QString hwid;
|
|
|
|
/**
|
|
* @brief The IPID of the client.
|
|
*
|
|
* @details Generated based on the client's IP, but cannot be reversed to identify the client's IP.
|
|
*/
|
|
QString ipid;
|
|
|
|
/**
|
|
* @brief The time in seconds since the client last sent a Witness Testimony / Cross Examination
|
|
* popup packet.
|
|
*
|
|
* @details Used to filter out potential spam.
|
|
*/
|
|
long last_wtce_time;
|
|
|
|
/**
|
|
* @brief The text of the last in-character message that was sent by the client.
|
|
*
|
|
* @details Used to determine if the incoming message is a duplicate.
|
|
*/
|
|
QString last_message;
|
|
|
|
/**
|
|
* @brief A helper function to add recorded packets to an area's judgelog.
|
|
*
|
|
* @param area Pointer to the area where the packet was sent.
|
|
*
|
|
* @param client Pointer to the client that sent the packet.
|
|
*
|
|
* @param action String containing the info that is being recorded.
|
|
*/
|
|
void updateJudgeLog(AreaData* area, AOClient* client, QString action);
|
|
|
|
/**
|
|
* @brief A helper function for decoding AO encoding from a QString.
|
|
*
|
|
* @param incoming_message QString to be decoded.
|
|
*/
|
|
QString decodeMessage(QString incoming_message);
|
|
|
|
/**
|
|
* @brief The size, in bytes, of the last data the client sent to the server.
|
|
*/
|
|
int last_read;
|
|
};
|
|
|
|
#endif // AOCLIENT_H
|