DiscordCoreAPI
A Discord bot library written in C++, with custom asynchronous coroutines.
Loading...
Searching...
No Matches
Utilities.cpp
Go to the documentation of this file.
1/*
2 MIT License
3
4 DiscordCoreAPI, A bot library for Discord, written in C++, and featuring explicit multithreading through the usage of custom, asynchronous C++ CoRoutines.
5
6 Copyright 2022, 2023 Chris M. (RealTimeChris)
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in all
16 copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
25*/
26/// Utilities.cpp - Source file for the utilities.
27/// Jun 28, 2022
28/// https://discordcoreapi.com
29/// \file Utilities.cpp
30
43#include <fstream>
44#include <time.h>
45
46namespace discord_core_api {
47
48 thread_local jsonifier::jsonifier_core parser{};
49
50 update_presence_data::update_presence_data(presence_update_state state) {
51 status = state;
52 switch (status) {
53 case presence_update_state::online: {
54 statusReal = "online";
55 return;
56 }
57 case presence_update_state::Do_Not_Disturb: {
58 statusReal = "dnd";
59 return;
60 }
61 case presence_update_state::idle: {
62 statusReal = "idle";
63 return;
64 }
65 case presence_update_state::invisible: {
66 statusReal = "invisible";
67 return;
68 }
69 case presence_update_state::offline: {
70 statusReal = "offline";
71 return;
72 }
73 }
74 }
75
76 std::basic_ostream<char>& operator<<(std::basic_ostream<char>& outputSttream, jsonifier::string_view (*function)(void)) {
77 outputSttream << function();
78 return outputSttream;
79 }
80
81 config_manager::config_manager(const discord_core_client_config& configNew) {
82 config = configNew;
83 }
84
85 bool config_manager::doWePrintWebSocketSuccessMessages() const {
86 return config.logOptions.logWebSocketSuccessMessages;
87 }
88
89 bool config_manager::doWePrintWebSocketErrorMessages() const {
90 return config.logOptions.logWebSocketErrorMessages;
91 }
92
93 bool config_manager::doWePrintHttpsSuccessMessages() const {
94 return config.logOptions.logHttpsSuccessMessages;
95 }
96
97 bool config_manager::doWePrintHttpsErrorMessages() const {
98 return config.logOptions.logHttpsErrorMessages;
99 }
100
101 bool config_manager::doWePrintGeneralSuccessMessages() const {
102 return config.logOptions.logGeneralSuccessMessages;
103 }
104
105 bool config_manager::doWePrintGeneralErrorMessages() const {
106 return config.logOptions.logGeneralErrorMessages;
107 }
108
109 bool config_manager::doWeCacheGuildMembers() const {
110 return config.cacheOptions.cacheGuildMembers;
111 }
112
113 bool config_manager::doWeCacheChannels() const {
114 return config.cacheOptions.cacheChannels;
115 }
116
117 bool config_manager::doWeCacheUsers() const {
118 return config.cacheOptions.cacheUsers;
119 }
120
121 bool config_manager::doWeCacheVoiceStates() const {
122 return config.cacheOptions.cacheVoiceStates;
123 }
124
125 bool config_manager::doWeCacheGuilds() const {
126 return config.cacheOptions.cacheGuilds;
127 }
128
129 bool config_manager::doWeCacheRoles() const {
130 return config.cacheOptions.cacheRoles;
131 }
132
133 update_presence_data config_manager::getPresenceData() const {
134 return config.presenceData;
135 }
136
137 jsonifier::string config_manager::getBotToken() const {
138 return config.botToken;
139 }
140
141 std::ostream* config_manager::getErrorStream() const {
142 return config.logOptions.errorStream;
143 }
144
145 std::ostream* config_manager::getOutputStream() const {
146 return config.logOptions.outputStream;
147 }
148
149 uint64_t config_manager::getTotalShardCount() const {
150 return config.shardOptions.totalNumberOfShards;
151 }
152
153 uint64_t config_manager::getStartingShard() const {
154 return config.shardOptions.startingShard;
155 }
156
157 uint64_t config_manager::getShardCountForThisProcess() const {
158 return config.shardOptions.numberOfShardsForThisProcess;
159 }
160
161 jsonifier::string config_manager::getConnectionAddress() const {
162 return config.connectionAddress;
163 }
164
165 void config_manager::setConnectionAddress(jsonifier::string_view connectionAddressNew) {
166 config.connectionAddress = connectionAddressNew;
167 }
168
169 uint16_t config_manager::getConnectionPort() const {
170 return config.connectionPort;
171 }
172
173 void config_manager::setConnectionPort(const uint16_t connectionPortNew) {
174 config.connectionPort = connectionPortNew;
175 }
176
177 jsonifier::vector<repeated_function_data> config_manager::getFunctionsToExecute() const {
178 return config.functionsToExecute;
179 }
180
181 text_format config_manager::getTextFormat() const {
182 return config.textFormat;
183 }
184
185 gateway_intents config_manager::getGatewayIntents() {
186 return config.intents;
187 }
188
189 audio_frame_data::audio_frame_data(audio_frame_type frameTypeNew) {
190 type = frameTypeNew;
191 }
192
193 audio_frame_data& audio_frame_data::operator+=(jsonifier::string_view_base<uint8_t> other) {
194 if (other.size() > 0) {
195 if (data.size() < other.size()) {
196 data.resize(other.size());
197 }
198 std::memcpy(data.data(), other.data(), other.size());
199 }
200 currentSize = static_cast<int64_t>(other.size());
201 return *this;
202 }
203
204 audio_frame_data& audio_frame_data::operator+=(jsonifier::vector<uint8_t> other) {
205 if (other.size() > 0) {
206 if (data.size() < other.size()) {
207 data.resize(other.size());
208 }
209 std::memcpy(data.data(), other.data(), other.size());
210 }
211 currentSize = static_cast<int64_t>(other.size());
212 return *this;
213 }
214
215 void audio_frame_data::clearData() {
217 currentSize = 0;
218 data.clear();
219 }
220
221 color_value::color_value(uint32_t colorValue) {
222 color = colorValue;
223 }
224
225 color_value::color_value(jsonifier::string_view hexColorValue) {
226 jsonifier::string returnString{};
227 if (hexColorValue == "") {
228 returnString = jsonifier::string{ "fefefe" };
229 } else {
230 returnString = hexColorValue;
231 }
232 color = static_cast<uint32_t>(jsonifier::strToInt64<16>(returnString));
233 }
234
235 rgbcolor_value color_value::getRgbColorValue() {
236 uint8_t red = static_cast<uint8_t>(color >> 16);
237 uint8_t green = static_cast<uint8_t>(color >> 8);
238 uint8_t blue = static_cast<uint8_t>(color);
239 rgbcolor_value colorNew{};
240 colorNew.green = green;
241 colorNew.blue = blue;
242 colorNew.red = red;
243 return colorNew;
244 }
245
246 hex_color_value color_value::getHexColorValue() {
247 std::stringstream stream{};
248 stream << std::hex << color;
249 return jsonifier::string{ stream.str() };
250 }
251
252 uint32_t color_value::getIntColorValue() {
253 return color;
254 }
255
256 icon_hash& icon_hash::operator=(jsonifier::string_view string) {
257 jsonifier::string newHash{ string };
258 if (newHash.empty() || newHash == "0") {
259 highBits = 0;
260 lowBits = 0;
261 return *this;
262 }
263 if (newHash.size() >= 32 && newHash.find("a_") != jsonifier::string::npos) {
264 newHash = newHash.substr(newHash.find("a_") + 2);
265 }
266 if (newHash.size() != 32) {
267 throw dca_exception{ "Sorry, but that is an incorrect icon_hash length, it must be 32 characters long." };
268 }
269 lowBits = fromString<uint64_t>(newHash.substr(0, 16), std::hex);
270 highBits = fromString<uint64_t>(newHash.substr(16, 16), std::hex);
271 return *this;
272 }
273
274 icon_hash::icon_hash(jsonifier::string_view string) {
275 *this = string;
276 }
277
278 icon_hash::operator jsonifier::string() const {
279 if (highBits == 0 || lowBits == 0) {
280 return {};
281 } else {
282 return toHex(lowBits) + toHex(highBits);
283 }
284 }
285
286 jsonifier::string operator+(const icon_hash& lhs, jsonifier::string_view rhs) {
287 jsonifier::string newString = lhs.operator jsonifier::string() += rhs;
288 return newString;
289 }
290
291 bool icon_hash::operator==(const icon_hash& rhs) const {
292 return highBits == rhs.highBits && lowBits == rhs.lowBits;
293 }
294
295 bool icon_hash::operator==(jsonifier::string_view rhs) const {
296 return operator jsonifier::string() == rhs;
297 }
298
299 template<>
300 jsonifier::string permissions_base<permissions>::computeOverwrites(jsonifier::string_view basePermissions, const guild_member_data& guildMember, const channel_data& channel) {
301 if ((jsonifier::strToUint64(basePermissions.data()) & static_cast<uint64_t>(permission::administrator)) & static_cast<uint64_t>(permission::administrator)) {
302 return getAllPermissions();
303 }
304
305 uint64_t permissions = jsonifier::strToUint64(basePermissions.data());
306 for (uint64_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
307 if (channel.permissionOverwrites.at(x).id == guildMember.guildId) {
308 permissions &= ~channel.permissionOverwrites.at(x).deny;
309 permissions |= channel.permissionOverwrites.at(x).allow;
310 break;
311 }
312 }
313 jsonifier::vector<role_data> guildMemberRoles{};
314 for (auto& value: guildMember.roles) {
315 guildMemberRoles.emplace_back(roles::getCachedRole({ .guildId = guildMember.guildId, .roleId = value }));
316 }
317 uint64_t allow{};
318 uint64_t deny{};
319 for (auto& value: guildMemberRoles) {
320 for (uint64_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
321 if (value.id == channel.permissionOverwrites.at(x).id) {
322 allow |= channel.permissionOverwrites.at(x).allow;
323 deny |= channel.permissionOverwrites.at(x).deny;
324 }
325 }
326 }
327 permissions &= ~deny;
328 permissions |= allow;
329 for (uint64_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
330 if (channel.permissionOverwrites.at(x).id == guildMember.user.id) {
331 permissions &= ~channel.permissionOverwrites.at(x).deny;
332 permissions |= channel.permissionOverwrites.at(x).allow;
333 break;
334 }
335 }
336 return jsonifier::toString(permissions);
337 }
338
339 template<> jsonifier::string permissions_base<permissions>::computeBasePermissions(const guild_member_data& guildMember) {
340 const guild_cache_data guild = guilds::getCachedGuild({ .guildId = guildMember.guildId });
341 if (guild.ownerId == guildMember.user.id) {
342 return getAllPermissions();
343 }
344 jsonifier::vector<role_data> guildRoles{};
345 if (roles::doWeCacheRoles()) {
346 for (auto& value: guild.roles) {
347 guildRoles.emplace_back(roles::getCachedRole({ .roleId = value }));
348 }
349 } else {
350 guildRoles = roles::getGuildRolesAsync({ .guildId = guildMember.guildId }).get();
351 }
352 role_data roleEveryone{};
353 for (auto& value: guildRoles) {
354 if (value.id == guild.id) {
355 roleEveryone = value;
356 }
357 }
358 uint64_t permissions{};
359 if (roleEveryone.permissions.operator std::basic_string_view<char, std::char_traits<char>>() != "0") {
360 permissions = roleEveryone.permissions;
361 }
362 get_guild_member_roles_data getRolesData{};
363 getRolesData.guildMember = guildMember;
364 getRolesData.guildId = guildMember.guildId;
365 jsonifier::vector<role_data> guildMemberRoles{};
366 if (roles::doWeCacheRoles()) {
367 for (auto& value: guildMember.roles) {
368 guildMemberRoles.emplace_back(roles::getCachedRole({ .roleId = value }));
369 }
370 } else {
371 guildMemberRoles = roles::getGuildMemberRolesAsync({ .guildMember = guildMember, .guildId = guildMember.guildId }).get();
372 }
373 for (auto& value: guildMemberRoles) {
374 permissions |= value.permissions.operator uint64_t();
375 }
376 if (permissions & static_cast<uint64_t>(permission::administrator)) {
377 return getAllPermissions();
378 }
379
380 return jsonifier::toString(permissions);
381 }
382
383 template<> jsonifier::string permissions_base<permissions_parse>::computeOverwrites(jsonifier::string_view basePermissions, const guild_member_data& guildMember,
384 const channel_data& channel) {
385 if ((jsonifier::strToUint64(basePermissions.data()) & static_cast<uint64_t>(permission::administrator)) & static_cast<uint64_t>(permission::administrator)) {
386 return getAllPermissions();
387 }
388
389 uint64_t permissions = jsonifier::strToUint64(basePermissions.data());
390 for (uint64_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
391 if (channel.permissionOverwrites.at(x).id == guildMember.guildId) {
392 permissions &= ~channel.permissionOverwrites.at(x).deny;
393 permissions |= channel.permissionOverwrites.at(x).allow;
394 break;
395 }
396 }
397 jsonifier::vector<role_data> guildMemberRoles{};
398 if (roles::doWeCacheRoles()) {
399 for (auto& value: guildMember.roles) {
400 guildMemberRoles.emplace_back(roles::getCachedRole({ .roleId = value }));
401 }
402 } else {
403 guildMemberRoles = roles::getGuildMemberRolesAsync({ .guildMember = guildMember, .guildId = guildMember.guildId }).get();
404 }
405 uint64_t allow{};
406 uint64_t deny{};
407 for (auto& value: guildMemberRoles) {
408 for (uint64_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
409 if (value.id == channel.permissionOverwrites.at(x).id) {
410 allow |= channel.permissionOverwrites.at(x).allow;
411 deny |= channel.permissionOverwrites.at(x).deny;
412 }
413 }
414 }
415 permissions &= ~deny;
416 permissions |= allow;
417 for (uint64_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
418 if (channel.permissionOverwrites.at(x).id == guildMember.user.id) {
419 permissions &= ~channel.permissionOverwrites.at(x).deny;
420 permissions |= channel.permissionOverwrites.at(x).allow;
421 break;
422 }
423 }
424 return jsonifier::toString(permissions);
425 }
426
427 template<> jsonifier::string permissions_base<permissions_parse>::computeBasePermissions(const guild_member_data& guildMember) {
428 const guild_data guild = guilds::getCachedGuild({ .guildId = guildMember.guildId });
429 if (guild.ownerId == guildMember.user.id) {
430 return getAllPermissions();
431 }
432 jsonifier::vector<role_data> guildRoles{};
433 for (auto& value: guild.roles) {
434 guildRoles.emplace_back(value);
435 }
436 role_data roleEveryone{};
437 for (auto& value: guildRoles) {
438 if (value.id == guild.id) {
439 roleEveryone = value;
440 }
441 }
442 uint64_t permissions{};
443 if (roleEveryone.permissions.operator std::basic_string_view<char, std::char_traits<char>>() != "0") {
444 permissions = roleEveryone.permissions;
445 }
446 get_guild_member_roles_data getRolesData{};
447 getRolesData.guildMember = guildMember;
448 getRolesData.guildId = guildMember.guildId;
449 jsonifier::vector<role_data> guildMemberRoles{};
450 for (auto& value: guildMember.roles) {
451 guildMemberRoles.emplace_back(value);
452 }
453 for (auto& value: guildMemberRoles) {
454 permissions |= value.permissions.operator uint64_t();
455 }
456
457 if (permissions & static_cast<uint64_t>(permission::administrator)) {
458 return getAllPermissions();
459 }
460
461 return jsonifier::toString(permissions);
462 }
463
464 jsonifier::string constructMultiPartData(jsonifier::string_view data, const jsonifier::vector<file>& files) {
465 const jsonifier::string boundary("boundary25");
466 const jsonifier::string partStart("--" + boundary + "\r\nContent-type: application/octet-stream\r\nContent-disposition: form-data; ");
467
468 jsonifier::string content("--" + boundary);
469
470 content += "\r\nContent-type: application/json\r\nContent-disposition: form-data; "
471 "name=\"payload_json\"\r\n\r\n";
472 content += data + "\r\n";
473 if (files.size() == 1) {
474 content += partStart + "name=\"file\"; filename=\"" + files.at(0).fileName + "\"" + "\r\n\r\n";
475 content += files.at(0).data;
476 } else {
477 for (uint64_t x = 0; x < files.size(); ++x) {
478 content += partStart + "name=\"files[" + jsonifier::toString(x) + "]\"; filename=\"" + files.at(x).fileName + "\"\r\n\r\n";
479 content += files.at(x).data;
480 content += "\r\n";
481 }
482 }
483 content += "\r\n--" + boundary + "--";
484 return content;
485 }
486
487 jsonifier::string convertToLowerCase(jsonifier::string_view stringToConvert) {
488 jsonifier::string newString;
489 for (auto& value: stringToConvert) {
490 if (isupper(static_cast<uint8_t>(value))) {
491 newString += static_cast<char>(tolower(static_cast<uint8_t>(value)));
492 } else {
493 newString += value;
494 }
495 }
496 return newString;
497 }
498
499 jsonifier::string base64Encode(jsonifier::string_view string, bool url) {
500 const char* base64CharsArray[2] = { "abcdefghijklmnopqrstuvwxyz"
501 "abcdefghijklmnopqrstuvwxyz"
502 "0123456789"
503 "+/",
504
505 "abcdefghijklmnopqrstuvwxyz"
506 "abcdefghijklmnopqrstuvwxyz"
507 "0123456789"
508 "-_" };
509
510 uint64_t encodedLength = (string.size() + 2) / 3 * 4;
511
512 char trailing_char = url ? '.' : '=';
513
514 const char* base64Chars = base64CharsArray[url];
515
516 jsonifier::string returnString{};
517 returnString.reserve(encodedLength);
518 stop_watch<milliseconds> stopWatch{ 1500ms };
519 stopWatch.reset();
520 uint64_t pos = 0;
521 while (pos < string.size()) {
522 if (stopWatch.hasTimeElapsed()) {
523 break;
524 }
525 returnString.pushBack(base64Chars[(string[static_cast<uint64_t>(pos + 0)] & 0xfc) >> 2]);
526
527 if (static_cast<uint64_t>(pos + 1) < string.size()) {
528 returnString.pushBack(base64Chars[((string[static_cast<uint64_t>(pos + 0)] & 0x03) << 4) + ((string[static_cast<uint64_t>(pos + 1)] & 0xf0) >> 4)]);
529
530 if (static_cast<uint64_t>(pos + 2) < string.size()) {
531 returnString.pushBack(base64Chars[((string[static_cast<uint64_t>(pos + 1)] & 0x0f) << 2) + ((string[static_cast<uint64_t>(pos + 2)] & 0xc0) >> 6)]);
532 returnString.pushBack(base64Chars[string[static_cast<uint64_t>(pos + 2)] & 0x3f]);
533 } else {
534 returnString.pushBack(base64Chars[(string[static_cast<uint64_t>(pos + 1)] & 0x0f) << 2]);
535 returnString.pushBack(trailing_char);
536 }
537 } else {
538 returnString.pushBack(base64Chars[(string[static_cast<uint64_t>(pos + 0)] & 0x03) << 4]);
539 returnString.pushBack(trailing_char);
540 returnString.pushBack(trailing_char);
541 }
542
543 pos += 3;
544 }
545
546 return returnString;
547 }
548
549 jsonifier::string loadFileContents(jsonifier::string_view filePath) {
550 std::ifstream file(filePath.data(), std::ios::in | std::ios::binary);
551 std::ostringstream stream{};
552 stream << file.rdbuf();
553 return jsonifier::string{ stream.str() };
554 }
555
556 jsonifier::string utf8MakeValid(jsonifier::string_view inputString) {
557 jsonifier::string returnString{};
558 for (auto& value: inputString) {
559 if (static_cast<uint8_t>(value) >= 128 || value < 0) {
560 uint64_t difference = 0ULL - value;
561 if (value + difference == '\0') {
562 continue;
563 } else {
564 returnString.pushBack(value + static_cast<char>(difference));
565 }
566 } else {
567 returnString.pushBack(value);
568 }
569 }
570 return returnString;
571 }
572
573 jsonifier::string urlEncode(jsonifier::string_view inputString) {
574 std::ostringstream escaped{};
575 escaped.fill('0');
576 escaped << std::hex;
577
578 for (jsonifier::string::const_iterator x = inputString.begin(), n = inputString.end(); x != n; ++x) {
579 jsonifier::string::value_type c = (*x);
580
581 if (isalnum(static_cast<uint8_t>(c)) || c == '-' || c == '_' || c == '.' || c == '~') {
582 escaped << c;
583 continue;
584 }
585
586 escaped << std::uppercase;
587 escaped << '%' << std::setw(2) << uint64_t(static_cast<uint8_t>(c));
588 escaped << std::nouppercase;
589 }
590 return jsonifier::string{ escaped.str() };
591 }
592
593 void spinLock(uint64_t timeInNsToSpinLockFor) {
594 int64_t startTime = std::chrono::duration_cast<nanoseconds>(hrclock::now().time_since_epoch()).count();
595 int64_t timePassed{};
596 while (timePassed < static_cast<int64_t>(timeInNsToSpinLockFor)) {
597 timePassed = std::chrono::duration_cast<nanoseconds>(hrclock::now().time_since_epoch()).count() - startTime;
598 }
599 }
600
601 jsonifier::string generateBase64EncodedKey() {
602 jsonifier::string returnString{};
603 returnString.resize(16);
604 std::mt19937_64 randomEngine{ static_cast<uint64_t>(hrclock::now().time_since_epoch().count()) };
605 for (uint64_t x = 0; x < 16; ++x) {
606 returnString.at(x) = static_cast<char>((static_cast<double>(randomEngine()) / static_cast<double>(randomEngine.max())) * 255.0f);
607 }
608 returnString = base64Encode(returnString, false);
609 return returnString;
610 }
611
612 bool nanoSleep(int64_t ns) {
613#if defined _WIN32
614 HANDLE timer = CreateWaitableTimerExW(nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
615 LARGE_INTEGER largeInt{ .QuadPart = -ns / 100 };
616 if (!timer) {
617 return false;
618 }
619
620 if (!SetWaitableTimerEx(timer, &largeInt, 0, nullptr, nullptr, nullptr, 0)) {
621 CloseHandle(timer);
622 return false;
623 }
624 WaitForSingleObjectEx(timer, INFINITE, false);
625 CloseHandle(timer);
626#else
627 std::this_thread::sleep_for(nanoseconds{ ns });
628#endif
629 return true;
630 }
631
632 jsonifier::string getTimeAndDate() {
633 std::time_t time = std::time({});
634 time = std::chrono::current_zone()->to_sys(std::chrono::local_time<std::chrono::seconds>(std::chrono::seconds{ time })).time_since_epoch().count();
635 char timeString[std::size("yyyy-mm-ddThh:mm:ss")];
636 std::strftime(std::data(timeString), std::size(timeString), "%FT%T", gmtime(&time));
637 return timeString;
638 }
639};
static guild_cache_data getCachedGuild(const get_guild_data dataPackage)
Collects a guild from the library's cache.
static co_routine< jsonifier::vector< role_data > > getGuildMemberRolesAsync(const get_guild_member_roles_data dataPackage)
Collects the roles that a guild_member has.
static co_routine< jsonifier::vector< role_data > > getGuildRolesAsync(const get_guild_roles_data dataPackage)
Collects the roles that a guild has.
static role_cache_data getCachedRole(const get_role_data dataPackage)
Collects a given role from the library's cache.
text_format
Represents which text format to use for websocket transfer.
Definition: Utilities.hpp:202
gateway_intents
Gateway intents.
Definition: Utilities.hpp:166
DiscordCoreAPI_Dll jsonifier::string getTimeAndDate()
Acquires a timeStamp with the current time and date - suitable for use in message-embeds.
Definition: Utilities.cpp:632
@ administrator
Allows all permissions and bypasses channel permission overwrites.
@ stream
Allows the user to go live.
audio_frame_type
Audio frame types.
Definition: Utilities.hpp:374
The main namespace for the forward-facing interfaces.
audio_frame_type type
The type of audio frame.
Definition: Utilities.hpp:382
jsonifier::vector< uint8_t > data
The audio data.
Definition: Utilities.hpp:383
int64_t currentSize
The current size of the allocated memory.
Definition: Utilities.hpp:384
presence_update_state status
current status.
Definition: Utilities.hpp:135