43 extern voice_connections_map voiceConnectionMap;
45 namespace discord_core_internal {
47 event_converter::event_converter(jsonifier::string newEvent) {
48 eventValue = newEvent;
51 event_converter::operator uint64_t() {
52 if (eventValue ==
"READY") {
54 }
else if (eventValue ==
"RESUMED") {
56 }
else if (eventValue ==
"APPLICATION_COMMAND_PERMISSIONS_UPDATE") {
58 }
else if (eventValue ==
"AUTO_MODERATION_RULE_CREATE") {
60 }
else if (eventValue ==
"AUTO_MODERATION_RULE_UPDATE") {
62 }
else if (eventValue ==
"AUTO_MODERATION_RULE_DELETE") {
64 }
else if (eventValue ==
"AUTO_MODERATION_ACTION_EXECUTION") {
66 }
else if (eventValue ==
"CHANNEL_CREATE") {
68 }
else if (eventValue ==
"CHANNEL_UPDATE") {
70 }
else if (eventValue ==
"CHANNEL_DELETE") {
72 }
else if (eventValue ==
"CHANNEL_PINS_UPDATE") {
74 }
else if (eventValue ==
"THREAD_CREATE") {
76 }
else if (eventValue ==
"THREAD_UPDATE") {
78 }
else if (eventValue ==
"THREAD_DELETE") {
80 }
else if (eventValue ==
"THREAD_LIST_SYNC") {
82 }
else if (eventValue ==
"THREAD_MEMBER_UPDATE") {
84 }
else if (eventValue ==
"THREAD_MEMBERS_UPDATE") {
86 }
else if (eventValue ==
"GUILD_CREATE") {
88 }
else if (eventValue ==
"GUILD_UPDATE") {
90 }
else if (eventValue ==
"GUILD_DELETE") {
92 }
else if (eventValue ==
"GUILD_BAN_ADD") {
94 }
else if (eventValue ==
"GUILD_BAN_REMOVE") {
96 }
else if (eventValue ==
"GUILD_EMOJIS_UPDATE") {
98 }
else if (eventValue ==
"GUILD_STICKERS_UPDATE") {
100 }
else if (eventValue ==
"GUILD_INTEGRATIONS_UPDATE") {
102 }
else if (eventValue ==
"GUILD_MEMBER_ADD") {
104 }
else if (eventValue ==
"GUILD_MEMBER_REMOVE") {
106 }
else if (eventValue ==
"GUILD_MEMBER_UPDATE") {
108 }
else if (eventValue ==
"GUILD_MEMBERS_CHUNK") {
110 }
else if (eventValue ==
"GUILD_ROLE_CREATE") {
112 }
else if (eventValue ==
"GUILD_ROLE_UPDATE") {
114 }
else if (eventValue ==
"GUILD_ROLE_DELETE") {
116 }
else if (eventValue ==
"GUILD_SCHEDULED_EVENT_CREATE") {
118 }
else if (eventValue ==
"GUILD_SCHEDULED_EVENT_UPDATE") {
120 }
else if (eventValue ==
"GUILD_SCHEDULED_EVENT_DELETE") {
122 }
else if (eventValue ==
"GUILD_SCHEDULED_EVENT_USER_ADD") {
124 }
else if (eventValue ==
"GUILD_SCHEDULED_EVENT_USER_REMOVE") {
126 }
else if (eventValue ==
"INTEGRATION_CREATE") {
128 }
else if (eventValue ==
"INTEGRATION_UPDATE") {
130 }
else if (eventValue ==
"INTEGRATION_DELETE") {
132 }
else if (eventValue ==
"INTERACTION_CREATE") {
134 }
else if (eventValue ==
"INVITE_CREATE") {
136 }
else if (eventValue ==
"INVITE_DELETE") {
138 }
else if (eventValue ==
"MESSAGE_CREATE") {
140 }
else if (eventValue ==
"MESSAGE_UPDATE") {
142 }
else if (eventValue ==
"MESSAGE_DELETE") {
144 }
else if (eventValue ==
"MESSAGE_DELETE_BULK") {
146 }
else if (eventValue ==
"MESSAGE_REACTION_ADD") {
148 }
else if (eventValue ==
"MESSAGE_REACTION_REMOVE") {
150 }
else if (eventValue ==
"MESSAGE_REACTION_REMOVE_ALL") {
152 }
else if (eventValue ==
"MESSAGE_REACTION_REMOVE_EMOJI") {
154 }
else if (eventValue ==
"PRESENCE_UPDATE") {
156 }
else if (eventValue ==
"STAGE_INSTANCE_CREATE") {
158 }
else if (eventValue ==
"STAGE_INSTANCE_UPDATE") {
160 }
else if (eventValue ==
"STAGE_INSTANCE_DELETE") {
162 }
else if (eventValue ==
"TYPING_START") {
164 }
else if (eventValue ==
"USER_UPDATE") {
166 }
else if (eventValue ==
"VOICE_STATE_UPDATE") {
168 }
else if (eventValue ==
"VOICE_SERVER_UPDATE") {
170 }
else if (eventValue ==
"WEBHOOKS_UPDATE") {
177 websocket_core::websocket_core(config_manager* configManagerNew, websocket_type typeOfWebSocketNew) : etf_parser{} {
178 configManager = configManagerNew;
179 wsType = typeOfWebSocketNew;
182 websocket_core& websocket_core::operator=(websocket_core&& other)
noexcept {
183 areWeCollectingData.store(other.areWeCollectingData.load(std::memory_order_acquire), std::memory_order_release);
184 currentState.store(other.currentState.load(std::memory_order_acquire), std::memory_order_release);
185 heartBeatStopWatch = std::move(other.heartBeatStopWatch);
186 haveWeReceivedHeartbeatAck = other.haveWeReceivedHeartbeatAck;
187 currentMessage = std::move(other.currentMessage);
188 tcpConnection = std::move(other.tcpConnection);
189 finalString = std::move(other.finalString);
190 currentReconnectTries = other.currentReconnectTries;
191 dataBuffer = std::move(other.dataBuffer);
192 lastNumberReceived = other.lastNumberReceived;
193 maxReconnectTries = other.maxReconnectTries;
194 areWeHeartBeating = other.areWeHeartBeating;
195 areWeResuming = other.areWeResuming;
196 configManager = other.configManager;
197 dataOpCode = other.dataOpCode;
198 shard.at(0) = other.shard.at(0);
199 shard.at(1) = other.shard.at(1);
200 dataSize = other.dataSize;
201 offSet = other.offSet;
202 wsType = other.wsType;
206 websocket_core::websocket_core(websocket_core&& other) noexcept : etf_parser{} {
207 *
this = std::move(other);
210 bool websocket_core::connect(
const jsonifier::string& baseUrlNew, jsonifier::string_view relativePath,
const uint16_t portNew) {
211 tcpConnection = websocket_tcpconnection{ baseUrlNew, portNew,
this };
212 if (tcpConnection.currentStatus != connection_status::NO_Error) {
213 std::this_thread::sleep_for(1s);
216 currentState.store(websocket_state::upgrading, std::memory_order_release);
217 jsonifier::string sendString{
"GET " + relativePath +
" HTTP/1.1\r\nHost: " + baseUrlNew +
218 "\r\nUpgrade: webSocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: " + generateBase64EncodedKey() +
"\r\nSec-WebSocket-Version: 13\r\n\r\n" };
219 tcpConnection.writeData(
static_cast<jsonifier::string_view
>(sendString),
true);
221 if (tcpConnection.currentStatus != connection_status::NO_Error) {
222 std::this_thread::sleep_for(1s);
228 websocket_tcpconnection::websocket_tcpconnection(
const jsonifier::string& baseUrlNew, uint16_t portNew, websocket_core* ptrNew) : tcp_connection{ baseUrlNew, portNew } {
232 bool websocket_core::sendMessage(jsonifier::string_base<uint8_t>& dataToSend,
bool priority) {
233 if (dataToSend.size() == 0) {
236 jsonifier::string webSocketTitle{ wsType == websocket_type::voice ?
"voice websocket" :
"WebSocket" };
237 message_printer::printSuccess<print_message_type::websocket>(jsonifier::string{
"sending " + webSocketTitle +
" [" + jsonifier::toString(shard.at(0)) +
"," +
238 jsonifier::toString(shard.at(1)) +
"]" + jsonifier::string{
"'s message: " } } +
240 std::unique_lock lock{ accessMutex };
241 if (areWeConnected()) {
242 tcpConnection.writeData(
static_cast<jsonifier::string_view_base<uint8_t>
>(dataToSend), priority);
243 if (tcpConnection.currentStatus != connection_status::NO_Error) {
251 void websocket_core::parseConnectionHeaders() {
252 if (areWeConnected() && currentState.load(std::memory_order_acquire) == websocket_state::upgrading) {
253 jsonifier::string_base<uint8_t> newString{};
255 std::memcpy(newString.data(),
"\r\n\r\n", 4);
256 auto theFindValue = currentMessage.find(newString);
257 if (theFindValue != jsonifier::string::npos) {
258 currentMessage.clear();
259 currentState.store(websocket_state::Collecting_Hello, std::memory_order_release);
265 bool websocket_core::checkForAndSendHeartBeat(
bool isImmediate) {
266 if ((currentState.load(std::memory_order_acquire) == websocket_state::authenticated && heartBeatStopWatch.hasTimeElapsed() && haveWeReceivedHeartbeatAck) ||
268 jsonifier::string_base<uint8_t>
string{};
269 if (dataOpCode == websocket_op_code::Op_Binary) {
270 etf_serializer data{};
271 data[
"d"] = lastNumberReceived;
273 string = data.operator jsonifier::string_base<uint8_t>();
275 websocket_message_data<uint64_t> message{};
276 message.d = lastNumberReceived;
278 parser.serializeJson<
true>(message, string);
280 haveWeReceivedHeartbeatAck =
false;
281 heartBeatStopWatch.reset();
282 createHeader(
string, dataOpCode);
283 return sendMessage(
string,
true);
288 bool websocket_core::parseMessage() {
289 if (currentMessage.size() < 4) {
292 websocket_op_code opcode =
static_cast<websocket_op_code
>(currentMessage.at(0) & ~webSocketMaskBit);
294 case websocket_op_code::Op_Continuation:
296 case websocket_op_code::Op_Text:
298 case websocket_op_code::Op_Binary:
300 case websocket_op_code::Op_Ping:
302 case websocket_op_code::Op_Pong: {
303 uint8_t length00 = currentMessage.at(1);
304 uint32_t messageOffset = 2;
306 if (length00 & webSocketMaskBit) {
310 uint64_t lengthFinal = length00;
312 if (length00 == webSocketPayloadLengthMagicLarge) {
313 if (currentMessage.size() < 8) {
317 uint8_t length01 =
static_cast<uint8_t
>(currentMessage.at(2));
318 uint8_t length02 =
static_cast<uint8_t
>(currentMessage.at(3));
319 lengthFinal =
static_cast<uint64_t
>((length01 << 8ULL) | length02);
322 }
else if (length00 == webSocketPayloadLengthMagicHuge) {
323 if (currentMessage.size() < 10) {
327 for (uint64_t x = 2, shift = 56; x < 10; ++x, shift -= 8) {
328 uint8_t length03 =
static_cast<uint8_t
>(currentMessage.at(x));
329 lengthFinal |=
static_cast<uint64_t
>(length03 & 0xff) << shift;
334 if (currentMessage.size() < messageOffset + lengthFinal) {
338 if (opcode == websocket_op_code::Op_Ping || opcode == websocket_op_code::Op_Pong) {
341 onMessageReceived({ currentMessage.data() + messageOffset, lengthFinal });
342 currentMessage.erase(messageOffset + lengthFinal);
346 case websocket_op_code::Op_Close: {
347 uint16_t closeValue =
static_cast<uint16_t
>(currentMessage.at(2) & 0xff);
349 closeValue |= currentMessage.at(3) & 0xff;
350 jsonifier::string closeString{};
351 if (wsType == websocket_type::voice) {
352 voice_websocket_close voiceClose{ closeValue };
353 closeString =
static_cast<jsonifier::string
>(voiceClose.operator jsonifier::string_view());
355 websocket_close wsClose{ closeValue };
356 closeString =
static_cast<jsonifier::string
>(wsClose.operator jsonifier::string_view());
358 jsonifier::string webSocketTitle = wsType == websocket_type::voice ?
"voice websocket" :
"WebSocket";
359 message_printer::printError<print_message_type::websocket>(jsonifier::string{ webSocketTitle +
" [" + jsonifier::toString(shard.at(0)) +
"," +
360 jsonifier::toString(shard.at(1)) +
"]" +
" closed; code: " + jsonifier::toString(closeValue) +
", " + closeString });
371 bool websocket_core::areWeConnected() {
372 return tcpConnection.areWeStillConnected();
375 void websocket_tcpconnection::handleBuffer() {
376 auto inputBufferNew = getInputBuffer();
377 auto oldSize = ptr->currentMessage.size();
378 if (ptr->currentMessage.size() < oldSize + inputBufferNew.size()) {
379 ptr->currentMessage.resize(oldSize + inputBufferNew.size());
381 std::memcpy(ptr->currentMessage.data() + oldSize, inputBufferNew.data(), inputBufferNew.size());
382 if (ptr->currentState.load(std::memory_order_acquire) == websocket_state::upgrading) {
383 ptr->parseConnectionHeaders();
385 while (ptr->parseMessage()) {
390 websocket_client::websocket_client(uint64_t currentShardNew, std::atomic_bool* doWeQuitNew)
391 : websocket_core(&discord_core_client::getInstance()->configManager, websocket_type::normal) {
392 configManager = &discord_core_client::getInstance()->configManager;
393 shard.at(0) = currentShardNew;
394 doWeQuit = doWeQuitNew;
395 if (discord_core_client::getInstance()) {
396 shard.at(1) = discord_core_client::getInstance()->configManager.getTotalShardCount();
397 if (discord_core_client::getInstance()->configManager.getTextFormat() == text_format::etf) {
398 dataOpCode = websocket_op_code::Op_Binary;
400 dataOpCode = websocket_op_code::Op_Text;
405 void websocket_client::getVoiceConnectionData(
const voice_connect_init_data& doWeCollect) {
406 while (currentState.load(std::memory_order_acquire) != websocket_state::authenticated) {
407 std::this_thread::sleep_for(1ms);
409 websocket_message_data<update_voice_state_data_dc> data01{};
410 data01.excludedKeys.emplace(
"t");
411 data01.excludedKeys.emplace(
"s");
412 data01.d.channelId = std::nullptr_t{};
413 data01.d.guildId = doWeCollect.guildId;
414 data01.d.selfDeaf = doWeCollect.selfDeaf;
415 data01.d.selfMute = doWeCollect.selfMute;
417 userId = doWeCollect.userId;
419 websocket_message_data<update_voice_state_data> data02{};
420 data02.excludedKeys.emplace(
"t");
421 data02.excludedKeys.emplace(
"s");
422 data02.d.channelId = doWeCollect.channelId;
423 data02.d.guildId = doWeCollect.guildId;
424 data02.d.selfDeaf = doWeCollect.selfDeaf;
425 data02.d.selfMute = doWeCollect.selfMute;
427 jsonifier::string_base<uint8_t>
string{};
428 auto serializer = data01.operator etf_serializer();
429 if (dataOpCode == websocket_op_code::Op_Binary) {
430 string = serializer.operator jsonifier::string_base<uint8_t>();
432 parser.serializeJson<
true>(data01, string);
434 createHeader(
string, dataOpCode);
435 if (!sendMessage(
string,
true)) {
438 if (snowflake{ doWeCollect.channelId } == 0) {
441 serializer = data02.operator etf_serializer();
442 if (dataOpCode == websocket_op_code::Op_Binary) {
443 string = serializer.operator jsonifier::string_base<uint8_t>();
445 parser.serializeJson<
true>(data02, string);
447 createHeader(
string, dataOpCode);
448 areWeCollectingData.store(
true, std::memory_order_release);
449 if (!sendMessage(
string,
true)) {
454 uint64_t countBackSlashes(jsonifier::string_base<uint8_t>::iterator& iter, jsonifier::string_base<uint8_t>::iterator end, uint64_t currentCount = 0) {
459 return countBackSlashes(iter, end, currentCount);
466 uint64_t findInvalidJSONIndex(jsonifier::string_view_base<uint8_t> jsonStr) {
467 std::stack<uint8_t> stack;
468 bool areWeInAString{
false };
469 jsonifier::string_base<uint8_t> stringNew{ jsonStr +
'\0' };
470 uint64_t backslashCount{};
471 for (jsonifier::string_base<uint8_t>::iterator iter{ stringNew.begin() }; iter != stringNew.end(); ++iter) {
472 if (iter > stringNew.begin()) {
473 uint8_t cMinus1 = *(iter - 1);
477 backslashCount = countBackSlashes(iter, stringNew.end());
479 cMinus1 = *(iter - 1);
482 if ((c ==
'{' || c ==
'[' || c ==
'"') && cMinus1 !=
'\\' && !areWeInAString && backslashCount % 1 == 0) {
484 areWeInAString =
true;
487 }
else if (areWeInAString && c ==
'"' && cMinus1 !=
'\\' && backslashCount % 1 == 0) {
488 areWeInAString =
false;
490 }
else if ((c ==
'}' || c ==
']' || c ==
'"') && !areWeInAString) {
492 uint8_t top = stack.top();
495 if ((c ==
'}' && top !=
'{') || (c ==
']' && top !=
'[') || (c ==
'"' && top !=
'"')) {
496 return static_cast<uint64_t
>(iter - stringNew.begin());
501 if ((c ==
'{' || c ==
'[' || c ==
'"') && !areWeInAString) {
503 areWeInAString =
true;
506 }
else if (areWeInAString && c ==
'"' ) {
507 areWeInAString =
false;
509 }
else if ((c ==
'}' || c ==
']' || c ==
'"') && !areWeInAString) {
510 uint8_t top = stack.top();
513 if ((c ==
'}' && top !=
'{') || (c ==
']' && top !=
'[') || (c ==
'"' && top !=
'"')) {
514 return static_cast<uint64_t
>(iter - stringNew.begin());
521 return std::numeric_limits<uint64_t>::max();
523 return jsonStr.size();
527 bool websocket_client::onMessageReceived(jsonifier::string_view_base<uint8_t> dataNew) {
529 if (areWeConnected() && currentMessage.size() > 0 && dataNew.size() > 0) {
530 websocket_message message{};
531 if (configManager->getTextFormat() == text_format::etf) {
533 dataNew = etf_parser::parseEtfToJson(dataNew);
534 auto newString = jsonifier::string{ dataNew };
535 parser.parseJson<
true,
true>(message, newString);
536 if (
auto result = parser.getErrors(); result.size() > 0) {
537 for (
auto& valueNew: result) {
538 message_printer::printError<print_message_type::websocket>(valueNew.reportError() +
", for data:" + dataNew);
541 }
catch (
const dca_exception& error) {
542 message_printer::printError<print_message_type::websocket>(error.what());
543 tcpConnection.getInputBuffer();
544 currentMessage.clear();
549 if (
auto result = findInvalidJSONIndex(dataNew); result != std::numeric_limits<uint64_t>::max()) {
550 throw dca_exception{
"Sorry, but that json data is invalid at index: " + jsonifier::toString(result) +
" and it is: " + dataNew };
553 parser.parseJson<
true,
true>(message, dataNew);
554 if (
auto result = parser.getErrors(); result.size() > 0) {
555 for (
auto& valueNew: result) {
556 message_printer::printError<print_message_type::websocket>(valueNew.reportError() +
", for data:" + dataNew);
561 if (message.s != 0) {
562 lastNumberReceived =
static_cast<uint32_t
>(message.s);
564 message_printer::printSuccess<print_message_type::websocket>(jsonifier::string{
"Message received from websocket [" + jsonifier::toString(shard.at(0)) +
"," +
565 jsonifier::toString(shard.at(1)) + jsonifier::string(
"]: ") + jsonifier::string{ dataNew } });
567 case websocket_op_codes::dispatch: {
568 if (message.t !=
"") {
569 switch (event_converter{ message.t }) {
571 websocket_message_data<ready_data> data{};
572 if (dataOpCode == websocket_op_code::Op_Text) {
573 data.d.excludedKeys.emplace(
"shard");
575 currentState.store(websocket_state::authenticated, std::memory_order_release);
576 parser.parseJson<
true,
true>(data, dataNew);
577 if (
auto result = parser.getErrors(); result.size() > 0) {
578 for (
auto& valueNew: result) {
579 message_printer::printError<print_message_type::websocket>(valueNew.reportError());
582 sessionId = data.d.sessionId;
583 if (data.d.resumeGatewayUrl.find(
"wss://") != jsonifier::string::npos) {
584 resumeUrl = data.d.resumeGatewayUrl.substr(data.d.resumeGatewayUrl.find(
"wss://") + jsonifier::string{
"wss://" }.size());
586 discord_core_client::getInstance()->currentUser = bot_user{ data.d.user,
587 discord_core_client::getInstance()
588 ->baseSocketAgentsMap[
static_cast<uint64_t
>(floor(
589 static_cast<uint64_t
>(shard.at(0)) %
static_cast<uint64_t
>(discord_core_client::getInstance()->baseSocketAgentsMap.size())))]
591 users::insertUser(
static_cast<user_cache_data
>(std::move(data.d.user)));
592 currentReconnectTries = 0;
596 currentState.store(websocket_state::authenticated, std::memory_order_release);
597 currentReconnectTries = 0;
601 if (discord_core_client::getInstance()->eventManager.onApplicationCommandPermissionsUpdateEvent.functions.size() > 0) {
602 unique_ptr<on_application_command_permissions_update_data> dataPackage{ makeUnique<on_application_command_permissions_update_data>(
604 discord_core_client::getInstance()->eventManager.onApplicationCommandPermissionsUpdateEvent(*dataPackage);
609 if (discord_core_client::getInstance()->eventManager.onAutoModerationRuleCreationEvent.functions.size() > 0) {
610 unique_ptr<on_auto_moderation_rule_creation_data> dataPackage{ makeUnique<on_auto_moderation_rule_creation_data>(parser, dataNew) };
611 discord_core_client::getInstance()->eventManager.onAutoModerationRuleCreationEvent(*dataPackage);
616 if (discord_core_client::getInstance()->eventManager.onAutoModerationRuleUpdateEvent.functions.size() > 0) {
617 unique_ptr<on_auto_moderation_rule_update_data> dataPackage{ makeUnique<on_auto_moderation_rule_update_data>(parser, dataNew) };
618 discord_core_client::getInstance()->eventManager.onAutoModerationRuleUpdateEvent(*dataPackage);
623 if (discord_core_client::getInstance()->eventManager.onAutoModerationRuleDeletionEvent.functions.size() > 0) {
624 unique_ptr<on_auto_moderation_rule_deletion_data> dataPackage{ makeUnique<on_auto_moderation_rule_deletion_data>(parser, dataNew) };
625 discord_core_client::getInstance()->eventManager.onAutoModerationRuleDeletionEvent(*dataPackage);
630 if (discord_core_client::getInstance()->eventManager.onAutoModerationActionExecutionEvent.functions.size() > 0) {
631 unique_ptr<on_auto_moderation_action_execution_data> dataPackage{ makeUnique<on_auto_moderation_action_execution_data>(parser,
633 discord_core_client::getInstance()->eventManager.onAutoModerationActionExecutionEvent(*dataPackage);
638 unique_ptr<on_channel_creation_data> dataPackage{ makeUnique<on_channel_creation_data>(parser, dataNew) };
639 if (discord_core_client::getInstance()->eventManager.onChannelCreationEvent.functions.size() > 0) {
640 discord_core_client::getInstance()->eventManager.onChannelCreationEvent(*dataPackage);
645 unique_ptr<on_channel_update_data> dataPackage{ makeUnique<on_channel_update_data>(parser, dataNew) };
646 if (discord_core_client::getInstance()->eventManager.onChannelUpdateEvent.functions.size() > 0) {
647 discord_core_client::getInstance()->eventManager.onChannelUpdateEvent(*dataPackage);
652 unique_ptr<on_channel_deletion_data> dataPackage{ makeUnique<on_channel_deletion_data>(parser, dataNew) };
653 if (discord_core_client::getInstance()->eventManager.onChannelDeletionEvent.functions.size() > 0) {
654 discord_core_client::getInstance()->eventManager.onChannelDeletionEvent(*dataPackage);
659 if (discord_core_client::getInstance()->eventManager.onChannelPinsUpdateEvent.functions.size() > 0) {
660 unique_ptr<on_channel_pins_update_data> dataPackage{ makeUnique<on_channel_pins_update_data>(parser, dataNew) };
661 discord_core_client::getInstance()->eventManager.onChannelPinsUpdateEvent(*dataPackage);
666 if (discord_core_client::getInstance()->eventManager.onThreadCreationEvent.functions.size() > 0) {
667 unique_ptr<on_thread_creation_data> dataPackage{ makeUnique<on_thread_creation_data>(parser, dataNew) };
668 discord_core_client::getInstance()->eventManager.onThreadCreationEvent(*dataPackage);
673 if (discord_core_client::getInstance()->eventManager.onThreadUpdateEvent.functions.size() > 0) {
674 unique_ptr<on_thread_update_data> dataPackage{ makeUnique<on_thread_update_data>(parser, dataNew) };
675 discord_core_client::getInstance()->eventManager.onThreadUpdateEvent(*dataPackage);
680 if (discord_core_client::getInstance()->eventManager.onThreadDeletionEvent.functions.size() > 0) {
681 unique_ptr<on_thread_deletion_data> dataPackage{ makeUnique<on_thread_deletion_data>(parser, dataNew) };
682 discord_core_client::getInstance()->eventManager.onThreadDeletionEvent(*dataPackage);
687 if (discord_core_client::getInstance()->eventManager.onThreadListSyncEvent.functions.size() > 0) {
688 unique_ptr<on_thread_list_sync_data> dataPackage{ makeUnique<on_thread_list_sync_data>(parser, dataNew) };
689 discord_core_client::getInstance()->eventManager.onThreadListSyncEvent(*dataPackage);
694 if (discord_core_client::getInstance()->eventManager.onThreadMemberUpdateEvent.functions.size() > 0) {
695 unique_ptr<on_thread_member_update_data> dataPackage{ makeUnique<on_thread_member_update_data>(parser, dataNew) };
696 discord_core_client::getInstance()->eventManager.onThreadMemberUpdateEvent(*dataPackage);
701 if (discord_core_client::getInstance()->eventManager.onThreadMembersUpdateEvent.functions.size() > 0) {
702 unique_ptr<on_thread_members_update_data> dataPackage{ makeUnique<on_thread_members_update_data>(parser, dataNew) };
703 discord_core_client::getInstance()->eventManager.onThreadMembersUpdateEvent(*dataPackage);
708 unique_ptr<on_guild_creation_data> dataPackage{ makeUnique<on_guild_creation_data>(parser, dataNew) };
709 if (discord_core_client::getInstance()->eventManager.onGuildCreationEvent.functions.size() > 0) {
710 discord_core_client::getInstance()->eventManager.onGuildCreationEvent(*dataPackage);
715 unique_ptr<on_guild_update_data> dataPackage{ makeUnique<on_guild_update_data>(parser, dataNew) };
716 if (discord_core_client::getInstance()->eventManager.onGuildUpdateEvent.functions.size() > 0) {
717 discord_core_client::getInstance()->eventManager.onGuildUpdateEvent(*dataPackage);
722 unique_ptr<on_guild_deletion_data> dataPackage{ makeUnique<on_guild_deletion_data>(parser, dataNew) };
723 if (discord_core_client::getInstance()->eventManager.onGuildDeletionEvent.functions.size() > 0) {
724 discord_core_client::getInstance()->eventManager.onGuildDeletionEvent(*dataPackage);
729 if (discord_core_client::getInstance()->eventManager.onGuildBanAddEvent.functions.size() > 0) {
730 unique_ptr<on_guild_ban_add_data> dataPackage{ makeUnique<on_guild_ban_add_data>(parser, dataNew) };
731 discord_core_client::getInstance()->eventManager.onGuildBanAddEvent(*dataPackage);
736 if (discord_core_client::getInstance()->eventManager.onGuildBanRemoveEvent.functions.size() > 0) {
737 unique_ptr<on_guild_ban_remove_data> dataPackage{ makeUnique<on_guild_ban_remove_data>(parser, dataNew) };
738 discord_core_client::getInstance()->eventManager.onGuildBanRemoveEvent(*dataPackage);
743 if (discord_core_client::getInstance()->eventManager.onGuildEmojisUpdateEvent.functions.size() > 0) {
744 unique_ptr<on_guild_emojis_update_data> dataPackage{ makeUnique<on_guild_emojis_update_data>(parser, dataNew) };
745 discord_core_client::getInstance()->eventManager.onGuildEmojisUpdateEvent(*dataPackage);
750 if (discord_core_client::getInstance()->eventManager.onGuildStickersUpdateEvent.functions.size() > 0) {
751 unique_ptr<on_guild_stickers_update_data> dataPackage{ makeUnique<on_guild_stickers_update_data>(parser, dataNew) };
752 discord_core_client::getInstance()->eventManager.onGuildStickersUpdateEvent(*dataPackage);
757 if (discord_core_client::getInstance()->eventManager.onGuildIntegrationsUpdateEvent.functions.size() > 0) {
758 unique_ptr<on_guild_integrations_update_data> dataPackage{ makeUnique<on_guild_integrations_update_data>(parser, dataNew) };
759 discord_core_client::getInstance()->eventManager.onGuildIntegrationsUpdateEvent(*dataPackage);
764 unique_ptr<on_guild_member_add_data> dataPackage{ makeUnique<on_guild_member_add_data>(parser, dataNew) };
765 if (discord_core_client::getInstance()->eventManager.onGuildMemberAddEvent.functions.size() > 0) {
766 discord_core_client::getInstance()->eventManager.onGuildMemberAddEvent(*dataPackage);
771 unique_ptr<on_guild_member_remove_data> dataPackage{ makeUnique<on_guild_member_remove_data>(parser, dataNew) };
772 if (discord_core_client::getInstance()->eventManager.onGuildMemberRemoveEvent.functions.size() > 0) {
773 discord_core_client::getInstance()->eventManager.onGuildMemberRemoveEvent(*dataPackage);
778 unique_ptr<on_guild_member_update_data> dataPackage{ makeUnique<on_guild_member_update_data>(parser, dataNew) };
779 if (discord_core_client::getInstance()->eventManager.onGuildMemberUpdateEvent.functions.size() > 0) {
780 discord_core_client::getInstance()->eventManager.onGuildMemberUpdateEvent(*dataPackage);
785 if (discord_core_client::getInstance()->eventManager.onGuildMembersChunkEvent.functions.size() > 0) {
786 unique_ptr<on_guild_members_chunk_data> dataPackage{ makeUnique<on_guild_members_chunk_data>(parser, dataNew) };
787 discord_core_client::getInstance()->eventManager.onGuildMembersChunkEvent(*dataPackage);
792 unique_ptr<on_role_creation_data> dataPackage{ makeUnique<on_role_creation_data>(parser, dataNew) };
793 if (discord_core_client::getInstance()->eventManager.onRoleCreationEvent.functions.size() > 0) {
794 discord_core_client::getInstance()->eventManager.onRoleCreationEvent(*dataPackage);
799 unique_ptr<on_role_update_data> dataPackage{ makeUnique<on_role_update_data>(parser, dataNew) };
800 if (discord_core_client::getInstance()->eventManager.onRoleUpdateEvent.functions.size() > 0) {
801 discord_core_client::getInstance()->eventManager.onRoleUpdateEvent(*dataPackage);
806 unique_ptr<on_role_deletion_data> dataPackage{ makeUnique<on_role_deletion_data>(parser, dataNew) };
807 if (discord_core_client::getInstance()->eventManager.onRoleDeletionEvent.functions.size() > 0) {
808 discord_core_client::getInstance()->eventManager.onRoleDeletionEvent(*dataPackage);
813 if (discord_core_client::getInstance()->eventManager.onGuildScheduledEventCreationEvent.functions.size() > 0) {
814 unique_ptr<on_guild_scheduled_event_creation_data> dataPackage{ makeUnique<on_guild_scheduled_event_creation_data>(parser, dataNew) };
815 discord_core_client::getInstance()->eventManager.onGuildScheduledEventCreationEvent(*dataPackage);
820 if (discord_core_client::getInstance()->eventManager.onGuildScheduledEventUpdateEvent.functions.size() > 0) {
821 unique_ptr<on_guild_scheduled_event_update_data> dataPackage{ makeUnique<on_guild_scheduled_event_update_data>(parser, dataNew) };
822 discord_core_client::getInstance()->eventManager.onGuildScheduledEventUpdateEvent(*dataPackage);
827 if (discord_core_client::getInstance()->eventManager.onGuildScheduledEventDeletionEvent.functions.size() > 0) {
828 unique_ptr<on_guild_scheduled_event_deletion_data> dataPackage{ makeUnique<on_guild_scheduled_event_deletion_data>(parser, dataNew) };
829 discord_core_client::getInstance()->eventManager.onGuildScheduledEventDeletionEvent(*dataPackage);
834 if (discord_core_client::getInstance()->eventManager.onGuildScheduledEventUserAddEvent.functions.size() > 0) {
835 unique_ptr<on_guild_scheduled_event_user_add_data> dataPackage{ makeUnique<on_guild_scheduled_event_user_add_data>(parser, dataNew) };
836 discord_core_client::getInstance()->eventManager.onGuildScheduledEventUserAddEvent(*dataPackage);
841 if (discord_core_client::getInstance()->eventManager.onGuildScheduledEventUserRemoveEvent.functions.size() > 0) {
842 unique_ptr<on_guild_scheduled_event_user_remove_data> dataPackage{ makeUnique<on_guild_scheduled_event_user_remove_data>(parser,
844 discord_core_client::getInstance()->eventManager.onGuildScheduledEventUserRemoveEvent(*dataPackage);
849 if (discord_core_client::getInstance()->eventManager.onIntegrationCreationEvent.functions.size() > 0) {
850 unique_ptr<on_integration_creation_data> dataPackage{ makeUnique<on_integration_creation_data>(parser, dataNew) };
851 discord_core_client::getInstance()->eventManager.onIntegrationCreationEvent(*dataPackage);
856 if (discord_core_client::getInstance()->eventManager.onIntegrationUpdateEvent.functions.size() > 0) {
857 unique_ptr<on_integration_update_data> dataPackage{ makeUnique<on_integration_update_data>(parser, dataNew) };
858 discord_core_client::getInstance()->eventManager.onIntegrationUpdateEvent(*dataPackage);
863 if (discord_core_client::getInstance()->eventManager.onIntegrationDeletionEvent.functions.size() > 0) {
864 unique_ptr<on_integration_deletion_data> dataPackage{ makeUnique<on_integration_deletion_data>(parser, dataNew) };
865 discord_core_client::getInstance()->eventManager.onIntegrationDeletionEvent(*dataPackage);
870 unique_ptr<on_interaction_creation_data> dataPackage{ makeUnique<on_interaction_creation_data>(parser, dataNew) };
871 if (discord_core_client::getInstance()->eventManager.onInteractionCreationEvent.functions.size() > 0) {
872 discord_core_client::getInstance()->eventManager.onInteractionCreationEvent(*dataPackage);
877 if (discord_core_client::getInstance()->eventManager.onInviteCreationEvent.functions.size() > 0) {
878 unique_ptr<on_invite_creation_data> dataPackage{ makeUnique<on_invite_creation_data>(parser, dataNew) };
879 discord_core_client::getInstance()->eventManager.onInviteCreationEvent(*dataPackage);
884 if (discord_core_client::getInstance()->eventManager.onInviteDeletionEvent.functions.size() > 0) {
885 unique_ptr<on_invite_deletion_data> dataPackage{ makeUnique<on_invite_deletion_data>(parser, dataNew) };
886 discord_core_client::getInstance()->eventManager.onInviteDeletionEvent(*dataPackage);
891 unique_ptr<on_message_creation_data> dataPackage{ makeUnique<on_message_creation_data>(parser, dataNew) };
892 if (discord_core_client::getInstance()->eventManager.onMessageCreationEvent.functions.size() > 0) {
893 discord_core_client::getInstance()->eventManager.onMessageCreationEvent(*dataPackage);
898 unique_ptr<on_message_update_data> dataPackage{ makeUnique<on_message_update_data>(parser, dataNew) };
899 if (discord_core_client::getInstance()->eventManager.onMessageUpdateEvent.functions.size() > 0) {
900 discord_core_client::getInstance()->eventManager.onMessageUpdateEvent(*dataPackage);
905 if (discord_core_client::getInstance()->eventManager.onMessageDeletionEvent.functions.size() > 0) {
906 unique_ptr<on_message_deletion_data> dataPackage{ makeUnique<on_message_deletion_data>(parser, dataNew) };
907 discord_core_client::getInstance()->eventManager.onMessageDeletionEvent(*dataPackage);
912 if (discord_core_client::getInstance()->eventManager.onMessageDeleteBulkEvent.functions.size() > 0) {
913 unique_ptr<on_message_delete_bulk_data> dataPackage{ makeUnique<on_message_delete_bulk_data>(parser, dataNew) };
914 discord_core_client::getInstance()->eventManager.onMessageDeleteBulkEvent(*dataPackage);
919 if (discord_core_client::getInstance()->eventManager.onReactionAddEvent.functions.size() > 0) {
920 unique_ptr<on_reaction_add_data> dataPackage{ makeUnique<on_reaction_add_data>(parser, dataNew) };
921 discord_core_client::getInstance()->eventManager.onReactionAddEvent(*dataPackage);
926 if (discord_core_client::getInstance()->eventManager.onReactionRemoveEvent.functions.size() > 0) {
927 unique_ptr<on_reaction_remove_data> dataPackage{ makeUnique<on_reaction_remove_data>(parser, dataNew) };
928 discord_core_client::getInstance()->eventManager.onReactionRemoveEvent(*dataPackage);
933 if (discord_core_client::getInstance()->eventManager.onReactionRemoveAllEvent.functions.size() > 0) {
934 unique_ptr<on_reaction_remove_all_data> dataPackage{ makeUnique<on_reaction_remove_all_data>(parser, dataNew) };
935 discord_core_client::getInstance()->eventManager.onReactionRemoveAllEvent(*dataPackage);
940 if (discord_core_client::getInstance()->eventManager.onReactionRemoveEmojiEvent.functions.size() > 0) {
941 unique_ptr<on_reaction_remove_emoji_data> dataPackage{ makeUnique<on_reaction_remove_emoji_data>(parser, dataNew) };
942 discord_core_client::getInstance()->eventManager.onReactionRemoveEmojiEvent(*dataPackage);
947 unique_ptr<on_presence_update_data> dataPackage{ makeUnique<on_presence_update_data>(parser, dataNew) };
948 if (discord_core_client::getInstance()->eventManager.onPresenceUpdateEvent.functions.size() > 0) {
949 discord_core_client::getInstance()->eventManager.onPresenceUpdateEvent(*dataPackage);
954 if (discord_core_client::getInstance()->eventManager.onStageInstanceCreationEvent.functions.size() > 0) {
955 unique_ptr<on_stage_instance_creation_data> dataPackage{ makeUnique<on_stage_instance_creation_data>(parser, dataNew) };
956 discord_core_client::getInstance()->eventManager.onStageInstanceCreationEvent(*dataPackage);
961 if (discord_core_client::getInstance()->eventManager.onStageInstanceUpdateEvent.functions.size() > 0) {
962 unique_ptr<on_stage_instance_update_data> dataPackage{ makeUnique<on_stage_instance_update_data>(parser, dataNew) };
963 discord_core_client::getInstance()->eventManager.onStageInstanceUpdateEvent(*dataPackage);
968 if (discord_core_client::getInstance()->eventManager.onStageInstanceDeletionEvent.functions.size() > 0) {
969 unique_ptr<on_stage_instance_deletion_data> dataPackage{ makeUnique<on_stage_instance_deletion_data>(parser, dataNew) };
970 discord_core_client::getInstance()->eventManager.onStageInstanceDeletionEvent(*dataPackage);
975 if (discord_core_client::getInstance()->eventManager.onTypingStartEvent.functions.size() > 0) {
976 unique_ptr<on_typing_start_data> dataPackage{ makeUnique<on_typing_start_data>(parser, dataNew) };
977 discord_core_client::getInstance()->eventManager.onTypingStartEvent(*dataPackage);
982 if (discord_core_client::getInstance()->eventManager.onUserUpdateEvent.functions.size() > 0) {
983 unique_ptr<on_user_update_data> dataPackage{ makeUnique<on_user_update_data>(parser, dataNew) };
984 discord_core_client::getInstance()->eventManager.onUserUpdateEvent(*dataPackage);
989 unique_ptr<on_voice_state_update_data> dataPackage{ makeUnique<on_voice_state_update_data>(parser, dataNew,
this) };
990 if (discord_core_client::getInstance()->eventManager.onVoiceStateUpdateEvent.functions.size() > 0) {
991 discord_core_client::getInstance()->eventManager.onVoiceStateUpdateEvent(*dataPackage);
996 unique_ptr<on_voice_server_update_data> dataPackage{ makeUnique<on_voice_server_update_data>(parser, dataNew,
this) };
997 if (discord_core_client::getInstance()->eventManager.onVoiceServerUpdateEvent.functions.size() > 0) {
998 discord_core_client::getInstance()->eventManager.onVoiceServerUpdateEvent(*dataPackage);
1003 if (discord_core_client::getInstance()->eventManager.onWebhookUpdateEvent.functions.size() > 0) {
1004 unique_ptr<on_webhook_update_data> dataPackage{ makeUnique<on_webhook_update_data>(parser, dataNew) };
1005 discord_core_client::getInstance()->eventManager.onWebhookUpdateEvent(*dataPackage);
1013 case websocket_op_codes::heartbeat: {
1014 if (!checkForAndSendHeartBeat(
true)) {
1019 case websocket_op_codes::reconnect: {
1020 message_printer::printError<print_message_type::websocket>(
1021 jsonifier::string{
"Shard [" + jsonifier::toString(shard.at(0)) +
"," + jsonifier::toString(shard.at(1)) +
"]" +
" reconnecting (type 7)!" });
1022 areWeResuming =
true;
1023 tcpConnection.disconnect();
1026 case websocket_op_codes::Invalid_Session: {
1027 websocket_message_data<bool> data{};
1028 parser.parseJson<
true,
true>(data, dataNew);
1029 if (
auto result = parser.getErrors(); result.size() > 0) {
1030 for (
auto& valueNew: result) {
1031 message_printer::printError<print_message_type::websocket>(valueNew.reportError());
1034 message_printer::printError<print_message_type::websocket>(
1035 jsonifier::string{
"Shard [" + jsonifier::toString(shard.at(0)) +
"," + jsonifier::toString(shard.at(1)) +
"]" +
" reconnecting (type 9)!" });
1036 std::mt19937_64 randomEngine{
static_cast<uint64_t
>(hrclock::now().time_since_epoch().count()) };
1037 uint64_t numOfMsToWait =
1038 static_cast<uint64_t
>(1000.0f + ((
static_cast<double>(randomEngine()) /
static_cast<double>(randomEngine.max())) *
static_cast<double>(4000.0f)));
1039 if (numOfMsToWait <= 5000 && numOfMsToWait > 0) {
1040 std::this_thread::sleep_for(milliseconds{ numOfMsToWait });
1042 if (data.d ==
true) {
1043 areWeResuming =
true;
1045 areWeResuming =
false;
1050 case websocket_op_codes::hello: {
1051 websocket_message_data<hello_data> data{};
1052 parser.parseJson<
true,
true>(data, dataNew);
1053 if (
auto result = parser.getErrors(); result.size() > 0) {
1054 for (
auto& valueNew: result) {
1055 message_printer::printError<print_message_type::websocket>(valueNew.reportError());
1058 if (data.d.heartbeatInterval != 0) {
1059 areWeHeartBeating =
true;
1060 heartBeatStopWatch = stop_watch<milliseconds>{ milliseconds{ data.d.heartbeatInterval } };
1061 heartBeatStopWatch.reset();
1062 haveWeReceivedHeartbeatAck =
true;
1064 if (areWeResuming) {
1065 websocket_message_data<websocket_resume_data> dataNewer{};
1066 dataNewer.d.botToken = configManager->getBotToken();
1067 dataNewer.d.lastNumberReceived = lastNumberReceived;
1068 dataNewer.d.sessionId = sessionId;
1070 jsonifier::string_base<uint8_t>
string{};
1071 if (dataOpCode == websocket_op_code::Op_Binary) {
1072 auto serializer = dataNewer.operator etf_serializer();
1073 string = serializer.operator jsonifier::string_base<uint8_t>();
1075 parser.serializeJson<
true>(dataNewer, string);
1077 createHeader(
string, dataOpCode);
1078 currentState.store(websocket_state::Sending_Identify, std::memory_order_release);
1079 if (!sendMessage(
string,
true)) {
1083 websocket_message_data<websocket_identify_data> dataNewer{};
1084 dataNewer.d.botToken = configManager->getBotToken();
1085 dataNewer.d.shard.at(0) = shard.at(0);
1086 dataNewer.d.shard.at(1) = shard.at(1);
1087 dataNewer.d.intents =
static_cast<int64_t
>(configManager->getGatewayIntents());
1088 dataNewer.d.presence = configManager->getPresenceData();
1089 for (
auto& value: dataNewer.d.presence.activities) {
1090 if (value.url ==
"") {
1091 value.excludedKeys.emplace(
"url");
1095 jsonifier::string_base<uint8_t>
string{};
1096 if (dataOpCode == websocket_op_code::Op_Binary) {
1097 auto serializer = dataNewer.operator etf_serializer();
1098 string = serializer.operator jsonifier::string_base<uint8_t>();
1100 parser.serializeJson<
true>(dataNewer, string);
1102 createHeader(
string, dataOpCode);
1103 currentState.store(websocket_state::Sending_Identify, std::memory_order_release);
1104 if (!sendMessage(
string,
true)) {
1110 case websocket_op_codes::Heartbeat_ACK: {
1111 haveWeReceivedHeartbeatAck =
true;
1114 case websocket_op_codes::identify: {
1117 case websocket_op_codes::Presence_Update: {
1120 case websocket_op_codes::Voice_State_Update: {
1123 case websocket_op_codes::resume: {
1126 case websocket_op_codes::Request_Guild_Members: {
1136 }
catch (
const dca_exception& error) {
1137 message_printer::printError<print_message_type::websocket>(error.what());
1142 void websocket_core::disconnect() {
1143 if (areWeConnected()) {
1144 jsonifier::string dataNew{
"\x03\xE8" };
1145 createHeader(dataNew, websocket_op_code::Op_Close);
1146 tcpConnection.writeData(
static_cast<jsonifier::string_view
>(dataNew),
true);
1147 tcpConnection.disconnect();
1148 currentState.store(websocket_state::disconnected, std::memory_order_release);
1149 areWeHeartBeating =
false;
1153 void websocket_client::disconnect() {
1154 websocket_core::disconnect();
1157 void websocket_client::onClosed() {
1158 if (maxReconnectTries > currentReconnectTries) {
1162 doWeQuit->store(
true, std::memory_order_release);
1167 websocket_client::~websocket_client() {
1171 base_socket_agent::base_socket_agent(std::atomic_bool* doWeQuitNew) {
1172 doWeQuit = doWeQuitNew;
1173 taskThread = std::jthread([
this](std::stop_token token) {
1178 void base_socket_agent::connect(websocket_client& value) {
1179 jsonifier::string connectionUrl{ value.areWeResuming ? value.resumeUrl : discord_core_client::getInstance()->configManager.getConnectionAddress() };
1180 message_printer::printSuccess<print_message_type::general>(jsonifier::string{
"Connecting shard " + jsonifier::toString(value.shard.at(0) + 1) +
" of " +
1181 jsonifier::toString(discord_core_client::getInstance()->configManager.getShardCountForThisProcess()) + jsonifier::string{
" shards for this process. (" } +
1182 jsonifier::toString(value.shard.at(0) + 1) +
" of " + jsonifier::toString(discord_core_client::getInstance()->configManager.getTotalShardCount()) +
1183 jsonifier::string{
" shards total across all processes)" } });
1184 jsonifier::string relativePath{
"/?v=10&encoding=" +
1185 jsonifier::string{ discord_core_client::getInstance()->configManager.getTextFormat() == text_format::etf ?
"etf" :
"json" } };
1187 value = websocket_client{ value.shard.at(0), doWeQuit };
1188 value.connect(connectionUrl, relativePath, discord_core_client::getInstance()->configManager.getConnectionPort());
1189 if (value.tcpConnection.currentStatus != connection_status::NO_Error) {
1190 std::cout <<
"WERE HERE THIS IS TI!" << std::endl;
1193 value.tcpConnection.processIO(0);
1194 discord_core_client::getInstance()->connectionStopWatch01.reset();
1197 void base_socket_agent::run(std::stop_token token) {
1198 unordered_map<uint64_t, websocket_tcpconnection*> processIOMapNew{};
1199 while (!discord_core_client::getInstance()->areWeReadyToConnect.load(std::memory_order_acquire)) {
1200 std::this_thread::sleep_for(1ms);
1202 for (
auto& [key, value]: shardMap) {
1203 while (key != discord_core_client::getInstance()->currentlyConnectingShard.load(std::memory_order_acquire) ||
1204 !discord_core_client::getInstance()->connectionStopWatch01.hasTimeElapsed()) {
1205 processIOMapNew.reserve(shardMap.size());
1206 for (
auto& [keyNew, valueNew]: shardMap) {
1207 if (valueNew.areWeConnected()) {
1208 processIOMapNew.emplace(keyNew, &valueNew.tcpConnection);
1211 tcp_connection<websocket_tcpconnection>::processIO(processIOMapNew);
1212 processIOMapNew.clear();
1213 std::this_thread::sleep_for(1ms);
1216 discord_core_client::getInstance()->currentlyConnectingShard.fetch_add(1, std::memory_order_release);
1218 processIOMapNew.clear();
1219 while (!token.stop_requested() && !doWeQuit->load(std::memory_order_acquire)) {
1221 for (
auto& [key, value]: shardMap) {
1222 if (value.areWeConnected()) {
1223 processIOMapNew.emplace(key, &value.tcpConnection);
1226 tcp_connection<websocket_tcpconnection>::processIO(processIOMapNew);
1227 processIOMapNew.clear();
1228 bool areWeConnected{};
1229 for (
auto& [key, value]: shardMap) {
1230 if (value.areWeConnected()) {
1231 if (value.checkForAndSendHeartBeat()) {
1232 on_gateway_ping_data dataNew{};
1233 dataNew.timeUntilNextPing =
static_cast<int32_t
>(value.heartBeatStopWatch.getTotalWaitTime().count());
1234 discord_core_client::getInstance()->eventManager.onGatewayPingEvent(dataNew);
1236 areWeConnected =
true;
1238 message_printer::printError<print_message_type::websocket>(
1239 jsonifier::string{
"Connection lost for websocket [" + jsonifier::toString(value.shard.at(0)) +
"," +
1240 jsonifier::toString(discord_core_client::getInstance()->configManager.getTotalShardCount()) +
"]... reconnecting." });
1241 std::this_thread::sleep_for(1s);
1242 if (discord_core_client::getInstance()->connectionStopWatch01.hasTimeElapsed()) {
1247 if (!areWeConnected) {
1248 std::this_thread::sleep_for(1ms);
1250 }
catch (
const dca_exception& error) {
1251 message_printer::printError<print_message_type::websocket>(error.what());
1256 base_socket_agent::~base_socket_agent(){}
websocket_op_codes
For the opcodes that could be sent/received via discord's websockets.
@ connect
Allows for joining of a voice channel.
The main namespace for the forward-facing interfaces.