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 DiscordCoreAPI, A bot library for Discord, written in C++, and featuring explicit multithreading through the usage of custom, asynchronous C++ CoRoutines.
3
4 Copyright 2021, 2022 Chris M. (RealTimeChris)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 USA
20*/
21/// Utilities.cpp - Source file for the Utilities.
22/// Jun 28, 2022
23/// https://discordcoreapi.com
24/// \file Utilities.cpp
25
37#include <fstream>
38
39namespace DiscordCoreInternal {
40
41 WebSocketClose& WebSocketClose::operator=(uint16_t valueNew) {
42 this->value = static_cast<WebSocketCloseCode>(valueNew);
43 return *this;
44 };
45
46 WebSocketClose::WebSocketClose(uint16_t valueNew) {
47 *this = valueNew;
48 };
49
50 WebSocketClose::operator std::string() {
51 return this->outputErrorValues[this->mappingValues[static_cast<uint16_t>(*this)]];
52 }
53
54 WebSocketClose::operator bool() {
55 return static_cast<std::underlying_type_t<decltype(this->value)>>(this->value) &
56 static_cast<std::underlying_type_t<decltype(this->value)>>(WebSocketCloseCode::We_Do_Reconnect);
57 }
58
59 VoiceWebSocketClose& VoiceWebSocketClose::operator=(uint16_t valueNew) {
60 this->value = static_cast<VoiceWebSocketCloseCode>(valueNew);
61 return *this;
62 };
63
64 VoiceWebSocketClose::VoiceWebSocketClose(uint16_t valueNew) {
65 *this = valueNew;
66 };
67
68 VoiceWebSocketClose::operator std::string() {
69 return this->outputErrorValues[this->mappingValues[static_cast<uint16_t>(*this)]];
70 }
71
72 VoiceWebSocketClose::operator bool() {
73 return true;
74 }
75
76 HttpsResponseCode& HttpsResponseCode::operator=(uint32_t valueNew) {
77 this->value = static_cast<HttpsResponseCodes>(valueNew);
78 return *this;
79 }
80
81 HttpsResponseCode::HttpsResponseCode(uint32_t valueNew) {
82 *this = valueNew;
83 }
84
85 HttpsResponseCode::operator std::string() {
86 return std::string{ "Code: " + std::to_string(static_cast<uint32_t>(this->value)) + ", Message: " + this->outputErrorValues[this->value] };
87 }
88
89 HttpsResponseCode::operator uint32_t() {
90 return static_cast<uint32_t>(this->value);
91 }
92}
93
94namespace DiscordCoreAPI {
95
96 DCAException::DCAException(const std::string& error, std::source_location location) noexcept : std::runtime_error(error) {
97 std::stringstream stream{};
98 stream << shiftToBrightRed() << "Error Report: \n"
99 << "Thrown From: " << location.file_name() << " (" << std::to_string(location.line()) << ":" << std::to_string(location.column())
100 << ")"
101 << "\nThe Error: \n"
102 << error << reset() << std::endl
103 << std::endl;
104 *static_cast<std::runtime_error*>(this) = std::runtime_error{ stream.str() };
105 }
106
107 Snowflake& Snowflake::operator=(const std::string& other) noexcept {
108 for (auto& value: other) {
109 if (!std::isdigit(static_cast<uint8_t>(value))) {
110 return *this;
111 }
112 }
113 if (other.size() == 0) {
114 return *this;
115 }
116 this->id = stoull(other);
117 return *this;
118 }
119
120 Snowflake::Snowflake(const std::string& other) noexcept {
121 *this = other;
122 }
123
124 Snowflake& Snowflake::operator=(const uint64_t other) noexcept {
125 this->id = other;
126 return *this;
127 }
128
129 Snowflake::Snowflake(const uint64_t other) noexcept {
130 *this = other;
131 }
132
133 Snowflake::operator std::string() const noexcept {
134 return std::to_string(this->id);
135 }
136
137 Snowflake::operator uint64_t() const noexcept {
138 return this->id;
139 }
140
141 bool Snowflake::operator==(const Snowflake& rhs) const noexcept {
142 return this->id == rhs.id;
143 }
144
145 EnumConverter::operator std::vector<uint64_t>() const noexcept {
146 return this->vector;
147 }
148
149 EnumConverter::operator uint64_t() const noexcept {
150 return this->integer;
151 }
152
153 bool EnumConverter::isItAVector() const noexcept {
154 return this->vectorType;
155 }
156
157 Jsonifier& Jsonifier::operator=(Jsonifier&& data) noexcept {
158 switch (data.type) {
159 case JsonType::Object: {
160 this->setValue(JsonType::Object);
161 *this->jsonValue.object = std::move(*data.jsonValue.object);
162 break;
163 }
164 case JsonType::Array: {
165 this->setValue(JsonType::Array);
166 *this->jsonValue.array = std::move(*data.jsonValue.array);
167 break;
168 }
169 case JsonType::String: {
170 this->setValue(JsonType::String);
171 *this->jsonValue.string = std::move(*data.jsonValue.string);
172 break;
173 }
174 case JsonType::Float: {
175 this->jsonValue.numberDouble = data.jsonValue.numberDouble;
176 break;
177 }
178 case JsonType::Uint64: {
179 this->jsonValue.numberUint = data.jsonValue.numberUint;
180 break;
181 }
182 case JsonType::Int64: {
183 this->jsonValue.numberInt = data.jsonValue.numberInt;
184 break;
185 }
186 case JsonType::Bool: {
187 this->jsonValue.boolean = data.jsonValue.boolean;
188 break;
189 }
190 }
191 this->string = std::move(data.string);
192 this->type = data.type;
193 return *this;
194 }
195
196 Jsonifier::Jsonifier(Jsonifier&& data) noexcept {
197 *this = std::move(data);
198 }
199
200 Jsonifier& Jsonifier::operator=(const Jsonifier& data) noexcept {
201 switch (data.type) {
202 case JsonType::Object: {
203 this->setValue(JsonType::Object);
204 *this->jsonValue.object = *data.jsonValue.object;
205 break;
206 }
207 case JsonType::Array: {
208 this->setValue(JsonType::Array);
209 *this->jsonValue.array = *data.jsonValue.array;
210 break;
211 }
212 case JsonType::String: {
213 this->setValue(JsonType::String);
214 *this->jsonValue.string = *data.jsonValue.string;
215 break;
216 }
217 case JsonType::Float: {
218 this->jsonValue.numberDouble = data.jsonValue.numberDouble;
219 break;
220 }
221 case JsonType::Uint64: {
222 this->jsonValue.numberUint = data.jsonValue.numberUint;
223 break;
224 }
225 case JsonType::Int64: {
226 this->jsonValue.numberInt = data.jsonValue.numberInt;
227 break;
228 }
229 case JsonType::Bool: {
230 this->jsonValue.boolean = data.jsonValue.boolean;
231 break;
232 }
233 }
234 this->string = data.string;
235 this->type = data.type;
236 return *this;
237 }
238
239 Jsonifier::Jsonifier(const Jsonifier& data) noexcept {
240 *this = data;
241 }
242
243 Jsonifier::operator std::string&&() noexcept {
244 return std::move(this->string);
245 }
246
247 Jsonifier::operator std::string() noexcept {
248 return this->string;
249 }
250
251 JsonType Jsonifier::getType() noexcept {
252 return this->type;
253 }
254
255 void Jsonifier::refreshString(JsonifierSerializeType opCode) {
256 this->string.clear();
257 if (opCode == JsonifierSerializeType::Etf) {
258 this->appendVersion();
259 this->serializeJsonToEtfString(this);
260 } else {
261 this->serializeJsonToJsonString(this);
262 }
263 }
264
265 Jsonifier& Jsonifier::operator=(EnumConverter&& data) noexcept {
266 if (data.isItAVector()) {
267 this->setValue(JsonType::Array);
268 for (auto& value: data.operator std::vector<uint64_t>()) {
269 this->jsonValue.array->emplace_back(std::move(value));
270 }
271 } else {
272 this->jsonValue.numberUint = uint64_t{ data };
273 this->type = JsonType::Uint64;
274 }
275 return *this;
276 }
277
278 Jsonifier::Jsonifier(EnumConverter&& data) noexcept {
279 *this = std::move(data);
280 }
281
282 Jsonifier& Jsonifier::operator=(const EnumConverter& data) noexcept {
283 if (data.isItAVector()) {
284 this->setValue(JsonType::Array);
285 for (auto& value: data.operator std::vector<uint64_t>()) {
286 this->jsonValue.array->emplace_back(value);
287 }
288 } else {
289 this->jsonValue.numberUint = uint64_t{ data };
290 this->type = JsonType::Uint64;
291 }
292 return *this;
293 }
294
295 Jsonifier::Jsonifier(const EnumConverter& data) noexcept {
296 *this = data;
297 }
298
299 Jsonifier& Jsonifier::operator=(std::string&& data) noexcept {
300 this->setValue(JsonType::String);
301 *this->jsonValue.string = std::move(data);
302 this->type = JsonType::String;
303 return *this;
304 }
305
306 Jsonifier::Jsonifier(std::string&& data) noexcept {
307 *this = std::move(data);
308 }
309
310 Jsonifier& Jsonifier::operator=(const std::string& data) noexcept {
311 this->setValue(JsonType::String);
312 *this->jsonValue.string = data;
313 this->type = JsonType::String;
314 return *this;
315 }
316
317 Jsonifier::Jsonifier(const std::string& data) noexcept {
318 *this = data;
319 }
320
321 Jsonifier& Jsonifier::operator=(const char* data) noexcept {
322 this->setValue(JsonType::String);
323 *this->jsonValue.string = data;
324 this->type = JsonType::String;
325 return *this;
326 }
327
328 Jsonifier::Jsonifier(const char* data) noexcept {
329 *this = data;
330 }
331
332 Jsonifier& Jsonifier::operator=(double data) noexcept {
333 this->jsonValue.numberDouble = data;
334 this->type = JsonType::Float;
335 return *this;
336 }
337
338 Jsonifier::Jsonifier(double data) noexcept {
339 *this = data;
340 }
341
342 Jsonifier& Jsonifier::operator=(float data) noexcept {
343 this->jsonValue.numberDouble = data;
344 this->type = JsonType::Float;
345 return *this;
346 }
347
348 Jsonifier::Jsonifier(float data) noexcept {
349 *this = data;
350 }
351
352 Jsonifier& Jsonifier::operator=(uint64_t data) noexcept {
353 this->jsonValue.numberUint = data;
354 this->type = JsonType::Uint64;
355 return *this;
356 }
357
358 Jsonifier::Jsonifier(uint64_t data) noexcept {
359 *this = data;
360 }
361
362 Jsonifier& Jsonifier::operator=(uint32_t data) noexcept {
363 this->jsonValue.numberUint = data;
364 this->type = JsonType::Uint64;
365 return *this;
366 }
367
368 Jsonifier::Jsonifier(uint32_t data) noexcept {
369 *this = data;
370 }
371
372 Jsonifier& Jsonifier::operator=(uint16_t data) noexcept {
373 this->jsonValue.numberUint = data;
374 this->type = JsonType::Uint64;
375 return *this;
376 }
377
378 Jsonifier::Jsonifier(uint16_t data) noexcept {
379 *this = data;
380 }
381
382 Jsonifier& Jsonifier::operator=(uint8_t data) noexcept {
383 this->jsonValue.numberUint = data;
384 this->type = JsonType::Uint64;
385 return *this;
386 }
387
388 Jsonifier::Jsonifier(uint8_t data) noexcept {
389 *this = data;
390 }
391
392 Jsonifier& Jsonifier::operator=(int64_t data) noexcept {
393 this->jsonValue.numberInt = data;
394 this->type = JsonType::Int64;
395 return *this;
396 }
397
398 Jsonifier::Jsonifier(int64_t data) noexcept {
399 *this = data;
400 }
401
402 Jsonifier& Jsonifier::operator=(int32_t data) noexcept {
403 this->jsonValue.numberInt = data;
404 this->type = JsonType::Int64;
405 return *this;
406 }
407
408 Jsonifier::Jsonifier(int32_t data) noexcept {
409 *this = data;
410 }
411
412 Jsonifier& Jsonifier::operator=(int16_t data) noexcept {
413 this->jsonValue.numberInt = data;
414 this->type = JsonType::Int64;
415 return *this;
416 }
417
418 Jsonifier::Jsonifier(int16_t data) noexcept {
419 *this = data;
420 }
421
422 Jsonifier& Jsonifier::operator=(int8_t data) noexcept {
423 this->jsonValue.numberInt = data;
424 this->type = JsonType::Int64;
425 return *this;
426 }
427
428 Jsonifier::Jsonifier(int8_t data) noexcept {
429 *this = data;
430 }
431
432 Jsonifier& Jsonifier::operator=(std::nullptr_t) noexcept {
433 this->type = JsonType::Null;
434 return *this;
435 }
436
437 Jsonifier::Jsonifier(std::nullptr_t data) noexcept {
438 *this = data;
439 }
440
441 Jsonifier& Jsonifier::operator=(bool data) noexcept {
442 this->jsonValue.boolean = data;
443 this->type = JsonType::Bool;
444 return *this;
445 }
446
447 Jsonifier::Jsonifier(bool data) noexcept {
448 *this = data;
449 }
450
451 Jsonifier& Jsonifier::operator=(JsonType typeNew) noexcept {
452 this->type = typeNew;
453 this->setValue(this->type);
454 return *this;
455 }
456
457 Jsonifier::Jsonifier(JsonType type) noexcept {
458 *this = type;
459 }
460
461 Jsonifier& Jsonifier::operator[](typename ObjectType::key_type key) {
462 if (this->type == JsonType::Null) {
463 this->setValue(JsonType::Object);
464 this->type = JsonType::Object;
465 }
466
467 if (this->type == JsonType::Object) {
468 auto result = this->jsonValue.object->emplace(std::move(key), Jsonifier{});
469 return result.first->second;
470 }
471 throw DCAException{ "Sorry, but that item-key could not be produced/accessed." };
472 }
473
474 Jsonifier& Jsonifier::operator[](uint64_t index) {
475 if (this->type == JsonType::Null) {
476 this->setValue(JsonType::Array);
477 this->type = JsonType::Array;
478 }
479
480 if (this->type == JsonType::Array) {
481 if (index >= this->jsonValue.array->size()) {
482 this->jsonValue.array->resize(index + 1);
483 }
484
485 return this->jsonValue.array->operator[](index);
486 }
487 throw DCAException{ "Sorry, but that index could not be produced/accessed." };
488 }
489
490 void Jsonifier::emplaceBack(Jsonifier&& other) noexcept {
491 if (this->type == JsonType::Null) {
492 this->setValue(JsonType::Array);
493 this->type = JsonType::Array;
494 }
495
496 if (this->type == JsonType::Array) {
497 this->jsonValue.array->emplace_back(std::move(other));
498 }
499 }
500
501 void Jsonifier::emplaceBack(Jsonifier& other) noexcept {
502 if (this->type == JsonType::Null) {
503 this->setValue(JsonType::Array);
504 this->type = JsonType::Array;
505 }
506
507 if (this->type == JsonType::Array) {
508 this->jsonValue.array->emplace_back(other);
509 }
510 }
511
512 void Jsonifier::serializeJsonToEtfString(const Jsonifier* dataToParse) {
513 switch (dataToParse->type) {
514 case JsonType::Object: {
515 return this->writeEtfObject(*dataToParse->jsonValue.object);
516 }
517 case JsonType::Array: {
518 return this->writeEtfArray(*dataToParse->jsonValue.array);
519 }
520 case JsonType::String: {
521 return this->writeEtfString(*dataToParse->jsonValue.string);
522 }
523 case JsonType::Float: {
524 return this->writeEtfFloat(dataToParse->jsonValue.numberDouble);
525 }
526 case JsonType::Uint64: {
527 return this->writeEtfUint(dataToParse->jsonValue.numberUint);
528 }
529 case JsonType::Int64: {
530 return this->writeEtfInt(dataToParse->jsonValue.numberInt);
531 }
532 case JsonType::Bool: {
533 return this->writeEtfBool(dataToParse->jsonValue.boolean);
534 }
535 case JsonType::Null: {
536 return this->writeEtfNull();
537 }
538 }
539 }
540
541 void Jsonifier::serializeJsonToJsonString(const Jsonifier* dataToParse) {
542 switch (dataToParse->type) {
543 case JsonType::Object: {
544 return this->writeJsonObject(*dataToParse->jsonValue.object);
545 }
546 case JsonType::Array: {
547 return this->writeJsonArray(*dataToParse->jsonValue.array);
548 }
549 case JsonType::String: {
550 return this->writeJsonString(*dataToParse->jsonValue.string);
551 }
552 case JsonType::Float: {
553 return this->writeJsonFloat(dataToParse->jsonValue.numberDouble);
554 }
555 case JsonType::Uint64: {
556 return this->writeJsonInt(dataToParse->jsonValue.numberUint);
557 }
558 case JsonType::Int64: {
559 return this->writeJsonInt(dataToParse->jsonValue.numberInt);
560 }
561 case JsonType::Bool: {
562 return this->writeJsonBool(dataToParse->jsonValue.boolean);
563 }
564 case JsonType::Null: {
565 return this->writeJsonNull();
566 }
567 }
568 }
569
570 void Jsonifier::writeJsonObject(const ObjectType& objectNew) {
571 if (objectNew.empty()) {
572 this->writeString("{}", 2);
573 return;
574 }
575 this->writeCharacter('{');
576
577 int32_t index{};
578 for (auto& [key, value]: objectNew) {
579 this->writeJsonString(key);
580 this->writeCharacter(':');
581 this->serializeJsonToJsonString(&value);
582
583 if (index != objectNew.size() - 1) {
584 this->writeCharacter(',');
585 }
586 ++index;
587 }
588
589 this->writeCharacter('}');
590 }
591
592 void Jsonifier::writeJsonArray(const ArrayType& arrayNew) {
593 if (arrayNew.empty()) {
594 this->writeString("[]", 2);
595 return;
596 }
597
598 this->writeCharacter('[');
599
600 int32_t index{};
601 for (auto& value: arrayNew) {
602 this->serializeJsonToJsonString(&value);
603 if (index != arrayNew.size() - 1) {
604 this->writeCharacter(',');
605 }
606 ++index;
607 }
608
609 this->writeCharacter(']');
610 }
611
612 void Jsonifier::writeJsonString(const StringType& stringNew) {
613 this->writeCharacter('"');
614 this->writeString(stringNew.data(), stringNew.size());
615 this->writeCharacter('"');
616 }
617
618 void Jsonifier::writeJsonFloat(const FloatType x) {
619 auto floatValue = std::to_string(x);
620 this->writeString(floatValue.data(), floatValue.size());
621 }
622
623 void Jsonifier::writeJsonBool(const BoolType jsonValueNew) {
624 if (jsonValueNew) {
625 this->writeString("true", 4);
626 } else {
627 this->writeString("false", 5);
628 }
629 }
630
631 void Jsonifier::writeJsonNull() {
632 this->writeString("null", 4);
633 }
634
635 void Jsonifier::writeEtfObject(const ObjectType& jsonData) {
636 this->appendMapHeader(static_cast<uint32_t>(jsonData.size()));
637 for (auto& [key, value]: jsonData) {
638 this->appendBinaryExt(key, static_cast<uint32_t>(key.size()));
639 this->serializeJsonToEtfString(&value);
640 }
641 }
642
643 void Jsonifier::writeEtfArray(const ArrayType& jsonData) {
644 this->appendListHeader(static_cast<uint32_t>(jsonData.size()));
645 for (auto& value: jsonData) {
646 this->serializeJsonToEtfString(&value);
647 }
648 this->appendNilExt();
649 }
650
651 void Jsonifier::writeEtfString(const StringType& jsonData) {
652 this->appendBinaryExt(jsonData, static_cast<uint32_t>(jsonData.size()));
653 }
654
655 void Jsonifier::writeEtfUint(const UintType jsonData) {
656 if (jsonData <= 255) {
657 this->appendSmallIntegerExt(static_cast<uint8_t>(jsonData));
658 } else if (jsonData <= std::numeric_limits<uint32_t>::max()) {
659 this->appendIntegerExt(static_cast<uint32_t>(jsonData));
660 } else {
661 this->appendUnsignedLongLong(jsonData);
662 }
663 }
664
665 void Jsonifier::writeEtfInt(const IntType jsonData) {
666 if (jsonData <= 127 && jsonData >= -127) {
667 this->appendSmallIntegerExt(static_cast<uint8_t>(jsonData));
668 } else if (jsonData <= std::numeric_limits<int32_t>::max() && jsonData >= std::numeric_limits<int32_t>::min()) {
669 this->appendIntegerExt(static_cast<uint32_t>(jsonData));
670 } else {
671 this->appendUnsignedLongLong(static_cast<uint64_t>(jsonData));
672 }
673 }
674
675 void Jsonifier::writeEtfFloat(const FloatType jsonData) {
676 this->appendNewFloatExt(jsonData);
677 }
678
679 void Jsonifier::writeEtfBool(const BoolType jsonData) {
680 this->appendBool(jsonData);
681 }
682
683 void Jsonifier::writeEtfNull() {
684 this->appendNil();
685 }
686
687 void Jsonifier::writeString(const char* data, size_t length) {
688 this->string.append(data, length);
689 }
690
691 void Jsonifier::writeCharacter(const char charValue) {
692 this->string.push_back(charValue);
693 }
694
695 bool operator==(const Jsonifier& lhs, const Jsonifier& rhs) {
696 if (lhs.type != rhs.type) {
697 return false;
698 }
699 switch (rhs.type) {
700 case JsonType::Object: {
701 if (*lhs.jsonValue.object != *rhs.jsonValue.object) {
702 return false;
703 }
704 break;
705 }
706 case JsonType::Array: {
707 if (*lhs.jsonValue.array != *rhs.jsonValue.array) {
708 return false;
709 }
710 break;
711 }
712 case JsonType::String: {
713 if (*lhs.jsonValue.string != *rhs.jsonValue.string) {
714 return false;
715 }
716 break;
717 }
718 case JsonType::Float: {
719 if (lhs.jsonValue.numberDouble != rhs.jsonValue.numberDouble) {
720 return false;
721 }
722 break;
723 }
724 case JsonType::Uint64: {
725 if (lhs.jsonValue.numberUint != rhs.jsonValue.numberUint) {
726 return false;
727 }
728 break;
729 }
730 case JsonType::Int64: {
731 if (lhs.jsonValue.numberInt != rhs.jsonValue.numberInt) {
732 return false;
733 }
734 break;
735 }
736 case JsonType::Bool: {
737 if (lhs.jsonValue.boolean != rhs.jsonValue.boolean) {
738 return false;
739 }
740 break;
741 }
742 }
743 return true;
744 }
745
746 void Jsonifier::appendBinaryExt(const std::string& bytes, uint32_t sizeNew) {
747 char newBuffer[5]{ static_cast<int8_t>(EtfType::Binary_Ext) };
748 storeBits(newBuffer + 1, sizeNew);
749 this->writeString(newBuffer, std::size(newBuffer));
750 this->writeString(bytes.data(), bytes.size());
751 }
752
753 void Jsonifier::appendUnsignedLongLong(uint64_t value) {
754 char newBuffer[11]{ static_cast<int8_t>(EtfType::Small_Big_Ext) };
755 char encodedBytes{};
756 while (value > 0) {
757 newBuffer[3 + encodedBytes] = value & 0xFF;
758 value >>= 8;
759 ++encodedBytes;
760 }
761 newBuffer[1] = encodedBytes;
762 newBuffer[2] = 0;
763 this->writeString(newBuffer, 1 + 2 + static_cast<size_t>(encodedBytes));
764 }
765
766 void Jsonifier::appendNewFloatExt(const double FloatValue) {
767 char newBuffer[9]{ static_cast<uint8_t>(EtfType::New_Float_Ext) };
768 const void* punner{ &FloatValue };
769 storeBits(newBuffer + 1, *static_cast<const uint64_t*>(punner));
770 this->writeString(newBuffer, std::size(newBuffer));
771 }
772
773 void Jsonifier::appendSmallIntegerExt(const uint8_t value) {
774 char newBuffer[2]{ static_cast<uint8_t>(EtfType::Small_Integer_Ext), static_cast<char>(value) };
775 this->writeString(newBuffer, std::size(newBuffer));
776 }
777
778 void Jsonifier::appendIntegerExt(const uint32_t value) {
779 char newBuffer[5]{ static_cast<uint8_t>(EtfType::Integer_Ext) };
780 storeBits(newBuffer + 1, value);
781 this->writeString(newBuffer, std::size(newBuffer));
782 }
783
784 void Jsonifier::appendListHeader(const uint32_t sizeNew) {
785 char newBuffer[5]{ static_cast<uint8_t>(EtfType::List_Ext) };
786 storeBits(newBuffer + 1, sizeNew);
787 this->writeString(newBuffer, std::size(newBuffer));
788 }
789
790 void Jsonifier::appendMapHeader(const uint32_t sizeNew) {
791 char newBuffer[5]{ static_cast<uint8_t>(EtfType::Map_Ext) };
792 storeBits(newBuffer + 1, sizeNew);
793 this->writeString(newBuffer, std::size(newBuffer));
794 }
795
796 void Jsonifier::appendBool(bool data) {
797 if (data) {
798 char newBuffer[6]{ static_cast<uint8_t>(EtfType::Small_Atom_Ext), static_cast<uint8_t>(4), 't', 'r', 'u', 'e' };
799 this->writeString(newBuffer, std::size(newBuffer));
800
801 } else {
802 char newBuffer[7]{ static_cast<uint8_t>(EtfType::Small_Atom_Ext), static_cast<uint8_t>(5), 'f', 'a', 'l', 's', 'e' };
803 this->writeString(newBuffer, std::size(newBuffer));
804 }
805 }
806
807 void Jsonifier::appendVersion() {
808 char newBuffer[1]{ static_cast<int8_t>(formatVersion) };
809 this->writeString(newBuffer, std::size(newBuffer));
810 }
811
812 void Jsonifier::appendNilExt() {
813 this->writeCharacter(static_cast<uint8_t>(EtfType::Nil_Ext));
814 }
815
816 void Jsonifier::appendNil() {
817 char newBuffer[5]{ static_cast<uint8_t>(EtfType::Small_Atom_Ext), static_cast<uint8_t>(3), 'n', 'i', 'l' };
818 this->writeString(newBuffer, std::size(newBuffer));
819 }
820
821 void Jsonifier::setValue(JsonType typeNew) {
822 this->destroy();
823 this->type = typeNew;
824 switch (this->type) {
825 case JsonType::Object: {
826 AllocatorType<ObjectType> allocator{};
827 this->jsonValue.object = AllocatorTraits<ObjectType>::allocate(allocator, 1);
828 AllocatorTraits<ObjectType>::construct(allocator, this->jsonValue.object);
829 break;
830 }
831 case JsonType::Array: {
832 AllocatorType<ArrayType> allocator{};
833 this->jsonValue.array = AllocatorTraits<ArrayType>::allocate(allocator, 1);
834 AllocatorTraits<ArrayType>::construct(allocator, this->jsonValue.array);
835 break;
836 }
837 case JsonType::String: {
838 AllocatorType<StringType> allocator{};
839 this->jsonValue.string = AllocatorTraits<StringType>::allocate(allocator, 1);
840 AllocatorTraits<StringType>::construct(allocator, this->jsonValue.string);
841 break;
842 }
843 }
844 }
845
846 void Jsonifier::destroy() noexcept {
847 switch (this->type) {
848 case JsonType::Object: {
849 AllocatorType<ObjectType> allocator{};
850 AllocatorTraits<ObjectType>::destroy(allocator, this->jsonValue.object);
851 AllocatorTraits<ObjectType>::deallocate(allocator, this->jsonValue.object, 1);
852 break;
853 }
854 case JsonType::Array: {
855 AllocatorType<ArrayType> allocator{};
856 AllocatorTraits<ArrayType>::destroy(allocator, this->jsonValue.array);
857 AllocatorTraits<ArrayType>::deallocate(allocator, this->jsonValue.array, 1);
858 break;
859 }
860 case JsonType::String: {
861 AllocatorType<StringType> allocator{};
862 AllocatorTraits<StringType>::destroy(allocator, this->jsonValue.string);
863 AllocatorTraits<StringType>::deallocate(allocator, this->jsonValue.string, 1);
864 break;
865 }
866 }
867 }
868
869 Jsonifier::~Jsonifier() noexcept {
870 this->destroy();
871 }
872
873 std::basic_ostream<char>& operator<<(std::basic_ostream<char>& outputSttream, const std::string& (*function)( void )) {
874 outputSttream << function();
875 return outputSttream;
876 }
877
878 ConfigManager::ConfigManager(const DiscordCoreClientConfig& configNew) {
879 this->config = configNew;
880 }
881
882 const bool ConfigManager::doWePrintWebSocketSuccessMessages() const {
883 return this->config.logOptions.logWebSocketSuccessMessages;
884 }
885
886 const bool ConfigManager::doWePrintWebSocketErrorMessages() const {
887 return this->config.logOptions.logWebSocketErrorMessages;
888 }
889
890 const bool ConfigManager::doWePrintHttpsSuccessMessages() const {
891 return this->config.logOptions.logHttpsSuccessMessages;
892 }
893
894 const bool ConfigManager::doWePrintHttpsErrorMessages() const {
895 return this->config.logOptions.logHttpsErrorMessages;
896 }
897
898 const bool ConfigManager::doWePrintFFMPEGSuccessMessages() const {
899 return this->config.logOptions.logFFMPEGSuccessMessages;
900 }
901
902 const bool ConfigManager::doWePrintFFMPEGErrorMessages() const {
903 return this->config.logOptions.logFFMPEGErrorMessages;
904 }
905
906 const bool ConfigManager::doWePrintGeneralSuccessMessages() const {
907 return this->config.logOptions.logGeneralSuccessMessages;
908 }
909
910 const bool ConfigManager::doWePrintGeneralErrorMessages() const {
911 return this->config.logOptions.logGeneralErrorMessages;
912 }
913
914 const bool ConfigManager::doWeCacheChannels() const {
915 return this->config.cacheOptions.cacheChannels;
916 }
917
918 const bool ConfigManager::doWeCacheUsers() const {
919 return this->config.cacheOptions.cacheUsers;
920 }
921
922 const bool ConfigManager::doWeCacheGuilds() const {
923 return this->config.cacheOptions.cacheGuilds;
924 }
925
926 const bool ConfigManager::doWeCacheRoles() const {
927 return this->config.cacheOptions.cacheRoles;
928 }
929
930 const UpdatePresenceData ConfigManager::getPresenceData() const {
931 return this->config.presenceData;
932 }
933
934 const std::string ConfigManager::getBotToken() const {
935 return this->config.botToken;
936 }
937
938 const uint32_t ConfigManager::getTotalShardCount() const {
939 return this->config.shardOptions.totalNumberOfShards;
940 }
941
942 const uint32_t ConfigManager::getStartingShard() const {
943 return this->config.shardOptions.startingShard;
944 }
945
946 const uint32_t ConfigManager::getShardCountForThisProcess() const {
947 return this->config.shardOptions.numberOfShardsForThisProcess;
948 }
949
950 const std::string ConfigManager::getConnectionAddress() const {
951 return this->config.connectionAddress;
952 }
953
954 void ConfigManager::setConnectionAddress(const std::string& connectionAddressNew) {
955 this->config.connectionAddress = connectionAddressNew;
956 }
957
958 const uint16_t ConfigManager::getConnectionPort() const {
959 return this->config.connectionPort;
960 }
961
962 void ConfigManager::setConnectionPort(const uint16_t connectionPortNew) {
963 this->config.connectionPort = connectionPortNew;
964 }
965
966 const std::vector<RepeatedFunctionData> ConfigManager::getFunctionsToExecute() const {
967 return this->config.functionsToExecute;
968 }
969
970 const TextFormat ConfigManager::getTextFormat() const {
971 return this->config.textFormat;
972 }
973
974 const GatewayIntents ConfigManager::getGatewayIntents() {
975 return this->config.intents;
976 }
977
978 StringWrapper& StringWrapper::operator=(StringWrapper&& other) noexcept {
979 if (this != &other) {
980 this->ptr.reset(nullptr);
981 this->ptr = std::move(other.ptr);
982 other.ptr.reset(nullptr);
983 other.ptr = nullptr;
984 }
985 return *this;
986 }
987
988 StringWrapper::StringWrapper(StringWrapper&& other) noexcept {
989 *this = std::move(other);
990 }
991
992 StringWrapper& StringWrapper::operator=(const StringWrapper& other) {
993 if (this != &other) {
994 this->ptr.reset(nullptr);
995 std::stringstream stream{};
996 if (other.ptr) {
997 stream << other.ptr;
998 }
999 auto length = stream.str().size();
1000 this->ptr = std::make_unique<char[]>(length + 1);
1001 for (uint64_t x = 0; x < length; ++x) {
1002 this->ptr[x] = other.ptr[x];
1003 }
1004 }
1005 return *this;
1006 }
1007
1008 StringWrapper::StringWrapper(const StringWrapper& other) {
1009 *this = other;
1010 }
1011
1012 StringWrapper& StringWrapper::operator=(const std::string& string) {
1013 auto length = string.size();
1014 this->ptr.reset(nullptr);
1015 this->ptr = std::make_unique<char[]>(length + 1);
1016 for (uint32_t x = 0; x < length; ++x) {
1017 this->ptr[x] = string[x];
1018 }
1019 return *this;
1020 }
1021
1022 StringWrapper::StringWrapper(const std::string& string) {
1023 *this = string;
1024 }
1025
1026 StringWrapper& StringWrapper::operator=(const char* string) {
1027 if (string) {
1028 this->ptr.reset(nullptr);
1029 std::stringstream stream{};
1030 stream << string;
1031 int64_t length = stream.str().size();
1032 this->ptr = std::make_unique<char[]>(length + 1);
1033 for (int64_t x = 0; x < length; ++x) {
1034 this->ptr[x] = string[x];
1035 }
1036 }
1037 return *this;
1038 }
1039
1040 StringWrapper::StringWrapper(const char* string) {
1041 *this = string;
1042 }
1043
1044 StringWrapper::operator std::string() {
1045 std::stringstream stream{};
1046 if (this->ptr) {
1047 stream << this->ptr;
1048 }
1049 std::string string{};
1050 for (int32_t x = 0; x < stream.str().size(); ++x) {
1051 string.push_back(stream.str()[x]);
1052 }
1053 return string;
1054 }
1055
1056 void StringWrapper::emplace_back(char value) {
1057 std::stringstream stream{};
1058 if (this->ptr) {
1059 stream << this->ptr;
1060 }
1061 auto length = stream.str().size();
1062 this->ptr = std::make_unique<char[]>(length + 2);
1063
1064 for (uint64_t x = 0; x < length; ++x) {
1065 this->ptr[x] = stream.str()[x];
1066 }
1067 this->ptr[length] = value;
1068 }
1069
1070 uint64_t StringWrapper::size() {
1071 std::stringstream stream{};
1072 if (this->ptr) {
1073 stream << this->ptr;
1074 }
1075 auto length = stream.str().size();
1076 return length;
1077 }
1078
1079 const char* StringWrapper::data() {
1080 return this->ptr.get();
1081 }
1082
1083 ColorValue::ColorValue(uint32_t colorValue) {
1084 this->color = colorValue;
1085 }
1086
1087 ColorValue::ColorValue(std::string hexColorValue) {
1088 if (hexColorValue == "") {
1089 hexColorValue = "fefefe";
1090 }
1091 this->color = stoull(hexColorValue, nullptr, 16);
1092 }
1093
1094 RGBColorValue ColorValue::getRgbColorValue() {
1095 uint8_t red = static_cast<uint8_t>(this->color >> 16);
1096 uint8_t green = static_cast<uint8_t>(this->color >> 8);
1097 uint8_t blue = static_cast<uint8_t>(this->color);
1098 RGBColorValue color{};
1099 color.green = green;
1100 color.blue = blue;
1101 color.red = red;
1102 return color;
1103 }
1104
1105 HexColorValue ColorValue::getHexColorValue() {
1106 std::stringstream stream{};
1107 stream << std::hex << this->color;
1108 return stream.str();
1109 }
1110
1111 uint32_t ColorValue::getIntColorValue() {
1112 return this->color;
1113 }
1114
1115 IconHash& IconHash::operator=(const std::string& string) {
1116 std::string newHash{ string };
1117 if (newHash.empty() || newHash == "0") {
1118 this->highBits = 0;
1119 this->lowBits = 0;
1120 return *this;
1121 }
1122 if (newHash.length() == 34 && newHash.substr(0, 2) == "a_") {
1123 newHash = newHash.substr(2);
1124 }
1125 if (newHash.length() != 32 && newHash.length() != 33) {
1126 throw std::length_error(
1127 "IconHash must be exactly 32 characters in length, passed value is: '" + std::to_string(newHash.size()) + "', in length.");
1128 }
1129 this->lowBits = fromString<uint64_t>(newHash.substr(0, 16), std::hex);
1130 this->highBits = fromString<uint64_t>(newHash.substr(16, 16), std::hex);
1131 return *this;
1132 }
1133
1134 IconHash::IconHash(const std::string& string) noexcept {
1135 *this = string;
1136 }
1137
1138 std::string IconHash::getIconHash() noexcept {
1139 if (this->highBits == 0 || this->lowBits == 0) {
1140 return {};
1141 } else {
1142 return std::string{ toHex(this->lowBits) + toHex(this->highBits) };
1143 }
1144 }
1145
1146 bool IconHash::operator==(const IconHash& other) {
1147 return this->lowBits == other.lowBits && this->highBits == other.highBits;
1148 }
1149
1150 uint64_t strtoull(std::string_view string) {
1151 for (auto& value: string) {
1152 if (!isdigit(value)) {
1153 return 0;
1154 }
1155 }
1156 if (!string.empty() && string != "") {
1157 return stoull(std::string{ string });
1158 } else {
1159 return 0;
1160 }
1161 }
1162
1163 Permissions& Permissions::operator=(Permission&& other) {
1164 this->permissions = static_cast<uint64_t>(other);
1165 return *this;
1166 }
1167
1168 Permissions::Permissions(Permission&& permsNew) {
1169 *this = std::move(permsNew);
1170 }
1171
1172 Permissions& Permissions::operator=(const Permission& other) {
1173 this->permissions = static_cast<uint64_t>(other);
1174 return *this;
1175 }
1176
1177 Permissions::Permissions(const Permission& permsNew) {
1178 *this = permsNew;
1179 }
1180
1181 Permissions& Permissions::operator=(std::string&& other) {
1182 if (other.size() == 0 || other == "") {
1183 this->permissions = 0;
1184 } else {
1185 for (auto& value: other) {
1186 this->permissions = stoull(other);
1187 }
1188 }
1189 other = "";
1190 return *this;
1191 }
1192
1193 Permissions::Permissions(std::string&& permsNew) {
1194 *this = std::move(permsNew);
1195 }
1196
1197 Permissions& Permissions::operator=(const std::string& other) {
1198 if (other.size() == 0 || other == "") {
1199 this->permissions = 0;
1200 } else {
1201 this->permissions = stoull(other);
1202 }
1203 return *this;
1204 }
1205
1206 Permissions::Permissions(const std::string& permsNew) {
1207 *this = permsNew;
1208 }
1209
1210
1211 Permissions& Permissions::operator=(uint64_t other) {
1212 this->permissions = other;
1213 return *this;
1214 }
1215
1216 Permissions::Permissions(uint64_t permsNew) {
1217 *this = permsNew;
1218 }
1219
1220 Permissions::operator uint64_t() {
1221 return this->permissions;
1222 }
1223
1224 Permissions::operator std::string() {
1225 return std::string{ std::to_string(this->permissions) };
1226 }
1227
1228 std::string Permissions::getCurrentChannelPermissions(const GuildMember& guildMember, const ChannelData& channel) {
1229 std::string permsString = Permissions::computePermissions(guildMember, channel);
1230 return permsString;
1231 }
1232
1233 bool Permissions::checkForPermission(const GuildMember& guildMember, const ChannelData& channel, Permission permission) {
1234 std::string permissionsString = Permissions::computePermissions(guildMember, channel);
1235 if ((stoull(permissionsString) & static_cast<uint64_t>(permission)) == static_cast<uint64_t>(permission)) {
1236 return true;
1237 } else {
1238 return false;
1239 }
1240 }
1241
1243 std::string permissions = Permissions::computeBasePermissions(guildMember);
1244 return permissions;
1245 }
1246
1247 void Permissions::removePermissions(const std::vector<Permission>& permissionsToRemove) {
1248 uint64_t permissionsInteger = this->permissions;
1249 for (auto value: permissionsToRemove) {
1250 permissionsInteger &= ~static_cast<uint64_t>(value);
1251 }
1252 std::stringstream sstream{};
1253 sstream << permissionsInteger;
1254 *this = sstream.str();
1255 }
1256
1257 void Permissions::addPermissions(const std::vector<Permission>& permissionsToAdd) {
1258 uint64_t permissionsInteger = this->permissions;
1259 for (auto value: permissionsToAdd) {
1260 permissionsInteger |= static_cast<uint64_t>(value);
1261 }
1262 std::stringstream sstream{};
1263 sstream << permissionsInteger;
1264 *this = sstream.str();
1265 }
1266
1267 std::vector<std::string> Permissions::displayPermissions() {
1268 std::vector<std::string> returnVector{};
1269 uint64_t permissionsInteger = this->permissions;
1270 if (permissionsInteger & (1ll << 3)) {
1271 for (int64_t x = 0; x < 41; ++x) {
1272 permissionsInteger |= 1ll << x;
1273 }
1274 }
1275 if (permissionsInteger & (1ll << 0)) {
1276 returnVector.emplace_back("Create Instant Invite");
1277 }
1278 if (permissionsInteger & (1ll << 1)) {
1279 returnVector.emplace_back("Kick Members");
1280 }
1281 if (permissionsInteger & (1ll << 2)) {
1282 returnVector.emplace_back("Ban Members");
1283 }
1284 if (permissionsInteger & (1ll << 3)) {
1285 returnVector.emplace_back("Administrator");
1286 }
1287 if (permissionsInteger & (1ll << 4)) {
1288 returnVector.emplace_back("Manage Channels");
1289 }
1290 if (permissionsInteger & (1ll << 5)) {
1291 returnVector.emplace_back("Manage Guild");
1292 }
1293 if (permissionsInteger & (1ll << 6)) {
1294 returnVector.emplace_back("Add Reactions");
1295 }
1296 if (permissionsInteger & (1ll << 7)) {
1297 returnVector.emplace_back("View Audit Log");
1298 }
1299 if (permissionsInteger & (1ll << 8)) {
1300 returnVector.emplace_back("Priority Speaker");
1301 }
1302 if (permissionsInteger & (1ll << 9)) {
1303 returnVector.emplace_back("Stream");
1304 }
1305 if (permissionsInteger & (1ll << 10)) {
1306 returnVector.emplace_back("View Channel");
1307 }
1308 if (permissionsInteger & (1ll << 11)) {
1309 returnVector.emplace_back("Send Messages");
1310 }
1311 if (permissionsInteger & (1ll << 12)) {
1312 returnVector.emplace_back("Send TTS Messages");
1313 }
1314 if (permissionsInteger & (1ll << 13)) {
1315 returnVector.emplace_back("Manage Messages");
1316 }
1317 if (permissionsInteger & (1ll << 14)) {
1318 returnVector.emplace_back("Embed Links");
1319 }
1320 if (permissionsInteger & (1ll << 15)) {
1321 returnVector.emplace_back("Attach Files");
1322 }
1323 if (permissionsInteger & (1ll << 16)) {
1324 returnVector.emplace_back("Read Message History");
1325 }
1326 if (permissionsInteger & (1ll << 17)) {
1327 returnVector.emplace_back("Mention Everyone");
1328 }
1329 if (permissionsInteger & (1ll << 18)) {
1330 returnVector.emplace_back("Use External Emoji");
1331 }
1332 if (permissionsInteger & (1ll << 19)) {
1333 returnVector.emplace_back("View Guild Insights");
1334 }
1335 if (permissionsInteger & (1ll << 20)) {
1336 returnVector.emplace_back("Connect");
1337 }
1338 if (permissionsInteger & (1ll << 21)) {
1339 returnVector.emplace_back("Speak");
1340 }
1341 if (permissionsInteger & (1ll << 22)) {
1342 returnVector.emplace_back("Mute Members");
1343 }
1344 if (permissionsInteger & (1ll << 23)) {
1345 returnVector.emplace_back("Deafen Members");
1346 }
1347 if (permissionsInteger & (1ll << 24)) {
1348 returnVector.emplace_back("Move Members");
1349 }
1350 if (permissionsInteger & (1ll << 25)) {
1351 returnVector.emplace_back("Use VAD");
1352 }
1353 if (permissionsInteger & (1ll << 26)) {
1354 returnVector.emplace_back("Change Nickname");
1355 }
1356 if (permissionsInteger & (1ll << 27)) {
1357 returnVector.emplace_back("Manage Nicknames");
1358 }
1359 if (permissionsInteger & (1ll << 28)) {
1360 returnVector.emplace_back("Manage Roles");
1361 }
1362 if (permissionsInteger & (1ll << 29)) {
1363 returnVector.emplace_back("Manage Webhooks");
1364 }
1365 if (permissionsInteger & (1ll << 30)) {
1366 returnVector.emplace_back("Manage Emojis And Stickers");
1367 }
1368 if (permissionsInteger & (1ll << 31)) {
1369 returnVector.emplace_back("Use Application Commands");
1370 }
1371 if (permissionsInteger & (1ll << 32)) {
1372 returnVector.emplace_back("Request To Speak");
1373 }
1374 if (permissionsInteger & (1ll << 33)) {
1375 returnVector.emplace_back("Manage Events");
1376 }
1377 if (permissionsInteger & (1ll << 34)) {
1378 returnVector.emplace_back("Manage Threads");
1379 }
1380 if (permissionsInteger & (1ll << 35)) {
1381 returnVector.emplace_back("Create Public Threads");
1382 }
1383 if (permissionsInteger & (1ll << 36)) {
1384 returnVector.emplace_back("Create Private Threads");
1385 }
1386 if (permissionsInteger & (1ll << 37)) {
1387 returnVector.emplace_back("Use External Stickers");
1388 }
1389 if (permissionsInteger & (1ll << 38)) {
1390 returnVector.emplace_back("Send Messages In Threads");
1391 }
1392 if (permissionsInteger & (1ll << 39)) {
1393 returnVector.emplace_back("Start Embedded Activities");
1394 }
1395 if (permissionsInteger & (1ll << 40)) {
1396 returnVector.emplace_back("Moderate Members");
1397 }
1398 return returnVector;
1399 }
1400
1402 std::string returnString = std::to_string(this->permissions);
1403 return returnString;
1404 }
1405
1407 uint64_t allPerms{};
1408 for (int64_t x = 0; x < 41; ++x) {
1409 allPerms |= 1ll << x;
1410 }
1411 std::stringstream stream{};
1412 stream << allPerms;
1413 return stream.str();
1414 }
1415
1416 std::string Permissions::computeOverwrites(const std::string& basePermissions, const GuildMember& guildMember, const ChannelData& channel) {
1417 if ((stoull(basePermissions) & static_cast<uint64_t>(Permission::Administrator)) == static_cast<uint64_t>(Permission::Administrator)) {
1419 }
1420
1421 uint64_t permissions = stoull(basePermissions);
1422 for (int32_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
1423 if (channel.permissionOverwrites[x].id == guildMember.guildId) {
1424 permissions &= ~channel.permissionOverwrites[x].deny;
1425 permissions |= channel.permissionOverwrites[x].allow;
1426 break;
1427 }
1428 }
1429 std::vector<RoleData> guildMemberRoles{};
1430 for (auto& value: guildMember.roles) {
1431 guildMemberRoles.emplace_back(Roles::getCachedRole({ .guildId = guildMember.guildId, .roleId = value }));
1432 }
1433 uint64_t allow{};
1434 uint64_t deny{};
1435 for (auto& value: guildMemberRoles) {
1436 for (int32_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
1437 if (value.id == channel.permissionOverwrites[x].id) {
1438 allow |= channel.permissionOverwrites[x].allow;
1439 deny |= channel.permissionOverwrites[x].deny;
1440 }
1441 }
1442 }
1443 permissions &= ~deny;
1444 permissions |= allow;
1445 for (int32_t x = 0; x < channel.permissionOverwrites.size(); ++x) {
1446 if (channel.permissionOverwrites[x].id == guildMember.id) {
1447 permissions &= ~channel.permissionOverwrites[x].deny;
1448 permissions |= channel.permissionOverwrites[x].allow;
1449 break;
1450 }
1451 }
1452 return std::to_string(permissions);
1453 }
1454
1455 std::string Permissions::computePermissions(const GuildMember& guildMember, const ChannelData& channel) {
1456 std::string permissions = Permissions::computeBasePermissions(guildMember);
1457 permissions = Permissions::computeOverwrites(permissions, guildMember, channel);
1458 return permissions;
1459 }
1460
1461 std::string Permissions::computeBasePermissions(const GuildMember& guildMember) {
1462 const GuildData guild = Guilds::getCachedGuild({ .guildId = guildMember.guildId });
1463 if (guild.ownerId == guildMember.id) {
1465 }
1466 std::vector<RoleData> guildRoles{};
1467 for (auto& value: guild.roles) {
1468 guildRoles.emplace_back(Roles::getCachedRole({ .guildId = guild.id, .roleId = value }));
1469 }
1470 RoleData roleEveryone{};
1471 for (auto& value: guildRoles) {
1472 if (value.id == guild.id) {
1473 roleEveryone = value;
1474 }
1475 }
1476 uint64_t permissions{};
1477 if (roleEveryone.permissions != 0) {
1478 permissions = roleEveryone.permissions;
1479 }
1480 GetGuildMemberRolesData getRolesData{};
1481 getRolesData.guildMember = guildMember;
1482 getRolesData.guildId = guildMember.guildId;
1483 std::vector<RoleData> guildMemberRoles{};
1484 for (auto& value: guildMember.roles) {
1485 guildMemberRoles.emplace_back(Roles::getCachedRole({ .guildId = guild.id, .roleId = value }));
1486 }
1487 for (auto& value: guildMemberRoles) {
1488 permissions |= value.permissions;
1489 }
1490
1491 if ((permissions & static_cast<uint64_t>(Permission::Administrator)) == static_cast<uint64_t>(Permission::Administrator)) {
1493 }
1494
1495 return std::to_string(permissions);
1496 }
1497
1498 void reportException(const std::string& currentFunctionName, std::source_location location) {
1499 try {
1500 auto currentException = std::current_exception();
1501 if (currentException) {
1502 std::rethrow_exception(currentException);
1503 }
1504 } catch (const std::exception& e) {
1505 std::stringstream stream{};
1506 stream << shiftToBrightRed() << "Error Report: \n"
1507 << "Caught At: " << currentFunctionName << ", in File: " << location.file_name() << " (" << std::to_string(location.line()) << ":"
1508 << std::to_string(location.column()) << ")"
1509 << "\nThe Error: \n"
1510 << e.what() << reset() << std::endl
1511 << std::endl;
1512 auto returnString = stream.str();
1513 cout << returnString;
1514 }
1515 }
1516
1517 void rethrowException(const std::string& currentFunctionName, std::source_location location) {
1518 try {
1519 auto currentException = std::current_exception();
1520 if (currentException) {
1521 std::rethrow_exception(currentException);
1522 }
1523 } catch (const std::exception& e) {
1524 std::stringstream stream{};
1525 stream << shiftToBrightRed() << "Caught At: " << currentFunctionName << ", in File: " << location.file_name() << " ("
1526 << std::to_string(location.line()) << ":" << std::to_string(location.column()) << ")"
1527 << "\nThe Error: \n"
1528 << e.what() << reset();
1529 auto returnString = stream.str();
1530 cout << returnString;
1531 if (std::current_exception()) {
1532 std::rethrow_exception(std::current_exception());
1533 }
1534 }
1535 }
1536
1537 std::string constructMultiPartData(const std::string& data, const std::vector<File>& files) {
1538 const std::string boundary("boundary25");
1539 const std::string partStart("--" + boundary + "\r\nContent-Type: application/octet-stream\r\nContent-Disposition: form-data; ");
1540
1541 std::string content("--" + boundary);
1542
1543 content += "\r\nContent-Type: application/json\r\nContent-Disposition: form-data; "
1544 "name=\"payload_json\"\r\n\r\n";
1545 content += data + "\r\n";
1546 if (files.size() == 1) {
1547 content += partStart + "name=\"file\"; filename=\"" + files[0].fileName + "\"" + "\r\n\r\n";
1548 content += files[0].data;
1549 } else {
1550 for (int8_t x = 0; x < files.size(); ++x) {
1551 content += partStart + "name=\"files[" + std::to_string(x) + "]\"; filename=\"" + files[x].fileName + "\"\r\n\r\n";
1552 content += files[x].data;
1553 content += "\r\n";
1554 }
1555 }
1556 content += "\r\n--" + boundary + "--";
1557 return content;
1558 }
1559
1560 std::string convertToLowerCase(const std::string& stringToConvert) {
1561 std::string newString;
1562 for (auto& value: stringToConvert) {
1563 if (isupper(static_cast<uint8_t>(value))) {
1564 newString += static_cast<char>(tolower(static_cast<uint8_t>(value)));
1565 } else {
1566 newString += value;
1567 }
1568 }
1569 return newString;
1570 }
1571
1572 std::string base64Encode(const std::string& string, bool url) {
1573 const char* base64CharsArray[2] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1574 "abcdefghijklmnopqrstuvwxyz"
1575 "0123456789"
1576 "+/",
1577
1578 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1579 "abcdefghijklmnopqrstuvwxyz"
1580 "0123456789"
1581 "-_" };
1582
1583 uint64_t encodedLength = (string.size() + 2) / 3 * 4;
1584
1585 uint8_t trailing_char = url ? '.' : '=';
1586
1587 const char* base64Chars = base64CharsArray[url];
1588
1589 std::string returnString{};
1590 returnString.reserve(encodedLength);
1591 StopWatch stopWatch{ 1500ms };
1592 uint64_t pos = 0;
1593 while (pos < string.size()) {
1594 if (stopWatch.hasTimePassed()) {
1595 break;
1596 }
1597 returnString.push_back(base64Chars[(string[static_cast<uint64_t>(pos + 0)] & 0xfc) >> 2]);
1598
1599 if (static_cast<uint64_t>(pos + 1) < string.size()) {
1600 returnString.push_back(
1601 base64Chars[((string[static_cast<int64_t>(pos + 0)] & 0x03) << 4) + ((string[static_cast<int64_t>(pos + 1)] & 0xf0) >> 4)]);
1602
1603 if (static_cast<uint64_t>(pos + 2) < string.size()) {
1604 returnString.push_back(
1605 base64Chars[((string[static_cast<int64_t>(pos + 1)] & 0x0f) << 2) + ((string[static_cast<int64_t>(pos + 2)] & 0xc0) >> 6)]);
1606 returnString.push_back(base64Chars[string[static_cast<int64_t>(pos + 2)] & 0x3f]);
1607 } else {
1608 returnString.push_back(base64Chars[(string[static_cast<int64_t>(pos + 1)] & 0x0f) << 2]);
1609 returnString.push_back(trailing_char);
1610 }
1611 } else {
1612 returnString.push_back(base64Chars[(string[static_cast<int64_t>(pos + 0)] & 0x03) << 4]);
1613 returnString.push_back(trailing_char);
1614 returnString.push_back(trailing_char);
1615 }
1616
1617 pos += 3;
1618 }
1619
1620 return returnString;
1621 }
1622
1623 std::string loadFileContents(const std::string& filePath) {
1624 std::ifstream file(filePath, std::ios::in | std::ios::binary);
1625 std::ostringstream stream{};
1626 stream << file.rdbuf();
1627 return stream.str();
1628 }
1629
1630 std::string utf8MakeValid(const std::string& inputString) {
1631 std::string returnString{};
1632 for (auto& value: inputString) {
1633 if (value >= 128 || value < 0) {
1634 int32_t difference = 0 - value;
1635 returnString.push_back(value + difference);
1636 } else {
1637 returnString.push_back(value);
1638 }
1639 }
1640 return returnString;
1641 }
1642
1643 std::string urlEncode(const std::string& inputString) {
1644 std::ostringstream escaped{};
1645 escaped.fill('0');
1646 escaped << std::hex;
1647
1648 for (std::string::const_iterator x = inputString.begin(), n = inputString.end(); x != n; ++x) {
1649 std::string::value_type c = (*x);
1650
1651 if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
1652 escaped << c;
1653 continue;
1654 }
1655
1656 escaped << std::uppercase;
1657 escaped << '%' << std::setw(2) << int32_t(static_cast<uint8_t>(c));
1658 escaped << std::nouppercase;
1659 }
1660 return escaped.str();
1661 }
1662
1663 void spinLock(uint64_t timeInNsToSpinLockFor) {
1664 uint64_t startTime = std::chrono::duration_cast<Nanoseconds>(HRClock::now().time_since_epoch()).count();
1665 uint64_t timePassed{};
1666 while (timePassed < timeInNsToSpinLockFor) {
1667 timePassed = std::chrono::duration_cast<Nanoseconds>(HRClock::now().time_since_epoch()).count() - startTime;
1668 }
1669 }
1670
1671 std::string generateBase64EncodedKey() {
1672 std::string returnString{};
1673 returnString.resize(16);
1674 std::mt19937_64 randomEngine{ static_cast<uint64_t>(HRClock::now().time_since_epoch().count()) };
1675 for (int32_t x = 0; x < 16; ++x) {
1676 returnString[x] = static_cast<uint8_t>((static_cast<double>(randomEngine()) / static_cast<double>(randomEngine.max())) * 255.0f);
1677 }
1678 returnString = base64Encode(returnString, false);
1679 return returnString;
1680 }
1681
1682 std::string shiftToBrightGreen() {
1683 return std::string("\033[1;40;92m");
1684 }
1685
1686 std::string shiftToBrightBlue() {
1687 return std::string("\033[1;40;96m");
1688 }
1689
1690 std::string shiftToBrightRed() {
1691 return std::string("\033[1;40;91m");
1692 }
1693
1694 bool nanoSleep(int64_t ns) {
1695#ifdef _WIN32
1696 HANDLE timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
1697 LARGE_INTEGER largeInt{ .QuadPart = -ns / 100 };
1698 if (!timer) {
1699 return false;
1700 }
1701
1702 if (!SetWaitableTimerEx(timer, &largeInt, 0, NULL, NULL, NULL, 0)) {
1703 CloseHandle(timer);
1704 return false;
1705 }
1706 WaitForSingleObjectEx(timer, INFINITE, false);
1707 CloseHandle(timer);
1708#else
1709 std::this_thread::sleep_for(Nanoseconds{ ns });
1710#endif
1711 return true;
1712 }
1713
1714 std::string reset() {
1715 return std::string("\033[0m");
1716 }
1717
1718 std::string getTimeAndDate() {
1719 const time_t now = std::time(nullptr);
1720 tm time = *std::localtime(&now);
1721 std::string timeStamp{};
1722 timeStamp.resize(48);
1723 if (time.tm_isdst) {
1724 if (time.tm_hour + 4 >= 24) {
1725 time.tm_hour = 0 + time.tm_hour + 4 - 24;
1726
1727 } else {
1728 time.tm_hour = time.tm_hour + 4;
1729 }
1730 } else {
1731 if (time.tm_hour + 5 >= 24) {
1732 time.tm_hour = 0 + time.tm_hour + 5 - 24;
1733 } else {
1734 time.tm_hour = time.tm_hour + 5;
1735 }
1736 }
1737 uint64_t size = strftime(timeStamp.data(), 48, "%F %R", &time);
1738 timeStamp.resize(size);
1739 return timeStamp;
1740 }
1741
1742 std::string escapeCharacters(std::string_view string) {
1743 std::string stringNew{};
1744 if (stringNew.size() <= string.size() * 2) {
1745 stringNew.resize(string.size() * 2);
1746 }
1747 uint64_t index{};
1748 for (int32_t x = 0; x < string.size(); ++x) {
1749 switch (static_cast<char>(string[x])) {
1750 case 0x00: {
1751 break;
1752 }
1753 case 0x22: {
1754 stringNew[index] = static_cast<char>('\\');
1755 stringNew[index + 1] = static_cast<char>('"');
1756 index += 2;
1757 break;
1758 }
1759 case 0x5c: {
1760 stringNew[index] = static_cast<char>('\\');
1761 stringNew[index + 1] = static_cast<char>('\\');
1762 index += 2;
1763 break;
1764 }
1765 case 0x07: {
1766 stringNew[index] = static_cast<char>('\\');
1767 stringNew[index + 1] = static_cast<char>('a');
1768 index += 2;
1769 break;
1770 }
1771 case 0x08: {
1772 stringNew[index] = static_cast<char>('\\');
1773 stringNew[index + 1] = static_cast<char>('b');
1774 index += 2;
1775 break;
1776 }
1777 case 0x0C: {
1778 stringNew[index] = static_cast<char>('\\');
1779 stringNew[index + 1] = static_cast<char>('f');
1780 index += 2;
1781 break;
1782 }
1783 case 0x0A: {
1784 stringNew[index] = static_cast<char>('\\');
1785 stringNew[index + 1] = static_cast<char>('n');
1786 index += 2;
1787 break;
1788 }
1789 case 0x0D: {
1790 stringNew[index] = static_cast<char>('\\');
1791 stringNew[index + 1] = static_cast<char>('r');
1792 index += 2;
1793 break;
1794 }
1795 case 0x0B: {
1796 stringNew[index] = static_cast<char>('\\');
1797 stringNew[index + 1] = static_cast<char>('v');
1798 index += 2;
1799 break;
1800 }
1801 case 0x09: {
1802 stringNew[index] = static_cast<char>('\\');
1803 stringNew[index + 1] = static_cast<char>('t');
1804 index += 2;
1805 break;
1806 }
1807 default: {
1808 stringNew[index] = string[x];
1809 ++index;
1810 break;
1811 }
1812 }
1813 }
1814 if (stringNew.size() > 1) {
1815 if (stringNew[stringNew.size() - 1] == '\0') {
1816 stringNew.erase(stringNew.size() - 1);
1817 }
1818 }
1819 stringNew.resize(index);
1820 return stringNew;
1821 }
1822
1823 TimeStamp::TimeStamp(TimeFormat formatNew) {
1824 this->timeStampInTimeUnits = std::chrono::duration_cast<Milliseconds>(SysClock::now().time_since_epoch()).count();
1825 }
1826
1827 TimeStamp::TimeStamp(std::string year, std::string month, std::string day, std::string hour, std::string minute, std::string second,
1828 TimeFormat formatNew) {
1829 this->getTimeSinceEpoch(stoull(year), stoull(month), stoull(day), stoull(hour), stoull(minute), stoull(second));
1830 }
1831
1832 TimeStamp::operator std::string() {
1833 return getISO8601TimeStamp(TimeFormat::LongDateTime);
1834 }
1835
1836 TimeStamp::operator uint64_t() {
1837 if (this->timeStampInTimeUnits == 0) {
1838 this->timeStampInTimeUnits = std::chrono::duration_cast<Milliseconds>(SysClock::now().time_since_epoch()).count();
1839 }
1840 return this->timeStampInTimeUnits;
1841 }
1842
1843 TimeStamp& TimeStamp::operator=(std::string&& originalTimeStampNew) {
1844 this->convertTimeStampToTimeUnits(TimeFormat::LongDateTime, originalTimeStampNew);
1845 return *this;
1846 }
1847
1848 TimeStamp::TimeStamp(std::string&& originalTimeStampNew) {
1849 *this = std::move(originalTimeStampNew);
1850 if (this->timeStampInTimeUnits == 0) {
1851 this->timeStampInTimeUnits = std::chrono::duration_cast<Milliseconds>(SysClock::now().time_since_epoch()).count();
1852 }
1853 }
1854
1855 TimeStamp& TimeStamp::operator=(std::string& originalTimeStampNew) {
1856 this->convertTimeStampToTimeUnits(TimeFormat::LongDateTime, originalTimeStampNew);
1857 return *this;
1858 }
1859
1860 TimeStamp::TimeStamp(std::string& originalTimeStampNew) {
1861 *this = originalTimeStampNew;
1862 }
1863
1864 TimeStamp& TimeStamp::operator=(const TimeStamp& other) {
1865 this->timeStampInTimeUnits = other.timeStampInTimeUnits;
1866 return *this;
1867 }
1868
1869 TimeStamp::TimeStamp(const TimeStamp& other) {
1870 *this = other;
1871 }
1872
1873 TimeStamp::TimeStamp(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t minute, int32_t second, TimeFormat formatNew) {
1874 this->getTimeSinceEpoch(year, month, day, hour, minute, second);
1875 };
1876
1877 TimeStamp::TimeStamp(uint64_t timeInTimeUnits, TimeFormat formatNew) {
1878 this->timeStampInTimeUnits = timeInTimeUnits;
1879 }
1880
1881 std::string TimeStamp::convertToFutureISO8601TimeStamp(int32_t minutesToAdd, int32_t hoursToAdd, int32_t daysToAdd, int32_t monthsToAdd,
1882 int32_t yearsToAdd, TimeFormat formatNew) {
1883 std::time_t result = std::time(nullptr);
1884 int32_t secondsPerMinute{ 60 };
1885 int32_t minutesPerHour{ 60 };
1886 int32_t secondsPerHour{ minutesPerHour * secondsPerMinute };
1887 int32_t hoursPerDay{ 24 };
1888 int32_t secondsPerDay{ secondsPerHour * hoursPerDay };
1889 int32_t daysPerMonth{ 30 };
1890 int32_t secondsPerMonth{ secondsPerDay * daysPerMonth };
1891 int32_t daysPerYear{ 365 };
1892 int32_t secondsPerYear{ secondsPerDay * daysPerYear };
1893 int32_t secondsToAdd = (yearsToAdd * secondsPerYear) + (monthsToAdd * secondsPerMonth) + (daysToAdd * secondsPerDay) +
1894 ((hoursToAdd + 8) * secondsPerHour) + (minutesToAdd * secondsPerMinute);
1895 result += secondsToAdd;
1896 auto resultTwo = std::localtime(&result);
1897 std::string returnString{};
1898 if (resultTwo->tm_isdst) {
1899 if (resultTwo->tm_hour + 4 >= 24) {
1900 resultTwo->tm_hour = resultTwo->tm_hour - 24;
1901 ++resultTwo->tm_mday;
1902 }
1903 TimeStamp timeStamp{ std::to_string(resultTwo->tm_year + 1900), std::to_string(resultTwo->tm_mon + 1), std::to_string(resultTwo->tm_mday),
1904 std::to_string(resultTwo->tm_hour + 4), std::to_string(resultTwo->tm_min), std::to_string(resultTwo->tm_sec), formatNew };
1905 timeStamp.getISO8601TimeStamp(formatNew);
1906 returnString = static_cast<std::string>(timeStamp);
1907 } else {
1908 if (resultTwo->tm_hour + 5 >= 24) {
1909 resultTwo->tm_hour = resultTwo->tm_hour - 24;
1910 ++resultTwo->tm_mday;
1911 }
1912 TimeStamp timeStamp{ std::to_string(resultTwo->tm_year + 1900), std::to_string(resultTwo->tm_mon + 1), std::to_string(resultTwo->tm_mday),
1913 std::to_string(resultTwo->tm_hour + 5), std::to_string(resultTwo->tm_min), std::to_string(resultTwo->tm_sec), formatNew };
1914 timeStamp.getISO8601TimeStamp(formatNew);
1915 returnString = static_cast<std::string>(timeStamp);
1916 }
1917 return returnString;
1918 }
1919
1920 std::string TimeStamp::convertToCurrentISO8601TimeStamp(TimeFormat timeFormat) {
1921 std::time_t result = std::time(nullptr);
1922 auto resultTwo = std::localtime(&result);
1923 std::string returnString{};
1924 if (resultTwo->tm_isdst) {
1925 if (resultTwo->tm_hour + 4 >= 24) {
1926 resultTwo->tm_hour = resultTwo->tm_hour - 24;
1927 ++resultTwo->tm_mday;
1928 }
1929 TimeStamp timeStamp{ std::to_string(resultTwo->tm_year + 1900), std::to_string(resultTwo->tm_mon + 1), std::to_string(resultTwo->tm_mday),
1930 std::to_string(resultTwo->tm_hour + 4), std::to_string(resultTwo->tm_min), std::to_string(resultTwo->tm_sec), timeFormat };
1931 returnString = timeStamp.getISO8601TimeStamp(timeFormat);
1932 } else {
1933 if (resultTwo->tm_hour + 5 >= 24) {
1934 resultTwo->tm_hour = resultTwo->tm_hour - 24;
1935 ++resultTwo->tm_mday;
1936 }
1937 TimeStamp timeStamp{ std::to_string(resultTwo->tm_year + 1900), std::to_string(resultTwo->tm_mon + 1), std::to_string(resultTwo->tm_mday),
1938 std::to_string(resultTwo->tm_hour + 5), std::to_string(resultTwo->tm_min), std::to_string(resultTwo->tm_sec), timeFormat };
1939 returnString = timeStamp.getISO8601TimeStamp(timeFormat);
1940 }
1941 return returnString;
1942 }
1943
1944 bool TimeStamp::hasTimeElapsed(uint64_t days, uint64_t hours, uint64_t minutes) {
1945 if (this->timeStampInTimeUnits <= 0) {
1946 this->timeStampInTimeUnits = std::chrono::duration_cast<Milliseconds>(SysClock::now().time_since_epoch()).count();
1947 }
1948 int64_t startTimeRaw = this->timeStampInTimeUnits;
1949 auto currentTime = std::chrono::duration_cast<Milliseconds>(SysClock::now().time_since_epoch()).count();
1950 int64_t secondsPerMinute = 60;
1951 int64_t secondsPerHour = secondsPerMinute * 60;
1952 int64_t secondsPerDay = secondsPerHour * 24;
1953 auto targetElapsedTime = ((static_cast<int64_t>(days) * secondsPerDay) + (static_cast<int64_t>(hours) * secondsPerHour) +
1954 (static_cast<int64_t>(minutes) * secondsPerMinute)) *
1955 1000;
1956 auto actualElapsedTime = currentTime - startTimeRaw;
1957 if (actualElapsedTime <= 0) {
1958 return false;
1959 }
1960 if (actualElapsedTime >= targetElapsedTime) {
1961 return true;
1962 } else {
1963 return false;
1964 }
1965 }
1966
1967 std::string TimeStamp::convertMsToDurationString(uint64_t durationInMs) {
1968 std::string newString{};
1969 uint64_t msPerSecond{ 1000 };
1970 uint64_t secondsPerMinute{ 60 };
1971 uint64_t minutesPerHour{ 60 };
1972 uint64_t msPerMinute{ msPerSecond * secondsPerMinute };
1973 uint64_t msPerHour{ msPerMinute * minutesPerHour };
1974 uint64_t hoursLeft = static_cast<uint64_t>(trunc(durationInMs / msPerHour));
1975 uint64_t minutesLeft = static_cast<uint64_t>(trunc((durationInMs % msPerHour) / msPerMinute));
1976 uint64_t secondsLeft = static_cast<uint64_t>(trunc(((durationInMs % msPerHour) % msPerMinute) / msPerSecond));
1977 if (hoursLeft >= 1) {
1978 newString += std::to_string(hoursLeft) + " Hours, ";
1979 newString += std::to_string(minutesLeft) + " Minutes, ";
1980 newString += std::to_string(secondsLeft) + " Seconds.";
1981 } else if (minutesLeft >= 1) {
1982 newString += std::to_string(minutesLeft) + " Minutes, ";
1983 newString += std::to_string(secondsLeft) + " Seconds.";
1984 } else {
1985 newString += std::to_string(secondsLeft) + " Seconds.";
1986 }
1987 return newString;
1988 }
1989
1990 void TimeStamp::getTimeSinceEpoch(int64_t year, int64_t month, int64_t day, int64_t hour, int64_t minute, int64_t second) {
1991 const uint32_t secondsInJan{ 31 * 24 * 60 * 60 };
1992 const uint32_t secondsInFeb{ 28 * 24 * 60 * 60 };
1993 const uint32_t secondsInMar{ 31 * 24 * 60 * 60 };
1994 const uint32_t secondsInApr{ 30 * 24 * 60 * 60 };
1995 const uint32_t secondsInMay{ 31 * 24 * 60 * 60 };
1996 const uint32_t secondsInJun{ 30 * 24 * 60 * 60 };
1997 const uint32_t secondsInJul{ 31 * 24 * 60 * 60 };
1998 const uint32_t secondsInAug{ 31 * 24 * 60 * 60 };
1999 const uint32_t secondsInSep{ 30 * 24 * 60 * 60 };
2000 const uint32_t secondsInOct{ 31 * 24 * 60 * 60 };
2001 const uint32_t secondsInNov{ 30 * 24 * 60 * 60 };
2002 const uint32_t secondsInDec{ 31 * 24 * 60 * 60 };
2003 const uint32_t secondsPerMinute{ 60 };
2004 const uint32_t secondsPerHour{ 60 * 60 };
2005 const uint32_t secondsPerDay{ 60 * 60 * 24 };
2006 Seconds value{};
2007 for (int32_t x = 1970; x < year; ++x) {
2008 value += Seconds{ secondsInJan };
2009 value += Seconds{ secondsInFeb };
2010 value += Seconds{ secondsInMar };
2011 value += Seconds{ secondsInApr };
2012 value += Seconds{ secondsInMay };
2013 value += Seconds{ secondsInJun };
2014 value += Seconds{ secondsInJul };
2015 value += Seconds{ secondsInAug };
2016 value += Seconds{ secondsInSep };
2017 value += Seconds{ secondsInOct };
2018 value += Seconds{ secondsInNov };
2019 value += Seconds{ secondsInDec };
2020 if (x % 4 == 0) {
2021 value += Seconds{ secondsPerDay };
2022 }
2023 }
2024 if (month > 0) {
2025 value += Seconds{ static_cast<uint64_t>((day - 1) * secondsPerDay) };
2026 value += Seconds{ static_cast<uint64_t>(hour * secondsPerHour) };
2027 value += Seconds{ static_cast<uint64_t>(minute * secondsPerMinute) };
2028 value += Seconds{ second };
2029 }
2030 if (month > 1) {
2031 value += Seconds{ secondsInJan };
2032 }
2033 if (month > 2) {
2034 value += Seconds{ secondsInFeb };
2035 }
2036 if (month > 3) {
2037 value += Seconds{ secondsInMar };
2038 }
2039 if (month > 4) {
2040 value += Seconds{ secondsInApr };
2041 }
2042 if (month > 5) {
2043 value += Seconds{ secondsInMay };
2044 }
2045 if (month > 6) {
2046 value += Seconds{ secondsInJun };
2047 }
2048 if (month > 7) {
2049 value += Seconds{ secondsInJul };
2050 }
2051 if (month > 8) {
2052 value += Seconds{ secondsInAug };
2053 }
2054 if (month > 9) {
2055 value += Seconds{ secondsInSep };
2056 }
2057 if (month > 10) {
2058 value += Seconds{ secondsInOct };
2059 }
2060 if (month > 11) {
2061 value += Seconds{ secondsInNov };
2062 }
2063 this->timeStampInTimeUnits = std::chrono::duration_cast<Milliseconds>(value).count();
2064 }
2065
2066 void TimeStamp::convertTimeStampToTimeUnits(TimeFormat formatNew, std::string originalTimeStamp) {
2067 try {
2068 if (originalTimeStamp != "" && originalTimeStamp != "0") {
2069 TimeStamp timeValue = TimeStamp{ stoi(originalTimeStamp.substr(0, 4)), stoi(originalTimeStamp.substr(5, 6)),
2070 stoi(originalTimeStamp.substr(8, 9)), stoi(originalTimeStamp.substr(11, 12)), stoi(originalTimeStamp.substr(14, 15)),
2071 stoi(originalTimeStamp.substr(17, 18)), formatNew };
2072 this->timeStampInTimeUnits = static_cast<uint64_t>(timeValue);
2073 } else {
2074 this->timeStampInTimeUnits = std::chrono::duration_cast<Milliseconds>(SysClock::now().time_since_epoch()).count();
2075 }
2076 } catch (...) {
2077 reportException("TimeStamp::convertTimeStampToTimeUnits()");
2078 }
2079 }
2080
2081 std::string TimeStamp::getISO8601TimeStamp(TimeFormat timeFormat) {
2082 if (this->timeStampInTimeUnits <= 0) {
2083 this->timeStampInTimeUnits = std::chrono::duration_cast<Milliseconds>(SysClock::now().time_since_epoch()).count();
2084 }
2085 uint64_t timeValue = this->timeStampInTimeUnits / 1000;
2086 time_t rawTime(timeValue);
2087 tm timeInfo = *localtime(&rawTime);
2088 std::string timeStamp{};
2089 timeStamp.resize(48);
2090 switch (timeFormat) {
2091 case TimeFormat::LongDate: {
2092 uint64_t sizeResponse = strftime(timeStamp.data(), 48, "%d %B %G", &timeInfo);
2093 timeStamp.resize(sizeResponse);
2094 break;
2095 }
2097 uint64_t sizeResponse = strftime(timeStamp.data(), 48, "%FT%T", &timeInfo);
2098 timeStamp.resize(sizeResponse);
2099 break;
2100 }
2101 case TimeFormat::LongTime: {
2102 uint64_t sizeResponse = strftime(timeStamp.data(), 48, "%T", &timeInfo);
2103 timeStamp.resize(sizeResponse);
2104 break;
2105 }
2106 case TimeFormat::ShortDate: {
2107 uint64_t sizeResponse = strftime(timeStamp.data(), 48, "%d/%m/%g", &timeInfo);
2108 timeStamp.resize(sizeResponse);
2109 break;
2110 }
2112 uint64_t sizeResponse = strftime(timeStamp.data(), 48, "%d %B %G %R", &timeInfo);
2113 timeStamp.resize(sizeResponse);
2114 break;
2115 }
2116 case TimeFormat::ShortTime: {
2117 uint64_t sizeResponse = strftime(timeStamp.data(), 48, "%R", &timeInfo);
2118 timeStamp.resize(sizeResponse);
2119 break;
2120 }
2121 default: {
2122 break;
2123 }
2124 }
2125 return timeStamp;
2126 }
2127
2128 std::unordered_map<std::string, UnboundedMessageBlock<MessageData>*> MessageCollector::objectsBuffersMap{};
2129};
2130
2131namespace DiscordCoreInternal {
2132
2133 StringBuffer::StringBuffer() noexcept {
2134 this->string.resize(1024 * 16);
2135 }
2136
2137 std::string_view StringBuffer::operator[](LengthData size) {
2138 std::string_view string{ this->string.data() + size.offSet, size.length };
2139 return string;
2140 }
2141
2142 char StringBuffer::operator[](uint64_t index) {
2143 return this->string[index];
2144 }
2145
2146 void StringBuffer::writeData(const char* ptr, uint64_t size) {
2147 if (this->sizeValue + size > this->string.size()) {
2148 this->string.resize(this->string.size() + size);
2149 }
2150 std::copy(ptr, ptr + size, this->string.data() + this->sizeValue);
2151 this->sizeValue += size;
2152 }
2153
2154 std::string::iterator StringBuffer::begin() {
2155 return this->string.begin();
2156 }
2157
2158 std::string::iterator StringBuffer::end() {
2159 return this->string.end();
2160 }
2161
2162 void StringBuffer::erase(uint64_t amount) {
2163 std::copy(this->string.data() + amount, this->string.data() + this->sizeValue, this->string.data());
2164 this->sizeValue = this->sizeValue - amount;
2165 }
2166
2167 uint64_t StringBuffer::size() {
2168 return this->sizeValue;
2169 }
2170
2171 char* StringBuffer::data() {
2172 return this->string.data();
2173 }
2174
2175 void StringBuffer::clear() {
2176 this->sizeValue = 0;
2177 }
2178}
TimeFormat
Time formatting methods.
Definition: Utilities.hpp:1329
@ ShortTime
"16:20" - Short Time
@ LongDate
"20 April 2021" - Long Date
@ ShortDate
"20/04/2021" - Short Date
@ LongDateTime
"Tuesday, 20 April 2021 16:20" - Long Date/Time
@ LongTime
"16:20:30" - Long Time
@ ShortDateTime
"20 April 2021 16:20" - Short Date/Time
GatewayIntents
Gateway intents.
Definition: Utilities.hpp:921
DiscordCoreAPI_Dll std::string getTimeAndDate()
Acquires a timeStamp with the current time and date - suitable for use in message-embeds.
Definition: Utilities.cpp:1718
TextFormat
Represents which text format to use for websocket transfer.
Definition: Utilities.hpp:955
HttpsResponseCodes
Voice Websocket close codes.
Definition: Utilities.hpp:814
DiscordCoreAPI_Dll void reportException(const std::string &currentFunctionName, std::source_location location=std::source_location::current())
Prints the current file, line, and column from which the function is being called - typically from wi...
Definition: Utilities.cpp:1498
VoiceWebSocketCloseCode
Voice Websocket close codes.
Definition: Utilities.hpp:756
Permission
Permission values, for a given Channel, by Role or GuildMember.
Definition: Utilities.hpp:1415
WebSocketCloseCode
Websocket close codes.
Definition: Utilities.hpp:684
@ Administrator
Administrator.
The main namespace for this library.
std::vector< Snowflake > roles
The Guild roles that they have.
Snowflake guildId
The current Guild's id.
Data structure representing a single Channel.
std::vector< OverWriteData > permissionOverwrites
Permission overwrites.
static GuildData getCachedGuild(GetGuildData dataPackage)
Collects a Guild from the library's cache.
static RoleData getCachedRole(GetRoleData dataPackage)
Collects a given Role from the library's cache.
void removePermissions(const std::vector< Permission > &permissionsToRemove)
Removes one or more Permissions from the current Permissions value.
Definition: Utilities.cpp:1247
std::string getCurrentPermissionString()
Returns a string containing the currently held Permissions.
Definition: Utilities.cpp:1401
std::vector< std::string > displayPermissions()
Displays the currently present Permissions in a string, and returns a vector with each of them stored...
Definition: Utilities.cpp:1267
bool checkForPermission(const GuildMember &guildMember, const ChannelData &channel, Permission permission)
Checks for a given Permission in a chosen Channel, for a specific User.
Definition: Utilities.cpp:1233
static std::string getAllPermissions()
Returns a string containing ALL of the possible Permissions.
Definition: Utilities.cpp:1406
static std::string getCurrentChannelPermissions(const GuildMember &guildMember, const ChannelData &channel)
Returns a string containing all of a given User's Permissions for a given Channel.
Definition: Utilities.cpp:1228
static std::string getCurrentGuildPermissions(const GuildMember &guildMember)
Returns a string containing the currently held Permissions in a given Guild.
Definition: Utilities.cpp:1242
void addPermissions(const std::vector< Permission > &permissionsToAdd)
Adds one or more Permissions to the current Permissions value.
Definition: Utilities.cpp:1257