|
17 | 17 | #include "discord_ipc_cpp/ipc_types.hpp" |
18 | 18 | #include "discord_ipc_cpp/json.hpp" |
19 | 19 |
|
| 20 | +/** |
| 21 | + * \namespace discord_ipc_cpp |
| 22 | + * |
| 23 | + * \brief High level namespace for the \c discord_ipc_cpp package. |
| 24 | + * |
| 25 | + * Contains all the necessary classes to interact with Discord's IPC socket, |
| 26 | + * with other helpful classes neatly categorized. |
| 27 | + */ |
20 | 28 | namespace discord_ipc_cpp { |
| 29 | +/** |
| 30 | + * \brief Represents a connection to Discord's IPC socket. |
| 31 | + * |
| 32 | + * This class is the highest level and least-customizable class used to interact |
| 33 | + * with Discord's IPC socket. It is specially designed to handle connections |
| 34 | + * with the purpose of sending rich presence updates. |
| 35 | + * |
| 36 | + * \see discord_ipc_cpp::websockets::SocketClient |
| 37 | + */ |
21 | 38 | class DiscordIPCClient { |
22 | 39 | private: |
| 40 | + /** |
| 41 | + * \brief Stores the executable's process ID. |
| 42 | + * |
| 43 | + * Each rich presence is required to have an attached process ID to |
| 44 | + * distinguish between different applications. |
| 45 | + */ |
23 | 46 | const pid_t _pid; |
| 47 | + /** |
| 48 | + * \brief ID of the application. |
| 49 | + * |
| 50 | + * This points to the Discord application that the rich presence is sent from. |
| 51 | + */ |
24 | 52 | std::string _client_id; |
25 | 53 |
|
| 54 | + /** |
| 55 | + * \brief Underlying socket connection. |
| 56 | + * |
| 57 | + * This is the actual class that handles connections to Discord's IPC socket. |
| 58 | + * |
| 59 | + * \see discord_ipc_cpp::websockets::SocketClient |
| 60 | + */ |
26 | 61 | websockets::SocketClient _socket; |
| 62 | + /** |
| 63 | + * \brief Handles incoming packets. |
| 64 | + * |
| 65 | + * This thread handles incoming packets sent by Discord through the IPC |
| 66 | + * socket. |
| 67 | + * |
| 68 | + * \see recv_thread |
| 69 | + */ |
27 | 70 | std::thread _socket_recv_thread; |
28 | 71 |
|
| 72 | + /** |
| 73 | + * \brief Controls the state of \ref _socket_recv_thread. |
| 74 | + * |
| 75 | + * When this variable is toggled from \c false to \c true, |
| 76 | + * \ref _socket_recv_thread will receive the notice to terminate the \c while |
| 77 | + * loop. |
| 78 | + * |
| 79 | + * \see recv_thread() |
| 80 | + */ |
29 | 81 | std::atomic_bool _stop_recv_thread; |
| 82 | + /** |
| 83 | + * \brief Indicates successful authentication with Discord socket. |
| 84 | + * |
| 85 | + * This variable ensures that packets are only sent after successful |
| 86 | + * authentication with Discord's IPC socket. Otherwise, each \ref send_packet |
| 87 | + * request will automatically return \c false. |
| 88 | + */ |
30 | 89 | std::atomic_bool _successful_auth; |
31 | 90 |
|
32 | 91 | private: |
| 92 | + /** |
| 93 | + * \brief Encodes payload into byte buffer. |
| 94 | + * |
| 95 | + * Takes an input \p payload and converts it into the formatted byte buffer |
| 96 | + * with the proper size that the Discord IPC socket expects. |
| 97 | + * |
| 98 | + * \param payload Data payload to encode. |
| 99 | + * |
| 100 | + * \return The \p payload converted into a byte buffer. |
| 101 | + */ |
33 | 102 | static std::vector<char> encode_packet(const ipc_types::Payload& payload); |
| 103 | + /** |
| 104 | + * \brief Receives and handles incoming packets. |
| 105 | + * |
| 106 | + * This function is wrapped by the thread \ref _socket_recv_thread to receive |
| 107 | + * incoming packets from the socket, ensuring the main thread is not blocked. |
| 108 | + * The longevity of the function is controlled by the variable |
| 109 | + * \ref _stop_recv_thread, which is the boolean checker within the \c while |
| 110 | + * statement. |
| 111 | + */ |
34 | 112 | void recv_thread(); |
35 | 113 |
|
36 | 114 | protected: |
| 115 | + /** |
| 116 | + * \brief Sends packet to socket. |
| 117 | + * |
| 118 | + * Attempts to send a payload packet to the Discord IPC socket and indicates |
| 119 | + * the success. This function is a wrapper for |
| 120 | + * \ref discord_ipc_cpp::websockets::SocketClient::send_data, as it takes an |
| 121 | + * input \p payload and encodes it first with \ref encode_packet before calling |
| 122 | + * the underlying method. |
| 123 | + * |
| 124 | + * \param payload Payload to send. |
| 125 | + * |
| 126 | + * \return Success of sending the packet. |
| 127 | + * |
| 128 | + * \see discord_ipc_cpp::websockets::SocketClient::send_data |
| 129 | + */ |
37 | 130 | bool send_packet(const ipc_types::Payload& payload); |
| 131 | + /** |
| 132 | + * \brief Receive packet from socket. |
| 133 | + * |
| 134 | + * Attempts to receive a packet from the socket using |
| 135 | + * \ref discord_ipc_cpp::websockets::SocketClient::recv_data(int,int) before |
| 136 | + * retrieving the rest of packet with |
| 137 | + * \ref discord_ipc_cpp::websockets::SocketClient::recv_data(int). The initial |
| 138 | + * attempt to retrieve a packet contains a timeout, after which it returns an |
| 139 | + * empty value. |
| 140 | + * |
| 141 | + * \return An optional payload. |
| 142 | + * |
| 143 | + * \see discord_ipc_cpp::websockets::SocketClient::recv_data(int) |
| 144 | + * \see discord_ipc_cpp::websockets::SocketClient::recv_data(int,int) |
| 145 | + */ |
38 | 146 | std::optional<ipc_types::Payload> recv_packet(); |
39 | 147 |
|
| 148 | + /** |
| 149 | + * \brief Constructs a presence payload. |
| 150 | + * |
| 151 | + * The converts an optional input \p presence into a payload that can be sent |
| 152 | + * to the socket. |
| 153 | + * |
| 154 | + * \param presence Presence to set into a payload. |
| 155 | + * |
| 156 | + * \return Payload with the corresponding \p presence. |
| 157 | + */ |
40 | 158 | ipc_types::Payload construct_presence_payload( |
41 | 159 | const std::optional<ipc_types::RichPresence>& presence); |
42 | 160 |
|
| 161 | + /** |
| 162 | + * \brief Attempts to send a payload. |
| 163 | + * |
| 164 | + * Wrapping around the method \ref send_packet, this method attempts to send |
| 165 | + * the \p payload \p max_retry_count times with a delay of one second between |
| 166 | + * each attempt. |
| 167 | + * |
| 168 | + * \param payload Payload to attempt sending. |
| 169 | + * \param max_retry_count Maximum number of times to attempt sending payload. |
| 170 | + * |
| 171 | + * \return Success of the attempt to send \p payload. |
| 172 | + */ |
43 | 173 | bool attempt_send_payload( |
44 | 174 | const ipc_types::Payload& payload, int max_retry_count); |
45 | 175 |
|
46 | 176 | public: |
| 177 | + /** |
| 178 | + * \brief Constructs the IPC client. |
| 179 | + * |
| 180 | + * Creates the IPC client with the \p client_id to be used when sending |
| 181 | + * rich presences. |
| 182 | + */ |
47 | 183 | explicit DiscordIPCClient(const std::string& client_id); |
| 184 | + /** |
| 185 | + * \brief Deallocates IPC client. |
| 186 | + * |
| 187 | + * Cleans up the IPC client by releasing the underlying socket connection. |
| 188 | + * |
| 189 | + * \see close |
| 190 | + */ |
48 | 191 | ~DiscordIPCClient(); |
49 | 192 |
|
| 193 | + /** |
| 194 | + * \brief Connect to IPC socket. |
| 195 | + * |
| 196 | + * Attempts to connect to IPC socket and authorize the application. After |
| 197 | + * proper authorization, \ref _socket_recv_thread will be set and the |
| 198 | + * application will start listening for incoming packets. |
| 199 | + * |
| 200 | + * \return Success of the attempt to connect. |
| 201 | + * |
| 202 | + * \see discord_ipc_cpp::websockets::SocketClient::connect |
| 203 | + */ |
50 | 204 | bool connect(); |
| 205 | + /** |
| 206 | + * \brief Close connection to IPC socket. |
| 207 | + * |
| 208 | + * Attempts to close the connection with the IPC socket by first sending a |
| 209 | + * closure Op code and then signalling for \ref _socket_recv_thread to stop by |
| 210 | + * setting \ref _stop_recv_thread to \c false. Lastly, the underlying socket |
| 211 | + * is closed. |
| 212 | + * |
| 213 | + * \return Success of the attempt to close connection. |
| 214 | + * |
| 215 | + * \see discord_ipc_cpp::websockets::SocketClient::close |
| 216 | + */ |
51 | 217 | bool close(); |
52 | 218 |
|
| 219 | + /** |
| 220 | + * \brief Sets the presence in Discord. |
| 221 | + * |
| 222 | + * Sends a request to set the presence of the connected Discord user with |
| 223 | + * \p presence. |
| 224 | + * |
| 225 | + * \param presence Presence to set. |
| 226 | + * |
| 227 | + * \return Success of setting the presence. |
| 228 | + */ |
53 | 229 | bool set_presence(const ipc_types::RichPresence& presence); |
| 230 | + /** |
| 231 | + * \brief Sets an empty presence in Discord. |
| 232 | + * |
| 233 | + * Sends a request to set an empty presence. |
| 234 | + * |
| 235 | + * \return Success fo setting an empty presence. |
| 236 | + */ |
54 | 237 | bool set_empty_presence(); |
55 | 238 | }; |
56 | 239 | } // namespace discord_ipc_cpp |
|
0 commit comments