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 theValueNew) {
42 this->theValue = this->mappingValues[theValueNew];
43 return *this;
44 };
45
46 WebSocketClose::WebSocketClose(Uint16 theValueNew) {
47 *this = theValueNew;
48 };
49
50 WebSocketClose::operator Uint16() {
51 for (auto& [key, value]: this->mappingValues) {
52 if (theValue == value) {
53 return key;
54 }
55 }
56 return Uint16{};
57 }
58
59 WebSocketClose::operator Bool() {
60 return utCast(this->theValue) & utCast(WebSocketCloseCode::We_Do_Reconnect);
61 }
62}
63
64namespace DiscordCoreAPI {
65
66 EnumConverter& EnumConverter::operator=(EnumConverter&& other) noexcept {
67 this->theVector = std::move(other.theVector);
68 this->vectorType = other.vectorType;
69 this->theUint = other.theUint;
70 return *this;
71 }
72
73 EnumConverter::EnumConverter(EnumConverter&& other) noexcept {
74 *this = std::move(other);
75 }
76
77 EnumConverter::operator std::vector<Uint64>() const noexcept {
78 std::vector<Uint64> theObject{};
79 for (auto& value: this->theVector) {
80 theObject.emplace_back(value);
81 }
82 return theObject;
83 }
84
85 EnumConverter::operator std::vector<Uint64>() noexcept {
86 std::vector<Uint64> theObject{};
87 for (auto& value: this->theVector) {
88 theObject.emplace_back(value);
89 }
90 return theObject;
91 }
92
93 EnumConverter::operator Uint64() const noexcept {
94 return this->theUint;
95 }
96
97 EnumConverter::operator Uint64() noexcept {
98 return this->theUint;
99 }
100
101 bool EnumConverter::isItAVector() const noexcept {
102 return this->vectorType;
103 }
104
105 bool EnumConverter::isItAVector() noexcept {
106 return this->vectorType;
107 }
108
109 JsonObject::JsonValue::JsonValue() noexcept {};
110
111 JsonObject::JsonValue& JsonObject::JsonValue::operator=(const StringType& theData) noexcept {
112 *this->string = theData;
113 return *this;
114 }
115
116 JsonObject::JsonValue& JsonObject::JsonValue::operator=(StringType&& theData) noexcept {
117 *this->string = theData;
118 return *this;
119 }
120
121 JsonObject::JsonValue& JsonObject::JsonValue::operator=(const char* theData) noexcept {
122 *this->string = theData;
123 return *this;
124 }
125
126 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Uint64 theData) noexcept {
127 this->numberUint = theData;
128 return *this;
129 }
130
131 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Uint32 theData) noexcept {
132 this->numberUint = theData;
133 return *this;
134 }
135
136 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Uint16 theData) noexcept {
137 this->numberUint = theData;
138 return *this;
139 }
140
141 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Uint8 theData) noexcept {
142 this->numberUint = theData;
143 return *this;
144 }
145
146 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Int64 theData) noexcept {
147 this->numberInt = theData;
148 return *this;
149 }
150
151 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Int32 theData) noexcept {
152 this->numberInt = theData;
153 return *this;
154 }
155
156 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Int16 theData) noexcept {
157 this->numberInt = theData;
158 return *this;
159 }
160
161 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Int8 theData) noexcept {
162 this->numberInt = theData;
163 return *this;
164 }
165
166 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Double theData) noexcept {
167 this->numberDouble = theData;
168 return *this;
169 }
170
171 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Float theData) noexcept {
172 this->numberDouble = theData;
173 return *this;
174 }
175
176 JsonObject::JsonValue& JsonObject::JsonValue::operator=(Bool theData) noexcept {
177 this->boolean = theData;
178 return *this;
179 }
180
181 JsonObject::JsonValue::~JsonValue() noexcept {};
182
183 JsonObject& JsonObject::operator=(EnumConverter&& theData) noexcept {
184 if (theData.isItAVector()) {
185 this->set(std::make_unique<ArrayType>());
186 for (auto& value: theData.operator std::vector<Uint64, std::allocator<Uint64>>()) {
187 this->theValue.array->push_back(value);
188 }
189 } else {
190 this->theValue.numberUint = Uint64{ theData };
191 this->theType = ValueType::Uint64;
192 }
193 return *this;
194 }
195
196 JsonObject::JsonObject(EnumConverter&& theData) noexcept {
197 *this = std::move(theData);
198 }
199
200 JsonObject& JsonObject::operator=(const EnumConverter& theData) noexcept {
201 if (theData.isItAVector()) {
202 this->set(std::make_unique<ArrayType>());
203 for (auto& value: theData.operator std::vector<Uint64, std::allocator<Uint64>>()) {
204 this->theValue.array->push_back(value);
205 }
206 } else {
207 this->theValue.numberUint = Uint64{ theData };
208 this->theType = ValueType::Uint64;
209 }
210 return *this;
211 }
212
213 JsonObject::JsonObject(const EnumConverter& theData) noexcept {
214 *this = theData;
215 }
216
217 JsonObject& JsonObject::operator=(JsonObject&& theKey) noexcept {
218 switch (theKey.theType) {
219 case ValueType::Object: {
220 this->set(std::make_unique<ObjectType>());
221 *this->theValue.object = *theKey.theValue.object;
222 break;
223 }
224 case ValueType::Array: {
225 this->set(std::make_unique<ArrayType>());
226 *this->theValue.array = *theKey.theValue.array;
227 break;
228 }
229 case ValueType::String: {
230 this->set(std::make_unique<StringType>());
231 *this->theValue.string = *theKey.theValue.string;
232 break;
233 break;
234 }
235 case ValueType::Bool: {
236 this->theValue.boolean = theKey.theValue.boolean;
237 break;
238 }
239 case ValueType::Int64: {
240 this->theValue.numberInt = theKey.theValue.numberInt;
241 break;
242 }
243 case ValueType::Uint64: {
244 this->theValue.numberUint = theKey.theValue.numberUint;
245 break;
246 }
247 case ValueType::Float: {
248 this->theValue.numberDouble = theKey.theValue.numberDouble;
249 break;
250 }
251 case ValueType::Null: {
252 break;
253 }
254 }
255 this->theType = theKey.theType;
256 return *this;
257 }
258
259 JsonObject::JsonObject(JsonObject&& theKey) noexcept {
260 *this = std::move(theKey);
261 }
262
263 JsonObject& JsonObject::operator=(const JsonObject& theKey) noexcept {
264 switch (theKey.theType) {
265 case ValueType::Object: {
266 this->set(std::make_unique<ObjectType>());
267 for (auto& [key, value]: *theKey.theValue.object) {
268 this->theValue.object->emplace(key, std::move(value));
269 }
270 this->theType = ValueType::Object;
271 break;
272 }
273 case ValueType::Array: {
274 this->set(std::make_unique<ArrayType>());
275 for (auto& value: *theKey.theValue.array) {
276 this->theValue.array->emplace_back(std::move(value));
277 }
278 this->theType = ValueType::Array;
279 break;
280 }
281 case ValueType::String: {
282 this->set(std::make_unique<StringType>());
283 *this->theValue.string = *theKey.theValue.string;
284 this->theType = ValueType::String;
285 break;
286 }
287 case ValueType::Bool: {
288 this->theValue.boolean = theKey.theValue.boolean;
289 this->theType = ValueType::Bool;
290 break;
291 }
292 case ValueType::Int64: {
293 this->theValue.numberInt = theKey.theValue.numberInt;
294 this->theType = ValueType::Int64;
295 break;
296 }
297 case ValueType::Uint64: {
298 this->theValue.numberUint = theKey.theValue.numberUint;
299 this->theType = ValueType::Uint64;
300 break;
301 }
302 case ValueType::Float: {
303 this->theValue.numberDouble = theKey.theValue.numberDouble;
304 this->theType = ValueType::Float;
305 break;
306 }
307 case ValueType::Null: {
308 this->theType = ValueType::Null;
309 break;
310 }
311 default: {
312 break;
313 }
314 }
315 this->theType = theKey.theType;
316 return *this;
317 }
318
319 JsonObject::JsonObject(const JsonObject& theKey) noexcept {
320 *this = theKey;
321 }
322
323 JsonObject& JsonObject::operator=(String&& theData) noexcept {
324 this->set(std::make_unique<StringType>());
325 *this->theValue.string = theData;
326 this->theType = ValueType::String;
327 return *this;
328 }
329
330 JsonObject::JsonObject(String&& theData) noexcept {
331 *this = std::move(theData);
332 }
333
334 JsonObject& JsonObject::operator=(const String& theData) noexcept {
335 this->set(std::make_unique<StringType>());
336 *this->theValue.string = theData;
337 this->theType = ValueType::String;
338 return *this;
339 }
340
341 JsonObject::JsonObject(const String& theData) noexcept {
342 *this = theData;
343 }
344
345 JsonObject& JsonObject::operator=(const char* theData) noexcept {
346 this->set(std::make_unique<StringType>());
347 *this->theValue.string = theData;
348 this->theType = ValueType::String;
349 return *this;
350 }
351
352 JsonObject::JsonObject(const char* theData) noexcept {
353 *this = theData;
354 }
355
356 JsonObject& JsonObject::operator=(Uint64 theData) noexcept {
357 this->theValue = theData;
358 this->theType = ValueType::Uint64;
359 return *this;
360 }
361
362 JsonObject::JsonObject(Uint64 theData) noexcept {
363 *this = theData;
364 }
365
366 JsonObject& JsonObject::operator=(Uint32 theData) noexcept {
367 this->theValue = theData;
368 this->theType = ValueType::Uint64;
369 return *this;
370 }
371
372 JsonObject::JsonObject(Uint32 theData) noexcept {
373 *this = theData;
374 }
375
376 JsonObject& JsonObject::operator=(Uint16 theData) noexcept {
377 this->theValue = theData;
378 this->theType = ValueType::Uint64;
379 return *this;
380 }
381
382 JsonObject::JsonObject(Uint16 theData) noexcept {
383 *this = theData;
384 }
385
386 JsonObject& JsonObject::operator=(Uint8 theData) noexcept {
387 this->theValue = theData;
388 this->theType = ValueType::Uint64;
389 return *this;
390 }
391
392 JsonObject::JsonObject(Uint8 theData) noexcept {
393 *this = theData;
394 }
395
396 JsonObject& JsonObject::operator=(Int64 theData) noexcept {
397 this->theValue = theData;
398 this->theType = ValueType::Int64;
399 return *this;
400 }
401
402 JsonObject::JsonObject(Int64 theData) noexcept {
403 *this = theData;
404 }
405
406 JsonObject& JsonObject::operator=(Int32 theData) noexcept {
407 this->theValue = theData;
408 this->theType = ValueType::Int64;
409 return *this;
410 }
411
412 JsonObject::JsonObject(Int32 theData) noexcept {
413 *this = theData;
414 }
415
416 JsonObject& JsonObject::operator=(Int16 theData) noexcept {
417 this->theValue = theData;
418 this->theType = ValueType::Int64;
419 return *this;
420 }
421
422 JsonObject::JsonObject(Int16 theData) noexcept {
423 *this = theData;
424 }
425
426 JsonObject& JsonObject::operator=(Int8 theData) noexcept {
427 this->theValue = theData;
428 this->theType = ValueType::Int64;
429 return *this;
430 }
431
432 JsonObject::JsonObject(Int8 theData) noexcept {
433 *this = theData;
434 }
435
436 JsonObject& JsonObject::operator=(Double theData) noexcept {
437 this->theValue = theData;
438 this->theType = ValueType::Float;
439 return *this;
440 }
441
442 JsonObject::JsonObject(Double theData) noexcept {
443 *this = theData;
444 }
445
446 JsonObject& JsonObject::operator=(Float theData) noexcept {
447 this->theValue = theData;
448 this->theType = ValueType::Float;
449 return *this;
450 }
451
452 JsonObject::JsonObject(Float theData) noexcept {
453 this->theValue = theData;
454 }
455
456 JsonObject& JsonObject::operator=(Bool theData) noexcept {
457 this->theValue = theData;
458 this->theType = ValueType::Bool;
459 return *this;
460 }
461
462 JsonObject::JsonObject(Bool theData) noexcept {
463 *this = theData;
464 }
465
466 JsonObject& JsonObject::operator=(ValueType theType) noexcept {
467 this->theType = theType;
468 return *this;
469 }
470
471 JsonObject::JsonObject(ValueType theType) noexcept {
472 *this = theType;
473 }
474
475 JsonObject& JsonObject::operator[](Uint64 index) const {
476 return this->theValue.array->operator[](index);
477 }
478
479 JsonObject& JsonObject::operator[](Uint64 index) {
480 if (this->theType == ValueType::Null) {
481 this->set(std::make_unique<ArrayType>());
482 this->theType = ValueType::Array;
483 }
484
485 if (this->theType == ValueType::Array) {
486 if (index >= this->theValue.array->size()) {
487 this->theValue.array->resize(index + 1);
488 }
489
490 return this->theValue.array->operator[](index);
491 }
492 throw std::runtime_error{ "Sorry, but that index could not be produced/accessed." };
493 }
494
495 JsonObject& JsonObject::operator[](const typename ObjectType::key_type& key) const {
496 if (this->theType == ValueType::Object) {
497 auto result = this->theValue.object->emplace(key, nullptr);
498 return result.first->second;
499 }
500 throw std::runtime_error{ "Sorry, but that item-key could not be produced/accessed." };
501 }
502
503 JsonObject& JsonObject::operator[](typename ObjectType::key_type key) {
504 if (this->theType == ValueType::Null) {
505 this->set(std::make_unique<ObjectType>());
506 this->theType = ValueType::Object;
507 }
508
509 if (this->theType == ValueType::Object) {
510 auto result = this->theValue.object->emplace(std::move(key), JsonObject{});
511 return result.first->second;
512 }
513 throw std::runtime_error{ "Sorry, but that item-key could not be produced/accessed." };
514 }
515
516 void JsonObject::pushBack(JsonObject&& other) noexcept {
517 if (this->theType == ValueType::Null) {
518 this->set(std::make_unique<ArrayType>());
519 this->theType = ValueType::Array;
520 }
521
522 if (this->theType == ValueType::Array) {
523 this->theValue.array->emplace_back(std::move(other));
524 }
525 }
526
527 void JsonObject::pushBack(JsonObject& other) noexcept {
528 if (this->theType == ValueType::Null) {
529 this->set(std::make_unique<ArrayType>());
530 this->theType = ValueType::Array;
531 }
532
533 if (this->theType == ValueType::Array) {
534 this->theValue.array->emplace_back(std::move(other));
535 }
536 }
537
538 JsonObject::operator String() const noexcept {
539 String theString{};
540 switch (this->theType) {
541 case ValueType::Object: {
542 if (this->theValue.object->empty()) {
543 theString += "{}";
544 }
545
546 theString += '{';
547
548 Uint64 theIndex{};
549 for (auto iterator = this->theValue.object->cbegin(); iterator != this->theValue.object->cend(); ++iterator) {
550 theString += '\"';
551 theString += iterator->first;
552 theString += "\":";
553 theString += iterator->second;
554 if (theIndex < this->theValue.object->size() - 1) {
555 theString += ',';
556 }
557 theIndex++;
558 }
559 theString += '}';
560 break;
561 }
562 case ValueType::Array: {
563 if (this->theValue.array->empty()) {
564 theString += "[]";
565 break;
566 }
567
568 theString += '[';
569
570 for (auto iterator = this->theValue.array->cbegin(); iterator != this->theValue.array->cend() - 1; ++iterator) {
571 theString += *iterator;
572 theString += ',';
573 }
574
575 theString += this->theValue.array->back();
576
577 theString += ']';
578 break;
579 }
580
581 case ValueType::String: {
582 theString += '\"';
583 theString += std::move(*this->theValue.string);
584 theString += '\"';
585 break;
586 }
587 case ValueType::Bool: {
588 std::stringstream theStream{};
589 theStream << std::boolalpha << this->theValue.boolean;
590 theString += theStream.str();
591 break;
592 }
593 case ValueType::Float: {
594 theString += std::to_string(this->theValue.numberDouble);
595 break;
596 }
597 case ValueType::Uint64: {
598 theString += std::to_string(this->theValue.numberUint);
599 break;
600 }
601 case ValueType::Int64: {
602 theString += std::to_string(this->theValue.numberInt);
603 break;
604 }
605 case ValueType::Null: {
606 theString += "null";
607 break;
608 }
609 case ValueType::Null_Ext: {
610 theString += "[]";
611 break;
612 }
613 }
614 return theString;
615 }
616
617 JsonObject::operator String() noexcept {
618 String theString{};
619 switch (this->theType) {
620 case ValueType::Object: {
621 if (this->theValue.object->empty()) {
622 theString += "{}";
623 }
624
625 theString += '{';
626
627 Uint64 theIndex{};
628 for (auto iterator = this->theValue.object->cbegin(); iterator != this->theValue.object->cend(); ++iterator) {
629 theString += '\"';
630 theString += iterator->first;
631 theString += "\":";
632 theString += iterator->second;
633 if (theIndex < this->theValue.object->size() - 1) {
634 theString += ',';
635 }
636 theIndex++;
637 }
638 theString += '}';
639 break;
640 }
641 case ValueType::Array: {
642 if (this->theValue.array->empty()) {
643 theString += "[]";
644 break;
645 }
646
647 theString += '[';
648
649 for (auto iterator = this->theValue.array->cbegin(); iterator != this->theValue.array->cend() - 1; ++iterator) {
650 theString += *iterator;
651 theString += ',';
652 }
653
654 theString += this->theValue.array->back();
655
656 theString += ']';
657 break;
658 }
659
660 case ValueType::String: {
661 theString += '\"';
662 theString += std::move(*this->theValue.string);
663 theString += '\"';
664 break;
665 }
666 case ValueType::Bool: {
667 std::stringstream theStream{};
668 theStream << std::boolalpha << this->theValue.boolean;
669 theString += theStream.str();
670 break;
671 }
672 case ValueType::Float: {
673 theString += std::to_string(this->theValue.numberDouble);
674 break;
675 }
676 case ValueType::Uint64: {
677 theString += std::to_string(this->theValue.numberUint);
678 break;
679 }
680 case ValueType::Int64: {
681 theString += std::to_string(this->theValue.numberInt);
682 break;
683 }
684 case ValueType::Null: {
685 theString += "null";
686 break;
687 }
688 case ValueType::Null_Ext: {
689 theString += "[]";
690 break;
691 }
692 }
693 return theString;
694 }
695
696 void JsonObject::set(std::unique_ptr<String> p) {
697 destroy();
698 new (&this->theValue.string) std::unique_ptr<String>{ std::move(p) };
699 this->theType = ValueType::String;
700 }
701
702 void JsonObject::set(std::unique_ptr<ArrayType> p) {
703 destroy();
704 new (&this->theValue.string) std::unique_ptr<ArrayType>{ std::move(p) };
705 this->theType = ValueType::Array;
706 }
707
708 void JsonObject::set(std::unique_ptr<ObjectType> p) {
709 destroy();
710 new (&this->theValue.string) std::unique_ptr<ObjectType>{ std::move(p) };
711 this->theType = ValueType::Object;
712 }
713
714 void JsonObject::destroy() noexcept {
715 switch (this->theType) {
716 case ValueType::Array: {
717 this->theValue.array.reset(nullptr);
718 break;
719 }
720 case ValueType::Object: {
721 this->theValue.object.reset(nullptr);
722 break;
723 }
724 case ValueType::String: {
725 this->theValue.string.reset(nullptr);
726 break;
727 }
728 }
729 }
730
731 JsonObject::~JsonObject() noexcept {
732 this->destroy();
733 }
734
735 std::basic_ostream<char>& operator<<(std::basic_ostream<char>& outputSttream, const String& (*theFunction)( void )) {
736 outputSttream << theFunction();
737 return outputSttream;
738 }
739
740 ConfigManager::ConfigManager(const DiscordCoreClientConfig& theConfigNew) {
741 this->theConfig = theConfigNew;
742 }
743
744 const Bool ConfigManager::doWePrintWebSocketSuccessMessages() {
745 return this->theConfig.logOptions.logWebSocketSuccessMessages;
746 }
747
748 const Bool ConfigManager::doWePrintWebSocketErrorMessages() {
749 return this->theConfig.logOptions.logWebSocketErrorMessages;
750 }
751
752 const Bool ConfigManager::doWePrintHttpsSuccessMessages() {
753 return this->theConfig.logOptions.logHttpsSuccessMessages;
754 }
755
756 const Bool ConfigManager::doWePrintHttpsErrorMessages() {
757 return this->theConfig.logOptions.logHttpsErrorMessages;
758 }
759
760 const Bool ConfigManager::doWePrintFFMPEGSuccessMessages() {
761 return this->theConfig.logOptions.logFFMPEGSuccessMessages;
762 }
763
764 const Bool ConfigManager::doWePrintFFMPEGErrorMessages() {
765 return this->theConfig.logOptions.logFFMPEGErrorMessages;
766 }
767
768 const Bool ConfigManager::doWePrintGeneralSuccessMessages() {
769 return this->theConfig.logOptions.logGeneralSuccessMessages;
770 }
771
772 const Bool ConfigManager::doWePrintGeneralErrorMessages() {
773 return this->theConfig.logOptions.logGeneralErrorMessages;
774 }
775
776 const Bool ConfigManager::doWeCacheChannels() {
777 return this->theConfig.cacheOptions.cacheChannels;
778 }
779
780 const Bool ConfigManager::doWeCacheUsers() {
781 return this->theConfig.cacheOptions.cacheUsers;
782 }
783
784 const Bool ConfigManager::doWeCacheGuilds() {
785 return this->theConfig.cacheOptions.cacheGuilds;
786 }
787
788 const Bool ConfigManager::doWeCacheRoles() {
789 return this->theConfig.cacheOptions.cacheRoles;
790 }
791
792 const DiscordCoreInternal::UpdatePresenceData ConfigManager::getPresenceData() {
793 return this->theConfig.presenceData;
794 }
795
796 const String ConfigManager::getBotToken() {
797 return this->theConfig.botToken;
798 }
799
800 const Uint32 ConfigManager::getTotalShardCount() {
801 return this->theConfig.shardOptions.totalNumberOfShards;
802 }
803
804 const Uint32 ConfigManager::getStartingShard() {
805 return this->theConfig.shardOptions.startingShard;
806 }
807
808 const Uint32 ConfigManager::getShardCountForThisProcess() {
809 return this->theConfig.shardOptions.numberOfShardsForThisProcess;
810 }
811
812 const String ConfigManager::getConnectionAddress() {
813 return this->theConfig.connectionAddress;
814 }
815
816 void ConfigManager::setConnectionAddress(const String& connectionAddressNew) {
817 this->theConfig.connectionAddress = connectionAddressNew;
818 }
819
820 const String ConfigManager::getConnectionPort() {
821 return this->theConfig.connectionPort;
822 }
823
824 void ConfigManager::setConnectionPort(const String& connectionPortNew) {
825 this->theConfig.connectionPort = connectionPortNew;
826 }
827
828 const std::vector<RepeatedFunctionData> ConfigManager::getFunctionsToExecute() {
829 return this->theConfig.functionsToExecute;
830 }
831
832 const TextFormat ConfigManager::getTextFormat() {
833 return this->theConfig.textFormat;
834 }
835
836 const GatewayIntents ConfigManager::getGatewayIntents() {
837 return this->theConfig.theIntents;
838 }
839
840 StringWrapper& StringWrapper::operator=(StringWrapper&& other) noexcept {
841 if (this != &other) {
842 this->thePtr.reset(nullptr);
843 this->thePtr = std::move(other.thePtr);
844 other.thePtr.reset(nullptr);
845 other.thePtr = nullptr;
846 }
847 return *this;
848 }
849
850 StringWrapper::StringWrapper(StringWrapper&& other) noexcept {
851 *this = std::move(other);
852 }
853
854 StringWrapper& StringWrapper::operator=(const StringWrapper& other) {
855 if (this != &other) {
856 this->thePtr.reset(nullptr);
857 StringStream theStream{};
858 if (other.thePtr) {
859 theStream << other.thePtr;
860 }
861 auto theLength = theStream.str().size();
862 this->thePtr = std::make_unique<char[]>(theLength + 1);
863 for (Uint64 x = 0; x < theLength; ++x) {
864 this->thePtr[x] = other.thePtr[x];
865 }
866 }
867 return *this;
868 }
869
870 StringWrapper::StringWrapper(const StringWrapper& other) {
871 *this = other;
872 }
873
874 StringWrapper& StringWrapper::operator=(const String& theString) {
875 auto theLength = theString.size();
876 this->thePtr.reset(nullptr);
877 this->thePtr = std::make_unique<char[]>(theLength + 1);
878 for (Int32 x = 0; x < theLength; ++x) {
879 this->thePtr[x] = theString[x];
880 }
881 return *this;
882 }
883
884 StringWrapper::StringWrapper(const String& theString) {
885 *this = theString;
886 }
887
888 StringWrapper& StringWrapper::operator=(const char* theString) {
889 if (theString) {
890 this->thePtr.reset(nullptr);
891 StringStream theStream{};
892 theStream << theString;
893 Int64 theLength = theStream.str().size();
894 this->thePtr = std::make_unique<char[]>(theLength + 1);
895 for (Int64 x = 0; x < theLength; ++x) {
896 this->thePtr[x] = theString[x];
897 }
898 }
899 return *this;
900 }
901
902 StringWrapper::StringWrapper(const char* theString) {
903 *this = theString;
904 }
905
906 StringWrapper::operator String() {
907 StringStream theStream{};
908 if (this->thePtr) {
909 theStream << this->thePtr;
910 }
911 String theString{};
912 for (Uint32 x = 0; x < theStream.str().size(); ++x) {
913 theString.push_back(theStream.str()[x]);
914 }
915 return theString;
916 }
917
918 void StringWrapper::emplace_back(char theChar) {
919 StringStream theStream{};
920 if (this->thePtr) {
921 theStream << this->thePtr;
922 }
923 auto theLength = theStream.str().size();
924 this->thePtr = std::make_unique<char[]>(theLength + 2);
925 for (Uint64 x = 0; x < theLength; ++x) {
926 this->thePtr[x] = theStream.str()[x];
927 }
928 this->thePtr[theLength] = theChar;
929 }
930
931 Uint64 StringWrapper::size() {
932 StringStream theStream{};
933 if (this->thePtr) {
934 theStream << this->thePtr;
935 }
936 auto theLength = theStream.str().size();
937 return theLength;
938 }
939
940 const char* StringWrapper::data() {
941 return this->thePtr.get();
942 }
943
944 ColorValue::ColorValue(Uint32 theColorValue) {
945 this->theColor = theColorValue;
946 }
947
948 ColorValue::ColorValue(String theHexColorValue) {
949 if (theHexColorValue == "") {
950 theHexColorValue = "fefefe";
951 }
952 this->theColor = stoull(theHexColorValue, nullptr, 16);
953 }
954
955 RGBColorValue ColorValue::getRgbColorValue() {
956 Uint8 red = static_cast<Uint8>(this->theColor >> 16);
957 Uint8 green = static_cast<Uint8>(this->theColor >> 8);
958 Uint8 blue = static_cast<Uint8>(this->theColor);
959 RGBColorValue theColor{};
960 theColor.blue = blue;
961 theColor.green = green;
962 theColor.red = red;
963 return theColor;
964 }
965
966 HexColorValue ColorValue::getHexColorValue() {
967 StringStream theStream{};
968 theStream << std::hex << this->theColor;
969 return theStream.str();
970 }
971
972 Uint32 ColorValue::getIntColorValue() {
973 return this->theColor;
974 }
975
976 IconHash& IconHash::operator=(const String theString) {
977 String newHash{ theString };
978 if (newHash.empty() || newHash == "0") {
979 this->highBits = 0;
980 this->lowBits = 0;
981 return *this;
982 }
983 if (newHash.length() == 34 && newHash.substr(0, 2) == "a_") {
984 newHash = newHash.substr(2);
985 }
986 if (newHash.length() != 32 && newHash.length() != 33) {
987 throw std::length_error("IconHash must be exactly 32 characters in length, passed value is: '" + std::to_string(newHash.size()) + "', in length.");
988 }
989 this->lowBits = fromString<Uint64>(newHash.substr(0, 16), std::hex);
990 this->highBits = fromString<Uint64>(newHash.substr(16, 16), std::hex);
991 return *this;
992 }
993
994 IconHash::IconHash(const String theString) noexcept {
995 *this = theString;
996 }
997
998 String IconHash::getIconHash() noexcept {
999 if (this->highBits == 0 || this->lowBits == 0) {
1000 return {};
1001 } else {
1002 return String{ toHex(this->lowBits) + toHex(this->highBits) };
1003 }
1004 }
1005
1006 Bool IconHash::operator==(const IconHash& other) {
1007 return this->lowBits == other.lowBits && this->highBits == other.highBits;
1008 }
1009
1010 Uint64 strtoull(const StringView theString) {
1011 for (auto& value: theString) {
1012 if (!isdigit(value)) {
1013 return 0;
1014 }
1015 }
1016 if (!theString.empty() && theString != "") {
1017 return stoull(std::string{ theString });
1018 } else {
1019 return 0;
1020 }
1021 }
1022
1023 Uint64 strtoull(const String& theString) {
1024 for (auto& value: theString) {
1025 if (!isdigit(value)) {
1026 return 0;
1027 }
1028 }
1029 if (!theString.empty() && theString != "") {
1030 return stoull(theString);
1031 } else {
1032 return 0;
1033 }
1034 }
1035
1036 Permissions& Permissions::operator=(Permission&& other) {
1037 this->thePermissions = static_cast<Uint64>(other);
1038 return *this;
1039 }
1040
1041 Permissions::Permissions(Permission&& permsNew) {
1042 *this = std::move(permsNew);
1043 }
1044
1045 Permissions& Permissions::operator=(const Permission& other) {
1046 this->thePermissions = static_cast<Uint64>(other);
1047 return *this;
1048 }
1049
1050 Permissions::Permissions(const Permission& permsNew) {
1051 *this = permsNew;
1052 }
1053
1054 Permissions& Permissions::operator=(String&& other) {
1055 if (other.size() == 0 || other == "") {
1056 this->thePermissions = 0;
1057 } else {
1058 for (auto& value: other) {
1059 this->thePermissions = stoull(other);
1060 }
1061 }
1062 other = "";
1063 return *this;
1064 }
1065
1066 Permissions::Permissions(String&& permsNew) {
1067 *this = std::move(permsNew);
1068 }
1069
1070 Permissions& Permissions::operator=(const String& other) {
1071 if (other.size() == 0 || other == "") {
1072 this->thePermissions = 0;
1073 } else {
1074 this->thePermissions = stoull(other);
1075 }
1076 return *this;
1077 }
1078
1079 Permissions::Permissions(const String& permsNew) {
1080 *this = permsNew;
1081 }
1082
1083
1084 Permissions& Permissions::operator=(Uint64 other) {
1085 this->thePermissions = other;
1086 return *this;
1087 }
1088
1089 Permissions::Permissions(Uint64 permsNew) {
1090 *this = permsNew;
1091 }
1092
1093 Permissions::operator Uint64() {
1094 return this->thePermissions;
1095 }
1096
1097 Permissions::operator String() {
1098 return String{ std::to_string(this->thePermissions) };
1099 }
1100
1102 String permsString = Permissions::computePermissions(guildMember, channel);
1103 return permsString;
1104 }
1105
1106 Bool Permissions::checkForPermission(const GuildMember& guildMember, ChannelData& channel, Permission permission) {
1107 String permissionsString = Permissions::computePermissions(guildMember, channel);
1108 if ((stoull(permissionsString) & static_cast<Uint64>(permission)) == static_cast<Uint64>(permission)) {
1109 return true;
1110 } else {
1111 return false;
1112 }
1113 }
1114
1116 String permissions = Permissions::computeBasePermissions(guildMember);
1117 return permissions;
1118 }
1119
1120 void Permissions::removePermissions(const std::vector<Permission>& permissionsToRemove) {
1121 Uint64 permissionsInteger = this->thePermissions;
1122 for (auto value: permissionsToRemove) {
1123 permissionsInteger &= ~static_cast<Uint64>(value);
1124 }
1125 StringStream sstream{};
1126 sstream << permissionsInteger;
1127 *this = sstream.str();
1128 }
1129
1130 void Permissions::addPermissions(const std::vector<Permission>& permissionsToAdd) {
1131 Uint64 permissionsInteger = this->thePermissions;
1132 for (auto value: permissionsToAdd) {
1133 permissionsInteger |= static_cast<Uint64>(value);
1134 }
1135 StringStream sstream{};
1136 sstream << permissionsInteger;
1137 *this = sstream.str();
1138 }
1139
1140 std::vector<String> Permissions::displayPermissions() {
1141 std::vector<String> returnVector{};
1142 Uint64 permissionsInteger = this->thePermissions;
1143 if (permissionsInteger & (1ll << 3)) {
1144 for (Uint64 x = 0; x < 41; ++x) {
1145 permissionsInteger |= 1ll << x;
1146 }
1147 }
1148 if (permissionsInteger & (1ll << 0)) {
1149 returnVector.emplace_back("Create Instant Invite");
1150 }
1151 if (permissionsInteger & (1ll << 1)) {
1152 returnVector.emplace_back("Kick Members");
1153 }
1154 if (permissionsInteger & (1ll << 2)) {
1155 returnVector.emplace_back("Ban Members");
1156 }
1157 if (permissionsInteger & (1ll << 3)) {
1158 returnVector.emplace_back("Administrator");
1159 }
1160 if (permissionsInteger & (1ll << 4)) {
1161 returnVector.emplace_back("Manage Channels");
1162 }
1163 if (permissionsInteger & (1ll << 5)) {
1164 returnVector.emplace_back("Manage Guild");
1165 }
1166 if (permissionsInteger & (1ll << 6)) {
1167 returnVector.emplace_back("Add Reactions");
1168 }
1169 if (permissionsInteger & (1ll << 7)) {
1170 returnVector.emplace_back("View Audit Log");
1171 }
1172 if (permissionsInteger & (1ll << 8)) {
1173 returnVector.emplace_back("Priority Speaker");
1174 }
1175 if (permissionsInteger & (1ll << 9)) {
1176 returnVector.emplace_back("Stream");
1177 }
1178 if (permissionsInteger & (1ll << 10)) {
1179 returnVector.emplace_back("View Channel");
1180 }
1181 if (permissionsInteger & (1ll << 11)) {
1182 returnVector.emplace_back("Send Messages");
1183 }
1184 if (permissionsInteger & (1ll << 12)) {
1185 returnVector.emplace_back("Send TTS Messages");
1186 }
1187 if (permissionsInteger & (1ll << 13)) {
1188 returnVector.emplace_back("Manage Messages");
1189 }
1190 if (permissionsInteger & (1ll << 14)) {
1191 returnVector.emplace_back("Embed Links");
1192 }
1193 if (permissionsInteger & (1ll << 15)) {
1194 returnVector.emplace_back("Attach Files");
1195 }
1196 if (permissionsInteger & (1ll << 16)) {
1197 returnVector.emplace_back("Read Message History");
1198 }
1199 if (permissionsInteger & (1ll << 17)) {
1200 returnVector.emplace_back("Mention Everyone");
1201 }
1202 if (permissionsInteger & (1ll << 18)) {
1203 returnVector.emplace_back("Use External Emoji");
1204 }
1205 if (permissionsInteger & (1ll << 19)) {
1206 returnVector.emplace_back("View Guild Insights");
1207 }
1208 if (permissionsInteger & (1ll << 20)) {
1209 returnVector.emplace_back("Connect");
1210 }
1211 if (permissionsInteger & (1ll << 21)) {
1212 returnVector.emplace_back("Speak");
1213 }
1214 if (permissionsInteger & (1ll << 22)) {
1215 returnVector.emplace_back("Mute Members");
1216 }
1217 if (permissionsInteger & (1ll << 23)) {
1218 returnVector.emplace_back("Deafen Members");
1219 }
1220 if (permissionsInteger & (1ll << 24)) {
1221 returnVector.emplace_back("Move Members");
1222 }
1223 if (permissionsInteger & (1ll << 25)) {
1224 returnVector.emplace_back("Use VAD");
1225 }
1226 if (permissionsInteger & (1ll << 26)) {
1227 returnVector.emplace_back("Change Nickname");
1228 }
1229 if (permissionsInteger & (1ll << 27)) {
1230 returnVector.emplace_back("Manage Nicknames");
1231 }
1232 if (permissionsInteger & (1ll << 28)) {
1233 returnVector.emplace_back("Manage Roles");
1234 }
1235 if (permissionsInteger & (1ll << 29)) {
1236 returnVector.emplace_back("Manage Webhooks");
1237 }
1238 if (permissionsInteger & (1ll << 30)) {
1239 returnVector.emplace_back("Manage Emojis And Stickers");
1240 }
1241 if (permissionsInteger & (1ll << 31)) {
1242 returnVector.emplace_back("Use Application Commands");
1243 }
1244 if (permissionsInteger & (1ll << 32)) {
1245 returnVector.emplace_back("Request To Speak");
1246 }
1247 if (permissionsInteger & (1ll << 33)) {
1248 returnVector.emplace_back("Manage Events");
1249 }
1250 if (permissionsInteger & (1ll << 34)) {
1251 returnVector.emplace_back("Manage Threads");
1252 }
1253 if (permissionsInteger & (1ll << 35)) {
1254 returnVector.emplace_back("Create Public Threads");
1255 }
1256 if (permissionsInteger & (1ll << 36)) {
1257 returnVector.emplace_back("Create Private Threads");
1258 }
1259 if (permissionsInteger & (1ll << 37)) {
1260 returnVector.emplace_back("Use External Stickers");
1261 }
1262 if (permissionsInteger & (1ll << 38)) {
1263 returnVector.emplace_back("Send Messages In Threads");
1264 }
1265 if (permissionsInteger & (1ll << 39)) {
1266 returnVector.emplace_back("Start Embedded Activities");
1267 }
1268 if (permissionsInteger & (1ll << 40)) {
1269 returnVector.emplace_back("Moderate Members");
1270 }
1271 return returnVector;
1272 }
1273
1275 String theReturnString = std::to_string(this->thePermissions);
1276 return theReturnString;
1277 }
1278
1280 Uint64 allPerms{ 0 };
1281 for (Uint64 x = 0; x < 41; ++x) {
1282 allPerms |= 1ll << x;
1283 }
1284 StringStream stream{};
1285 stream << allPerms;
1286 return stream.str();
1287 }
1288
1289 String Permissions::computeOverwrites(const String& basePermissions, const GuildMember& guildMember, ChannelData& channel) {
1290 if ((stoull(basePermissions) & static_cast<Uint64>(Permission::Administrator)) == static_cast<Uint64>(Permission::Administrator)) {
1292 }
1293
1294 Uint64 permissions = stoull(basePermissions);
1295 for (Int32 x = 0; x < channel.permissionOverwrites.size(); ++x) {
1296 if (channel.permissionOverwrites[x].id == guildMember.guildId) {
1297 permissions &= ~channel.permissionOverwrites[x].deny;
1298 permissions |= channel.permissionOverwrites[x].allow;
1299 break;
1300 }
1301 }
1302 std::vector<RoleData> guildMemberRoles{};
1303 for (auto& value: guildMember.roles) {
1304 guildMemberRoles.emplace_back(Roles::getCachedRoleAsync({ .guildId = guildMember.guildId, .roleId = value }).get());
1305 }
1306 Uint64 allow{ 0 };
1307 Uint64 deny{ 0 };
1308 for (auto& value: guildMemberRoles) {
1309 for (Int32 x = 0; x < channel.permissionOverwrites.size(); ++x) {
1310 if (value.id == channel.permissionOverwrites[x].id) {
1311 allow |= channel.permissionOverwrites[x].allow;
1312 deny |= channel.permissionOverwrites[x].deny;
1313 }
1314 }
1315 }
1316 permissions &= ~deny;
1317 permissions |= allow;
1318 for (Int32 x = 0; x < channel.permissionOverwrites.size(); ++x) {
1319 if (channel.permissionOverwrites[x].id == guildMember.id) {
1320 permissions &= ~channel.permissionOverwrites[x].deny;
1321 permissions |= channel.permissionOverwrites[x].allow;
1322 break;
1323 }
1324 }
1325 return std::to_string(permissions);
1326 }
1327
1328 String Permissions::computePermissions(const GuildMember& guildMember, ChannelData& channel) {
1329 String permissions = Permissions::computeBasePermissions(guildMember);
1330 permissions = Permissions::computeOverwrites(permissions, guildMember, channel);
1331 return permissions;
1332 }
1333
1334 String Permissions::computeBasePermissions(const GuildMember& guildMember) {
1335 const GuildData guild = Guilds::getCachedGuildAsync({ .guildId = guildMember.guildId }).get();
1336 if (guild.ownerId == guildMember.id) {
1338 }
1339 std::vector<RoleData> guildRoles{};
1340 for (auto& value: guild.roles) {
1341 guildRoles.emplace_back(Roles::getCachedRoleAsync({ .guildId = guild.id, .roleId = value }).get());
1342 }
1343 RoleData roleEveryone{};
1344 for (auto& value: guildRoles) {
1345 if (value.id == guild.id) {
1346 roleEveryone = value;
1347 }
1348 }
1349 Uint64 permissions{};
1350 if (roleEveryone.permissions != 0) {
1351 permissions = roleEveryone.permissions;
1352 }
1353 GetGuildMemberRolesData getRolesData{};
1354 getRolesData.guildMember = guildMember;
1355 getRolesData.guildId = guildMember.guildId;
1356 std::vector<RoleData> guildMemberRoles{};
1357 for (auto& value: guildMember.roles) {
1358 guildMemberRoles.emplace_back(Roles::getCachedRoleAsync({ .guildId = guild.id, .roleId = value }).get());
1359 }
1360 for (auto& value: guildMemberRoles) {
1361 permissions |= value.permissions;
1362 }
1363
1364 if ((permissions & static_cast<Uint64>(Permission::Administrator)) == static_cast<Uint64>(Permission::Administrator)) {
1366 }
1367
1368 return std::to_string(permissions);
1369 }
1370
1371 void reportException(const String& currentFunctionName, std::source_location theLocation) {
1372 try {
1373 auto currentException = std::current_exception();
1374 if (currentException) {
1375 std::rethrow_exception(currentException);
1376 }
1377 } catch (const std::exception& e) {
1378 StringStream theStream{};
1379 theStream << shiftToBrightRed() << "Error Report: \n"
1380 << "Caught At: " << currentFunctionName << ", in File: " << theLocation.file_name() << " (" << std::to_string(theLocation.line()) << ":"
1381 << std::to_string(theLocation.column()) << ")"
1382 << "\nThe Error: \n"
1383 << e.what() << reset() << std::endl
1384 << std::endl;
1385 auto theReturnString = theStream.str();
1386 cout << theReturnString;
1387 }
1388 }
1389
1390 void rethrowException(const String& currentFunctionName, std::source_location theLocation) {
1391 try {
1392 auto currentException = std::current_exception();
1393 if (currentException) {
1394 std::rethrow_exception(currentException);
1395 }
1396 } catch (const std::exception& e) {
1397 StringStream theStream{};
1398 theStream << shiftToBrightRed() << "Caught At: " << currentFunctionName << ", in File: " << theLocation.file_name() << " (" << std::to_string(theLocation.line()) << ":"
1399 << std::to_string(theLocation.column()) << ")"
1400 << "\nThe Error: \n"
1401 << e.what() << reset();
1402 auto theReturnString = theStream.str();
1403 cout << theReturnString;
1404 if (std::current_exception()) {
1405 std::rethrow_exception(std::current_exception());
1406 }
1407 }
1408 }
1409
1410 String constructMultiPartData(String theData, const std::vector<File>& files) {
1411 const String boundary("boundary25");
1412 const String partStart("--" + boundary + "\r\nContent-Type: application/octet-stream\r\nContent-Disposition: form-data; ");
1413
1414 String content("--" + boundary);
1415
1416 content += "\r\nContent-Type: application/json\r\nContent-Disposition: form-data; "
1417 "name=\"payload_json\"\r\n\r\n";
1418 content += theData + "\r\n";
1419 if (files.size() == 1) {
1420 content += partStart + "name=\"file\"; filename=\"" + files[0].fileName + "\"" + "\r\n\r\n";
1421 content += files[0].data;
1422 } else {
1423 for (Uint8 x = 0; x < files.size(); ++x) {
1424 content += partStart + "name=\"files[" + std::to_string(x) + "]\"; filename=\"" + files[x].fileName + "\"\r\n\r\n";
1425 content += files[x].data;
1426 content += "\r\n";
1427 }
1428 }
1429 content += "\r\n--" + boundary + "--";
1430 return content;
1431 }
1432
1433 String convertToLowerCase(const String& stringToConvert) {
1434 String newString;
1435 for (auto& value: stringToConvert) {
1436 if (isupper(static_cast<Uint8>(value))) {
1437 newString += static_cast<char>(tolower(static_cast<Uint8>(value)));
1438 } else {
1439 newString += value;
1440 }
1441 }
1442 return newString;
1443 }
1444
1445 String base64Encode(const String& theString, Bool url) {
1446 const char* base64CharsArray[2] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1447 "abcdefghijklmnopqrstuvwxyz"
1448 "0123456789"
1449 "+/",
1450
1451 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1452 "abcdefghijklmnopqrstuvwxyz"
1453 "0123456789"
1454 "-_" };
1455
1456 Uint64 encodedLength = (theString.size() + 2) / 3 * 4;
1457
1458 Uint8 trailing_char = url ? '.' : '=';
1459
1460 const char* base64Chars = base64CharsArray[url];
1461
1462 String theReturnString{};
1463 theReturnString.reserve(encodedLength);
1464 DiscordCoreAPI::StopWatch theStopWatch{ 1500ms };
1465 Uint64 pos = 0;
1466 while (pos < theString.size()) {
1467 if (theStopWatch.hasTimePassed()) {
1468 break;
1469 }
1470 theReturnString.push_back(base64Chars[(theString[static_cast<Uint64>(pos + 0)] & 0xfc) >> 2]);
1471
1472 if (static_cast<Uint64>(pos + 1) < theString.size()) {
1473 theReturnString.push_back(base64Chars[((theString[static_cast<Int64>(pos + 0)] & 0x03) << 4) + ((theString[static_cast<Int64>(pos + 1)] & 0xf0) >> 4)]);
1474
1475 if (static_cast<Uint64>(pos + 2) < theString.size()) {
1476 theReturnString.push_back(base64Chars[((theString[static_cast<Int64>(pos + 1)] & 0x0f) << 2) + ((theString[static_cast<Int64>(pos + 2)] & 0xc0) >> 6)]);
1477 theReturnString.push_back(base64Chars[theString[static_cast<Int64>(pos + 2)] & 0x3f]);
1478 } else {
1479 theReturnString.push_back(base64Chars[(theString[static_cast<Int64>(pos + 1)] & 0x0f) << 2]);
1480 theReturnString.push_back(trailing_char);
1481 }
1482 } else {
1483 theReturnString.push_back(base64Chars[(theString[static_cast<Int64>(pos + 0)] & 0x03) << 4]);
1484 theReturnString.push_back(trailing_char);
1485 theReturnString.push_back(trailing_char);
1486 }
1487
1488 pos += 3;
1489 }
1490
1491 return theReturnString;
1492 }
1493
1494 String loadFileContents(const String& filePath) {
1495 std::ifstream file(filePath, std::ios::in | std::ios::binary);
1496 std::ostringstream stream{};
1497 stream << file.rdbuf();
1498 return stream.str();
1499 }
1500
1501 String utf8MakeValid(const String& inputString) {
1502 String theReturnString{};
1503 for (auto& value: inputString) {
1504 if (value >= 128 || value < 0) {
1505 Int32 theDifference = 0 - value;
1506 theReturnString.push_back(value + theDifference);
1507 } else {
1508 theReturnString.push_back(value);
1509 }
1510 }
1511 return theReturnString;
1512 }
1513
1514 String urlEncode(const String& inputString) {
1515 std::ostringstream escaped{};
1516 escaped.fill('0');
1517 escaped << std::hex;
1518
1519 for (String::const_iterator i = inputString.begin(), n = inputString.end(); i != n; ++i) {
1520 String::value_type c = (*i);
1521
1522 if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
1523 escaped << c;
1524 continue;
1525 }
1526
1527 escaped << std::uppercase;
1528 escaped << '%' << std::setw(2) << Int32(static_cast<Uint8>(c));
1529 escaped << std::nouppercase;
1530 }
1531 return escaped.str();
1532 }
1533
1534 void spinLock(Uint64 timeInNsToSpinLockFor) {
1535 Uint64 startTime = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
1536 Uint64 timePassed{ 0 };
1537 while (timePassed < timeInNsToSpinLockFor) {
1538 timePassed = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() - startTime;
1539 }
1540 }
1541
1542 String generateBase64EncodedKey() {
1543 String theReturnString{};
1544 theReturnString.resize(16);
1545 std::mt19937_64 randomEngine{ static_cast<Uint64>(std::chrono::steady_clock::now().time_since_epoch().count()) };
1546 for (Uint32 x = 0; x < 16; ++x) {
1547 theReturnString[x] = static_cast<Uint8>((static_cast<Float>(randomEngine()) / static_cast<Float>(randomEngine.max())) * 255.0f);
1548 }
1549 theReturnString = base64Encode(theReturnString, false);
1550 return theReturnString;
1551 }
1552
1553 String shiftToBrightGreen() {
1554 return String("\033[1;40;92m");
1555 }
1556
1557 String shiftToBrightBlue() {
1558 return String("\033[1;40;96m");
1559 }
1560
1561 String shiftToBrightRed() {
1562 return String("\033[1;40;91m");
1563 }
1564
1565 Bool nanoSleep(Int64 ns) {
1566#ifdef _WIN32
1567 HANDLE timer = CreateWaitableTimerExW(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
1568 LARGE_INTEGER largeInt{ .QuadPart = -ns / 100 };
1569 if (!timer) {
1570 return false;
1571 }
1572
1573 if (!SetWaitableTimerEx(timer, &largeInt, 0, NULL, NULL, NULL, 0)) {
1574 CloseHandle(timer);
1575 return false;
1576 }
1577 WaitForSingleObjectEx(timer, INFINITE, false);
1578 CloseHandle(timer);
1579#else
1580 std::this_thread::sleep_for(std::chrono::nanoseconds{ ns });
1581#endif
1582 return true;
1583 }
1584
1585 String reset() {
1586 return String("\033[0m");
1587 }
1588
1590 const time_t now = std::time(nullptr);
1591 tm time = *std::localtime(&now);
1592 String timeStamp{};
1593 timeStamp.resize(48);
1594 if (time.tm_isdst) {
1595 if (time.tm_hour + 4 >= 24) {
1596 time.tm_hour = 0 + time.tm_hour + 4 - 24;
1597
1598 } else {
1599 time.tm_hour = time.tm_hour + 4;
1600 }
1601 } else {
1602 if (time.tm_hour + 5 >= 24) {
1603 time.tm_hour = 0 + time.tm_hour + 5 - 24;
1604 } else {
1605 time.tm_hour = time.tm_hour + 5;
1606 }
1607 }
1608 Uint64 size = strftime(timeStamp.data(), 48, "%F %R", &time);
1609 timeStamp.resize(size);
1610 return timeStamp;
1611 }
1612
1613 String escapeCharacters(StringView theString) {
1614 String theStringNew{};
1615 if (theStringNew.size() <= theString.size() * 2) {
1616 theStringNew.resize(theString.size() * 2);
1617 }
1618 Uint64 theIndex{};
1619 for (Uint32 x = 0; x < theString.size(); ++x) {
1620 switch (static_cast<char>(theString[x])) {
1621 case 0x00: {
1622 break;
1623 }
1624 case 0x22: {
1625 theStringNew[theIndex] = static_cast<char>('\\');
1626 theStringNew[theIndex + 1] = static_cast<char>('"');
1627 theIndex += 2;
1628 break;
1629 }
1630 case 0x5c: {
1631 theStringNew[theIndex] = static_cast<char>('\\');
1632 theStringNew[theIndex + 1] = static_cast<char>('\\');
1633 theIndex += 2;
1634 break;
1635 }
1636 case 0x07: {
1637 theStringNew[theIndex] = static_cast<char>('\\');
1638 theStringNew[theIndex + 1] = static_cast<char>('a');
1639 theIndex += 2;
1640 break;
1641 }
1642 case 0x08: {
1643 theStringNew[theIndex] = static_cast<char>('\\');
1644 theStringNew[theIndex + 1] = static_cast<char>('b');
1645 theIndex += 2;
1646 break;
1647 }
1648 case 0x0C: {
1649 theStringNew[theIndex] = static_cast<char>('\\');
1650 theStringNew[theIndex + 1] = static_cast<char>('f');
1651 theIndex += 2;
1652 break;
1653 }
1654 case 0x0A: {
1655 theStringNew[theIndex] = static_cast<char>('\\');
1656 theStringNew[theIndex + 1] = static_cast<char>('n');
1657 theIndex += 2;
1658 break;
1659 }
1660 case 0x0D: {
1661 theStringNew[theIndex] = static_cast<char>('\\');
1662 theStringNew[theIndex + 1] = static_cast<char>('r');
1663 theIndex += 2;
1664 break;
1665 }
1666 case 0x0B: {
1667 theStringNew[theIndex] = static_cast<char>('\\');
1668 theStringNew[theIndex + 1] = static_cast<char>('v');
1669 theIndex += 2;
1670 break;
1671 }
1672 case 0x09: {
1673 theStringNew[theIndex] = static_cast<char>('\\');
1674 theStringNew[theIndex + 1] = static_cast<char>('t');
1675 theIndex += 2;
1676 break;
1677 }
1678 default: {
1679 theStringNew[theIndex] = theString[x];
1680 theIndex++;
1681 break;
1682 }
1683 }
1684 }
1685 if (theStringNew.size() > 1) {
1686 if (theStringNew[theStringNew.size() - 1] == '\0') {
1687 theStringNew.erase(theStringNew.size() - 1);
1688 }
1689 }
1690 theStringNew.resize(theIndex);
1691 return theStringNew;
1692 }
1693
1694 template<typename Object> std::unordered_map<String, UnboundedMessageBlock<Object>*> ObjectCollector<Object>::objectsBufferMap{};
1695};
1696
1697namespace DiscordCoreInternal {
1698
1699 StringBuffer::StringBuffer() noexcept {
1700 this->theString01.resize(1024 * 16);
1701 this->theString02.resize(1024 * 16);
1702 }
1703
1704 StringView StringBuffer::operator[](LengthData size) {
1705 if (this->whichOneAreWeOn == 0) {
1706 StringView theString{ this->theString01.data() + size.offSet, size.length };
1707 return theString;
1708 } else {
1709 StringView theString{ this->theString02.data() + size.offSet, size.length };
1710 return theString;
1711 }
1712 }
1713
1714 void StringBuffer::erase(Uint64 offSet, Uint64 amount) {
1715 this->theSize = this->theSize - amount;
1716 if (this->whichOneAreWeOn == 0) {
1717 if (this->theString02.size() < this->theString01.size()) {
1718 this->theString02.resize(this->theString01.size());
1719 }
1720 memcpy(this->theString02.data(), this->theString01.data() + amount, this->theSize);
1721 this->whichOneAreWeOn = 1;
1722 } else {
1723 if (this->theString01.size() < this->theString02.size()) {
1724 this->theString01.resize(this->theString02.size());
1725 }
1726 memcpy(this->theString01.data(), this->theString02.data() + amount, this->theSize);
1727 this->whichOneAreWeOn = 0;
1728 }
1729 }
1730
1731 void StringBuffer::writeData(const char* thePtr, Uint64 theSize) {
1732 if (this->whichOneAreWeOn == 0) {
1733 if (this->theSize + theSize < this->theString01.size()) {
1734 memcpy(this->theString01.data() + this->theSize, thePtr, theSize);
1735 this->theSize += theSize;
1736 } else {
1737 this->theString01.resize(this->theString01.size() * 2);
1738 memcpy(this->theString01.data() + this->theSize, thePtr, theSize);
1739 this->theSize += theSize;
1740 }
1741 } else {
1742 if (this->theSize + theSize < this->theString02.size()) {
1743 memcpy(this->theString02.data() + this->theSize, thePtr, theSize);
1744 this->theSize += theSize;
1745 } else {
1746 this->theString02.resize(this->theString02.size() * 2);
1747 memcpy(this->theString02.data() + this->theSize, thePtr, theSize);
1748 this->theSize += theSize;
1749 }
1750 }
1751 }
1752
1753 StringBuffer::operator StringView() {
1754 if (this->whichOneAreWeOn == 0) {
1755 StringView theString{ this->theString01.data(), this->theSize };
1756 return theString;
1757 } else {
1758 StringView theString{ this->theString02.data(), this->theSize };
1759 return theString;
1760 }
1761 }
1762
1763 char StringBuffer::operator[](Uint64 theIndex) {
1764 if (this->whichOneAreWeOn == 0) {
1765 return this->theString01[theIndex];
1766 } else {
1767 return this->theString02[theIndex];
1768 }
1769 }
1770
1771 Uint64 StringBuffer::size() {
1772 return this->theSize;
1773 }
1774
1775 void StringBuffer::clear() {
1776 this->whichOneAreWeOn = 0;
1777 this->theSize = 0;
1778 }
1779
1780 char* StringBuffer::data() {
1781 if (this->whichOneAreWeOn == 0) {
1782 return this->theString01.data();
1783 } else {
1784 return this->theString02.data();
1785 }
1786 }
1787}
DiscordCoreAPI_Dll String getTimeAndDate()
Acquires a timestamp with the current time and date - suitable for use in message-embeds.
Definition: Utilities.cpp:1589
Permission
Permission values, for a given Channel, by Role or GuildMember.
Definition: Utilities.hpp:1285
TextFormat
Represents which text format to use for websocket transfer.
Definition: Utilities.hpp:600
GatewayIntents
Gateway intents.
Definition: Utilities.hpp:567
DiscordCoreAPI_Dll void reportException(const String &currentFunctionName, std::source_location theLocation=std::source_location::current())
Prints the current file, line, and column from which the function is being called - typically from wi...
Definition: Utilities.cpp:1371
@ 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.
static CoRoutine< GuildData > getCachedGuildAsync(GetGuildData dataPackage)
Collects a Guild from the library's cache.
static CoRoutine< RoleData > getCachedRoleAsync(GetRoleData dataPackage)
Collects a given Role from the library's cache.
For updating a User's presence.
Definition: Utilities.hpp:477
Bool checkForPermission(const GuildMember &guildMember, ChannelData &channel, Permission permission)
Checks for a given Permission in a chosen Channel, for a specific User.
Definition: Utilities.cpp:1106
String getCurrentPermissionString()
Returns a string containing the currently held Permissions.
Definition: Utilities.cpp:1274
void removePermissions(const std::vector< Permission > &permissionsToRemove)
Removes one or more Permissions from the current Permissions value.
Definition: Utilities.cpp:1120
std::vector< String > displayPermissions()
Displays the currently present Permissions in a string, and returns a vector with each of them stored...
Definition: Utilities.cpp:1140
static String getCurrentGuildPermissions(const GuildMember &guildMember)
Returns a string containing the currently held Permissions in a given Guild.
Definition: Utilities.cpp:1115
static String getCurrentChannelPermissions(const GuildMember &guildMember, ChannelData &channel)
Returns a string containing all of a given User's Permissions for a given Channel.
Definition: Utilities.cpp:1101
static String getAllPermissions()
Returns a string containing ALL of the possible Permissions.
Definition: Utilities.cpp:1279
void addPermissions(const std::vector< Permission > &permissionsToAdd)
Adds one or more Permissions to the current Permissions value.
Definition: Utilities.cpp:1130