Skip to content

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed

include/dpp/discordclient.h

+11
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,12 @@ class DPP_EXPORT discord_client : public websocket_client
257257
*/
258258
void end_zlib();
259259

260+
/**
261+
* @brief Update the websocket hostname with the resume url
262+
* from the last READY event
263+
*/
264+
void set_resume_hostname();
265+
260266
public:
261267
/**
262268
* @brief Owning cluster
@@ -350,6 +356,11 @@ class DPP_EXPORT discord_client : public websocket_client
350356
*/
351357
std::unordered_map<snowflake, voiceconn*> connecting_voice_channels;
352358

359+
/**
360+
* @brief The gateway address we reconnect to when we resume a session
361+
*/
362+
std::string resume_gateway_url;
363+
353364
/**
354365
* @brief Log a message to whatever log the user is using.
355366
* The logged message is passed up the chain to the on_log event in user code which can then do whatever

src/dpp/discordclient.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ discord_client::discord_client(dpp::cluster* _cluster, uint32_t _shard_id, uint3
9393
websocket_ping(0.0),
9494
ready(false),
9595
last_heartbeat_ack(time(nullptr)),
96-
protocol(ws_proto)
96+
protocol(ws_proto),
97+
resume_gateway_url(DEFAULT_GATEWAY)
9798
{
9899
zlib = new zlibcontext();
99100
etf = new etf_parser();
@@ -141,6 +142,11 @@ void discord_client::end_zlib()
141142
}
142143
}
143144

145+
void discord_client::set_resume_hostname()
146+
{
147+
hostname = resume_gateway_url;
148+
}
149+
144150
void discord_client::thread_run()
145151
{
146152
utility::set_thread_name(std::string("shard/") + std::to_string(shard_id));
@@ -155,9 +161,10 @@ void discord_client::thread_run()
155161
end_zlib();
156162
setup_zlib();
157163
do {
158-
this->log(ll_debug, "Attempting reconnection of shard " + std::to_string(this->shard_id));
164+
this->log(ll_debug, "Attempting reconnection of shard " + std::to_string(this->shard_id) + " to wss://" + resume_gateway_url);
159165
error = false;
160166
try {
167+
set_resume_hostname();
161168
ssl_client::connect();
162169
websocket_client::connect();
163170
}

src/dpp/events/ready.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <dpp/discordevents.h>
2222
#include <dpp/cluster.h>
2323
#include <dpp/stringops.h>
24+
#include <dpp/dns.h>
2425
#include <dpp/nlohmann/json.hpp>
2526

2627
using json = nlohmann::json;
@@ -43,6 +44,21 @@ std::mutex protect_the_loot;
4344
void ready::handle(discord_client* client, json &j, const std::string &raw) {
4445
client->log(dpp::ll_info, "Shard id " + std::to_string(client->shard_id) + " (" + std::to_string(client->shard_id + 1) + "/" + std::to_string(client->max_shards) + ") ready!");
4546
client->sessionid = j["d"]["session_id"];
47+
/* Session-specific gateway resume url
48+
* https://discord.com/developers/docs/change-log#sessionspecific-gateway-resume-urls
49+
*
50+
* Discord give us the hostname wrapped in wss://crap/ like we're going to pass it to
51+
* some top-heavy lib. Let's strip all this out if given to us so we just have a
52+
* hostname.
53+
*/
54+
std::string ugly(j["d"]["resume_gateway_url"]);
55+
if (ugly.substr(0, 6) == "wss://") {
56+
client->resume_gateway_url = ugly.substr(6, ugly.length() - 7);
57+
} else {
58+
client->resume_gateway_url = ugly;
59+
}
60+
/* Pre-resolve it into our cache so that we aren't waiting on this when we need it later */
61+
static_cast<void>(resolve_hostname(client->resume_gateway_url, "443"));
4662

4763
client->ready = true;
4864

src/unittest.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ std::map<std::string, test_t> tests = {
7676
{"COMPARISON", {tt_offline, "dpp::manged object comparison", false, false}},
7777
{"CHANNELCACHE", {tt_online, "dpp::find_channel()", false, false}},
7878
{"CHANNELTYPES", {tt_online, "dpp::channel type flags", false, false}},
79-
{"PERMISSION_CLASS", {tt_offline, "testing dpp::permission functionality", false, false}},
80-
{"USER.GET_MENTION", {tt_offline, "testing dpp::user::get_mention functionality", false, false}},
81-
{"USER.FORMAT_USERNAME", {tt_offline, "testing dpp::user::format_username functionality", false, false}},
82-
{"USER.GET_CREATION_TIME", {tt_offline, "testing dpp::user::get_creation_time functionality", false, false}},
83-
{"UTILITY.ICONHASH", {tt_offline, "testing dpp::utility::iconhash functionality", false, false}},
84-
{"UTILITY.MAKE_URL_PARAMETERS", {tt_offline, "testing dpp::utility::make_url_parameters functionality", false, false}},
85-
{"UTILITY.MARKDOWN_ESCAPE", {tt_offline, "testing dpp::utility::markdown_escape functionality", false, false}},
86-
{"UTILITY.TOKENIZE", {tt_offline, "testing dpp::utility::tokenize functionality", false, false}},
87-
{"UTILITY.URL_ENCODE", {tt_offline, "testing dpp::utility::url_encode functionality", false, false}},
79+
{"PERMISSION_CLASS", {tt_offline, "dpp::permission", false, false}},
80+
{"USER.GET_MENTION", {tt_offline, "dpp::user::get_mention", false, false}},
81+
{"USER.FORMAT_USERNAME", {tt_offline, "dpp::user::format_username", false, false}},
82+
{"USER.GET_CREATION_TIME", {tt_offline, "dpp::user::get_creation_time", false, false}},
83+
{"UTILITY.ICONHASH", {tt_offline, "dpp::utility::iconhash", false, false}},
84+
{"UTILITY.MAKE_URL_PARAMETERS", {tt_offline, "dpp::utility::make_url_parameters", false, false}},
85+
{"UTILITY.MARKDOWN_ESCAPE", {tt_offline, "dpp::utility::markdown_escape", false, false}},
86+
{"UTILITY.TOKENIZE", {tt_offline, "dpp::utility::tokenize", false, false}},
87+
{"UTILITY.URL_ENCODE", {tt_offline, "dpp::utility::url_encode", false, false}},
8888
};
8989

9090
double start = dpp::utility::time_f();

0 commit comments

Comments
 (0)