Merge pull request #1 from AttorneyOnline/master
Synch with Akashi master
This commit is contained in:
		
						commit
						9f206584bd
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -73,3 +73,4 @@ Thumbs.db
 | 
				
			|||||||
build/
 | 
					build/
 | 
				
			||||||
bin/akashi
 | 
					bin/akashi
 | 
				
			||||||
bin/config/
 | 
					bin/config/
 | 
				
			||||||
 | 
					doxygen/html
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								bin/config_sample/text/praise.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								bin/config_sample/text/praise.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					:3
 | 
				
			||||||
 | 
					\o/
 | 
				
			||||||
 | 
					Be safe!
 | 
				
			||||||
 | 
					Have fun!
 | 
				
			||||||
 | 
					Be careful!
 | 
				
			||||||
 | 
					Have a nice day!
 | 
				
			||||||
 | 
					Be responsible!
 | 
				
			||||||
 | 
					Be good!
 | 
				
			||||||
 | 
					I believe in you!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								bin/config_sample/text/reprimands.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								bin/config_sample/text/reprimands.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					>:(
 | 
				
			||||||
 | 
					;w;
 | 
				
			||||||
 | 
					I should have you held in contempt.
 | 
				
			||||||
 | 
					You should be ashamed of yourself.
 | 
				
			||||||
 | 
					Tsk, tsk.
 | 
				
			||||||
 | 
					What did you do this time?
 | 
				
			||||||
 | 
					You're better than this.
 | 
				
			||||||
 | 
					*sigh*
 | 
				
			||||||
 | 
					Didn't anyone ever teach you manners?
 | 
				
			||||||
 | 
					Really?
 | 
				
			||||||
 | 
					Shameful.
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								doxygen/akashi.qch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doxygen/akashi.qch
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -25,31 +25,106 @@
 | 
				
			|||||||
#include <QString>
 | 
					#include <QString>
 | 
				
			||||||
#include <QTcpSocket>
 | 
					#include <QTcpSocket>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A communicator class to update the master server on the server's status.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md#master-server-protocol
 | 
				
			||||||
 | 
					 * for more explanation about how to communicate with the master server.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class Advertiser : public QObject {
 | 
					class Advertiser : public QObject {
 | 
				
			||||||
    Q_OBJECT
 | 
					    Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    Advertiser(QString p_ip, int p_port, int p_ws_port, int p_local_port,
 | 
					    /**
 | 
				
			||||||
               QString p_name, QString p_description,
 | 
					     * @brief Constructor for the Advertiser class.
 | 
				
			||||||
               QObject* parent = nullptr);
 | 
					     *
 | 
				
			||||||
 | 
					     * @param p_ip The IP of the master server.
 | 
				
			||||||
 | 
					     * @param p_port The port on which the connection to the master server should be established.
 | 
				
			||||||
 | 
					     * @param p_ws_port The port on which the server will accept connections from clients through WebSocket.
 | 
				
			||||||
 | 
					     * @param p_local_port The port on which the server will accept connections from clients through TCP.
 | 
				
			||||||
 | 
					     * @param p_name The name of the server, as reported in the client's server browser.
 | 
				
			||||||
 | 
					     * @param p_description The description of the server, as reported in the client's server browser.
 | 
				
			||||||
 | 
					     * @param p_parent Qt-based parent, passed along to inherited constructor from QObject.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Advertiser(const QString p_ip, const int p_port, const int p_ws_port, const int p_local_port,
 | 
				
			||||||
 | 
					               const QString p_name, const QString p_description, QObject* p_parent = nullptr) :
 | 
				
			||||||
 | 
					        QObject(p_parent),
 | 
				
			||||||
 | 
					        ip(p_ip),
 | 
				
			||||||
 | 
					        port(p_port),
 | 
				
			||||||
 | 
					        ws_port(p_ws_port),
 | 
				
			||||||
 | 
					        local_port(p_local_port),
 | 
				
			||||||
 | 
					        name(p_name),
 | 
				
			||||||
 | 
					        description(p_description)
 | 
				
			||||||
 | 
					    {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Destructor for the Advertiser class.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Marks the socket used to establish connection to the master server to be deleted later.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    ~Advertiser();
 | 
					    ~Advertiser();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Sets up the socket used for master server connection, establishes connection to the master server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void contactMasterServer();
 | 
					    void contactMasterServer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public slots:
 | 
					  public slots:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Handles data that was read from the master server's socket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note Currently does nothing.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void readData();
 | 
					    void readData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Announces the server's presence to the master server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void socketConnected();
 | 
					    void socketConnected();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Handles disconnection from the master server through the socket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note Currently does nothing but outputs a line about the disconnection in the debug output.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void socketDisconnected();
 | 
					    void socketDisconnected();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @copydoc ConfigManager::server_settings::ms_ip
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString ip;
 | 
					    QString ip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @copydoc ConfigManager::server_settings::ms_port
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int port;
 | 
					    int port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @copydoc ConfigManager::server_settings::ws_port
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int ws_port;
 | 
					    int ws_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @copydoc ConfigManager::server_settings::port
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @bug See #port.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int local_port;
 | 
					    int local_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @copydoc ConfigManager::server_settings::name
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString name;
 | 
					    QString name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @copydoc ConfigManager::server_settings::description
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString description;
 | 
					    QString description;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The socket used to establish connection to the master server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QTcpSocket* socket;
 | 
					    QTcpSocket* socket;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1485
									
								
								include/aoclient.h
									
									
									
									
									
								
							
							
						
						
									
										1485
									
								
								include/aoclient.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -23,14 +23,51 @@
 | 
				
			|||||||
#include <QString>
 | 
					#include <QString>
 | 
				
			||||||
#include <QStringList>
 | 
					#include <QStringList>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief An Attorney Online 2 compatible packet.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @see https://github.com/AttorneyOnline/docs/blob/master/docs/development/network.md for a general explanation
 | 
				
			||||||
 | 
					 * on Attorney Online 2's network protocol.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class AOPacket {
 | 
					class AOPacket {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Creates an AOPacket with the given header and contents.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param p_header The header for the packet.
 | 
				
			||||||
 | 
					     * @param p_contents The contents of the packet.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    AOPacket(QString p_header, QStringList p_contents);
 | 
					    AOPacket(QString p_header, QStringList p_contents);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief AOPacket Interprets a string of a full (header + content) packet into an AOPacket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param packet The string to interpret.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    AOPacket(QString packet);
 | 
					    AOPacket(QString packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Returns the string representation of the packet.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return See brief description.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString toString();
 | 
					    QString toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience function over AOPacket::toString() + QString::toUtf8().
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A UTF-8 representation of the packet.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QByteArray toUtf8();
 | 
					    QByteArray toUtf8();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The string that indentifies the type of the packet.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString header;
 | 
					    QString header;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The list of parameters for the packet. Can be empty.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QStringList contents;
 | 
					    QStringList contents;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,58 +28,248 @@
 | 
				
			|||||||
#include <QElapsedTimer>
 | 
					#include <QElapsedTimer>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Logger;
 | 
					class Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @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.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param p_name The name of the area. This must be in the format of `"X:YYYYYY"`, where `X` is an integer,
 | 
				
			||||||
 | 
					     * and `YYYYYY` is the actual name of the area.
 | 
				
			||||||
 | 
					     * @param p_index The index of the area in the area list.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    AreaData(QString p_name, int p_index);
 | 
					    AreaData(QString p_name, int p_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The data for evidence in the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    struct Evidence {
 | 
					    struct Evidence {
 | 
				
			||||||
        QString name;
 | 
					        QString name; //!< The name of the evidence, shown when hovered over clientside.
 | 
				
			||||||
        QString description;
 | 
					        QString description; //!< The longer description of the evidence, when the user opens the evidence window.
 | 
				
			||||||
        QString image;
 | 
					        QString image; //!< A path originating from `base/evidence/` that points to an image file.
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The list of timers available in the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QList<QTimer*> timers;
 | 
					    QList<QTimer*> timers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The user-facing and internal name of the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString name;
 | 
					    QString name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The index of the area in the server's area list.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int index;
 | 
					    int index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A list of the character IDs of all characters taken.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QList<int> characters_taken;
 | 
					    QList<int> characters_taken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A list of Evidence currently available in the area's court record.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details This contains *all* evidence, not just the ones a given side can see.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see HIDDEN_CM
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QList<Evidence> evidence;
 | 
					    QList<Evidence> evidence;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The amount of clients inside the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int player_count;
 | 
					    int player_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The status of an area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @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.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    enum Status {
 | 
					    enum Status {
 | 
				
			||||||
      IDLE,
 | 
					      IDLE, //!< The area is currently not busy with anything, or the area is empty.
 | 
				
			||||||
      RP,
 | 
					      RP, //!< There is some (non-Ace Attorney-related) roleplay going on in the area.
 | 
				
			||||||
      CASING,
 | 
					      CASING, //!< An Ace Attorney or Danganronpa-styled case is currently being held in the area.
 | 
				
			||||||
      LOOKING_FOR_PLAYERS,
 | 
					      LOOKING_FOR_PLAYERS, //!< Something is being planned in the area, but it needs more players.
 | 
				
			||||||
      RECESS,
 | 
					      RECESS, //!< The area is currently taking a break from casing, but will continue later.
 | 
				
			||||||
      GAMING
 | 
					      GAMING //!< The users inside the area are playing some game outside of AO, and are using the area to communicate.
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Exposes the metadata of the Status enum.
 | 
				
			||||||
    Q_ENUM(Status);
 | 
					    Q_ENUM(Status);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The status of the area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see Status
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    Status status;
 | 
					    Status status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The IDs of all the owners (or Case Makers / CMs) of the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QList<int> owners;
 | 
					    QList<int> owners;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The list of clients invited to the area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see LOCKED and SPECTATABLE for the benefits of being invited.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QList<int> invited;
 | 
					    QList<int> invited;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Determines who may traverse and communicate in the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    enum LockStatus {
 | 
					    enum LockStatus {
 | 
				
			||||||
      FREE,
 | 
					      FREE,
 | 
				
			||||||
      LOCKED,
 | 
					      LOCKED,
 | 
				
			||||||
      SPECTATABLE
 | 
					      SPECTATABLE
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var LockStatus FREE
 | 
				
			||||||
 | 
					     * Anyone may enter the area, and there are no restrictions on communicating in-character.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var LockStatus LOCKED
 | 
				
			||||||
 | 
					     * Only invited clients may enter the area, but those who are invited are free to communicate in-character.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * When an area transitions from FREE to LOCKED, anyone present in the area
 | 
				
			||||||
 | 
					     * at the time of the transition is considered invited.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var LockStatus SPECTATABLE
 | 
				
			||||||
 | 
					     * Anyone may enter the area, but only invited clients may communicate in-character.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * When an area transitions from FREE to SPECTATABLE, anyone present in the area
 | 
				
			||||||
 | 
					     * at the time of the transition is considered invited.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Exposes the metadata of the LockStatus enum.
 | 
				
			||||||
    Q_ENUM(LockStatus);
 | 
					    Q_ENUM(LockStatus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The status of the area's accessibility to clients.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see LockStatus
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    LockStatus locked;
 | 
					    LockStatus locked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The background of the area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Represents a directory's name in `base/background/` clientside.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString background;
 | 
					    QString background;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief If true, nobody may become the CM of this area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool is_protected;
 | 
					    bool is_protected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief If true, clients are allowed to put on "shownames", custom names
 | 
				
			||||||
 | 
					     * in place of their character's normally displayed name.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool showname_allowed;
 | 
					    bool showname_allowed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief If true, clients are allowed to use the cursed art of iniswapping in the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool iniswap_allowed;
 | 
					    bool iniswap_allowed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief If true, the background of the area cannot be changed except by a moderator.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool bg_locked;
 | 
					    bool bg_locked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The hyperlink to the document of the area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Documents are generally used for cases or roleplays, where they contain the related game's
 | 
				
			||||||
 | 
					     * rules. #document can also be something like "None" if there is no case or roleplay being run.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString document;
 | 
					    QString document;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The Confidence Gauge's value for the Defence side.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Unit is 10%, and the values range from 0 (= 0%) to 10 (= 100%).
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int def_hp;
 | 
					    int def_hp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The Confidence Gauge's value for the Prosecutor side.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @copydetails #def_hp
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int pro_hp;
 | 
					    int pro_hp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The title of the music currently being played in the area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Title is a path to the music file, with the starting point on
 | 
				
			||||||
 | 
					     * `base/sounds/music/` clientside, with file extension.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString current_music;
 | 
					    QString current_music;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The name of the client (or client's character) that started the currently playing music.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString music_played_by;
 | 
					    QString music_played_by;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A pointer to a Logger, used to send requests to log data.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    Logger* logger;
 | 
					    Logger* logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The level of "authorisation" needed to be able to modify, add, and remove evidence in the area.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    enum EvidenceMod{
 | 
					    enum EvidenceMod{
 | 
				
			||||||
        FFA,
 | 
					        FFA,
 | 
				
			||||||
        MOD,
 | 
					        MOD,
 | 
				
			||||||
        CM,
 | 
					        CM,
 | 
				
			||||||
        HIDDEN_CM
 | 
					        HIDDEN_CM
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var EvidenceMod FFA
 | 
				
			||||||
 | 
					     * "Free-for-all" -- anyone can add, remove or modify evidence.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var EvidenceMod MOD
 | 
				
			||||||
 | 
					     * Only mods can add, remove or modify evidence.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var EvidenceMod CM
 | 
				
			||||||
 | 
					     * Only Case Makers and Mods can add, remove or modify evidence.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @var EvidenceMod HIDDEN_CM
 | 
				
			||||||
 | 
					     * Only Case Makers and Mods can add, remove or modify evidence.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * CMs can also hide evidence from various sides by putting `<owner=XXX>` into the evidence's description,
 | 
				
			||||||
 | 
					     * where `XXX` is either a position, of a list of positions separated by `,`.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The evidence mod of the area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see EvidenceMod
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    EvidenceMod evi_mod;
 | 
					    EvidenceMod evi_mod;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -26,26 +26,72 @@
 | 
				
			|||||||
#include <QFileInfo>
 | 
					#include <QFileInfo>
 | 
				
			||||||
#include <QSettings>
 | 
					#include <QSettings>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief The config file handler class.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class ConfigManager {
 | 
					class ConfigManager {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    ConfigManager();
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief An empty constructor for ConfigManager.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    ConfigManager() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Performs some preliminary checks for the various configuration files used by the server.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return True if the config file exists, is up-to-date, and valid, false otherwise.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool initConfig();
 | 
					    bool initConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Updates the config file's version to the one used by the server currently.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details The function can return false if the server's expected config version is 0
 | 
				
			||||||
 | 
					     * (doesn't actually exist), or negative (nonsense).
 | 
				
			||||||
 | 
					     * If the current config file lags more than one version behind the expected, all intermediate
 | 
				
			||||||
 | 
					     * updates are also performed on the config file.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param current_version The current configuration version expected by the server.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return True if a version update took place, false otherwise.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool updateConfig(int current_version);
 | 
					    bool updateConfig(int current_version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The collection of server-specific settings.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    struct server_settings {
 | 
					    struct server_settings {
 | 
				
			||||||
        QString ms_ip;
 | 
					        QString ms_ip; //!< The IP address of the master server to establish connection to.
 | 
				
			||||||
        int port;
 | 
					        int port; //!< The TCP port the server will accept client connections through.
 | 
				
			||||||
        int ws_port;
 | 
					        int ws_port; //!< The WebSocket port the server will accept client connections through.
 | 
				
			||||||
        int ms_port;
 | 
					        int ms_port; //!< The port of the master server to establish connection to.
 | 
				
			||||||
        QString name;
 | 
					        QString name; //!< The name of the server as advertised on the server browser.
 | 
				
			||||||
        QString description;
 | 
					        QString description; //!< The description of the server as advertised on the server browser.
 | 
				
			||||||
        bool advertise_server;
 | 
					        bool advertise_server; //!< The server will only be announced to the master server (and thus appear on the master server list) if this is true.
 | 
				
			||||||
        int zalgo_tolerance;
 | 
					        int zalgo_tolerance; //!< The amount of subscripts zalgo is stripped by.
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Loads the server settings into the given struct from the config file.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param[out] settings Pointer to a server_settings file to be filled with data.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return False if any of the ports (the master server connection port,
 | 
				
			||||||
 | 
					     * the TCP port used by clients, or the WebSocket port used by WebAO) failed
 | 
				
			||||||
 | 
					     * to be read in from the settings correctly, true otherwise.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre initConfig() must have been run beforehand to check for the config file's existence.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool loadServerSettings(server_settings* settings);
 | 
					    bool loadServerSettings(server_settings* settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience function to check if the object exists, and is a file.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param file The object to check.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return See brief description.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool fileExists(QFileInfo *file);
 | 
					    bool fileExists(QFileInfo *file);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,47 +28,236 @@
 | 
				
			|||||||
#include <QSqlError>
 | 
					#include <QSqlError>
 | 
				
			||||||
#include <QSqlQuery>
 | 
					#include <QSqlQuery>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A class used to handle database interaction.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @details This class offers a layer above the QSqlDatabase class to manage semi-critical data.
 | 
				
			||||||
 | 
					 * Contrast with Logger, which dumbs its data into simple `.log` files.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The DBManager handles user data, keeping track of only 'special' persons who are handled
 | 
				
			||||||
 | 
					 * differently than the average user.
 | 
				
			||||||
 | 
					 * This comes in two forms, when the user's client is banned, and when the user is a moderator.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class DBManager{
 | 
					class DBManager{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Constructor for the DBManager class.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Creates a database file at `config/akashi.db`, and creates two tables in it:
 | 
				
			||||||
 | 
					     * one for banned clients, and one for authorised users / moderators.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    DBManager();
 | 
					    DBManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					      * @brief Destructor for the DBManager class. Closes the underlying database.
 | 
				
			||||||
 | 
					      */
 | 
				
			||||||
    ~DBManager();
 | 
					    ~DBManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Checks if there is a record in the Bans table with the given IP address.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ip The IP address to check if it is banned.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return True if the query could return at least one such record.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool isIPBanned(QHostAddress ip);
 | 
					    bool isIPBanned(QHostAddress ip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Checks if there is a record in the Bans table with the given hardware ID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param hdid The hardware ID to check if it is banned.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return True if the query could return at least one such record.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool isHDIDBanned(QString hdid);
 | 
					    bool isHDIDBanned(QString hdid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Returns the reason the given IP address was banned with.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ip The IP address whose ban reason needs to be returned.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The ban reason if the IP address is actually banned,
 | 
				
			||||||
 | 
					     * or `"Ban reason not found."` if the IP address is not actually banned.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString getBanReason(QHostAddress ip);
 | 
					    QString getBanReason(QHostAddress ip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @overload
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString getBanReason(QString hdid);
 | 
					    QString getBanReason(QString hdid);
 | 
				
			||||||
    long long getBanDuration(QString hdid);
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Returns the reason the given IP address was banned with.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ip The IP address whose ban duration to get.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The ban duration if the IP address is actually banned,
 | 
				
			||||||
 | 
					     * or `-1` if the IP address is not actually banned.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    long long getBanDuration(QHostAddress ip);
 | 
					    long long getBanDuration(QHostAddress ip);
 | 
				
			||||||
    int getBanID(QString hdid);
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @overload
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    long long getBanDuration(QString hdid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Gets the ID number of a given ban.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ip The IP address whose associated ban's ID we need.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The ID of the ban if the IP address is actually banned,
 | 
				
			||||||
 | 
					     * or `-1` if the IP address is not actually banned.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int getBanID(QHostAddress ip);
 | 
					    int getBanID(QHostAddress ip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @overload
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    int getBanID(QString hdid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Details about a ban.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    struct BanInfo {
 | 
					    struct BanInfo {
 | 
				
			||||||
        QString ipid;
 | 
					        QString ipid; //!< The banned user's IPID.
 | 
				
			||||||
        QHostAddress ip;
 | 
					        QHostAddress ip; //!< The banned user's IP.
 | 
				
			||||||
        QString hdid;
 | 
					        QString hdid; //!< The banned user's hardware ID.
 | 
				
			||||||
        unsigned long time;
 | 
					        unsigned long time; //!< The time the ban was registered.
 | 
				
			||||||
        QString reason;
 | 
					        QString reason; //!< The reason given for the ban by the moderator who registered it.
 | 
				
			||||||
        long long duration;
 | 
					        long long duration; //!< The duration of the ban, in seconds.
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Gets the last five bans made on the server.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return See brief description.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QList<BanInfo> getRecentBans();
 | 
					    QList<BanInfo> getRecentBans();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Registers a ban into the database.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ban The details of the ban.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void addBan(BanInfo ban);
 | 
					    void addBan(BanInfo ban);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Sets the duration of a given ban to 0, effectively removing the ban the associated user.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param id The ID of the ban to invalidate.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return False if no such ban exists, true if the invalidation was successful.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool invalidateBan(int id);
 | 
					    bool invalidateBan(int id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Creates an authorised user.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param username The username clients can use to log in with.
 | 
				
			||||||
 | 
					     * @param salt The salt to obfuscate the password with.
 | 
				
			||||||
 | 
					     * @param password The user's password.
 | 
				
			||||||
 | 
					     * @param acl The user's authority bitflag -- what special permissions does the user have.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return False if the user already exists, true if the user was successfully created.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see AOClient::cmdLogin() and AOClient::cmdLogout() for the username and password's contexts.
 | 
				
			||||||
 | 
					     * @see AOClient::ACLFlags for the potential special permissions a user may have.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool createUser(QString username, QString salt, QString password, unsigned long long acl);
 | 
					    bool createUser(QString username, QString salt, QString password, unsigned long long acl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Deletes an authorised user from the database.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param username The username whose associated user to delete.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return False if the user didn't even exist, true if the user was successfully deleted.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool deleteUser(QString username);
 | 
					    bool deleteUser(QString username);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Gets the permissions of a given user.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param moderator_name The authorised user's name.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return `0` if `moderator_name` is empty, `0` if such user does not exist in the Users table,
 | 
				
			||||||
 | 
					     * or the primitive representation of an AOClient::ACLFlags permission matrix if neither of the above are true.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see AOClient::ACLFlags for the potential permissions a user may have.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    unsigned long long getACL(QString moderator_name);
 | 
					    unsigned long long getACL(QString moderator_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Authenticates a given user.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param username The username of the user trying to log in.
 | 
				
			||||||
 | 
					     * @param password The password of the user.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return True if the salted version of the inputted password matches the one stored in the user's record,
 | 
				
			||||||
 | 
					     * false if the user does not exist in the records, of if the passwords don't match.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool authenticate(QString username, QString password);
 | 
					    bool authenticate(QString username, QString password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Updates the permissions of a given user.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details This function can add or remove permissions as needed.
 | 
				
			||||||
 | 
					     * `acl` determines what permissions are modified, while `mode` determines whether said permissions are
 | 
				
			||||||
 | 
					     * added or removed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * `acl` **is not** the user's current permissions *or* the sum permissions you want for the user at the end
 | 
				
			||||||
 | 
					     * -- it is the 'difference' between the user's current and desired permissions.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * If `acl` is `"NONE"`, then no matter the mode, the user's permissions are cleared.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * For some practical examples, consult this example table:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * | Starting permissions |    `acl`    | `mode`  | Resulting permissions |
 | 
				
			||||||
 | 
					     * | -------------------: | :---------: | :-----: | :-------------------- |
 | 
				
			||||||
 | 
					     * | KICK                 | BAN         | `TRUE`  | KICK, BAN             |
 | 
				
			||||||
 | 
					     * | BAN, KICK            | BAN         | `TRUE`  | KICK, BAN             |
 | 
				
			||||||
 | 
					     * | KICK                 | BAN, BGLOCK | `TRUE`  | KICK, BAN, BGLOCK     |
 | 
				
			||||||
 | 
					     * | BGLOCK, BAN, KICK    | NONE        | `TRUE`  | NONE                  |
 | 
				
			||||||
 | 
					     * | KICK                 | BAN         | `FALSE` | KICK                  |
 | 
				
			||||||
 | 
					     * | BAN, KICK            | BAN         | `FALSE` | KICK                  |
 | 
				
			||||||
 | 
					     * | BGLOCK, BAN, KICK    | BAN, BGLOCK | `FALSE` | KICK                  |
 | 
				
			||||||
 | 
					     * | BGLOCK, BAN, KICK    | NONE        | `FALSE` | NONE                  |
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param username The username of the user whose permissions should be updated.
 | 
				
			||||||
 | 
					     * @param acl The primitive representation of the permission matrix being modified.
 | 
				
			||||||
 | 
					     * @param mode If true, the permissions described in `acl` are *added* to the user;
 | 
				
			||||||
 | 
					     * if false, they are removed instead.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return True if the modification was successful, false if the user does not exist in the records.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    bool updateACL(QString username, unsigned long long acl, bool mode);
 | 
					    bool updateACL(QString username, unsigned long long acl, bool mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Returns a list of the recorded users' usernames, ordered by ID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return See brief description.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QStringList getUsers();
 | 
					    QStringList getUsers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The name of the database connection driver.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    const QString DRIVER;
 | 
					    const QString DRIVER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @note Unused.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    const QString CONN_NAME;
 | 
					    const QString CONN_NAME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @note Unused.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void openDB();
 | 
					    void openDB();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The backing database that stores user details.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QSqlDatabase db;
 | 
					    QSqlDatabase db;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -30,24 +30,113 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class AOClient;
 | 
					class AOClient;
 | 
				
			||||||
class AreaData;
 | 
					class AreaData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief A class associated with an AreaData class to log various events happening inside the latter.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class Logger
 | 
					class Logger
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    Logger(int p_max_length, AreaData* p_area);
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Constructs a Logger instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param p_max_length The maximum amount of entries the Logger can store at once.
 | 
				
			||||||
 | 
					     * @param p_area The area associated with the Logger from which it should log entries.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Logger(int p_max_length, AreaData* p_area) : max_length(p_max_length), area(p_area) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Logs an IC message.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param client The client who sent the IC message.
 | 
				
			||||||
 | 
					     * @param packet The IC packet itself, used to grab the text of the IC message.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void logIC(AOClient* client, AOPacket* packet);
 | 
					    void logIC(AOClient* client, AOPacket* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Logs an OOC message.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param client The client who sent the OOC message.
 | 
				
			||||||
 | 
					     * @param packet The OOC packet itself, used to grab the text of the OOC message.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void logOOC(AOClient* client, AOPacket* packet);
 | 
					    void logOOC(AOClient* client, AOPacket* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Logs a mod call message.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param client The client who sent the mod call.
 | 
				
			||||||
 | 
					     * @param packet The ZZ packet itself, used to grab the reason field of the modcall.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void logModcall(AOClient* client, AOPacket* packet);
 | 
					    void logModcall(AOClient* client, AOPacket* packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Logs a command called in OOC.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details If the command is not one of any of the 'special' ones, it defaults to logOOC().
 | 
				
			||||||
 | 
					     * The only thing that makes a command 'special' if it is handled differently in here.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param client The client who sent the command.
 | 
				
			||||||
 | 
					     * @param packet The OOC packet. Passed to logOOC() if the command is not 'special' (see details).
 | 
				
			||||||
 | 
					     * @param cmd The command called in the OOC -- this is the first word after the `/` character.
 | 
				
			||||||
 | 
					     * @param args The arguments interpreted for the command, every word separated by a whitespace.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void logCmd(AOClient* client, AOPacket* packet, QString cmd, QStringList args);
 | 
					    void logCmd(AOClient* client, AOPacket* packet, QString cmd, QStringList args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Logs a login attempt.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param client The client that attempted to login.
 | 
				
			||||||
 | 
					     * @param success True if the client successfully authenticated as a mod.
 | 
				
			||||||
 | 
					     * @param modname If the client logged in with a modname, then this is it. Otherwise, it's `"moderator"`.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note Why does this exist? logCmd() already does this in part.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void logLogin(AOClient* client, bool success, QString modname);
 | 
					    void logLogin(AOClient* client, bool success, QString modname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Appends the contents of #buffer into `config/server.log`, emptying the former.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void flush();
 | 
					    void flush();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience function to format entries to the acceptable standard for logging.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param client The client who 'caused' the source event for the entry to happen.
 | 
				
			||||||
 | 
					     * @param type The type of entry that is being built, something that uniquely identifies entries of similar being.
 | 
				
			||||||
 | 
					     * @param message Any additional information related to the entry.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A formatted string representation of the entry.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString buildEntry(AOClient* client, QString type, QString message);
 | 
					    QString buildEntry(AOClient* client, QString type, QString message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Convenience function to add an entry to #buffer.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details If the buffer's size is equal to #max_length, the first entry in the queue is removed,
 | 
				
			||||||
 | 
					     * and the newest entry is added to the end.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param entry The string representation of the entry to add.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre You would probably call buildEntry() to format the entry before adding it to the buffer.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void addEntry(QString entry);
 | 
					    void addEntry(QString entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The max amount of entries that may be contained in #buffer.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int max_length;
 | 
					    int max_length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Contains entries that have not yet been flushed out into a log file.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QQueue<QString> buffer;
 | 
					    QQueue<QString> buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A pointer to the area this logger is associated with.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Used for logging in what area did a given packet event happen.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    AreaData* area;
 | 
					    AreaData* area;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										171
									
								
								include/server.h
									
									
									
									
									
								
							
							
						
						
									
										171
									
								
								include/server.h
									
									
									
									
									
								
							@ -38,47 +38,214 @@ class AOClient;
 | 
				
			|||||||
class DBManager;
 | 
					class DBManager;
 | 
				
			||||||
class AreaData;
 | 
					class AreaData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @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:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Creates a Server instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param p_port The TCP 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.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    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.
 | 
				
			||||||
 | 
					      *
 | 
				
			||||||
 | 
					      * @details Marks every Client, the WSProxy, the underlying #server, and the database manager to be deleted later.
 | 
				
			||||||
 | 
					      */
 | 
				
			||||||
    ~Server();
 | 
					    ~Server();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Starts the server.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Amongst other things, this function starts the listening on the given TCP port, sets up the server
 | 
				
			||||||
 | 
					     * according to the configuration file, and starts listening on the WebSocket port if it is not `-1`.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Advertising is not done here -- see Advertiser::contactMasterServer() for that.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void start();
 | 
					    void start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Gets a pointer to a client by IPID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ipid The IPID to look for.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A pointer to the client if found, a nullpointer if not.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see Server::getClientsByIpid() to get all clients ran by the same user.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    AOClient* getClient(QString ipid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Gets a list of pointers to all clients with the given IPID.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ipid The IPID to look for.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @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.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param id The user ID to look for.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A pointer to the client if found, a nullpointer if not.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    AOClient* getClientByID(int id);
 | 
					    AOClient* getClientByID(int id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Updates which characters are taken in the given area, and sends out an update packet to
 | 
				
			||||||
 | 
					     * all clients present the area.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @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.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param packet The packet to send to the clients.
 | 
				
			||||||
 | 
					     * @param area_index The index of the area to look for clients in.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note Does nothing if an area by the given index does not exist.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void broadcast(AOPacket packet, int area_index);
 | 
					    void broadcast(AOPacket packet, int area_index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Sends a packet to all clients in the server.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param packet The packet to send to the clients.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void broadcast(AOPacket packet);
 | 
					    void broadcast(AOPacket packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Returns the server's name according to the configuration file.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return See brief description.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString getServerName();
 | 
					    QString getServerName();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Returns some value regarding the @ref AOClient::diceThrower "dice thrower commands".
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param value_type `max_value` for the maximum amount of faces a die may have,
 | 
				
			||||||
 | 
					     * `max_dice` for the maximum amount of dice that may be thrown at once.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The associated value if it is found in the configuration file under the "Dice" section,
 | 
				
			||||||
 | 
					     * or `100` if not.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int getDiceValue(QString value_type);
 | 
					    int getDiceValue(QString value_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Returns the character's character ID (= their index in the character list).
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param char_name The 'internal' name for the character whose character ID to look up. This is equivalent to
 | 
				
			||||||
 | 
					     * the name of the directory of the character.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The character ID if a character with that name exists in the character selection list, `-1` if not.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int getCharID(QString char_name);
 | 
					    int getCharID(QString char_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The collection of all currently connected clients.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QVector<AOClient*> clients;
 | 
					    QVector<AOClient*> clients;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The overall player count in the server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int player_count;
 | 
					    int player_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The characters available on the server to use.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QStringList characters;
 | 
					    QStringList characters;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The areas on the server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QVector<AreaData*> areas;
 | 
					    QVector<AreaData*> areas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The names of the areas on the server.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Equivalent to iterating over #areas and getting the area names individually, but grouped together
 | 
				
			||||||
 | 
					     * here for faster access.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QStringList area_names;
 | 
					    QStringList area_names;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The available songs on the server.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details Does **not** include the area names, the actual music list packet should be constructed from
 | 
				
			||||||
 | 
					     * #area_names and this combined.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QStringList music_list;
 | 
					    QStringList music_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The backgrounds on the server that may be used in areas.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QStringList backgrounds;
 | 
					    QStringList backgrounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The database manager on the server, used to store users' bans and authorisation details.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    DBManager* db_manager;
 | 
					    DBManager* db_manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The user-facing server name.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note Unused. getServerName() serves its purpose instead.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString server_name;
 | 
					    QString server_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The Message Of The Day of the server, shown upon entry to the server and on request.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QString MOTD;
 | 
					    QString MOTD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The server-wide global timer.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QTimer* timer;
 | 
					    QTimer* timer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  signals:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public slots:
 | 
					  public slots:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @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();
 | 
					    void clientConnected();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The proxy used for WebSocket connections.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see WSProxy and WSClient for an explanation as to why this is a thing.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    WSProxy* proxy;
 | 
					    WSProxy* proxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Listens for incoming TCP connections.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QTcpServer* server;
 | 
					    QTcpServer* server;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The port through which the server will accept TCP connections.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int port;
 | 
					    int port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The port through which the server will accept WebSocket connections.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int ws_port;
 | 
					    int ws_port;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,21 +23,86 @@
 | 
				
			|||||||
#include <QTcpSocket>
 | 
					#include <QTcpSocket>
 | 
				
			||||||
#include <QString>
 | 
					#include <QString>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Represents a WebSocket client (generally WebAO) connected to the server.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @details To give a common interface to both desktop AO and WebAO clients, the incoming data from
 | 
				
			||||||
 | 
					 * WebSocket connections are directed through local TCP sockets.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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:
 | 
				
			||||||
    WSClient(QTcpSocket* p_tcp_socket, QWebSocket* p_web_socket, QObject* parent = nullptr);
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Creates an instance of the WSClient class.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param p_tcp_socket The locally created TCP socket to direct data through.
 | 
				
			||||||
 | 
					     * @param p_web_socket The WebSocket that actually represents the connecting client.
 | 
				
			||||||
 | 
					     * @param parent Qt-based parent, passed along to inherited constructor from QObject.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @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.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    WSClient(QTcpSocket* p_tcp_socket, QWebSocket* p_web_socket, QObject* parent = nullptr)
 | 
				
			||||||
 | 
					        : QObject(parent), tcp_socket(p_tcp_socket), web_socket(p_web_socket) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					      * @brief Destructor for the WSClient class.
 | 
				
			||||||
 | 
					      *
 | 
				
			||||||
 | 
					      * @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.
 | 
				
			||||||
 | 
					     * Will read all data in the socket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details The incoming data is separated per-packet due to the WebAO bug, and the packets are sent
 | 
				
			||||||
 | 
					     * through #web_socket.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void onTcpData();
 | 
					    void onTcpData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A slot that can be signalled to push packets received from WebSocket into the
 | 
				
			||||||
 | 
					     * associated local TCP socket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param message The incoming packet.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void onWsData(QString message);
 | 
					    void onWsData(QString message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A slot that can be signalled when the WebSocket client disconnect.
 | 
				
			||||||
 | 
					     * Disconnects the associated TCP socket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see onTcpDisconnect() for the opposite scenario.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void onWsDisconnect();
 | 
					    void onWsDisconnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A slot that can be signalled when the TCP socket is disconnected.
 | 
				
			||||||
 | 
					     * Severs the connection to the WebSocket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @see onWsDisconnect() for the opposite scenario.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void onTcpDisconnect();
 | 
					    void onTcpDisconnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief A slot that can be signalled when the TCP socket is connected.
 | 
				
			||||||
 | 
					     * Sends identification over the socket.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void onTcpConnect();
 | 
					    void onTcpConnect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @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.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QWebSocket* web_socket;
 | 
					    QWebSocket* web_socket;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -25,21 +25,66 @@
 | 
				
			|||||||
#include <QtWebSockets/QtWebSockets>
 | 
					#include <QtWebSockets/QtWebSockets>
 | 
				
			||||||
#include <QHostAddress>
 | 
					#include <QHostAddress>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Handles WebSocket connections by redirecting data sent through them through a local TCP connection
 | 
				
			||||||
 | 
					 * for common handling.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class WSProxy : public QObject {
 | 
					class WSProxy : public QObject {
 | 
				
			||||||
    Q_OBJECT
 | 
					    Q_OBJECT
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Creates a WSProxy instance.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param p_local_port The port through which the TCP connection should be directed. Should the same as with
 | 
				
			||||||
 | 
					     * non-WebAO 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.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    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.
 | 
				
			||||||
 | 
					      *
 | 
				
			||||||
 | 
					      * @details Marks the WebSocket server that is used to handle the proxy process to be deleted later.
 | 
				
			||||||
 | 
					      */
 | 
				
			||||||
    ~WSProxy();
 | 
					    ~WSProxy();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Starts listening for WebSocket connections on the given port.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void start();
 | 
					    void start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public slots:
 | 
					public slots:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Sets up the proxy process to the newly connected WebSocket.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @details This function creates a TCP socket to establish the proxy, creates a WSClient to represent the client connecting through WebSocket.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void wsConnected();
 | 
					    void wsConnected();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The WebSocket server listening to incoming WebSocket connections.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QWebSocketServer* server;
 | 
					    QWebSocketServer* server;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief Every client connected through WebSocket.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    QVector<WSClient*> clients;
 | 
					    QVector<WSClient*> clients;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The TCP port that the WebSocket connections will be redirected through.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note Should be the same that desktop clients connect through, and that was announced to the master server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int local_port;
 | 
					    int local_port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @brief The port for incoming WebSocket connections.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note Should be the same that was announced to the master server.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    int ws_port;
 | 
					    int ws_port;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,19 +17,6 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/advertiser.h"
 | 
					#include "include/advertiser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Advertiser::Advertiser(QString p_ip, int p_port, int p_ws_port,
 | 
					 | 
				
			||||||
                       int p_local_port, QString p_name, QString p_description,
 | 
					 | 
				
			||||||
                       QObject* parent)
 | 
					 | 
				
			||||||
    : QObject(parent)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ip = p_ip;
 | 
					 | 
				
			||||||
    port = p_port;
 | 
					 | 
				
			||||||
    ws_port = p_ws_port;
 | 
					 | 
				
			||||||
    local_port = p_local_port;
 | 
					 | 
				
			||||||
    name = p_name;
 | 
					 | 
				
			||||||
    description = p_description;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Advertiser::contactMasterServer()
 | 
					void Advertiser::contactMasterServer()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    socket = new QTcpSocket(this);
 | 
					    socket = new QTcpSocket(this);
 | 
				
			||||||
 | 
				
			|||||||
@ -17,23 +17,6 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/aoclient.h"
 | 
					#include "include/aoclient.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AOClient::AOClient(Server* p_server, QTcpSocket* p_socket, QObject* parent, int user_id)
 | 
					 | 
				
			||||||
    : QObject(parent)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    socket = p_socket;
 | 
					 | 
				
			||||||
    server = p_server;
 | 
					 | 
				
			||||||
    id = user_id;
 | 
					 | 
				
			||||||
    joined = false;
 | 
					 | 
				
			||||||
    password = "";
 | 
					 | 
				
			||||||
    current_area = 0;
 | 
					 | 
				
			||||||
    current_char = "";
 | 
					 | 
				
			||||||
    remote_ip = p_socket->peerAddress();
 | 
					 | 
				
			||||||
    calculateIpid();
 | 
					 | 
				
			||||||
    is_partial = false;
 | 
					 | 
				
			||||||
    last_wtce_time = 0;
 | 
					 | 
				
			||||||
    last_message = "";
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void AOClient::clientData()
 | 
					void AOClient::clientData()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QString data = QString::fromUtf8(socket->readAll());
 | 
					    QString data = QString::fromUtf8(socket->readAll());
 | 
				
			||||||
 | 
				
			|||||||
@ -17,12 +17,18 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/area_data.h"
 | 
					#include "include/area_data.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AreaData::AreaData(QString p_name, int p_index)
 | 
					AreaData::AreaData(QString p_name, int p_index) :
 | 
				
			||||||
 | 
					    index(p_index),
 | 
				
			||||||
 | 
					    player_count(0),
 | 
				
			||||||
 | 
					    status(IDLE),
 | 
				
			||||||
 | 
					    locked(FREE),
 | 
				
			||||||
 | 
					    document("No document."),
 | 
				
			||||||
 | 
					    def_hp(10),
 | 
				
			||||||
 | 
					    pro_hp(10)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QStringList name_split = p_name.split(":");
 | 
					    QStringList name_split = p_name.split(":");
 | 
				
			||||||
    name_split.removeFirst();
 | 
					    name_split.removeFirst();
 | 
				
			||||||
    name = name_split.join(":");
 | 
					    name = name_split.join(":");
 | 
				
			||||||
    index = p_index;
 | 
					 | 
				
			||||||
    QSettings areas_ini("config/areas.ini", QSettings::IniFormat);
 | 
					    QSettings areas_ini("config/areas.ini", QSettings::IniFormat);
 | 
				
			||||||
    areas_ini.beginGroup(p_name);
 | 
					    areas_ini.beginGroup(p_name);
 | 
				
			||||||
    background = areas_ini.value("background", "gs4").toString();
 | 
					    background = areas_ini.value("background", "gs4").toString();
 | 
				
			||||||
@ -31,12 +37,6 @@ AreaData::AreaData(QString p_name, int p_index)
 | 
				
			|||||||
    bg_locked = areas_ini.value("bg_locked", "false").toBool();
 | 
					    bg_locked = areas_ini.value("bg_locked", "false").toBool();
 | 
				
			||||||
    QString configured_evi_mod = areas_ini.value("evidence_mod", "FFA").toString().toLower();
 | 
					    QString configured_evi_mod = areas_ini.value("evidence_mod", "FFA").toString().toLower();
 | 
				
			||||||
    areas_ini.endGroup();
 | 
					    areas_ini.endGroup();
 | 
				
			||||||
    player_count = 0;
 | 
					 | 
				
			||||||
    locked = FREE;
 | 
					 | 
				
			||||||
    status = IDLE;
 | 
					 | 
				
			||||||
    def_hp = 10;
 | 
					 | 
				
			||||||
    pro_hp = 10;
 | 
					 | 
				
			||||||
    document = "No document.";
 | 
					 | 
				
			||||||
    QSettings config_ini("config/config.ini", QSettings::IniFormat);
 | 
					    QSettings config_ini("config/config.ini", QSettings::IniFormat);
 | 
				
			||||||
    config_ini.beginGroup("Options");
 | 
					    config_ini.beginGroup("Options");
 | 
				
			||||||
    int log_size = config_ini.value("logbuffer", 50).toInt();
 | 
					    int log_size = config_ini.value("logbuffer", 50).toInt();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										211
									
								
								src/commands.cpp
									
									
									
									
									
								
							
							
						
						
									
										211
									
								
								src/commands.cpp
									
									
									
									
									
								
							@ -953,38 +953,6 @@ void AOClient::cmdGM(int argc, QStringList argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AOClient::cmdMute(int argc, QStringList argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bool conv_ok = false;
 | 
					 | 
				
			||||||
    int uid = argv[0].toInt(&conv_ok);
 | 
					 | 
				
			||||||
    if (!conv_ok) {
 | 
					 | 
				
			||||||
        sendServerMessage("Invalid user ID.");
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (server->getClientByID(uid)->is_muted)
 | 
					 | 
				
			||||||
        sendServerMessage("That player is already muted!");
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        sendServerMessage("Muted player.");
 | 
					 | 
				
			||||||
    server->getClientByID(uid)->is_muted = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void AOClient::cmdUnmute(int argc, QStringList argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bool conv_ok = false;
 | 
					 | 
				
			||||||
    int uid = argv[0].toInt(&conv_ok);
 | 
					 | 
				
			||||||
    if (!conv_ok) {
 | 
					 | 
				
			||||||
        sendServerMessage("Invalid user ID.");
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!server->getClientByID(uid)->is_muted)
 | 
					 | 
				
			||||||
        sendServerMessage("That player is already unmuted!");
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        sendServerMessage("Unmuted player.");
 | 
					 | 
				
			||||||
    server->getClientByID(uid)->is_muted = false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void AOClient::cmdBans(int argc, QStringList argv)
 | 
					void AOClient::cmdBans(int argc, QStringList argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QStringList recent_bans;
 | 
					    QStringList recent_bans;
 | 
				
			||||||
@ -1035,6 +1003,167 @@ void AOClient::cmdAbout(int argc, QStringList argv)
 | 
				
			|||||||
    sendPacket("CT", {"The akashi dev team", "Thank you for using akashi! Made with love by scatterflower, with help from in1tiate and Salanto. akashi " + QCoreApplication::applicationVersion()});
 | 
					    sendPacket("CT", {"The akashi dev team", "Thank you for using akashi! Made with love by scatterflower, with help from in1tiate and Salanto. akashi " + QCoreApplication::applicationVersion()});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdMute(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (target->is_muted)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is already muted!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("Muted player.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("You were muted by a moderator. " + getReprimand());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_muted = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdUnMute(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!target->is_muted)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is not muted!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("Unmuted player.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("You were unmuted by a moderator. " + getReprimand(true));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_muted = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdOocMute(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (target->is_ooc_muted)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is already OOC muted!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("OOC muted player.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("You were OOC muted by a moderator. " + getReprimand());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_ooc_muted = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdOocUnMute(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!target->is_ooc_muted)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is not OOC muted!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("OOC unmuted player.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("You were OOC unmuted by a moderator. " + getReprimand(true));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_ooc_muted = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdBlockDj(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (target->is_dj_blocked)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is already DJ blocked!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("DJ blocked player.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("You were blocked from changing the music by a moderator. " + getReprimand());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_dj_blocked = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdUnBlockDj(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!target->is_dj_blocked)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is not DJ blocked!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("DJ permissions restored to player.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("A moderator restored your music permissions. " + getReprimand(true));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_dj_blocked = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdBlockWtce(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (target->is_wtce_blocked)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is already judge blocked!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("Revoked player's access to judge controls.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("A moderator revoked your judge controls access. " + getReprimand());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_wtce_blocked = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AOClient::cmdUnBlockWtce(int argc, QStringList argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool conv_ok = false;
 | 
				
			||||||
 | 
					    int uid = argv[0].toInt(&conv_ok);
 | 
				
			||||||
 | 
					    if (!conv_ok) {
 | 
				
			||||||
 | 
					        sendServerMessage("Invalid user ID.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AOClient* target = server->getClientByID(uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!target->is_wtce_blocked)
 | 
				
			||||||
 | 
					        sendServerMessage("That player is not judge blocked!");
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        sendServerMessage("Restored player's access to judge controls.");
 | 
				
			||||||
 | 
					        target->sendServerMessage("A moderator restored your judge controls access. " + getReprimand(true));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    target->is_wtce_blocked = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QStringList AOClient::buildAreaList(int area_idx)
 | 
					QStringList AOClient::buildAreaList(int area_idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QStringList entries;
 | 
					    QStringList entries;
 | 
				
			||||||
@ -1193,3 +1322,21 @@ long long AOClient::parseTime(QString input)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return total;
 | 
					    return total;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString AOClient::getReprimand(bool positive)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QString filename = positive ? "praise" : "reprimands";
 | 
				
			||||||
 | 
					    QFileInfo reprimands_info("config/text/" + filename + ".txt");
 | 
				
			||||||
 | 
					    if (!(reprimands_info.exists() && reprimands_info.isFile())) {
 | 
				
			||||||
 | 
					        qWarning() << filename + ".txt doesn't exist!";
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    QStringList reprimands;
 | 
				
			||||||
 | 
					    QFile file("config/text/" + filename + ".txt");
 | 
				
			||||||
 | 
					    file.open(QIODevice::ReadOnly | QIODevice::Text);
 | 
				
			||||||
 | 
					    while (!file.atEnd()) {
 | 
				
			||||||
 | 
					        reprimands.append(file.readLine().trimmed());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    file.close();
 | 
				
			||||||
 | 
					    return reprimands[genRand(0, reprimands.size() - 1)];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -17,8 +17,6 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/config_manager.h"
 | 
					#include "include/config_manager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConfigManager::ConfigManager() { }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Validate and set up the config
 | 
					// Validate and set up the config
 | 
				
			||||||
bool ConfigManager::initConfig()
 | 
					bool ConfigManager::initConfig()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -17,12 +17,6 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/logger.h"
 | 
					#include "include/logger.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Logger::Logger(int p_max_length, AreaData* p_area)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    area = p_area;
 | 
					 | 
				
			||||||
    max_length = p_max_length;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Logger::logIC(AOClient *client, AOPacket *packet)
 | 
					void Logger::logIC(AOClient *client, AOPacket *packet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QString message = packet->contents[4];
 | 
					    QString message = packet->contents[4];
 | 
				
			||||||
 | 
				
			|||||||
@ -172,6 +172,11 @@ void AOClient::pktIcChat(AreaData* area, int argc, QStringList argv, AOPacket pa
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
					void AOClient::pktOocChat(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    if (is_ooc_muted) {
 | 
				
			||||||
 | 
					        sendServerMessage("You are OOC muted, and cannot speak.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ooc_name = dezalgo(argv[0]).replace(QRegExp("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), ""); // no fucky wucky shit here
 | 
					    ooc_name = dezalgo(argv[0]).replace(QRegExp("\\[|\\]|\\{|\\}|\\#|\\$|\\%|\\&"), ""); // no fucky wucky shit here
 | 
				
			||||||
    if (ooc_name.isEmpty() || ooc_name == server->getServerName()) // impersonation & empty name protection
 | 
					    if (ooc_name.isEmpty() || ooc_name == server->getServerName()) // impersonation & empty name protection
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
@ -203,6 +208,10 @@ void AOClient::pktPing(AreaData* area, int argc, QStringList argv, AOPacket pack
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
					void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    if (is_dj_blocked) {
 | 
				
			||||||
 | 
					        sendServerMessage("You are blocked from changing the music.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    // Due to historical reasons, this
 | 
					    // Due to historical reasons, this
 | 
				
			||||||
    // packet has two functions:
 | 
					    // packet has two functions:
 | 
				
			||||||
    // Change area, and set music.
 | 
					    // Change area, and set music.
 | 
				
			||||||
@ -243,6 +252,10 @@ void AOClient::pktChangeMusic(AreaData* area, int argc, QStringList argv, AOPack
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void AOClient::pktWtCe(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
					void AOClient::pktWtCe(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    if (is_wtce_blocked) {
 | 
				
			||||||
 | 
					        sendServerMessage("You are blocked from using the judge controls.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (QDateTime::currentDateTime().toSecsSinceEpoch() - last_wtce_time <= 5)
 | 
					    if (QDateTime::currentDateTime().toSecsSinceEpoch() - last_wtce_time <= 5)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    last_wtce_time = QDateTime::currentDateTime().toSecsSinceEpoch();
 | 
					    last_wtce_time = QDateTime::currentDateTime().toSecsSinceEpoch();
 | 
				
			||||||
@ -251,6 +264,10 @@ void AOClient::pktWtCe(AreaData* area, int argc, QStringList argv, AOPacket pack
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void AOClient::pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
					void AOClient::pktHpBar(AreaData* area, int argc, QStringList argv, AOPacket packet)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    if (is_wtce_blocked) {
 | 
				
			||||||
 | 
					        sendServerMessage("You are blocked from using the judge controls.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (argv[0] == "1") {
 | 
					    if (argv[0] == "1") {
 | 
				
			||||||
        area->def_hp = std::min(std::max(0, argv[1].toInt()), 10);
 | 
					        area->def_hp = std::min(std::max(0, argv[1].toInt()), 10);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -403,6 +420,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        qDebug() << "INI swap detected from " << getIpid();
 | 
					        qDebug() << "INI swap detected from " << getIpid();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    current_iniswap = incoming_args[2].toString();
 | 
				
			||||||
    args.append(incoming_args[2].toString());
 | 
					    args.append(incoming_args[2].toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // emote
 | 
					    // emote
 | 
				
			||||||
@ -485,7 +503,7 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // text color
 | 
					    // text color
 | 
				
			||||||
    int text_color = incoming_args[14].toInt();
 | 
					    int text_color = incoming_args[14].toInt();
 | 
				
			||||||
    if (text_color != 0 && text_color != 1 && text_color != 2 && text_color != 3 && text_color != 4 && text_color != 5 && text_color != 6)
 | 
					    if (text_color < 0 || text_color > 11)
 | 
				
			||||||
        return invalid;
 | 
					        return invalid;
 | 
				
			||||||
    args.append(QString::number(text_color));
 | 
					    args.append(QString::number(text_color));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -511,8 +529,11 @@ AOPacket AOClient::validateIcPacket(AOPacket packet)
 | 
				
			|||||||
        QString other_offset = "0";
 | 
					        QString other_offset = "0";
 | 
				
			||||||
        QString other_flip = "0";
 | 
					        QString other_flip = "0";
 | 
				
			||||||
        for (AOClient* client : server->clients) {
 | 
					        for (AOClient* client : server->clients) {
 | 
				
			||||||
            if (client->pairing_with == char_id && other_charid != char_id && client->char_id == pairing_with) {
 | 
					            if (client->pairing_with == char_id
 | 
				
			||||||
                other_name = server->characters.at(other_charid);
 | 
					                    && other_charid != char_id
 | 
				
			||||||
 | 
					                    && client->char_id == pairing_with
 | 
				
			||||||
 | 
					                    && client->pos == pos) {
 | 
				
			||||||
 | 
					                other_name = client->current_iniswap;
 | 
				
			||||||
                other_emote = client->emote;
 | 
					                other_emote = client->emote;
 | 
				
			||||||
                other_offset = client->offset;
 | 
					                other_offset = client->offset;
 | 
				
			||||||
                other_flip = client->flipping;
 | 
					                other_flip = client->flipping;
 | 
				
			||||||
 | 
				
			|||||||
@ -17,17 +17,17 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/server.h"
 | 
					#include "include/server.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Server::Server(int p_port, int p_ws_port, QObject* parent) : QObject(parent)
 | 
					Server::Server(int p_port, int p_ws_port, QObject* parent) :
 | 
				
			||||||
 | 
					    QObject(parent),
 | 
				
			||||||
 | 
					    player_count(0),
 | 
				
			||||||
 | 
					    port(p_port),
 | 
				
			||||||
 | 
					    ws_port(p_ws_port)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    server = new QTcpServer(this);
 | 
					    server = new QTcpServer(this);
 | 
				
			||||||
    connect(server, SIGNAL(newConnection()), this, SLOT(clientConnected()));
 | 
					    connect(server, SIGNAL(newConnection()), this, SLOT(clientConnected()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    port = p_port;
 | 
					 | 
				
			||||||
    ws_port = p_ws_port;
 | 
					 | 
				
			||||||
    timer = new QTimer();
 | 
					    timer = new QTimer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    player_count = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db_manager = new DBManager();
 | 
					    db_manager = new DBManager();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,13 +17,6 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/ws_client.h"
 | 
					#include "include/ws_client.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WSClient::WSClient(QTcpSocket* p_tcp_socket, QWebSocket* p_web_socket, QObject* parent)
 | 
					 | 
				
			||||||
    : QObject(parent)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    tcp_socket = p_tcp_socket;
 | 
					 | 
				
			||||||
    web_socket = p_web_socket;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void WSClient::onWsData(QString message)
 | 
					void WSClient::onWsData(QString message)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    tcp_socket->write(message.toUtf8());
 | 
					    tcp_socket->write(message.toUtf8());
 | 
				
			||||||
 | 
				
			|||||||
@ -17,10 +17,11 @@
 | 
				
			|||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					//////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
#include "include/ws_proxy.h"
 | 
					#include "include/ws_proxy.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WSProxy::WSProxy(int p_local_port, int p_ws_port, QObject* parent) : QObject(parent)
 | 
					WSProxy::WSProxy(int p_local_port, int p_ws_port, QObject* parent) :
 | 
				
			||||||
 | 
					    QObject(parent),
 | 
				
			||||||
 | 
					    local_port(p_local_port),
 | 
				
			||||||
 | 
					    ws_port(p_ws_port)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    local_port = p_local_port;
 | 
					 | 
				
			||||||
    ws_port = p_ws_port;
 | 
					 | 
				
			||||||
    server = new QWebSocketServer(QStringLiteral(""),
 | 
					    server = new QWebSocketServer(QStringLiteral(""),
 | 
				
			||||||
                                  QWebSocketServer::NonSecureMode, this);
 | 
					                                  QWebSocketServer::NonSecureMode, this);
 | 
				
			||||||
    connect(server, &QWebSocketServer::newConnection, this,
 | 
					    connect(server, &QWebSocketServer::newConnection, this,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user