D++ (DPP)  10.0.30
C++ Discord API Bot Library
dpp::discord_client Class Reference

Implements a discord client. More...

#include "discordclient.h"

Inheritance diagram for dpp::discord_client:
Collaboration diagram for dpp::discord_client:

Public Member Functions

 discord_client (dpp::cluster *_cluster, uint32_t _shard_id, uint32_t _max_shards, const std::string &_token, uint32_t intents=0, bool compressed=true, websocket_protocol_t ws_protocol=ws_json)
 Construct a new discord_client object. More...
 
virtual ~discord_client ()
 Destroy the discord client object. More...
 
discord_clientclear_queue ()
 Clear the outbound message queue. More...
 
virtual void close ()
 Close websocket. More...
 
discord_clientconnect_voice (snowflake guild_id, snowflake channel_id, bool self_mute=false, bool self_deaf=false)
 Connect to a voice channel. More...
 
discord_clientdisconnect_voice (snowflake guild_id)
 Disconnect from the connected voice channel on a guild. More...
 
virtual void error (uint32_t errorcode)
 Handle a websocket error. More...
 
uint64_t get_bytes_in ()
 Get total bytes received. More...
 
uint64_t get_bytes_out ()
 Get the bytes out objectGet total bytes sent. More...
 
uint64_t get_channel_count ()
 Get the Channel Count for this shard. More...
 
std::string get_cipher ()
 Get SSL cipher name. More...
 
uint64_t get_decompressed_bytes_in ()
 Get the decompressed bytes in objectGet decompressed total bytes received. More...
 
uint64_t get_guild_count ()
 Get the Guild Count for this shard. More...
 
uint64_t get_member_count ()
 Get the Member Count for this shard. More...
 
size_t get_queue_size ()
 Get the size of the outbound message queue. More...
 
dpp::utility::uptime get_uptime ()
 Returns the connection time of the shard. More...
 
voiceconnget_voice (snowflake guild_id)
 Get the dpp::voiceconn object for a specific guild on this shard. More...
 
virtual bool handle_buffer (std::string &buffer)
 Processes incoming frames from the SSL socket input buffer. More...
 
virtual void handle_event (const std::string &event, json &j, const std::string &raw)
 Handle an event (opcode 0) More...
 
virtual bool handle_frame (const std::string &buffer)
 Handle JSON from the websocket. More...
 
bool is_connected ()
 Returns true if the shard is connected. More...
 
virtual void log (dpp::loglevel severity, const std::string &msg) const
 Log a message to whatever log the user is using. More...
 
virtual void one_second_timer ()
 Fires every second from the underlying socket I/O loop, used for sending heartbeats. More...
 
void queue_message (const std::string &j, bool to_front=false)
 Queue a message to be sent via the websocket. More...
 
void read_loop ()
 Nonblocking I/O loop. More...
 
void run ()
 Start and monitor I/O loop. More...
 
void send_close_packet ()
 Send OP_CLOSE error code 1000 to the other side of the connection. More...
 
virtual void write (const std::string &data)
 Write to websocket. More...
 

Public Attributes

std::unordered_map< snowflake, std::unique_ptr< voiceconn > > connecting_voice_channels
 List of voice channels we are connecting to keyed by guild id. More...
 
class dpp::clustercreator
 Owning cluster. More...
 
socket_callback_t custom_readable_fd
 Attaching an additional file descriptor to this function will send notifications when there is data to read. More...
 
socket_notification_t custom_readable_ready
 This event will be called when you can read from the custom fd. More...
 
socket_callback_t custom_writeable_fd
 Attaching an additional file descriptor to this function will send notifications when you are able to write to the socket. More...
 
socket_notification_t custom_writeable_ready
 This event will be called when you can write to a custom fd. More...
 
uint32_t heartbeat_interval
 Heartbeat interval for sending heartbeat keepalive. More...
 
uint32_t intents
 Privileged gateway intents. More...
 
bool keepalive
 True if we are keeping the connection alive after it has finished. More...
 
time_t last_heartbeat
 Last heartbeat. More...
 
time_t last_heartbeat_ack
 Last heartbeat ACK (opcode 11) More...
 
uint64_t last_seq
 Last sequence number received, for resumes and pings. More...
 
uint32_t max_shards
 Total number of shards. More...
 
websocket_protocol_t protocol
 Current websocket protocol, currently either ETF or JSON. More...
 
bool ready
 True if READY or RESUMED has been received. More...
 
uint32_t reconnects
 Reconnection count. More...
 
std::string resume_gateway_url
 The gateway address we reconnect to when we resume a session. More...
 
uint32_t resumes
 Resume count. More...
 
std::string sessionid
 Discord session id. More...
 
uint32_t shard_id
 Shard ID of this client. More...
 
std::thread::native_handle_type thread_id
 Thread ID. More...
 
std::string token
 Discord bot token. More...
 
std::shared_mutex voice_mutex
 Mutex for voice connections map. More...
 
double websocket_ping
 Websocket latency in fractional seconds. More...
 

Protected Member Functions

virtual void connect ()
 (Re)connect More...
 
void disconnect_voice_internal (snowflake guild_id, bool send_json=true)
 Disconnect from the connected voice channel on a guild. More...
 
ws_state get_state ()
 Get websocket state. More...
 

Protected Attributes

std::string buffer
 Input buffer received from socket. More...
 
uint64_t bytes_in
 Bytes in. More...
 
uint64_t bytes_out
 Bytes out. More...
 
std::string cipher
 SSL cipher in use. More...
 
std::string hostname
 Hostname connected to. More...
 
time_t last_tick
 For timers. More...
 
bool make_new
 True if we are establishing a new connection, false if otherwise. More...
 
bool nonblocking
 True if in nonblocking mode. More...
 
std::string obuffer
 Output buffer for sending to socket. More...
 
bool plaintext
 True for a plain text connection. More...
 
std::string port
 Port connected to. More...
 
dpp::socket sfd
 Raw file descriptor of connection. More...
 
openssl_connectionssl
 Openssl opaque contexts. More...
 
bool terminating
 True if the shard is terminating. More...
 

Friends

class dpp::cluster
 Needed to allow cluster::set_presence to use the ETF functions. More...
 
class dpp::events::guild_create
 Needed so that guild_create can request member chunks if you have the correct intents. More...
 
class dpp::events::voice_state_update
 Needed so that voice_state_update can call dpp::discord_client::disconnect_voice_internal. More...
 

Detailed Description

Implements a discord client.

Each discord_client connects to one shard and derives from a websocket client.

Constructor & Destructor Documentation

◆ discord_client()

dpp::discord_client::discord_client ( dpp::cluster _cluster,
uint32_t  _shard_id,
uint32_t  _max_shards,
const std::string &  _token,
uint32_t  intents = 0,
bool  compressed = true,
websocket_protocol_t  ws_protocol = ws_json 
)

Construct a new discord_client object.

Parameters
_clusterThe owning cluster for this shard
_shard_idThe ID of the shard to start
_max_shardsThe total number of shards across all clusters
_tokenThe bot token to use for identifying to the websocket
intentsPrivileged intents to use, a bitmask of values from dpp::intents
compressedTrue if the received data will be gzip compressed
ws_protocolWebsocket protocol to use for the connection, JSON or ETF
Exceptions
std::bad_allocPassed up to the caller if any internal objects fail to allocate, after cleanup has completed

References dpp::websocket_client::connect().

Here is the call graph for this function:

◆ ~discord_client()

dpp::discord_client::~discord_client ( )
virtual

Destroy the discord client object.

Member Function Documentation

◆ clear_queue()

discord_client & dpp::discord_client::clear_queue ( )

Clear the outbound message queue.

Returns
reference to self

◆ close()

void dpp::websocket_client::close ( )
virtualinherited

Close websocket.

Reimplemented from dpp::ssl_client.

Referenced by handle_frame().

Here is the caller graph for this function:

◆ connect()

void dpp::websocket_client::connect ( )
protectedvirtualinherited

(Re)connect

Reimplemented from dpp::ssl_client.

Referenced by discord_client(), dpp::discord_voice_client::discord_voice_client(), and dpp::discord_voice_client::discover_ip().

Here is the caller graph for this function:

◆ connect_voice()

discord_client & dpp::discord_client::connect_voice ( snowflake  guild_id,
snowflake  channel_id,
bool  self_mute = false,
bool  self_deaf = false 
)

Connect to a voice channel.

Parameters
guild_idGuild where the voice channel is
channel_idChannel ID of the voice channel
self_muteTrue if the bot should mute itself
self_deafTrue if the bot should deafen itself
Returns
reference to self
Note
This is NOT a synchronous blocking call! The bot isn't instantly ready to send or listen for audio, as we have to wait for the connection to the voice server to be established! e.g. wait for dpp::cluster::on_voice_ready event, and then send the audio within that event.

References connecting_voice_channels, dpp::ll_debug, dpp::unicode_emoji::lock, log(), queue_message(), and voice_mutex.

Here is the call graph for this function:

◆ disconnect_voice()

discord_client & dpp::discord_client::disconnect_voice ( snowflake  guild_id)

Disconnect from the connected voice channel on a guild.

Parameters
guild_idThe guild who's voice channel you wish to disconnect from
Returns
reference to self
Note
This is NOT a synchronous blocking call! The bot isn't instantly disconnected.

References disconnect_voice_internal().

Here is the call graph for this function:

◆ disconnect_voice_internal()

void dpp::discord_client::disconnect_voice_internal ( snowflake  guild_id,
bool  send_json = true 
)
protected

Disconnect from the connected voice channel on a guild.

Parameters
guild_idThe guild who's voice channel you wish to disconnect from
send_jsonTrue if we should send a json message confirming we are leaving the VC Should be set to false if we already receive this message in an event.

References connecting_voice_channels, dpp::ll_debug, dpp::unicode_emoji::lock, log(), queue_message(), dpp::unicode_emoji::v, and voice_mutex.

Referenced by disconnect_voice().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ error()

void dpp::discord_client::error ( uint32_t  errorcode)
virtual

Handle a websocket error.

Parameters
errorcodeThe error returned from the websocket

Reimplemented from dpp::websocket_client.

References dpp::ll_warning, and log().

Referenced by handle_frame().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_bytes_in()

uint64_t dpp::ssl_client::get_bytes_in ( )
inherited

Get total bytes received.

Returns
uint64_t bytes received

References dpp::ssl_client::bytes_in.

◆ get_bytes_out()

uint64_t dpp::ssl_client::get_bytes_out ( )
inherited

Get the bytes out objectGet total bytes sent.

Returns
uint64_t bytes sent

References dpp::ssl_client::bytes_out.

◆ get_channel_count()

uint64_t dpp::discord_client::get_channel_count ( )

Get the Channel Count for this shard.

Returns
uint64_t channel count

References dpp::guild::channels, dpp::cache< T >::get_container(), dpp::get_guild_cache(), dpp::cache< T >::get_mutex(), if, and dpp::guild::shard_id.

Here is the call graph for this function:

◆ get_cipher()

std::string dpp::ssl_client::get_cipher ( )
inherited

Get SSL cipher name.

Returns
std::string ssl cipher name

References dpp::ssl_client::cipher.

◆ get_decompressed_bytes_in()

uint64_t dpp::discord_client::get_decompressed_bytes_in ( )

Get the decompressed bytes in objectGet decompressed total bytes received.

Returns
uint64_t bytes received

◆ get_guild_count()

uint64_t dpp::discord_client::get_guild_count ( )

Get the Guild Count for this shard.

Returns
uint64_t guild count

References dpp::cache< T >::get_container(), dpp::get_guild_cache(), dpp::cache< T >::get_mutex(), if, and dpp::guild::shard_id.

Here is the call graph for this function:

◆ get_member_count()

uint64_t dpp::discord_client::get_member_count ( )

◆ get_queue_size()

size_t dpp::discord_client::get_queue_size ( )

Get the size of the outbound message queue.

Returns
The size of the queue

◆ get_state()

ws_state dpp::websocket_client::get_state ( )
protectedinherited

Get websocket state.

Returns
websocket state

References dpp::WS_MASKBIT.

Referenced by is_connected(), dpp::discord_voice_client::is_connected(), and dpp::discord_voice_client::one_second_timer().

Here is the caller graph for this function:

◆ get_uptime()

dpp::utility::uptime dpp::discord_client::get_uptime ( )

Returns the connection time of the shard.

Returns
dpp::utility::uptime Detail of how long the shard has been connected for

◆ get_voice()

voiceconn * dpp::discord_client::get_voice ( snowflake  guild_id)

Get the dpp::voiceconn object for a specific guild on this shard.

Parameters
guild_idThe guild ID to retrieve the voice connection for
Returns
voiceconn* The voice connection for the guild, or nullptr if there is no voice connection to this guild.

References connecting_voice_channels, dpp::unicode_emoji::lock, dpp::unicode_emoji::v, and voice_mutex.

◆ handle_buffer()

bool dpp::websocket_client::handle_buffer ( std::string &  buffer)
virtualinherited

Processes incoming frames from the SSL socket input buffer.

Parameters
bufferThe buffer contents. Can modify this value removing the head elements when processed.

Reimplemented from dpp::ssl_client.

References dpp::CONNECTED.

◆ handle_event()

void dpp::discord_client::handle_event ( const std::string &  event,
json j,
const std::string &  raw 
)
virtual

Handle an event (opcode 0)

Parameters
eventEvent name, e.g. MESSAGE_CREATE
jJSON object for the event content
rawRaw JSON event string

References dpp::event_map, dpp::ll_debug, and log().

Referenced by handle_frame().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_frame()

bool dpp::discord_client::handle_frame ( const std::string &  buffer)
virtual

Handle JSON from the websocket.

Parameters
bufferThe entire buffer content from the websocket client
Returns
True if a frame has been handled

This section parses the input frames from the websocket after they're decompressed. Note that both ETF and JSON parsers return an nlohmann::json object, so that the rest of the library or any user code does not need to be concerned with protocol differences. Generally, ETF is faster and consumes much less memory, but provides less opportunities to diagnose if it goes wrong.

Reimplemented from dpp::websocket_client.

References dpp::ssl_client::buffer, dpp::websocket_client::close(), creator, dpp::zlibcontext::d_stream, dpp::utility::debug_dump(), DECOMP_BUFFER_SIZE, DPP_OS, dpp::err_compression_data, dpp::err_compression_memory, dpp::err_compression_stream, dpp::err_reconnection, error(), handle_event(), heartbeat_interval, last_heartbeat_ack, dpp::cluster::last_identify, last_seq, dpp::ll_debug, dpp::ll_error, log(), max_shards, dpp::unicode_emoji::o, dpp::etf_parser::parse(), protocol, reconnects, resumes, sessionid, shard_id, STRINGIFY, dpp::utility::time_f(), token, websocket_ping, dpp::websocket_client::write(), dpp::ws_etf, and dpp::ws_json.

Here is the call graph for this function:

◆ is_connected()

bool dpp::discord_client::is_connected ( )

Returns true if the shard is connected.

Returns
True if connected

References dpp::CONNECTED, dpp::websocket_client::get_state(), and ready.

Referenced by one_second_timer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ log()

void dpp::discord_client::log ( dpp::loglevel  severity,
const std::string &  msg 
) const
virtual

Log a message to whatever log the user is using.

The logged message is passed up the chain to the on_log event in user code which can then do whatever it wants to do with it.

Parameters
severityThe log level from dpp::loglevel
msgThe log message to output

Reimplemented from dpp::ssl_client.

References creator, dpp::log_t::message, dpp::cluster::on_log, and dpp::log_t::severity.

Referenced by dpp::voiceconn::connect(), connect_voice(), disconnect_voice_internal(), error(), handle_event(), handle_frame(), and one_second_timer().

Here is the caller graph for this function:

◆ one_second_timer()

void dpp::discord_client::one_second_timer ( )
virtual

◆ queue_message()

void dpp::discord_client::queue_message ( const std::string &  j,
bool  to_front = false 
)

Queue a message to be sent via the websocket.

Parameters
jThe JSON data of the message to be sent
to_frontIf set to true, will place the message at the front of the queue not the back (this is for urgent messages such as heartbeat, presence, so they can take precedence over chunk requests etc)

Referenced by connect_voice(), disconnect_voice_internal(), and one_second_timer().

Here is the caller graph for this function:

◆ read_loop()

◆ run()

void dpp::discord_client::run ( )

Start and monitor I/O loop.

Note
this is a blocking call and is usually executed within a thread by whatever creates the object.

References dpp::unicode_emoji::thread, and thread_id.

◆ send_close_packet()

void dpp::websocket_client::send_close_packet ( )
inherited

Send OP_CLOSE error code 1000 to the other side of the connection.

This indicates graceful close.

References dpp::ssl_client::close(), and dpp::HTTP_HEADERS.

Here is the call graph for this function:

◆ write()

void dpp::websocket_client::write ( const std::string &  data)
virtualinherited

Write to websocket.

Encapsulates data in frames if the status is CONNECTED.

Parameters
dataThe data to send.

Reimplemented from dpp::ssl_client.

Referenced by handle_frame(), dpp::discord_voice_client::handle_frame(), one_second_timer(), dpp::discord_voice_client::one_second_timer(), and dpp::websocket_client::websocket_client().

Here is the caller graph for this function:

Friends And Related Function Documentation

◆ dpp::cluster

friend class dpp::cluster
friend

Needed to allow cluster::set_presence to use the ETF functions.

◆ dpp::events::guild_create

friend class dpp::events::guild_create
friend

Needed so that guild_create can request member chunks if you have the correct intents.

◆ dpp::events::voice_state_update

friend class dpp::events::voice_state_update
friend

Needed so that voice_state_update can call dpp::discord_client::disconnect_voice_internal.

Member Data Documentation

◆ buffer

std::string dpp::ssl_client::buffer
protectedinherited

Input buffer received from socket.

Referenced by dpp::ssl_client::close(), handle_frame(), and dpp::ssl_client::read_loop().

◆ bytes_in

uint64_t dpp::ssl_client::bytes_in
protectedinherited

◆ bytes_out

uint64_t dpp::ssl_client::bytes_out
protectedinherited

◆ cipher

std::string dpp::ssl_client::cipher
protectedinherited

SSL cipher in use.

Referenced by dpp::ssl_client::connect(), and dpp::ssl_client::get_cipher().

◆ connecting_voice_channels

std::unordered_map<snowflake, std::unique_ptr<voiceconn> > dpp::discord_client::connecting_voice_channels

List of voice channels we are connecting to keyed by guild id.

Referenced by connect_voice(), disconnect_voice_internal(), and get_voice().

◆ creator

◆ custom_readable_fd

socket_callback_t dpp::ssl_client::custom_readable_fd
inherited

Attaching an additional file descriptor to this function will send notifications when there is data to read.

NOTE: Only hook this if you NEED it as it can increase CPU usage of the thread! Returning -1 means that you don't want to be notified.

Referenced by dpp::discord_voice_client::handle_frame(), and dpp::ssl_client::read_loop().

◆ custom_readable_ready

socket_notification_t dpp::ssl_client::custom_readable_ready
inherited

This event will be called when you can read from the custom fd.

Referenced by dpp::discord_voice_client::handle_frame(), and dpp::ssl_client::read_loop().

◆ custom_writeable_fd

socket_callback_t dpp::ssl_client::custom_writeable_fd
inherited

Attaching an additional file descriptor to this function will send notifications when you are able to write to the socket.

NOTE: Only hook this if you NEED it as it can increase CPU usage of the thread! You should toggle this to -1 when you do not have anything to write otherwise it'll keep triggering repeatedly (it is level triggered).

Referenced by dpp::discord_voice_client::handle_frame(), and dpp::ssl_client::read_loop().

◆ custom_writeable_ready

socket_notification_t dpp::ssl_client::custom_writeable_ready
inherited

This event will be called when you can write to a custom fd.

Referenced by dpp::discord_voice_client::handle_frame(), and dpp::ssl_client::read_loop().

◆ heartbeat_interval

uint32_t dpp::discord_client::heartbeat_interval

Heartbeat interval for sending heartbeat keepalive.

Note
value in milliseconds

Referenced by handle_frame(), and one_second_timer().

◆ hostname

std::string dpp::ssl_client::hostname
protectedinherited

◆ intents

uint32_t dpp::discord_client::intents

Privileged gateway intents.

See also
dpp::intents

◆ keepalive

bool dpp::ssl_client::keepalive
inherited

True if we are keeping the connection alive after it has finished.

Referenced by dpp::ssl_client::close(), and dpp::ssl_client::ssl_client().

◆ last_heartbeat

time_t dpp::discord_client::last_heartbeat

Last heartbeat.

Referenced by one_second_timer().

◆ last_heartbeat_ack

time_t dpp::discord_client::last_heartbeat_ack

Last heartbeat ACK (opcode 11)

Referenced by handle_frame(), and one_second_timer().

◆ last_seq

uint64_t dpp::discord_client::last_seq

Last sequence number received, for resumes and pings.

Referenced by handle_frame(), and one_second_timer().

◆ last_tick

time_t dpp::ssl_client::last_tick
protectedinherited

For timers.

Referenced by dpp::ssl_client::read_loop().

◆ make_new

bool dpp::ssl_client::make_new
protectedinherited

True if we are establishing a new connection, false if otherwise.

Referenced by dpp::ssl_client::connect(), and dpp::ssl_client::ssl_client().

◆ max_shards

uint32_t dpp::discord_client::max_shards

Total number of shards.

Referenced by handle_frame().

◆ nonblocking

bool dpp::ssl_client::nonblocking
protectedinherited

True if in nonblocking mode.

The socket switches to nonblocking mode once ReadLoop is called.

Referenced by dpp::ssl_client::connect(), dpp::ssl_client::read_loop(), and dpp::ssl_client::write().

◆ obuffer

std::string dpp::ssl_client::obuffer
protectedinherited

Output buffer for sending to socket.

Referenced by dpp::ssl_client::close(), dpp::ssl_client::read_loop(), and dpp::ssl_client::write().

◆ plaintext

bool dpp::ssl_client::plaintext
protectedinherited

◆ port

std::string dpp::ssl_client::port
protectedinherited

◆ protocol

websocket_protocol_t dpp::discord_client::protocol

Current websocket protocol, currently either ETF or JSON.

Referenced by handle_frame().

◆ ready

bool dpp::discord_client::ready

True if READY or RESUMED has been received.

Referenced by is_connected().

◆ reconnects

uint32_t dpp::discord_client::reconnects

Reconnection count.

Referenced by handle_frame().

◆ resume_gateway_url

std::string dpp::discord_client::resume_gateway_url

The gateway address we reconnect to when we resume a session.

◆ resumes

uint32_t dpp::discord_client::resumes

Resume count.

Referenced by handle_frame().

◆ sessionid

std::string dpp::discord_client::sessionid

Discord session id.

Referenced by handle_frame(), and one_second_timer().

◆ sfd

dpp::socket dpp::ssl_client::sfd
protectedinherited

◆ shard_id

uint32_t dpp::discord_client::shard_id

Shard ID of this client.

Referenced by handle_frame().

◆ ssl

◆ terminating

bool dpp::discord_client::terminating
protected

True if the shard is terminating.

Referenced by one_second_timer().

◆ thread_id

std::thread::native_handle_type dpp::discord_client::thread_id

Thread ID.

Referenced by run().

◆ token

std::string dpp::discord_client::token

Discord bot token.

Referenced by handle_frame().

◆ voice_mutex

std::shared_mutex dpp::discord_client::voice_mutex

Mutex for voice connections map.

Referenced by connect_voice(), disconnect_voice_internal(), and get_voice().

◆ websocket_ping

double dpp::discord_client::websocket_ping

Websocket latency in fractional seconds.

Referenced by handle_frame(), and main().


The documentation for this class was generated from the following files: