Skip to content

Commit 000f5d1

Browse files
add all public-facing docs
1 parent 2e872c7 commit 000f5d1

11 files changed

Lines changed: 3896 additions & 56 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
build/
22
.vscode/
3+
docs/

Doxyfile

Lines changed: 2947 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,88 @@
11
# Discord IPC CPP
22

3-
C++ library for interfacing with Discord IPC socket.
3+
C++ library for interfacing with Discord IPC socket. This library was initial made for the parent project [apple-music-rpc-cpp](https://github.com/TheMoonThatRises/apple-music-rpc-cpp), and thus may not be contain full compatibility with Discord IPC protocols. Because of the criteria for the parent project, this library is entirely self-contained, and does not include any external libraries. Feel free to create a [new issue](https://github.com/TheMoonThatRises/discord_ipc_cpp/issues/new) or submit [pull requests](https://github.com/TheMoonThatRises/discord_ipc_cpp/pulls) if you encounter any issues.
4+
5+
## Documentation
6+
7+
Read the full documentation here: [https://plduanm.com/projects/documentation/discord_ipc_cpp](https://plduanm.com/projects/documentation/discord_ipc_cpp)
8+
9+
## Installation
10+
11+
Requirements:
12+
13+
- A Unix system
14+
- CMake >= 3.14
15+
- C++ >= 20
16+
17+
Clone this repository as a submodule under `src/`:
18+
19+
```bash
20+
git submodule add https://github.com/TheMoonThatRises/discord_ipc_cpp src/discord_ipc_cpp
21+
```
22+
23+
And add the following into your `CMakeLists.txt`:
24+
25+
```cmake
26+
...
27+
28+
add_subdirectory(src/discord_ipc_cpp)
29+
30+
...
31+
32+
target_link_libraries(<EXECUTABLE> PRIVATE discord_ipc_cpp)
33+
```
34+
35+
## Basic Usage
36+
37+
All of the code below will incorporate the following metacode:
38+
39+
```c++
40+
#include <discord_ipc_cpp/discord_ipc_client.hpp>
41+
#include <discord_ipc_cpp/ipc_types.hpp>
42+
43+
using discord_ipc_cpp::DiscordIPCClient;
44+
45+
using discord_ipc_cpp::ipc_types::RichPresence;
46+
```
47+
48+
Create a Discord IPC client and connect to it:
49+
50+
```c++
51+
DiscordIPCClient client("<APPLICATION ID>");
52+
53+
// indicates success of connecting to socket
54+
bool ret = client.connect();
55+
```
56+
57+
Construct a rich presence:
58+
59+
```c++
60+
RichPresence presence = {
61+
.name = "Apple Music",
62+
.type = RichPresence::at_listening,
63+
.status_display_type = RichPresence::sdt_details,
64+
.assets = {
65+
.large_text = "Kawakiwoameku - EP"
66+
},
67+
.details = "Hollowness",
68+
.state = "Minami"
69+
}
70+
```
71+
72+
Set the user's rich presence:
73+
74+
```c++
75+
client.set_presence(presence);
76+
```
77+
78+
Clear the user's rich presence:
79+
80+
```c++
81+
client.set_empty_presence();
82+
```
83+
84+
Close the IPC connection:
85+
86+
```c++
87+
client.close();
88+
```

include/discord_ipc_cpp/discord_ipc_client.hpp

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,40 +17,223 @@
1717
#include "discord_ipc_cpp/ipc_types.hpp"
1818
#include "discord_ipc_cpp/json.hpp"
1919

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+
*/
2028
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+
*/
2138
class DiscordIPCClient {
2239
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+
*/
2346
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+
*/
2452
std::string _client_id;
2553

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+
*/
2661
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+
*/
2770
std::thread _socket_recv_thread;
2871

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+
*/
2981
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+
*/
3089
std::atomic_bool _successful_auth;
3190

3291
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+
*/
33102
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+
*/
34112
void recv_thread();
35113

36114
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+
*/
37130
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+
*/
38146
std::optional<ipc_types::Payload> recv_packet();
39147

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+
*/
40158
ipc_types::Payload construct_presence_payload(
41159
const std::optional<ipc_types::RichPresence>& presence);
42160

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+
*/
43173
bool attempt_send_payload(
44174
const ipc_types::Payload& payload, int max_retry_count);
45175

46176
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+
*/
47183
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+
*/
48191
~DiscordIPCClient();
49192

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+
*/
50204
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+
*/
51217
bool close();
52218

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+
*/
53229
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+
*/
54237
bool set_empty_presence();
55238
};
56239
} // namespace discord_ipc_cpp

0 commit comments

Comments
 (0)