diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8eb7740f3d..39be04f8f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: run: cd build && make -j2 - name: Run unit tests - run: cd build/library && ./unittest + run: cd build && ctest -VV env: DPP_UNIT_TEST_TOKEN: ${{secrets.DPP_UNIT_TEST_TOKEN}} TEST_GUILD_ID: ${{secrets.TEST_GUILD_ID}} @@ -133,8 +133,15 @@ jobs: macos: permissions: contents: write - name: macOS x64 - runs-on: macos-latest + name: macOS ${{matrix.cfg.arch}} (${{matrix.cfg.cpp-version}}) + runs-on: ${{matrix.cfg.os}} + strategy: + fail-fast: false # Don't fail everything if one fails. We want to test each OS/Compiler individually + matrix: + # arm64 is a self-hosted runner on a Mac M2 Mini, ran inside a virtual machine by Archie Jaskowicz. + cfg: + - { arch: 'x64', concurrency: 3, os: macos-latest, cpp-version: clang++-14, cmake-flags: '', cpack: 'no' } + - { arch: 'arm64', concurrency: 2, os: [self-hosted, ARM64, macOS], cpp-version: clang++-15, cmake-flags: '', cpack: 'no' } steps: - name: Harden Runner uses: step-security/harden-runner@1b05615854632b887b69ae1be8cbefe72d3ae423 # v2.6.0 @@ -145,7 +152,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Install homebrew packages - run: brew install cmake make libsodium opus openssl + run: brew install cmake make libsodium opus openssl pkg-config - name: Generate CMake run: mkdir build && cd build && cmake -DDPP_NO_VCPKG=ON -DCMAKE_BUILD_TYPE=Release -DDPP_CORO=ON -DAVX_TYPE=AVX0 .. @@ -153,10 +160,13 @@ jobs: DONT_RUN_VCPKG: true - name: Build Project - run: cd build && make -j3 + run: cd build && make -j${{ matrix.cfg.concurrency }} env: DONT_RUN_VCPKG: true + - name: Run offline unit tests + run: cd build && ctest -VV + windows: # Windows x64 and x86 build matrix permissions: contents: write diff --git a/.gitignore b/.gitignore index 21df953333..bbf269173b 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ config.json .misspell-fixer.ignore compile_commands.json src/dpp/dpp.rc +.DS_STORE diff --git a/CMakeLists.txt b/CMakeLists.txt index 1da071574a..de0b161d85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,12 @@ if (NOT DPP_NO_VCPKG AND EXISTS "${_VCPKG_ROOT_DIR}") HOMEPAGE_URL "https://dpp.dev/" DESCRIPTION "An incredibly lightweight C++ Discord library." ) + + # Required before we add any subdirectories. + if (DPP_BUILD_TEST) + enable_testing(${CMAKE_CURRENT_SOURCE_DIR}) + endif() + add_subdirectory(library-vcpkg) else() set(PROJECT_NAME "libdpp") @@ -79,6 +85,12 @@ else() HOMEPAGE_URL "https://dpp.dev/" DESCRIPTION "An incredibly lightweight C++ Discord library." ) + + # Required before we add any subdirectories. + if (DPP_BUILD_TEST) + enable_testing(${CMAKE_CURRENT_SOURCE_DIR}) + endif() + add_subdirectory(library) endif() diff --git a/README.md b/README.md index 05439971d3..361e845917 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,9 @@ You can find more examples in our [example page](https://dpp.dev/example-program The library runs ideally on **Linux**. -### Mac OS X and FreeBSD and OpenBSD +### Mac OS X, FreeBSD, and OpenBSD -The library is well-functional and stable on **Mac OS X**, **FreeBSD**, and **OpenBSD** too. +The library is well-functional and stable on **Mac OS X**, **FreeBSD**, and **OpenBSD** too! ### Raspberry Pi diff --git a/buildtools/emojis.php b/buildtools/emojis.php index 2a6f9b5cc0..ba130eb5c4 100644 --- a/buildtools/emojis.php +++ b/buildtools/emojis.php @@ -12,9 +12,11 @@ namespace dpp { /** - * The unicode emojis in this namespace are auto-generated from {$url} + * @brief Emoji unicodes. * - * If you want to use this, you have to pull the header in separately. e.g. + * @note The unicode emojis in this namespace are auto-generated from https://raw.githubusercontent.com/ArkinSolomon/discord-emoji-converter/master/emojis.json + * + * @warning If you want to use this, you have to pull the header in separately. For example: * ```cpp * #include * #include diff --git a/docpages/INDEX.md b/docpages/INDEX.md index 7d4e93f919..f64b505ae2 100644 --- a/docpages/INDEX.md +++ b/docpages/INDEX.md @@ -48,8 +48,8 @@ You can find further releases in other architectures and formats or the source c ### Linux The library runs ideally on **Linux**. -### Mac OS X and FreeBSD -The library is well-functional and stable on **Mac OS X** and **FreeBSD** too. +### Mac OS X, FreeBSD, and OpenBSD +The library is well-functional and stable on **Mac OS X**, **FreeBSD**, and **OpenBSD** too! ### Raspberry Pi For running your bot on a **Raspberry Pi**, we offer a prebuilt .deb package for ARM64, ARM6, and ARM7 so that you do not have to wait for it to compile. @@ -63,10 +63,10 @@ The library should work fine on other operating systems as well, and if you run ## Getting started * [GitHub Repository](https://github.com/brainboxdotcc/DPP) * [Discord Server](https://discord.gg/dpp) -* \ref frequently-asked-questions "Frequently Asked Questions" -* \ref installing "Installing D++" -* \ref example-programs "Example Programs" -* \ref glossary-of-common-discord-terms "Commonly used terms" +* \ref frequently-asked-questions +* \ref installing +* \ref example-programs +* \ref glossary-of-common-discord-terms ## Architecture * \ref clusters-shards-guilds diff --git a/docpages/building/linux.md b/docpages/building/linux.md index 9abad1ce41..41d81e1ae6 100644 --- a/docpages/building/linux.md +++ b/docpages/building/linux.md @@ -2,9 +2,10 @@ \note You might not need to build a copy of the library for Linux - precompiled deb files for 64 bit and 32 bit Debian and Ubuntu are provided in the GitHub version releases. Unless you are on a different Linux distribution which does not support the installation of deb files, or wish to submit fixes and enhancements to the library itself you should have an easier time installing the precompiled version instead. -## 1. Build Source Code - +## 1. Copy & Build Source code ```bash +git clone https://github.com/brainboxdotcc/DPP +cd DPP/ cmake -B ./build cmake --build ./build -j8 ``` @@ -23,7 +24,7 @@ sudo make install If you want to install the library, its dependencies, and header files to a different directory, specify this directory when running `cmake`: ```bash -cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install +cmake -B ./build -DCMAKE_INSTALL_PREFIX=/path/to/install ``` Then once the build is complete, run `make install` to install to the location you specified. @@ -36,12 +37,31 @@ Once installed to the `/usr/local` directory, you can make use of the library in g++ -std=c++17 mydppbot.cpp -o dppbot -ldpp ``` +If you are on **Arch Linux**: + +- You need to give proper permission to `libdpp.so` and `libdpp.so.10.0.29` +```bash +sudo chmod 644 /usr/local/lib/libdpp.so && sudo chmod +x /usr/local/lib/dpp.so +sudo chmod 644 /usr/local/lib/libdpp.so.10.0.29 && sudo chmod +x /usr/local/lib/dpp.so.10.0.29 +``` + +- You need to specify the location for `libdpp.so` when compilling: + +```bash +g++ -std=c++17 -I/usr/local/include mydppbot.cpp -o dppbot /usr/local/lib/libdpp.so -Wl,-rpath,/usr/local/lib +``` + The important flags in this command-line are: * `-std=c++17` - Required to compile the headers -* `-ldpp` - Link to libdpp.so +* `-L/usr/local/lib` - Required to tell the linker where libdpp is located +* `-I/usr/local/include` - Required to tell the linker where dpp headers are located * `mydppbot.cpp` - Your source code * `dppbot` - The name of the executable to make +* `-ldpp` - Link to libdpp.so +* `/usr/local/lib/libdpp.so` - Required to specifies the path to the shared library +* `-Wl` - Required to pass options directly to the linker +* `-rpath,/usr/local/lib` - Required to specifies the runtime library search path \include{doc} install_prebuilt_footer.dox diff --git a/docpages/building/osx.md b/docpages/building/osx.md index a54a25b4c6..b43a99e9e1 100644 --- a/docpages/building/osx.md +++ b/docpages/building/osx.md @@ -10,9 +10,11 @@ Before compiling make sure you have all the tools installed. ## 2. Install External Dependencies ```bash -brew install openssl +brew install openssl pkgconfig ``` +\note Usually, you do not need pkgconfig. However, it seems that it throws errors about openssl without. + For voice support, additional dependencies are required: ```bash @@ -43,7 +45,7 @@ If you want to install the library, its dependencies, and header files to a diff cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install ``` -Then once the build is complete, run `make install` to install to the location you specified. +Then once the build is complete, run `sudo make install` to install to the location you specified. ## 6. Using the Library diff --git a/docpages/example_code/clearing_slashcommands.cpp b/docpages/example_code/clearing_slashcommands.cpp index b977813d8d..f2bb28936b 100644 --- a/docpages/example_code/clearing_slashcommands.cpp +++ b/docpages/example_code/clearing_slashcommands.cpp @@ -1,7 +1,6 @@ #include -int main() -{ +int main() { dpp::cluster bot("token"); bot.on_log(dpp::utility::cout_logger()); @@ -12,7 +11,7 @@ int main() if (dpp::run_once()) { /* Now, we're going to wipe our commands */ bot.global_bulk_command_delete(); - /* This one requires a guild id, otherwise it won't what guild's commands it needs to wipe! */ + /* This one requires a guild id, otherwise it won't know what guild's commands it needs to wipe! */ bot.guild_bulk_command_delete(857692897221033129); } diff --git a/docpages/example_programs/the_basics/firstbot.md b/docpages/example_programs/the_basics/firstbot.md index c0b4296a49..bcf52c79c0 100644 --- a/docpages/example_programs/the_basics/firstbot.md +++ b/docpages/example_programs/the_basics/firstbot.md @@ -100,7 +100,7 @@ The `event.reply` function (dpp::slashcommand_t::reply) replies to a slash comma To make the bot start, we must call the dpp::cluster::start method, e.g. in our program by using `bot.start(dpp::st_wait)`. -We also add a line to tell the library to output all its log information to the console, `bot.on_log(dpp::utility::cout_logger());` - if you wanted to do something more advanced, you can replace this parameter with a lambda just like all other events. +We also add a line to tell the library to output all its log information to the console, use `bot.on_log(dpp::utility::cout_logger());` (dpp::utility::cout_logger) - if you wanted to do something more advanced, you can replace this parameter with a lambda just like all other events. The parameter which we set to false indicates if the function should return once all shards are created. Passing dpp::st_wait here tells the program you do not need to do anything once `bot.start` is called. diff --git a/docpages/install/install-arch-aur.md b/docpages/install/install-arch-aur.md index 2e76432ae0..4d1382a641 100644 --- a/docpages/install/install-arch-aur.md +++ b/docpages/install/install-arch-aur.md @@ -12,9 +12,11 @@ or use your favourite package manager: ```bash # example with `yay` (without root) -yay -Sy dpp +yay -Syu dpp ``` +\note The package is currently outdated. We are looking for a new maintainer. For now, please use `dpp-git` or build it from \ref buildlinux "source". + This will do the following three things: - Clone the D++ AUR repository to a directory called `dpp` diff --git a/include/dpp/cluster.h b/include/dpp/cluster.h index f7cec818c4..a3a632e95e 100644 --- a/include/dpp/cluster.h +++ b/include/dpp/cluster.h @@ -1368,11 +1368,9 @@ class DPP_EXPORT cluster { * @param method Method, e.g. GET, POST * @param postdata Post data (usually JSON encoded) * @param callback Function to call when the HTTP call completes. The callback parameter will contain amongst other things, the decoded json. - * @param filename List of filenames to post for POST requests (for uploading files) - * @param filecontent List of file content to post for POST requests (for uploading files) - * @param filemimetypes List of mime types for each file to post for POST requests (for uploading files) + * @param file_data List of files to post for POST requests (for uploading files) */ - void post_rest_multipart(const std::string &endpoint, const std::string &major_parameters, const std::string ¶meters, http_method method, const std::string &postdata, json_encode_t callback, const std::vector &filename = {}, const std::vector& filecontent = {}, const std::vector& filemimetypes = {}); + void post_rest_multipart(const std::string &endpoint, const std::string &major_parameters, const std::string ¶meters, http_method method, const std::string &postdata, json_encode_t callback, const std::vector &file_data = {}); /** * @brief Make a HTTP(S) request. For use when wanting asynchronous access to HTTP APIs outside of Discord. diff --git a/include/dpp/discordvoiceclient.h b/include/dpp/discordvoiceclient.h index 4a13ab6725..adfb37e417 100644 --- a/include/dpp/discordvoiceclient.h +++ b/include/dpp/discordvoiceclient.h @@ -564,7 +564,10 @@ class DPP_EXPORT discord_voice_client : public websocket_client snowflake channel_id; /** - * @brief The audio type to be sent. The default type is recorded audio. + * @brief The audio type to be sent. + * + * @note On Windows, the default type is overlap audio. + * On all other platforms, it is recorded audio. * * If the audio is recorded, the sending of audio packets is throttled. * Otherwise, if the audio is live, the sending is not throttled. @@ -594,10 +597,15 @@ class DPP_EXPORT discord_voice_client : public websocket_client */ enum send_audio_type_t { - satype_recorded_audio, - satype_live_audio, + satype_recorded_audio, + satype_live_audio, satype_overlap_audio - } send_audio_type = satype_recorded_audio; + } send_audio_type = +#ifdef _WIN32 + satype_overlap_audio; +#else + satype_recorded_audio; +#endif /** * @brief Sets the gain for the specified user. diff --git a/include/dpp/emoji.h b/include/dpp/emoji.h index 40b38b1571..7e0549bd2a 100644 --- a/include/dpp/emoji.h +++ b/include/dpp/emoji.h @@ -45,17 +45,17 @@ enum emoji_flags : uint8_t { /** * @brief Managed (introduced by application) */ - e_managed = 0b00000010, + e_managed = 0b00000010, /** * @brief Animated emoji. */ - e_animated = 0b00000100, + e_animated = 0b00000100, /** * @brief Available (false if the guild doesn't meet boosting criteria, etc) */ - e_available = 0b00001000, + e_available = 0b00001000, }; /** diff --git a/include/dpp/isa/avx.h b/include/dpp/isa/avx.h index 1700ca7808..3dc2914d0f 100644 --- a/include/dpp/isa/avx.h +++ b/include/dpp/isa/avx.h @@ -73,7 +73,10 @@ namespace dpp { } protected: - alignas(16) float values[byte_blocks_per_register]{};///< Array for storing the values to be loaded/stored. + /** + * @brief Array for storing the values to be loaded/stored. + */ + alignas(16) float values[byte_blocks_per_register]{}; /** * @brief Stores values from a 128-bit AVX vector to a storage location. diff --git a/include/dpp/isa/avx2.h b/include/dpp/isa/avx2.h index 579025f246..1e02eaa935 100644 --- a/include/dpp/isa/avx2.h +++ b/include/dpp/isa/avx2.h @@ -76,7 +76,10 @@ namespace dpp { } protected: - alignas(32) float values[byte_blocks_per_register]{};///< Array for storing the values to be loaded/stored. + /** + * @brief Array for storing the values to be loaded/stored. + */ + alignas(32) float values[byte_blocks_per_register]{}; /** * @brief Stores values from a 256-bit AVX2 vector to a storage location. diff --git a/include/dpp/isa/avx512.h b/include/dpp/isa/avx512.h index 2bdc3344e6..bdf1d47859 100644 --- a/include/dpp/isa/avx512.h +++ b/include/dpp/isa/avx512.h @@ -79,7 +79,10 @@ namespace dpp { } protected: - alignas(64) float values[byte_blocks_per_register]{};///< Array for storing the values to be loaded/stored. + /** + * @brief Array for storing the values to be loaded/stored. + */ + alignas(64) float values[byte_blocks_per_register]{}; /** * @brief Stores values from a 512-bit AVX512 vector to a storage location. diff --git a/include/dpp/message.h b/include/dpp/message.h index bd1864f4f4..ac9ca0716f 100644 --- a/include/dpp/message.h +++ b/include/dpp/message.h @@ -36,21 +36,44 @@ namespace dpp { * @brief Represents the type of a component */ enum component_type : uint8_t { - /// Action row, a container for other components + /** + * @brief Action row, a container for other components. + */ cot_action_row = 1, - /// Clickable button + + /** + * @brief Clickable button. + */ cot_button = 2, - /// Select menu for picking from defined text options + + /** + * @brief Select menu for picking from defined text options. + */ cot_selectmenu = 3, - /// Text input + + /** + * @brief Text input. + */ cot_text = 4, - /// Select menu for users + + /** + * @brief Select menu for users. + */ cot_user_selectmenu = 5, - /// Select menu for roles + + /** + * @brief Select menu for roles. + */ cot_role_selectmenu = 6, - /// Select menu for mentionables (users and roles) + + /** + * @brief Select menu for mentionables (users and roles). + */ cot_mentionable_selectmenu = 7, - /// Select menu for channels + + /** + * @brief Select menu for channels. + */ cot_channel_selectmenu = 8, }; @@ -91,13 +114,42 @@ struct component_emoji { bool animated{false}; }; +/** + * @brief The data for a file attached to a message. + * + * @todo Change the naming of this and make stickers (and potentially anything else that has data like this) use this. + */ +struct message_file_data { + /** + * @brief Name of file to upload (for use server-side in discord's url). + */ + std::string name{}; + + /** + * @brief File content to upload (raw binary) + */ + std::string content{}; + + /** + * @brief Mime type of files to upload. + * + * @todo Look at turning this into an enum? This would allow people to easily compare mimetypes if they happen to change. + */ + std::string mimetype{}; +}; + /** * @brief Types of text input */ enum text_style_type : uint8_t { - /// Intended for short single-line text. + /** + * @brief Intended for short single-line text. + */ text_short = 1, - /// Intended for much longer inputs. + + /** + * @brief Intended for much longer inputs. + */ text_paragraph = 2, }; @@ -105,15 +157,29 @@ enum text_style_type : uint8_t { * @brief Represents the style of a button */ enum component_style : uint8_t { - /// Blurple + /** + * @brief Blurple + */ cos_primary = 1, - /// Grey + + /** + * @brief Grey + */ cos_secondary, - /// Green + + /** + * @brief Green + */ cos_success, - /// Red + + /** + * @brief Red + */ cos_danger, - /// An external hyperlink to a website + + /** + * @brief An external hyperlink to a website + */ cos_link }; @@ -136,6 +202,7 @@ struct DPP_EXPORT component_default_value { * @brief The type this default value represents */ component_default_value_type type; + /** * @brief Default value. ID of a user, role, or channel */ @@ -160,14 +227,17 @@ struct DPP_EXPORT select_option : public json_interface { * @brief User-facing name of the option */ std::string label; + /** * @brief Dev-defined value of the option */ std::string value; + /** * @brief Additional description of the option */ std::string description; + /** * @brief True if option is the default option */ @@ -271,85 +341,107 @@ class DPP_EXPORT component : public json_interface { component& fill_from_json_impl(nlohmann::json* j); public: - /** Component type, either a button or action row + /** + * @brief Component type, either a button or action row */ component_type type; - /** Sub components, buttons on an action row + /** + * @brief Sub components, buttons on an action row */ std::vector components; - /** Component label (for buttons, text inputs). + /** + * @brief Component label (for buttons, text inputs). * Maximum of 80 characters. */ std::string label; - /** Component style (for buttons) + /** + * @brief Component style (for buttons). */ component_style style; /** - * @brief Text style (for text inputs) + * @brief Text style (for text inputs). */ text_style_type text_style; - /** Component id (for buttons, menus, text inputs). + /** + * @brief Component id (for buttons, menus, text inputs). * Maximum of 100 characters. */ std::string custom_id; - /** URL for link types (dpp::cos_link). + /** + * @brief URL for link types (dpp::cos_link). * Maximum of 512 characters. */ std::string url; - /** Placeholder text for select menus and text inputs (max 150 characters) + /** + * @brief Placeholder text for select menus and text inputs (max 150 characters) */ std::string placeholder; - /** Minimum number of items that must be chosen for a select menu (0-25). - * Default is -1 to not set this + /** + * @brief Minimum number of items that must be chosen for a select menu (0-25). + * + * @note Use -1 to not set this. This is done by default. */ int32_t min_values; - /** Maximum number of items that can be chosen for a select menu (0-25). - * Default is -1 to not set this + /** + * @brief Maximum number of items that can be chosen for a select menu (0-25). + * + * @note Use -1 to not set this. This is done by default. */ int32_t max_values; - /** Minimum length for text input (0-4000) + /** + * @brief Minimum length for text input (0-4000) */ int32_t min_length; - /** Maximum length for text input (1-4000) + /** + * @brief Maximum length for text input (1-4000) */ int32_t max_length; - /** Select options for select menus. Only required and available for select menus of type dpp::cot_selectmenu + /** + * @brief Select options for select menus. + * + * @warning Only required and available for select menus of type dpp::cot_selectmenu */ std::vector options; - /** List of channel types (dpp::channel_type) to include in the channel select component (dpp::cot_channel_selectmenu) + /** + * @brief List of channel types (dpp::channel_type) to include in the channel select component (dpp::cot_channel_selectmenu) */ std::vector channel_types; /** - * List of default values for auto-populated select menu components. The amount of default values must be in the range defined by dpp::component::min_value and dpp::component::max_values. + * @brief List of default values for auto-populated select menu components. * - * @note Only available for auto-populated select menu components, which include dpp::cot_user_selectmenu, dpp::cot_role_selectmenu, dpp::cot_mentionable_selectmenu, and dpp::cot_channel_selectmenu components. + * @note The amount of default values must be in the range defined by dpp::component::min_values and dpp::component::max_values. + * + * @warning Only available for auto-populated select menu components, which include dpp::cot_user_selectmenu, dpp::cot_role_selectmenu, dpp::cot_mentionable_selectmenu, and dpp::cot_channel_selectmenu components. */ std::vector default_values; - /** Disabled flag (for buttons) + /** + * @brief Disabled flag (for buttons) */ bool disabled; - /** Whether the text input is required to be filled + /** + * @brief Whether the text input is required to be filled */ bool required; - /** Value of the modal (filled or valid when populated from an - * on_form_submit event, or from the set_value function) + /** + * @brief Value of the modal. + * Filled or valid when populated from an on_form_submit event, or from the set_value function. */ std::variant value; @@ -358,11 +450,13 @@ class DPP_EXPORT component : public json_interface { */ component_emoji emoji; - /** Constructor + /** + * @brief Constructor */ component(); - /** Destructor + /** + * @brief Destructor */ virtual ~component() = default; @@ -559,28 +653,41 @@ class DPP_EXPORT component : public json_interface { * @brief A footer in a dpp::embed */ struct DPP_EXPORT embed_footer { - /** Footer text */ + /** + * @brief Footer text + */ std::string text; - /** Footer icon url (only supports http(s) and attachments) */ + + /** + * @brief Footer icon url. + * + * @warning Only supports http(s) and attachments. + */ std::string icon_url; - /** Proxied icon url */ + + /** + * @brief Proxied icon url. + */ std::string proxy_url; - /** Set footer's text. Returns footer itself so these methods may be "chained" + /** + * @brief Set footer's text. * @param t string to set as footer text. It will be truncated to the maximum length of 2048 UTF-8 characters. - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed_footer& set_text(const std::string& t); - /** Set footer's icon url. Returns footer itself so these methods may be "chained" + /** + * @brief Set footer's icon url. * @param i url to set as footer icon url - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed_footer& set_icon(const std::string& i); - /** Set footer's proxied icon url. Returns footer itself so these methods may be "chained" + /** + * @brief Set footer's proxied icon url. * @param p url to set as footer proxied icon url - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed_footer& set_proxy(const std::string& p); }; @@ -589,13 +696,24 @@ struct DPP_EXPORT embed_footer { * @brief An video, image or thumbnail in a dpp::embed */ struct DPP_EXPORT embed_image { - /** URL to image or video */ + /** + * @brief URL to image or video. + */ std::string url; - /** Proxied image url */ + + /** + * @brief Proxied image url. + */ std::string proxy_url; - /** Height (calculated by discord) */ + + /** + * @brief Height (calculated by discord). + */ std::string height; - /** Width (calculated by discord) */ + + /** + * @brief Width (calculated by discord). + */ std::string width; }; @@ -603,9 +721,14 @@ struct DPP_EXPORT embed_image { * @brief Embed provider in a dpp::embed. Received from discord but cannot be sent */ struct DPP_EXPORT embed_provider { - /** Provider name */ + /** + * @brief Provider name. + */ std::string name; - /** Provider URL */ + + /** + * @brief Provider URL. + */ std::string url; }; @@ -613,186 +736,298 @@ struct DPP_EXPORT embed_provider { * @brief Author within a dpp::embed object */ struct DPP_EXPORT embed_author { - /** Author name */ + /** + * @brief Author name. + */ std::string name; - /** Author url (only supports http(s)) */ + + /** + * @brief Author url. + * + * @warning Only supports http(s). + */ std::string url; - /** Author icon url (only supports http(s) and attachments) */ + + /** + * @brief Author icon url. + * + * @warning Only supports http(s) and attachments. + */ std::string icon_url; - /** Proxied icon url */ + + /** + * @brief Proxied icon url. + */ std::string proxy_icon_url; }; /** - * @brief A dpp::embed may contain zero or more fields + * @brief A dpp::embed may contain zero or more fields. */ struct DPP_EXPORT embed_field { - /** Name of field (max length 256) */ + /** + * @brief Name of field (max length 256). + */ std::string name; - /** Value of field (max length 1024) */ + + /** + * @brief Value of field (max length 1024). + */ std::string value; - /** True if the field is to be displayed inline */ + + /** + * @brief True if the field is to be displayed inline. + */ bool is_inline; }; /** - * @brief A rich embed for display within a dpp::message + * @brief A rich embed for display within a dpp::message. */ struct DPP_EXPORT embed { - /** Optional: title of embed */ - std::string title; - /** Optional: type of embed (always "rich" for webhook embeds) */ - std::string type; - /** Optional: description of embed */ - std::string description; - /** Optional: url of embed */ - std::string url; - /** Optional: timestamp of embed content */ - time_t timestamp; - /** Optional: color code of the embed */ - std::optional color; - /** Optional: footer information */ - std::optional footer; - /** Optional: image information */ - std::optional image; - /** Optional: thumbnail information */ - std::optional thumbnail; - /** Optional: video information (can't send these) */ - std::optional video; - /** Optional: provider information (can't send these) */ - std::optional provider; - /** Optional: author information */ - std::optional author; - /** Optional: fields information */ - std::vector fields; - - /** Constructor */ + /** + * @brief Optional: Title of embed. + */ + std::string title; + + /** + * @brief Optional: Type of embed. + * + * @note Always "rich" for webhook embeds. + */ + std::string type; + + /** + * @brief Optional: Description of embed. + */ + std::string description; + + /** + * @brief Optional: URL of embed. + */ + std::string url; + + /** + * @brief Optional: Timestamp of embed content. + */ + time_t timestamp; + + /** + * @brief Optional: Color code of the embed. + */ + std::optional color; + + /** + * @brief Optional: Footer information. + */ + std::optional footer; + + /** + * @brief Optional: Image information. + */ + std::optional image; + + /** + * @brief Optional: Thumbnail information. + */ + std::optional thumbnail; + + /** + * @brief Optional: Video information + * + * @warning Can't send this. + */ + std::optional video; + + /** + * @brief Optional: Provider information. + * + * @warning Can't send this. + */ + std::optional provider; + + /** + * @brief Optional: Author information. + */ + std::optional author; + + /** + * @brief Optional: Fields information. + */ + std::vector fields; + + /** + * @brief Constructor + */ embed(); - /** Constructor to build embed from json object + /** + * @brief Constructor to build embed from json object * @param j JSON to read content from */ embed(nlohmann::json* j); - /** Destructor */ + /** + * @brief Destructor + */ ~embed(); - /** Set embed title. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed title. * @param text The text of the title. It will be truncated to the maximum length of 256 UTF-8 characters. - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_title(const std::string &text); - /** Set embed description. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed description. * @param text The text of the title. It will be truncated to the maximum length of 4096 UTF-8 characters. - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_description(const std::string &text); - /** Set the footer of the embed. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set the footer of the embed. * @param f the footer to set - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_footer(const embed_footer& f); - /** Set the footer of the embed. Returns the embed itself so these method calls may be "chained" - * @param text string to set as footer text. It will be truncated to the maximum length of 2048 UTF-8 characters. - * @param icon_url an url to set as footer icon url (only supports http(s) and attachments) - * @return A reference to self - */ + /** + * @brief Set the footer of the embed. + * @param text string to set as footer text. It will be truncated to the maximum length of 2048 UTF-8 characters. + * @param icon_url an url to set as footer icon url (only supports http(s) and attachments) + * @return A reference to self so this method may be "chained". + */ embed& set_footer(const std::string& text, const std::string& icon_url); - /** Set embed colour. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed colour. * @param col The colour of the embed - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_color(uint32_t col); - /** Set embed colour. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed colour. * @param col The colour of the embed - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_colour(uint32_t col); - /** Set embed timestamp. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed timestamp. * @param tstamp The timestamp to show in the footer, should be in UTC - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_timestamp(time_t tstamp); - /** Set embed url. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed url. * @param url the url of the embed - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_url(const std::string &url); - /** Add an embed field. Returns the embed itself so these method calls may be "chained" + /** + * @brief Add an embed field. * @param name The name of the field. It will be truncated to the maximum length of 256 UTF-8 characters. * @param value The value of the field. It will be truncated to the maximum length of 1024 UTF-8 characters. * @param is_inline Whether or not to display the field 'inline' or on its own line - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& add_field(const std::string& name, const std::string &value, bool is_inline = false); - /** Set embed author. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed author. * @param a The author to set - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_author(const dpp::embed_author& a); - /** Set embed author. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed author. * @param name The name of the author. It will be truncated to the maximum length of 256 UTF-8 characters. * @param url The url of the author (only supports http(s)) * @param icon_url The icon URL of the author (only supports http(s) and attachments) - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_author(const std::string& name, const std::string& url, const std::string& icon_url); - /** Set embed provider. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed provider. * @param name The provider name. It will be truncated to the maximum length of 256 UTF-8 characters. * @param url The provider url - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_provider(const std::string& name, const std::string& url); - /** Set embed image. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed image. * @param url The embed image URL (only supports http(s) and attachments) - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_image(const std::string& url); - /** Set embed video. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed video. * @param url The embed video url - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_video(const std::string& url); - /** Set embed thumbnail. Returns the embed itself so these method calls may be "chained" + /** + * @brief Set embed thumbnail. * @param url The embed thumbnail url (only supports http(s) and attachments) - * @return A reference to self + * @return A reference to self so this method may be "chained". */ embed& set_thumbnail(const std::string& url); }; /** - * @brief Represents a reaction to a dpp::message + * @brief Represents a reaction to a dpp::message. */ struct DPP_EXPORT reaction { - /** Total number of times this emoji has been used to react (including super reacts) */ + /** + * @brief Total number of times this emoji has been used to react (including super reacts) + */ uint32_t count; - /** Count of super reactions */ + + /** + * @brief Count of super reactions + */ uint32_t count_burst; - /** Count of normal reactions */ + + /** + * @brief Count of normal reactions + */ uint32_t count_normal; - /** ID of emoji for reaction */ + + /** + * @brief ID of emoji for reaction + */ snowflake emoji_id; - /** Name of emoji, if applicable */ + + /** + * @brief Name of emoji, if applicable + */ std::string emoji_name; - /** Whether your bot reacted using this emoji */ + + /** + * @brief Whether your bot reacted using this emoji + */ bool me; - /** Whether your bot super-reacted using this emoji */ + + /** + * @brief Whether your bot super-reacted using this emoji + */ bool me_burst; - /** HEX colors used for super reaction. Stored as integers */ + + /** + * @brief HEX colors used for super reaction. + * + * @note Stored as integers. + */ std::vector burst_colors; /** @@ -816,7 +1051,9 @@ struct DPP_EXPORT reaction { * @brief Bitmask flags for a dpp::attachment */ enum attachment_flags : uint8_t { - /// this attachment has been edited using the remix feature on mobile + /** + * @brief This attachment has been edited using the remix feature on mobile. + */ a_is_remix = 1 << 2, }; @@ -824,33 +1061,79 @@ enum attachment_flags : uint8_t { * @brief Represents an attachment in a dpp::message */ struct DPP_EXPORT attachment { - /** ID of attachment */ + /** + * @brief ID of attachment. + */ snowflake id; - /** Size of the attachment in bytes */ + + /** + * @brief Size of the attachment in bytes. + */ uint32_t size; - /** File name of the attachment */ + + /** + * @brief File name of the attachment. + */ std::string filename; - /** Optional: Description of the attachment (max 1024 characters) */ + + /** + * @brief Optional: Description of the attachment. + * Max 1024 characters. + */ std::string description; - /** URL which points to the attachment */ + + /** + * @brief URL which points to the attachment. + */ std::string url; - /** Proxied URL which points to the attachment */ + + /** + * @brief Proxied URL which points to the attachment. + */ std::string proxy_url; - /** Width of the attachment, if applicable */ + + /** + * @brief Width of the attachment, if applicable. + */ uint32_t width; - /** Height of the attachment, if applicable */ + + /** + * @brief Height of the attachment, if applicable. + */ uint32_t height; - /** MIME type of the attachment, if applicable */ + + /** + * @brief MIME type of the attachment, if applicable. + */ std::string content_type; - /** Whether this attachment is ephemeral, if applicable */ + + /** + * @brief Whether this attachment is ephemeral, if applicable. + */ bool ephemeral; - /** The duration of the audio file (currently for voice messages) */ + + /** + * @brief The duration of the audio file. + * + * @note Currently for voice messages. + */ double duration_secs; - /** base64 encoded bytearray representing a sampled waveform (currently for voice messages) */ + + /** + * @brief Base64 encoded bytearray representing a sampled waveform. + * + * @note Currently for voice messages. + */ std::string waveform; - /** Flags. Made of bits in dpp::attachment_flags */ - uint8_t flags; - /** Owning message */ + + /** + * @brief Flags made from dpp::attachment_flags. + */ + uint8_t flags; + + /** + * @brief Owning message + */ struct message* owner; /** @@ -873,6 +1156,7 @@ struct DPP_EXPORT attachment { /** * @brief Download this attachment + * * @param callback A callback which is called when the download completes. * @note The content of the file will be in the http_info.body parameter of the * callback parameter. @@ -893,9 +1177,14 @@ struct DPP_EXPORT attachment { * @brief Represents the type of a sticker */ enum sticker_type : uint8_t { - /// An official sticker in a pack + /** + * @brief An official sticker in a pack. + */ st_standard = 1, - /// Guild sticker + + /** + * @brief Guild sticker. + */ st_guild = 2 }; @@ -929,40 +1218,82 @@ struct DPP_EXPORT sticker : public managed, public json_interface { virtual json to_json_impl(bool with_id = true) const; public: - /** Optional: for standard stickers, id of the pack the sticker is from + /** + * @brief Optional: for standard stickers, id of the pack the sticker is from */ - snowflake pack_id; - /** The name of the sticker */ - std::string name; - /// description of the sticker (may be empty) - std::string description; - /** for guild stickers, the Discord name of a unicode emoji representing the sticker's expression. - * for standard stickers, a comma-separated list of related expressions. + snowflake pack_id; + + /** + * @brief The name of the sticker. + */ + std::string name; + + /** + * @brief Description of the sticker + * + * @note This may be empty. */ - std::string tags; + std::string description; + + /** + * @brief The sticker's (or related) expressions. + * + * @note If it's a guild sticker, this will be the Discord name of + * a unicode emoji representing the sticker's expression. + * Otherwise, this will be a comma-separated list of related expressions. + */ + std::string tags; + /** * @brief Asset ID + * * @deprecated now an empty string but still sent by discord. - * While discord still send this empty string value we will still have a field - * here in the library. - */ - std::string asset; - /** The type of sticker */ - sticker_type type; - /// type of sticker format - sticker_format format_type; - /// Optional: whether this guild sticker can be used, may be false due to loss of Server Boosts - bool available; - /// Optional: id of the guild that owns this sticker - snowflake guild_id; - /// Optional: the user that uploaded the guild sticker - user sticker_user; - /// Optional: the standard sticker's sort order within its pack - uint8_t sort_value; - /** Name of file to upload (when adding or editing a sticker) */ - std::string filename; - /** File content to upload (raw binary) */ - std::string filecontent; + * While discord still send this empty string value, + * we will still have this field here in the library. + */ + std::string asset; + + /** + * @brief The type of sticker. + */ + sticker_type type; + + /** + * @brief type of sticker format. + */ + sticker_format format_type; + + /** + * @brief Optional: Whether this guild sticker can be used. + * + * @note May be false due to loss of Server Boosts. + */ + bool available; + + /** + * @brief Optional: ID of the guild that owns this sticker. + */ + snowflake guild_id; + + /** + * @brief Optional: The user that uploaded the guild sticker. + */ + user sticker_user; + + /** + * @brief Optional: The standard sticker's sort order within its pack. + */ + uint8_t sort_value; + + /** + * @brief Name of file to upload (when adding or editing a sticker). + */ + std::string filename; + + /** + * @brief File content to upload (raw binary). + */ + std::string filecontent; /** * @brief Construct a new sticker object @@ -1016,18 +1347,35 @@ struct DPP_EXPORT sticker_pack : public managed, public json_interface stickers; - /// name of the sticker pack - std::string name; - /// id of the pack's SKU - snowflake sku_id; - /// Optional: id of a sticker in the pack which is shown as the pack's icon - snowflake cover_sticker_id; - /// description of the sticker pack - std::string description; - /// id of the sticker pack's banner image - snowflake banner_asset_id; + + /** + * @brief Name of the sticker pack. + */ + std::string name; + + /** + * @brief ID of the pack's SKU. + */ + snowflake sku_id; + + /** + * @brief Optional: ID of a sticker in the pack which is shown as the pack's icon. + */ + snowflake cover_sticker_id; + + /** + * @brief Description of the sticker pack. + */ + std::string description; + + /** + * @brief ID of the sticker pack's banner image. + */ + snowflake banner_asset_id; /** * @brief Construct a new sticker pack object @@ -1041,60 +1389,99 @@ struct DPP_EXPORT sticker_pack : public managed, public json_interface { return to_json(with_id, false); } public: - /** id of the channel the message was sent in */ - snowflake channel_id; - /** Optional: id of the guild the message was sent in */ - snowflake guild_id; - /** the author of this message (not guaranteed to be a valid user) */ - user author; - /** Optional: member properties for this message's author */ - guild_member member; - /** contents of the message */ - std::string content; - /** message components */ + /** + * @brief ID of the channel the message was sent in. + */ + snowflake channel_id; + + /** + * @brief Optional: ID of the guild the message was sent in. + */ + snowflake guild_id; + + /** + * @brief The author of this message. + * + * @warning This is not guaranteed to be a valid user. + */ + user author; + + /** + * @brief Optional: member properties for this message's author + */ + guild_member member; + + /** + * @brief Contents of the message. + */ + std::string content; + + /** + * @brief Message components. + */ std::vector components; - /** when this message was sent */ - time_t sent; - /** when this message was edited (may be 0 if never edited) */ - time_t edited; - /** users specifically mentioned in the message */ - std::vector> mentions; - /** roles specifically mentioned in this message (only IDs currently)*/ + + /** + * @brief When this message was sent. + */ + time_t sent; + + /** + * @brief When this message was edited. + * + * @note This may be 0 if never edited. + */ + time_t edited; + + /** + * @brief Users specifically mentioned in the message. + */ + std::vector> mentions; + + /** + * @brief Roles specifically mentioned in this message (only IDs currently). + */ std::vector mention_roles; - /** Channels mentioned in the message. (Discord: not all types supported) - * Discord: Only textual channels that are visible to everyone in a lurkable guild will ever be included. Only crossposted messages (via Channel Following) currently include mention_channels at all. (includes ID, Guild ID, Type, Name)*/ + + /** + * @brief Channels mentioned in the message. + * + * @warning Not all types supported. + * + * @note Discord: Only textual channels that are visible to everyone in a lurkable guild will ever be included. + * Only crossposted messages (via Channel Following) currently include mention_channels at all. (includes ID, Guild ID, Type, Name). + */ std::vector mention_channels; - /** any attached files */ + + /** + * @brief Any attached files. + */ std::vector attachments; - /** Up to 10 dpp::embed objects */ + + /** + * @brief Up to 10 dpp::embed objects. + */ std::vector embeds; - /** Optional: reactions to the message */ + + /** + * @brief Optional: reactions to the message. + */ std::vector reactions; - /** Optional: used for validating a message was sent */ - std::string nonce; - /** Optional: if the message is generated by a webhook, its id will be here otherwise the field will be 0 */ - snowflake webhook_id; - /** Stickers */ - std::vector stickers; - /** Name of file to upload (for use server-side in discord's url) */ - std::vector filename; + /** + * @brief Optional: Used for validating a message was sent. + */ + std::string nonce; + + /** + * @brief Optional: Webhook ID. + * + * @note If the message is generated by a webhook, its ID will be here. Otherwise, the field will be 0. + */ + snowflake webhook_id; - /** File content to upload (raw binary) */ - std::vector filecontent; + /** + * @brief Stickers. + */ + std::vector stickers; - /** Mime type of files to upload */ - std::vector filemimetype; + /** + * @brief An array of file data to use for uploading files. + * + * @note You should use dpp::message::add_file to add data to this! + */ + std::vector file_data; /** * @brief Reference to another message, e.g. a reply */ struct message_ref { - /// id of the originating message + /** + * @brief ID of the originating message. + */ snowflake message_id; - /// id of the originating message's channel + + /** + * @brief ID of the originating message's channel. + */ snowflake channel_id; - /// id of the originating message's guild + + /** + * @brief ID of the originating message's guild. + */ snowflake guild_id; - /// when sending, whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message, default true + + /** + * @brief when sending, whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message. + * Default true. + */ bool fail_if_not_exists; } message_reference; @@ -1337,13 +1888,24 @@ struct DPP_EXPORT message : public managed, json_interface { * @brief Reference to an interaction */ struct message_interaction_struct{ - /// id of the interaction + /** + * @brief ID of the interaction. + */ snowflake id; - /// type of interaction + + /** + * @brief Type of interaction. + */ uint8_t type; - /// name of the application command + + /** + * @brief Name of the application command. + */ std::string name; - /// the user who invoked the interaction + + /** + * @brief The user who invoked the interaction. + */ user usr; } interaction; @@ -1355,22 +1917,27 @@ struct DPP_EXPORT message : public managed, json_interface { * @brief Set to true to parse user mentions in the text. Default is false */ bool parse_users; + /** * @brief Set to true to at-everyone and at-here mentions in the text. Default is false */ bool parse_everyone; + /** * @brief Set to true to parse role mentions in the text. Default is false */ bool parse_roles; + /** * @brief Set to true to mention the user who sent the message this one is replying to. Default is false */ bool replied_user; + /** * @brief List of users to allow pings for */ std::vector users; + /** * @brief List of roles to allow pings for */ @@ -1378,22 +1945,34 @@ struct DPP_EXPORT message : public managed, json_interface { } allowed_mentions; /** - * @brief The cluster which created this message object + * @brief The cluster which created this message object. */ class cluster* owner; - /** Message type */ + /** + * @brief Message type. + */ message_type type; - /** Flags. Made of bits in dpp::message_flags */ - uint16_t flags; + /** + * @brief Flags made from dpp::message_flags + */ + uint16_t flags; + + /** + * @brief Whether this message is pinned. + */ + bool pinned; + + /** + * @brief Whether this was a TTS message. + */ + bool tts; - /** whether this message is pinned */ - bool pinned; - /** whether this was a TTS message */ - bool tts; - /** whether this message mentions everyone */ - bool mention_everyone; + /** + * @brief Whether this message mentions everyone. + */ + bool mention_everyone; /** * @brief Construct a new message object @@ -1663,13 +2242,19 @@ struct DPP_EXPORT message : public managed, json_interface { std::string get_url() const; }; -/** A group of messages */ +/** + * @brief A group of messages + */ typedef std::unordered_map message_map; -/** A group of stickers */ +/** + * @brief A group of stickers + */ typedef std::unordered_map sticker_map; -/** A group of sticker packs */ +/** + * @brief A group of sticker packs + */ typedef std::unordered_map sticker_pack_map; } // namespace dpp diff --git a/include/dpp/misc-enum.h b/include/dpp/misc-enum.h index feb84b6329..1a65371dec 100644 --- a/include/dpp/misc-enum.h +++ b/include/dpp/misc-enum.h @@ -47,7 +47,6 @@ enum image_type { /** * @brief Webp. */ - /// WebP i_webp, }; diff --git a/include/dpp/role.h b/include/dpp/role.h index 069ab2f446..44ca4a597e 100644 --- a/include/dpp/role.h +++ b/include/dpp/role.h @@ -30,21 +30,51 @@ namespace dpp { -/** Various flags related to dpp::role */ +/** + * @brief Various flags related to dpp::role + */ enum role_flags : uint8_t { - r_hoist = 0b00000001, //!< Hoisted role (if the role is pinned in the user listing) - r_managed = 0b00000010, //!< Managed role (introduced by a bot or application) - r_mentionable = 0b00000100, //!< Whether this role is mentionable with a ping - r_premium_subscriber = 0b00001000, //!< Whether this is the guild's booster role - r_available_for_purchase = 0b00010000, //!< Whether the role is available for purchase - r_guild_connections = 0b00100000, //!< Whether the role is a guild's linked role - r_in_prompt = 0b01000000, //!< Whether the role can be selected by members in an onboarding prompt + /** + * @brief Hoisted role (if the role is pinned in the user listing). + */ + r_hoist = 0b00000001, + + /** + * @brief Managed role (introduced by a bot or application). + */ + r_managed = 0b00000010, + + /** + * @brief Whether this role is mentionable with a ping. + */ + r_mentionable = 0b00000100, + + /** + * @brief Whether this is the guild's booster role. + */ + r_premium_subscriber = 0b00001000, + + /** + * @brief Whether the role is available for purchase. + */ + r_available_for_purchase = 0b00010000, + + /** + * @brief Whether the role is a guild's linked role. + */ + r_guild_connections = 0b00100000, + + /** + * @brief Whether the role can be selected by members in an onboarding prompt. + */ + r_in_prompt = 0b01000000, }; /** * @brief Represents a role within a dpp::guild. * Roles are combined via logical OR of the permission bitmasks, then channel-specific overrides * can be applied on top, deny types apply a logic NOT to the bit mask, and allows apply a logical OR. + * * @note Every guild has at least one role, called the 'everyone' role, which always has the same role * ID as the guild's ID. This is the base permission set applied to all users where no other role or override * applies, and is the starting value of the bit mask looped through to calculate channel permissions. @@ -75,31 +105,61 @@ class DPP_EXPORT role : public managed, public json_interface { * Between 1 and 100 characters. */ std::string name{}; + /** * @brief Guild ID */ snowflake guild_id{0}; + /** * @brief Role colour. * A colour of 0 means no colour. If you want a black role, * you must use the value 0x000001. */ uint32_t colour{0}; - /** Role position */ + + /** + * @brief Role position. + */ uint8_t position{0}; - /** Role permissions bitmask values from dpp::permissions */ + + /** + * @brief Role permissions bitmask values from dpp::permissions. + */ permission permissions{}; - /** Role flags from dpp::role_flags */ + + /** + * @brief Role flags from dpp::role_flags + */ uint8_t flags{0}; - /** Integration id if any (e.g. role is a bot's role created when it was invited) */ + + /** + * @brief Integration id if any. + * (e.g. role is a bot's role created when it was invited). + */ snowflake integration_id{}; - /** Bot id if any (e.g. role is a bot's role created when it was invited) */ + + /** + * @brief Bot id if any. + * (e.g. role is a bot's role created when it was invited) + */ snowflake bot_id{}; - /** The id of the role's subscription sku and listing */ + + /** + * @brief The id of the role's subscription sku and listing. + */ snowflake subscription_listing_id{}; - /** The unicode emoji used for the role's icon, can be an empty string */ + + /** + * @brief The unicode emoji used for the role's icon. + * + * @note This can be an empty string. + */ std::string unicode_emoji{}; - /** The role icon */ + + /** + * @brief The role icon. + */ utility::icon icon{}; /** @@ -148,7 +208,7 @@ class DPP_EXPORT role : public managed, public json_interface { static std::string get_mention(const snowflake& id); /** - * @brief Set the name of the role + * @brief Set the name of the role. * Maximum length: 100 * Minimum length: 1 * @param n Name to set @@ -158,7 +218,7 @@ class DPP_EXPORT role : public managed, public json_interface { role& set_name(const std::string& n); /** - * @brief Set the colour + * @brief Set the colour. * * @param c Colour to set * @note There is an americanised version of this method, role::set_color(). @@ -167,7 +227,7 @@ class DPP_EXPORT role : public managed, public json_interface { role& set_colour(uint32_t c); /** - * @brief Set the color + * @brief Set the color. * * @param c Colour to set * @note This is an alias of role::set_colour for American spelling. @@ -176,7 +236,7 @@ class DPP_EXPORT role : public managed, public json_interface { role& set_color(uint32_t c); /** - * @brief Set the flags + * @brief Set the flags. * * @param f Flags to set from dpp::role_flags * @return role& reference to self @@ -184,7 +244,7 @@ class DPP_EXPORT role : public managed, public json_interface { role& set_flags(uint8_t f); /** - * @brief Set the integration id + * @brief Set the integration ID. * * @param i Integration ID to set * @return role& reference to self @@ -192,7 +252,7 @@ class DPP_EXPORT role : public managed, public json_interface { role& set_integration_id(snowflake i); /** - * @brief Set the bot id + * @brief Set the bot ID. * * @param b Bot ID to set * @return role& reference to self @@ -200,7 +260,7 @@ class DPP_EXPORT role : public managed, public json_interface { role& set_bot_id(snowflake b); /** - * @brief Set the guild id + * @brief Set the guild ID. * * @param gid Guild ID to set * @return role& reference to self @@ -219,14 +279,14 @@ class DPP_EXPORT role : public managed, public json_interface { role& fill_from_json(snowflake guild_id, nlohmann::json* j); /** - * @brief Get the mention/ping for the role + * @brief Get the mention/ping for the role. * * @return std::string mention */ std::string get_mention() const; /** - * @brief Returns the role's icon url if they have one, otherwise returns an empty string + * @brief Returns the role's icon url if they have one, otherwise returns an empty string. * * @param size The size of the icon in pixels. It can be any power of two between 16 and 4096, * otherwise the default sized icon is returned. @@ -236,7 +296,7 @@ class DPP_EXPORT role : public managed, public json_interface { std::string get_icon_url(uint16_t size = 0, const image_type format = i_png) const; /** - * @brief Load a role icon + * @brief Load a role icon. * * @param image_blob Image binary data * @param type Type of image. It can be one of `i_gif`, `i_jpg` or `i_png`. @@ -245,7 +305,7 @@ class DPP_EXPORT role : public managed, public json_interface { role& load_image(std::string_view image_blob, const image_type type); /** - * @brief Load a role icon + * @brief Load a role icon. * * @param image_blob Image binary data * @param type Type of image. It can be one of `i_gif`, `i_jpg` or `i_png`. @@ -260,8 +320,7 @@ class DPP_EXPORT role : public managed, public json_interface { * @param rhs second role to compare * @return true if lhs is less than rhs */ - friend inline bool operator< (const role& lhs, const role& rhs) - { + friend inline bool operator< (const role& lhs, const role& rhs) { return lhs.position < rhs.position; } @@ -272,8 +331,7 @@ class DPP_EXPORT role : public managed, public json_interface { * @param rhs second role to compare * @return true if lhs is greater than rhs */ - friend inline bool operator> (const role& lhs, const role& rhs) - { + friend inline bool operator> (const role& lhs, const role& rhs) { return lhs.position > rhs.position; } @@ -283,8 +341,7 @@ class DPP_EXPORT role : public managed, public json_interface { * @param other role to compare * @return true if is equal to other */ - inline bool operator== (const role& other) const - { + inline bool operator== (const role& other) const { return this->position == other.position; } @@ -294,358 +351,467 @@ class DPP_EXPORT role : public managed, public json_interface { * @param other role to compare * @return true if is not equal to other */ - inline bool operator!= (const role& other) const - { + inline bool operator!= (const role& other) const { return this->position != other.position; } /** - * @brief True if the role is hoisted + * @brief True if the role is hoisted. + * * @return bool Role appears separated from others in the member list */ bool is_hoisted() const; + /** - * @brief True if the role is mentionable + * @brief True if the role is mentionable. + * * @return bool Role is mentionable */ bool is_mentionable() const; + /** - * @brief True if the role is managed (belongs to a bot or application) + * @brief True if the role is managed (belongs to a bot or application). + * * @return bool True if the role is managed (introduced for a bot or other application by Discord) */ bool is_managed() const; + /** - * @brief True if the role is the guild's Booster role + * @brief True if the role is the guild's Booster role. + * * @return bool whether the role is the premium subscriber, AKA "boost", role for the guild */ bool is_premium_subscriber() const; + /** - * @brief True if the role is available for purchase + * @brief True if the role is available for purchase. + * * @return bool whether this role is available for purchase */ bool is_available_for_purchase() const; + /** - * @brief True if the role is a linked role + * @brief True if the role is a linked role. + * * @return bool True if the role is a linked role */ bool is_linked() const; + /** - * @brief True if the role can be selected by members in an onboarding prompt + * @brief True if the role can be selected by members in an onboarding prompt. + * * @return bool True if the role can be selected by members in an onboarding prompt */ bool is_selectable_in_prompt() const; + /** - * @brief True if has create instant invite permission + * @brief True if has create instant invite permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the instant invite permission or is administrator. */ bool has_create_instant_invite() const; + /** * @brief True if has the kick members permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the kick members permission or is administrator. */ bool has_kick_members() const; + /** * @brief True if has the ban members permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the ban members permission or is administrator. */ bool has_ban_members() const; + /** * @brief True if has the administrator permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the administrator permission or is administrator. */ bool has_administrator() const; + /** * @brief True if has the manage channels permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage channels permission or is administrator. */ bool has_manage_channels() const; + /** * @brief True if has the manage guild permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage guild permission or is administrator. */ bool has_manage_guild() const; + /** * @brief True if has the add reactions permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the add reactions permission or is administrator. */ bool has_add_reactions() const; + /** * @brief True if has the view audit log permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the view audit log permission or is administrator. */ bool has_view_audit_log() const; + /** * @brief True if has the priority speaker permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the priority speaker permission or is administrator. */ bool has_priority_speaker() const; + /** * @brief True if has the stream permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the stream permission or is administrator. */ bool has_stream() const; + /** * @brief True if has the view channel permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the view channel permission or is administrator. */ bool has_view_channel() const; + /** * @brief True if has the send messages permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the send messages permission or is administrator. */ bool has_send_messages() const; + /** * @brief True if has the send TTS messages permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the send TTS messages permission or is administrator. */ bool has_send_tts_messages() const; + /** * @brief True if has the manage messages permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage messages permission or is administrator. */ bool has_manage_messages() const; + /** * @brief True if has the embed links permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the embed links permission or is administrator. */ bool has_embed_links() const; + /** * @brief True if has the attach files permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the attach files permission or is administrator. */ bool has_attach_files() const; + /** * @brief True if has the read message history permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the read message history permission or is administrator. */ bool has_read_message_history() const; + /** * @brief True if has the mention \@everyone and \@here permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the mention \@everyone and \@here permission or is administrator. */ bool has_mention_everyone() const; + /** * @brief True if has the use external emojis permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the use external emojis permission or is administrator. */ bool has_use_external_emojis() const; + /** * @brief True if has the view guild insights permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the view guild insights permission or is administrator. */ bool has_view_guild_insights() const; + /** * @brief True if has the connect voice permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the connect voice permission or is administrator. */ bool has_connect() const; + /** * @brief True if has the speak permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the speak permission or is administrator. */ bool has_speak() const; + /** * @brief True if has the mute members permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the mute members permission or is administrator. */ bool has_mute_members() const; + /** * @brief True if has the deafen members permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the deafen members permission or is administrator. */ bool has_deafen_members() const; + /** * @brief True if has the move members permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the move members permission or is administrator. */ bool has_move_members() const; - /** True if has use voice activity detection permission */ + + /** + * @brief True if has use voice activity detection permission + * + * @note Having the administrator permission causes this method to always return true + * Channel specific overrides may apply to permissions. + * @return bool True if user has use voice activity detection permission or is administrator. + */ bool has_use_vad() const; + /** * @brief True if has the change nickname permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the change nickname permission or is administrator. */ bool has_change_nickname() const; + /** * @brief True if has the manage nicknames permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage nicknames permission or is administrator. */ bool has_manage_nicknames() const; + /** * @brief True if has the manage roles permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage roles permission or is administrator. */ bool has_manage_roles() const; + /** * @brief True if has the manage webhooks permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage webhooks permission or is administrator. */ bool has_manage_webhooks() const; + /** * @brief True if has the manage emojis and stickers permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage emojis and stickers permission or is administrator. */ bool has_manage_emojis_and_stickers() const; + /** * @brief True if has the use application commands permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the use application commands permission or is administrator. */ bool has_use_application_commands() const; + /** * @brief True if has the request to speak permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the request to speak permission or is administrator. */ bool has_request_to_speak() const; + /** * @brief True if has the manage threads permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage threads permission or is administrator. */ bool has_manage_threads() const; + /** * @brief True if has the create public threads permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the create public threads permission or is administrator. */ bool has_create_public_threads() const; + /** * @brief True if has the create private threads permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the create private threads permission or is administrator. */ bool has_create_private_threads() const; + /** * @brief True if has the use external stickers permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the use external stickers permission or is administrator. */ + bool has_use_external_stickers() const; /** * @brief True if has the send messages in threads permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the send messages in threads permission or is administrator. */ bool has_send_messages_in_threads() const; + /** * @brief True if has the start embedded activities permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the start embedded activities permission or is administrator. */ bool has_use_embedded_activities() const; + /** * @brief True if has the manage events permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the manage events permission or is administrator. */ bool has_manage_events() const; + /** * @brief True if has the moderate users permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the moderate users permission or is administrator. */ bool has_moderate_members() const; + /** * @brief True if has the view creator monetization analytics permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the view creator monetization analytics permission or is administrator. */ bool has_view_creator_monetization_analytics() const; + /** * @brief True if has the use soundboard permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the use soundboard permission or is administrator. */ bool has_use_soundboard() const; + /** * @brief True if has the use external sounds permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the use external sounds permission or is administrator. */ bool has_use_external_sounds() const; + /** * @brief True if has the send voice messages permission. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the send voice messages permission or is administrator. */ bool has_send_voice_messages() const; + /** * @brief True if has permission to use clyde AI. + * * @note Having the administrator permission causes this method to always return true * Channel specific overrides may apply to permissions. * @return bool True if user has the clyde AI permission or is administrator. @@ -653,7 +819,8 @@ class DPP_EXPORT role : public managed, public json_interface { bool has_use_clyde_ai() const; /** - * @brief Get guild members who have this role + * @brief Get guild members who have this role. + * * @note This method requires user/members cache to be active * @return members_container List of members who have this role */ @@ -663,17 +830,51 @@ class DPP_EXPORT role : public managed, public json_interface { /** * @brief Application Role Connection Metadata Type * - * @note Each metadata type offers a comparison operation that allows guilds to configure role requirements based on metadata values stored by the bot. Bots specify a `metadata value` for each user and guilds specify the required `guild's configured value` within the guild role settings. + * @note Each metadata type offers a comparison operation that allows guilds + * to configure role requirements based on metadata values stored by the bot. + * Bots specify a `metadata value` for each user and guilds specify the + * required `guild's configured value` within the guild role settings. */ enum application_role_connection_metadata_type : uint8_t { - rc_integer_less_than_or_equal = 1, //!< The metadata value (integer) is less than or equal to the guild's configured value (integer) - rc_integer_greater_than_or_equal = 2, //!< The metadata value (integer) is greater than or equal to the guild's configured value (integer) - rc_integer_equal = 3, //!< The metadata value (integer) is equal to the guild's configured value (integer) - rc_integer_not_equal = 4, //!< The metadata value (integer) is not equal to the guild's configured value (integer) - rc_datetime_less_than_or_equal = 5, //!< The metadata value (ISO8601 string) is less than or equal to the guild's configured value (integer; days before current date) - rc_datetime_greater_than_or_equal = 6, //!< The metadata value (ISO8601 string) is greater than or equal to the guild's configured value (integer; days before current date) - rc_boolean_equal = 7, //!< The metadata value (integer) is equal to the guild's configured value (integer; 1) - rc_boolean_not_equal = 8, //!< The metadata value (integer) is not equal to the guild's configured value (integer; 1) + /** + * @brief The metadata value (integer) is less than or equal to the guild's configured value (integer). + */ + rc_integer_less_than_or_equal = 1, + + /** + * @brief The metadata value (integer) is greater than or equal to the guild's configured value (integer). + */ + rc_integer_greater_than_or_equal = 2, + + /** + * @brief The metadata value (integer) is equal to the guild's configured value (integer). + */ + rc_integer_equal = 3, + + /** + * @brief The metadata value (integer) is not equal to the guild's configured value (integer). + */ + rc_integer_not_equal = 4, + + /** + * @brief The metadata value (ISO8601 string) is less than or equal to the guild's configured value (integer; days before current date). + */ + rc_datetime_less_than_or_equal = 5, + + /** + * @brief The metadata value (ISO8601 string) is greater than or equal to the guild's configured value (integer; days before current date). + */ + rc_datetime_greater_than_or_equal = 6, + + /** + * @brief The metadata value (integer) is equal to the guild's configured value (integer; 1). + */ + rc_boolean_equal = 7, + + /** + * @brief The metadata value (integer) is not equal to the guild's configured value (integer; 1). + */ + rc_boolean_not_equal = 8, }; /** @@ -698,15 +899,38 @@ class DPP_EXPORT application_role_connection_metadata : public json_interface name_localizations; //!< Translations of the name - std::string description; //!< Description of the metadata field (1-200 characters) - std::map description_localizations; //!< Translations of the description + /** + * @brief Type of metadata value. + */ + application_role_connection_metadata_type type; + + /** + * @brief Dictionary key for the metadata field (must be `a-z`, `0-9`, or `_` characters; 1-50 characters). + */ + std::string key; /** - * Constructor + * @brief Name of the metadata field (1-100 characters). + */ + std::string name; + + /** + * @brief Translations of the name. + */ + std::map name_localizations; + + /** + * @brief Description of the metadata field (1-200 characters). + */ + std::string description; + + /** + * @brief Translations of the description. + */ + std::map description_localizations; + + /** + * @brief Constructor */ application_role_connection_metadata(); @@ -720,7 +944,8 @@ class DPP_EXPORT application_role_connection : public json_interface; - /** Fill this record from json. + /** + * @brief Fill this record from json. * @param j The json to fill this record from * @return Reference to self */ @@ -735,22 +960,37 @@ class DPP_EXPORT application_role_connection : public json_interface metadata; //!< Optional: Object mapping application role connection metadata keys to their stringified value (max 100 characters) for the user on the platform a bot has connected + /** + * @brief Optional: The vanity name of the platform a bot has connected (max 50 characters). + */ + std::string platform_name; /** - * Constructor + * @brief Optional: The username on the platform a bot has connected (max 100 characters). + */ + std::string platform_username; + + /** + * @brief Optional: Object mapping application role connection metadata keys to their "stringified" value (max 100 characters) for the user on the platform a bot has connected. + */ + std::variant metadata; + + /** + * @brief Constructor */ application_role_connection(); virtual ~application_role_connection() = default; }; -/** A group of roles */ +/** + * @brief A group of roles. + */ typedef std::unordered_map role_map; -/** A group of application_role_connection_metadata objects */ +/** + * @brief A group of dpp::application_role_connection_metadata objects. + */ typedef std::vector application_role_connection_metadata_list; } // namespace dpp diff --git a/include/dpp/scheduled_event.h b/include/dpp/scheduled_event.h index c8e8565cbd..b0617719e1 100644 --- a/include/dpp/scheduled_event.h +++ b/include/dpp/scheduled_event.h @@ -31,69 +31,94 @@ namespace dpp { /** - * @brief Represents the privacy of an event + * @brief Represents the privacy of an event. */ enum event_privacy_level : uint8_t { - /// The event is visible to only guild members. + /** + * @brief The event is visible to only guild members. + */ ep_guild_only = 2 }; /** - * @brief Event entity types + * @brief Event entity types. */ enum event_entity_type : uint8_t { - /// A stage instance + /** + * @brief A stage instance. + */ eet_stage_instance = 1, - /// A voice channel + + /** + * @brief A voice channel. + */ eet_voice = 2, - /// External to discord, or a text channel etc + + /** + * @brief External to discord, or a text channel etc. + */ eet_external = 3 }; /** - * @brief Event status types + * @brief Event status types. */ enum event_status : uint8_t { - /// Scheduled - es_scheduled = 1, - /// Active now - es_active = 2, - /// Completed - es_completed = 3, - /// Cancelled - es_cancelled = 4 + /** + * @brief Scheduled. + */ + es_scheduled = 1, + + /** + * @brief Active now. + */ + es_active = 2, + + /** + * @brief Completed. + */ + es_completed = 3, + + /** + * @brief Cancelled. + */ + es_cancelled = 4 }; /** - * @brief Entities for the event + * @brief Entities for the event. */ struct DPP_EXPORT event_entities { - /// location of the event + /** + * @brief Location of the event. + */ std::string location; }; /** - * @brief Represents a guild member/user who has registered interest in an event + * @brief Represents a guild member/user who has registered interest in an event. * */ struct DPP_EXPORT event_member { /** - * @brief Event ID associated with + * @brief Event ID associated with. */ snowflake guild_scheduled_event_id; + /** - * @brief User details of associated user + * @brief User details of associated user. * */ dpp::user user; + /** - * @brief Member details of user on the associated guild + * @brief Member details of user on the associated guild. */ dpp::guild_member member; }; /** - * @brief A scheduled event + * @brief A scheduled event. */ struct DPP_EXPORT scheduled_event : public managed, public json_interface { protected: @@ -115,29 +140,100 @@ struct DPP_EXPORT scheduled_event : public managed, public json_interface scheduled_event_map; /** - * @brief A group of scheduled event members + * @brief A group of scheduled event members. */ typedef std::unordered_map event_member_map; diff --git a/include/dpp/sku.h b/include/dpp/sku.h index 80db89ff2e..a163dde489 100644 --- a/include/dpp/sku.h +++ b/include/dpp/sku.h @@ -91,7 +91,7 @@ class DPP_EXPORT sku : public managed, public json_interface { /** * @brief The type of SKU. */ - sku_type type = sku_type::SUBSCRIPTION; + sku_type type{sku_type::SUBSCRIPTION}; /** * @brief ID of the parent application diff --git a/include/dpp/stage_instance.h b/include/dpp/stage_instance.h index a39cefc9d0..6b0d2719a0 100644 --- a/include/dpp/stage_instance.h +++ b/include/dpp/stage_instance.h @@ -33,9 +33,14 @@ namespace dpp { * @brief Represents the privacy of a stage instance */ enum stage_privacy_level : uint8_t { - /// The Stage instance is visible publicly, such as on Stage Discovery. + /** + * @brief The Stage instance is visible publicly, such as on Stage Discovery. + */ sp_public = 1, - /// The Stage instance is visible to only guild members. + + /** + * @brief The Stage instance is visible to only guild members. + */ sp_guild_only = 2 }; @@ -63,15 +68,29 @@ struct DPP_EXPORT stage_instance : public managed, public json_interface stage_instance_map; } // namespace dpp diff --git a/include/dpp/timed_listener.h b/include/dpp/timed_listener.h index d9031847a5..c5d7d0229b 100644 --- a/include/dpp/timed_listener.h +++ b/include/dpp/timed_listener.h @@ -40,20 +40,30 @@ namespace dpp { template class timed_listener { private: - /// Owning cluster + /** + * @brief Owning cluster. + */ cluster* owner; - /// Duration of listen + /** + * @brief Duration of listen. + */ time_t duration; - /// Reference to attached event in cluster + /** + * @brief Reference to attached event in cluster. + */ //event_router_t on_thread_member_update; attached_event& ev; - /// Timer handle + /** + * @brief Timer handle. + */ timer th; - /// Event handle + /** + * @brief Event handle. + */ event_handle listener_handle; public: diff --git a/include/dpp/timer.h b/include/dpp/timer.h index bfcbf990c6..e3e10943d1 100644 --- a/include/dpp/timer.h +++ b/include/dpp/timer.h @@ -51,18 +51,22 @@ struct DPP_EXPORT timer_t { * @brief Timer handle */ timer handle; + /** * @brief Next timer tick as unix epoch */ time_t next_tick; + /** * @brief Frequency between ticks */ uint64_t frequency; + /** * @brief Lambda to call on tick */ timer_callback_t on_tick; + /** * @brief Lambda to call on stop (optional) */ @@ -87,9 +91,14 @@ typedef std::unordered_map timer_reg_t; class DPP_EXPORT oneshot_timer { private: - /// Owning cluster + /** + * @brief Owning cluster. + */ class cluster* owner; - /// Timer handle + + /** + * @brief Timer handle. + */ timer th; public: /** @@ -120,6 +129,4 @@ class DPP_EXPORT oneshot_timer ~oneshot_timer(); }; - - } // namespace dpp diff --git a/include/dpp/unicode_emoji.h b/include/dpp/unicode_emoji.h index 1fe77f1d0b..2a0e556706 100644 --- a/include/dpp/unicode_emoji.h +++ b/include/dpp/unicode_emoji.h @@ -3,9 +3,11 @@ namespace dpp { /** - * The unicode emojis in this namespace are auto-generated from https://raw.githubusercontent.com/ArkinSolomon/discord-emoji-converter/master/emojis.json + * @brief Emoji unicodes. * - * If you want to use this, you have to pull the header in separately. e.g. + * @note The unicode emojis in this namespace are auto-generated from https://raw.githubusercontent.com/ArkinSolomon/discord-emoji-converter/master/emojis.json + * + * @warning If you want to use this, you have to pull the header in separately. For example: * ```cpp * #include * #include diff --git a/include/dpp/user.h b/include/dpp/user.h index 8c5ae38530..060273b6da 100644 --- a/include/dpp/user.h +++ b/include/dpp/user.h @@ -32,53 +32,126 @@ namespace dpp { * @brief Various bitmask flags used to represent information about a dpp::user */ enum user_flags : uint32_t { - /// User is a bot - u_bot = 0b00000000000000000000000000000001, - /// User is a system user (Clyde!) - u_system = 0b00000000000000000000000000000010, - /// User has multi-factor authentication enabled - u_mfa_enabled = 0b00000000000000000000000000000100, - /// User is verified (verified email address) - u_verified = 0b00000000000000000000000000001000, - /// User has full nitro - u_nitro_full = 0b00000000000000000000000000010000, - /// User has nitro classic - u_nitro_classic = 0b00000000000000000000000000100000, - /// User is discord staff - u_discord_employee = 0b00000000000000000000000001000000, - /// User owns a partnered server - u_partnered_owner = 0b00000000000000000000000010000000, - /// User is a member of hypesquad events - u_hypesquad_events = 0b00000000000000000000000100000000, - /// User has BugHunter level 1 - u_bughunter_1 = 0b00000000000000000000001000000000, - /// User is a member of House Bravery - u_house_bravery = 0b00000000000000000000010000000000, - /// User is a member of House Brilliance - u_house_brilliance = 0b00000000000000000000100000000000, - /// User is a member of House Balance - u_house_balance = 0b00000000000000000001000000000000, - /// User is an early supporter - u_early_supporter = 0b00000000000000000010000000000000, - /// User is a team user - u_team_user = 0b00000000000000000100000000000000, - /// User is has Bug Hunter level 2 - u_bughunter_2 = 0b00000000000000001000000000000000, - /// User is a verified bot - u_verified_bot = 0b00000000000000010000000000000000, - /// User has the Early Verified Bot Developer badge - u_verified_bot_dev = 0b00000000000000100000000000000000, - /// User's icon is animated - u_animated_icon = 0b00000000000001000000000000000000, - /// User is a certified moderator - u_certified_moderator = 0b00000000000010000000000000000000, - /// User is a bot using HTTP interactions (shows online even when not connected to a websocket) - u_bot_http_interactions = 0b00000000000100000000000000000000, - /// User has nitro basic - u_nitro_basic = 0b00000000001000000000000000000000, - /// User has the active developer badge - u_active_developer = 0b00000000010000000000000000000000, - /// User's banner is animated + /** + * @brief User is a bot. + */ + u_bot = 0b00000000000000000000000000000001, + + /** + * @brief User is a system user (Clyde!). + */ + u_system = 0b00000000000000000000000000000010, + + /** + * @brief User has multi-factor authentication enabled. + */ + u_mfa_enabled = 0b00000000000000000000000000000100, + + /** + * @brief User is verified (verified email address). + */ + u_verified = 0b00000000000000000000000000001000, + + /** + * @brief User has full nitro. + */ + u_nitro_full = 0b00000000000000000000000000010000, + + /** + * @brief User has nitro classic. + */ + u_nitro_classic = 0b00000000000000000000000000100000, + + /** + * @brief User is discord staff. + */ + u_discord_employee = 0b00000000000000000000000001000000, + + /** + * @brief User owns a partnered server. + */ + u_partnered_owner = 0b00000000000000000000000010000000, + + /** + * @brief User is a member of hypesquad events. + */ + u_hypesquad_events = 0b00000000000000000000000100000000, + + /** + * @brief User has BugHunter level 1. + */ + u_bughunter_1 = 0b00000000000000000000001000000000, + + /** + * @brief User is a member of House Bravery. + */ + u_house_bravery = 0b00000000000000000000010000000000, + + /** + * @brief User is a member of House Brilliance. + */ + u_house_brilliance = 0b00000000000000000000100000000000, + + /** + * @brief User is a member of House Balance. + */ + u_house_balance = 0b00000000000000000001000000000000, + + /** + * @brief User is an early supporter. + */ + u_early_supporter = 0b00000000000000000010000000000000, + + /** + * @brief User is a team user. + */ + u_team_user = 0b00000000000000000100000000000000, + + /** + * @brief User is has Bug Hunter level 2. + */ + u_bughunter_2 = 0b00000000000000001000000000000000, + + /** + * @brief User is a verified bot. + */ + u_verified_bot = 0b00000000000000010000000000000000, + + /** + * @brief User has the Early Verified Bot Developer badge. + */ + u_verified_bot_dev = 0b00000000000000100000000000000000, + + /** + * @brief User's icon is animated. + */ + u_animated_icon = 0b00000000000001000000000000000000, + + /** + * @brief User is a certified moderator. + */ + u_certified_moderator = 0b00000000000010000000000000000000, + + /** + * @brief User is a bot using HTTP interactions. + * + * @note shows online even when not connected to a websocket. + */ + u_bot_http_interactions = 0b00000000000100000000000000000000, + + /** + * @brief User has nitro basic. + */ + u_nitro_basic = 0b00000000001000000000000000000000, + + /** + * @brief User has the active developer badge. + */ + u_active_developer = 0b00000000010000000000000000000000, + + /** + * @brief User's banner is animated. + */ u_animated_banner = 0b00000000100000000000000000000000, }; @@ -104,23 +177,42 @@ class DPP_EXPORT user : public managed, public json_interface { virtual json to_json_impl(bool with_id = true) const; public: - /** Discord username */ + /** + * @brief Discord username. + */ std::string username; - /** Global display name */ + + /** + * @brief Global display name. + */ std::string global_name; - /** Avatar hash */ + + /** + * @brief Avatar hash. + */ utility::iconhash avatar; - /** Avatar decoration hash */ + + /** + * @brief Avatar decoration hash. + */ utility::iconhash avatar_decoration; - /** Flags built from a bitmask of values in dpp::user_flags */ + + /** + * @brief Flags built from a bitmask of values in dpp::user_flags. + */ uint32_t flags; - /** Discriminator (aka tag), 4 digits usually displayed with leading zeroes. + + /** + * @brief Discriminator (aka tag), 4 digits usually displayed with leading zeroes. * * @note To print the discriminator with leading zeroes, use format_username(). * 0 for users that have migrated to the new username format. */ uint16_t discriminator; - /** Reference count of how many guilds this user is in */ + + /** + * @brief Reference count of how many guilds this user is in. + */ uint8_t refcount; /** @@ -134,10 +226,10 @@ class DPP_EXPORT user : public managed, public json_interface { virtual ~user() = default; /** - * @brief Create a mentionable user. + * @brief Create a mentionable user. * @param id The ID of the user. * @return std::string The formatted mention of the user. - */ + */ static std::string get_mention(const snowflake& id); /** @@ -191,30 +283,35 @@ class DPP_EXPORT user : public managed, public json_interface { * @return true if has active developer */ bool is_active_developer() const; + /** * @brief User is a bot * * @return True if the user is a bot */ bool is_bot() const; + /** * @brief User is a system user (Clyde) * * @return true if user is a system user */ bool is_system() const; + /** * @brief User has multi-factor authentication enabled * * @return true if multi-factor is enabled */ bool is_mfa_enabled() const; + /** * @brief Return true if user has verified account * * @return true if verified */ bool is_verified() const; + /** * @brief Return true if user has full nitro. * This is mutually exclusive with full nitro. @@ -222,6 +319,7 @@ class DPP_EXPORT user : public managed, public json_interface { * @return true if user has full nitro */ bool has_nitro_full() const; + /** * @brief Return true if user has nitro classic. * This is mutually exclusive with nitro classic. @@ -229,6 +327,7 @@ class DPP_EXPORT user : public managed, public json_interface { * @return true if user has nitro classic */ bool has_nitro_classic() const; + /** * @brief Return true if user has nitro basic. * This is mutually exclusive with nitro basic. @@ -236,84 +335,98 @@ class DPP_EXPORT user : public managed, public json_interface { * @return true if user has nitro basic */ bool has_nitro_basic() const; + /** * @brief Return true if user is a discord employee * * @return true if user is discord staff */ bool is_discord_employee() const; + /** * @brief Return true if user owns a partnered server * * @return true if user has partnered server */ bool is_partnered_owner() const; + /** * @brief Return true if user has hypesquad events * * @return true if has hypesquad events */ bool has_hypesquad_events() const; + /** * @brief Return true if user has the bughunter level 1 badge * * @return true if has bughunter level 1 */ bool is_bughunter_1() const; + /** * @brief Return true if user is in house bravery * * @return true if in house bravery */ bool is_house_bravery() const; + /** * @brief Return true if user is in house brilliance * * @return true if in house brilliance */ bool is_house_brilliance() const; + /** * @brief Return true if user is in house balance * * @return true if in house brilliance */ bool is_house_balance() const; + /** * @brief Return true if user is an early supporter * * @return true if early supporter */ bool is_early_supporter() const; + /** * @brief Return true if user is a team user * * @return true if a team user */ bool is_team_user() const; + /** * @brief Return true if user has the bughunter level 2 badge * * @return true if has bughunter level 2 */ bool is_bughunter_2() const; + /** * @brief Return true if user has the verified bot badge * * @return true if verified bot */ bool is_verified_bot() const; + /** * @brief Return true if user is an early verified bot developer * * @return true if verified bot developer */ bool is_verified_bot_dev() const; + /** * @brief Return true if user is a certified moderator * * @return true if certified moderator */ bool is_certified_moderator() const; + /** * @brief Return true if user is a bot which exclusively uses HTTP interactions. * Bots using HTTP interactions are always considered online even when not connected to a websocket. @@ -321,6 +434,7 @@ class DPP_EXPORT user : public managed, public json_interface { * @return true if is a http interactions only bot */ bool is_bot_http_interactions() const; + /** * @brief Return true if user has an animated icon * @@ -332,6 +446,9 @@ class DPP_EXPORT user : public managed, public json_interface { * @brief Format a username into user\#discriminator * * For example Brain#0001 + * + * @note This will, most often, return something like Brain#0000 due to discriminators slowly being removed. + * Some accounts, along with most bots, still have discriminators, so they will still show as Bot#1234. * * @return Formatted username and discriminator */ @@ -362,11 +479,37 @@ class DPP_EXPORT user_identified : public user, public json_interface user_map; } // namespace dpp diff --git a/include/dpp/utility.h b/include/dpp/utility.h index aec94a32e3..55ec9e83b5 100644 --- a/include/dpp/utility.h +++ b/include/dpp/utility.h @@ -40,7 +40,9 @@ namespace dpp { enum sticker_format : uint8_t; -/** @brief Macro that expands to static_asserts checking sizeof and alignof are equal between two types */ +/** + * @brief Macro that expands to static_asserts checking sizeof and alignof are equal between two types. + */ #define DPP_CHECK_ABI_COMPAT(a, b) \ static_assert(sizeof(a) == sizeof(b), #a " and " #b " must be the same size for ABI compatibility"); \ static_assert(alignof(a) == alignof(b), #a " and " #b " must be the same alignment for ABI compatibility"); \ @@ -51,7 +53,9 @@ static_assert(alignof(a) == alignof(b), #a " and " #b " must be the same alignme namespace utility { /** - * For internal use only. Helper function to easily create discord's cdn endpoint urls + * @brief Helper function to easily create discord's cdn endpoint urls. + * @warning **For internal use only!** + * * @see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints * @param allowed_formats A vector of supported formats for the endpoint from the discord docs * @param path_without_extension The path for the endpoint (without the extension e.g. `.png`) @@ -66,7 +70,9 @@ namespace utility { std::string DPP_EXPORT cdn_endpoint_url(const std::vector &allowed_formats, const std::string &path_without_extension, const dpp::image_type format, uint16_t size, bool prefer_animated = false, bool is_animated = false); /** - * For internal use only. Helper function to easily create discord's cdn endpoint urls + * @brief Helper function to easily create discord's cdn endpoint urls. + * @warning **For internal use only!** + * * @see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints * @param allowed_formats A vector of supported formats for the endpoint from the discord docs * @param path_without_extension The path for the endpoint (without the extension e.g. `.png`) @@ -82,7 +88,9 @@ std::string DPP_EXPORT cdn_endpoint_url(const std::vector &allowed_f std::string DPP_EXPORT cdn_endpoint_url_hash(const std::vector &allowed_formats, const std::string &path_without_extension, const std::string &hash, const dpp::image_type format, uint16_t size, bool prefer_animated = false, bool is_animated = false); /** - * For internal use only. Helper function to easily create discord's cdn endpoint urls (specialised for stickers) + * @brief Helper function to easily create discord's cdn endpoint urls (specialised for stickers) + * @warning **For internal use only!** + * * @see https://discord.com/developers/docs/reference#image-formatting-cdn-endpoints * @param sticker_id The sticker ID. Returns empty string if 0 * @param format The format type @@ -98,14 +106,17 @@ enum avx_type_t : uint8_t { * @brief No AVX Support */ avx_none, + /** * @brief AVX support */ avx_1, + /** * @brief AVX2 support */ avx_2, + /** * @brief AVX512 support */ @@ -120,31 +131,59 @@ enum avx_type_t : uint8_t { * They have been sorted into numerical order of their ASCII value to keep C++ happy. */ enum time_format : uint8_t { - /// "20 April 2021" - Long Date - tf_long_date = 'D', - /// "Tuesday, 20 April 2021 16:20" - Long Date/Time - tf_long_datetime = 'F', - /// "2 months ago" - Relative Time - tf_relative_time = 'R', - /// "16:20:30" - Long Time - tf_long_time = 'T', - /// "20/04/2021" - Short Date - tf_short_date = 'd', - /// "20 April 2021 16:20" - Short Date/Time - tf_short_datetime = 'f', - /// "16:20" - Short Time - tf_short_time = 't', + /** + * @brief "20 April 2021" - Long Date + */ + tf_long_date = 'D', + + /** + * @brief "Tuesday, 20 April 2021 16:20" - Long Date/Time + */ + tf_long_datetime = 'F', + + /** + * @brief "2 months ago" - Relative Time + */ + tf_relative_time = 'R', + + /** + * @brief "16:20:30" - Long Time + */ + tf_long_time = 'T', + + /** + * @brief "20/04/2021" - Short Date + */ + tf_short_date = 'd', + + /** + * @brief "20 April 2021 16:20" - Short Date/Time + */ + tf_short_datetime = 'f', + + /** + * @brief "16:20" - Short Time + */ + tf_short_time = 't', }; /** * @brief Guild navigation types for dpp::utility::guild_navigation() */ enum guild_navigation_type { - /// _Customize_ tab with the server's dpp::onboarding_prompt + /** + * @brief _Customize_ tab with the server's dpp::onboarding_prompt + */ gnt_customize, - /// _Browse Channels_ tab + + /** + * @brief "16:20" _Browse Channels_ tab + */ gnt_browse, - /// Server Guide + + /** + * @brief Server Guide + */ gnt_guide, }; @@ -166,8 +205,8 @@ typedef std::function cmd_result_t; /** * @brief Run a commandline program asynchronously. The command line program * is spawned in a separate std::thread, and when complete, its output from - * stdout is passed to the callback function in its string parameter. For example - * ``` + * stdout is passed to the callback function in its string parameter. For example: + * ```cpp * dpp::utility::exec("/bin/ls", {"-al"}, [](const std::string& output) { * std::cout << "Output of 'ls -al': " << output << "\n"; * }); @@ -218,9 +257,14 @@ std::string DPP_EXPORT loglevel(dpp::loglevel in); * the value back in string form. */ struct DPP_EXPORT iconhash { - /** @brief High 64 bits */ + /** + * @brief High 64 bits. + */ uint64_t first; - /** @brief Low 64 bits */ + + /** + * @brief Low 64 bits. + */ uint64_t second; /** @@ -562,10 +606,25 @@ std::string DPP_EXPORT bytes(uint64_t c); * and display as a string. */ struct DPP_EXPORT uptime { - uint16_t days; //!< Number of days - uint8_t hours; //!< Number of hours - uint8_t mins; //!< Number of minutes - uint8_t secs; //!< Number of seconds + /** + * @brief Number of days. + */ + uint16_t days; + + /** + * @brief Number of hours. + */ + uint8_t hours; + + /** + * @brief Number of minutes. + */ + uint8_t mins; + + /** + * @brief Number of seconds. + */ + uint8_t secs; /** * @brief Construct a new uptime object diff --git a/include/dpp/voiceregion.h b/include/dpp/voiceregion.h index 5bec303671..15d9306294 100644 --- a/include/dpp/voiceregion.h +++ b/include/dpp/voiceregion.h @@ -31,10 +31,20 @@ namespace dpp { * @brief Flags related to a voice region */ enum voiceregion_flags { - v_optimal = 0x00000001, - v_deprecated = 0x00000010, - v_custom = 0x00000100, - v_vip = 0x00001000 + /** + * @brief The closest (optimal) voice region. + */ + v_optimal = 0x00000001, + + /** + * @brief A Deprecated voice region (avoid switching to these). + */ + v_deprecated = 0x00000010, + + /** + * @brief A custom voice region (used for events/etc). + */ + v_custom = 0x00000100 }; /** @@ -106,13 +116,6 @@ class DPP_EXPORT voiceregion : public json_interface { * @return true if custom */ bool is_custom() const; - - /** - * @brief True if is a VIP voice server - * - * @return true if VIP - */ - bool is_vip() const; }; /** diff --git a/include/dpp/voicestate.h b/include/dpp/voicestate.h index 29fb61d570..b5f9b55bcf 100644 --- a/include/dpp/voicestate.h +++ b/include/dpp/voicestate.h @@ -32,13 +32,40 @@ namespace dpp { * @brief Bit mask flags relating to voice states */ enum voicestate_flags { - vs_deaf = 0b00000001, //!< Deafened by the server - vs_mute = 0b00000010, //!< Muted by the server - vs_self_mute = 0b00000100, //!< Locally Muted - vs_self_deaf = 0b00001000, //!< Locally deafened - vs_self_stream = 0b00010000, //!< Whether this user is streaming using "Go Live" - vs_self_video = 0b00100000, //!< Whether this user's camera is enabled - vs_suppress = 0b01000000 //!< Whether this user's permission to speak is denied + /** + * @brief Deafened by the server. + */ + vs_deaf = 0b00000001, + + /** + * @brief Muted by the server. + */ + vs_mute = 0b00000010, + + /** + * @brief Locally Muted. + */ + vs_self_mute = 0b00000100, + + /** + * @brief Locally deafened. + */ + vs_self_deaf = 0b00001000, + + /** + * @brief Whether this user is streaming using "Go Live". + */ + vs_self_stream = 0b00010000, + + /** + * @brief Whether this user's camera is enabled. + */ + vs_self_video = 0b00100000, + + /** + * @brief Whether this user's permission to speak is denied. + */ + vs_suppress = 0b01000000 }; /** @@ -59,13 +86,44 @@ class DPP_EXPORT voicestate : public json_interface { voicestate& fill_from_json_impl(nlohmann::json* j); public: - class discord_client* shard; //!< Owning shard - snowflake guild_id; //!< Optional: the guild id this voice state is for - snowflake channel_id; //!< the channel id this user is connected to (may be empty) - snowflake user_id; //!< the user id this voice state is for - std::string session_id; //!< the session id for this voice state - uint8_t flags; //!< Voice state flags (see dpp::voicestate_flags) - time_t request_to_speak; //!< The time at which the user requested to speak, or 0 + /** + * @brief Owning shard. + */ + class discord_client* shard; + + /** + * @brief Optional: The guild id this voice state is for. + */ + snowflake guild_id{0}; + + /** + * @brief The channel id this user is connected to. + * + * @note This may be empty. + */ + snowflake channel_id{0}; + + /** + * @brief The user id this voice state is for. + */ + snowflake user_id{0}; + + /** + * @brief The session id for this voice state. + */ + std::string session_id; + + /** + * @brief Voice state flags from dpp::voicestate_flags. + */ + uint8_t flags{0}; + + /** + * @brief The time at which the user requested to speak. + * + * @note If the user never requested to speak, this is 0. + */ + time_t request_to_speak{0}; /** * @brief Construct a new voicestate object @@ -77,26 +135,41 @@ class DPP_EXPORT voicestate : public json_interface { */ virtual ~voicestate() = default; - /// Return true if the user is deafened by the server + /** + * @brief Return true if the user is deafened by the server. + */ bool is_deaf() const; - /// Return true if the user is muted by the server + /** + * @brief Return true if the user is muted by the server. + */ bool is_mute() const; - /// Return true if user muted themselves + /** + * @brief Return true if user muted themselves. + */ bool is_self_mute() const; - /// Return true if user deafened themselves + /** + * @brief Return true if user deafened themselves. + */ bool is_self_deaf() const; - /// Return true if the user is streaming using "Go Live" + /** + * @brief Return true if the user is streaming using "Go Live". + */ bool self_stream() const; - /// Return true if the user's camera is enabled + /** + * @brief Return true if the user's camera is enabled. + */ bool self_video() const; - /// Return true if user is suppressed. - /// "HELP HELP I'M BEING SUPPRESSED!" + /** + * @brief Return true if user is suppressed. + * + * "HELP HELP I'M BEING SUPPRESSED!" + */ bool is_suppressed() const; }; diff --git a/include/dpp/webhook.h b/include/dpp/webhook.h index 0593a9fcb4..304565c26b 100644 --- a/include/dpp/webhook.h +++ b/include/dpp/webhook.h @@ -37,9 +37,20 @@ namespace dpp { * @brief Defines types of webhook */ enum webhook_type { - w_incoming = 1, //!< Incoming webhook - w_channel_follower = 2, //!< Channel following webhook - w_application = 3 //!< Application webhooks for interactions. + /** + * @brief Incoming webhook. + */ + w_incoming = 1, + + /** + * @brief Channel following webhook. + */ + w_channel_follower = 2, + + /** + * @brief Application webhooks for interactions. + */ + w_application = 3 }; /** @@ -73,18 +84,21 @@ class DPP_EXPORT webhook : public managed, public json_interface { /** * @brief The guild id this webhook is for. + * * @note This field is optional, and may also be empty. */ snowflake guild_id; /** * @brief The channel id this webhook is for. + * * @note This may be empty. */ snowflake channel_id; /** * @brief The user this webhook was created by. + * * @note This field is optional. * @warning This is not returned when getting a webhook with its token! */ @@ -92,36 +106,42 @@ class DPP_EXPORT webhook : public managed, public json_interface { /** * @brief The default name of the webhook. + * * @note This may be empty. */ std::string name; /** - * @brief The default avatar of the webhook + * @brief The default avatar of the webhook. + * * @note This may be empty. */ utility::iconhash avatar; /** * @brief The secure token of the webhook (returned for Incoming Webhooks). + * * @note This field is optional. */ std::string token; /** * @brief The bot/OAuth2 application that created this webhook. + * * @note This may be empty. */ snowflake application_id; /** * @brief The guild of the channel that this webhook is following (only for Channel Follower Webhooks). + * * @warning This will be absent if the webhook creator has since lost access to the guild where the followed channel resides! */ guild source_guild; /** * @brief The channel that this webhook is following (only for Channel Follower Webhooks). + * * @warning This will be absent if the webhook creator has since lost access to the guild where the followed channel resides! */ channel source_channel; @@ -133,6 +153,7 @@ class DPP_EXPORT webhook : public managed, public json_interface { /** * @brief base64 encoded image data if uploading a new image. + * * @warning You should only ever read data from here. If you want to set the data, use dpp::webhook::load_image. */ std::string image_data; diff --git a/include/dpp/wsclient.h b/include/dpp/wsclient.h index 7f047fd6c6..b1a1b1870d 100644 --- a/include/dpp/wsclient.h +++ b/include/dpp/wsclient.h @@ -64,8 +64,7 @@ enum ws_state : uint8_t { /** * @brief Low-level websocket opcodes for frames */ -enum ws_opcode : uint8_t -{ +enum ws_opcode : uint8_t { /** * @brief Continuation. */ @@ -100,8 +99,7 @@ enum ws_opcode : uint8_t /** * @brief Implements a websocket client based on the SSL client */ -class DPP_EXPORT websocket_client : public ssl_client -{ +class DPP_EXPORT websocket_client : public ssl_client { /** * @brief Connection key used in the HTTP headers */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 81dd43693f..12f50fb85b 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -365,9 +365,8 @@ if (DPP_BUILD_TEST) endif() endforeach() add_test( - NAME unittests - COMMAND library/unittest - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/library + NAME unittest + COMMAND unittest ) endif() diff --git a/src/dpp/cluster.cpp b/src/dpp/cluster.cpp index 5341e87b71..ece2949d9f 100644 --- a/src/dpp/cluster.cpp +++ b/src/dpp/cluster.cpp @@ -339,7 +339,17 @@ void cluster::post_rest(const std::string &endpoint, const std::string &major_pa }, postdata, method, get_audit_reason(), filename, filecontent, filemimetype, protocol)); } -void cluster::post_rest_multipart(const std::string &endpoint, const std::string &major_parameters, const std::string ¶meters, http_method method, const std::string &postdata, json_encode_t callback, const std::vector &filename, const std::vector &filecontent, const std::vector &filemimetypes) { +void cluster::post_rest_multipart(const std::string &endpoint, const std::string &major_parameters, const std::string ¶meters, http_method method, const std::string &postdata, json_encode_t callback, const std::vector &file_data) { + std::vector file_names{}; + std::vector file_contents{}; + std::vector file_mimetypes{}; + + for(const message_file_data& data : file_data) { + file_names.push_back(data.name); + file_contents.push_back(data.content); + file_mimetypes.push_back(data.mimetype); + } + /* NOTE: This is not a memory leak! The request_queue will free the http_request once it reaches the end of its lifecycle */ rest->post_request(new http_request(endpoint + (!major_parameters.empty() ? "/" : "") + major_parameters, parameters, [endpoint, callback](http_request_completion_t rv) { json j; @@ -354,7 +364,7 @@ void cluster::post_rest_multipart(const std::string &endpoint, const std::string if (callback) { callback(j, rv); } - }, postdata, method, get_audit_reason(), filename, filecontent, filemimetypes)); + }, postdata, method, get_audit_reason(), file_names, file_contents, file_mimetypes)); } diff --git a/src/dpp/cluster/appcommand.cpp b/src/dpp/cluster/appcommand.cpp index eb1f056d5c..15a2bb1416 100644 --- a/src/dpp/cluster/appcommand.cpp +++ b/src/dpp/cluster/appcommand.cpp @@ -140,7 +140,7 @@ void cluster::interaction_response_create(snowflake interaction_id, const std::s if (callback) { callback(confirmation_callback_t(this, confirmation(), http)); } - }, r.msg.filename, r.msg.filecontent, r.msg.filemimetype); + }, r.msg.file_data); } void cluster::interaction_response_edit(const std::string &token, const message &m, command_completion_event_t callback) { @@ -148,7 +148,7 @@ void cluster::interaction_response_edit(const std::string &token, const message if (callback) { callback(confirmation_callback_t(this, confirmation(), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } void cluster::interaction_response_get_original(const std::string &token, command_completion_event_t callback) { @@ -160,7 +160,7 @@ void cluster::interaction_followup_create(const std::string &token, const messag if (callback) { callback(confirmation_callback_t(this, confirmation(), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } void cluster::interaction_followup_edit_original(const std::string &token, const message &m, command_completion_event_t callback) { @@ -168,7 +168,7 @@ void cluster::interaction_followup_edit_original(const std::string &token, const if (callback) { callback(confirmation_callback_t(this, confirmation(), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } void cluster::interaction_followup_delete(const std::string &token, command_completion_event_t callback) { @@ -180,7 +180,7 @@ void cluster::interaction_followup_edit(const std::string &token, const message if (callback) { callback(confirmation_callback_t(this, confirmation(), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } void cluster::interaction_followup_get(const std::string &token, snowflake message_id, command_completion_event_t callback) { diff --git a/src/dpp/cluster/message.cpp b/src/dpp/cluster/message.cpp index 36ddaa433b..231670b31c 100644 --- a/src/dpp/cluster/message.cpp +++ b/src/dpp/cluster/message.cpp @@ -40,7 +40,7 @@ void cluster::message_create(const message &m, command_completion_event_t callba if (callback) { callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } @@ -116,7 +116,7 @@ void cluster::message_edit(const message &m, command_completion_event_t callback if (callback) { callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } diff --git a/src/dpp/cluster/thread.cpp b/src/dpp/cluster/thread.cpp index be58b82b41..8e8ab147e3 100644 --- a/src/dpp/cluster/thread.cpp +++ b/src/dpp/cluster/thread.cpp @@ -111,6 +111,7 @@ void cluster::thread_create_in_forum(const std::string& thread_name, snowflake c j["auto_archive_duration"] = 10080; break; } + this->post_rest_multipart(API_PATH "/channels", std::to_string(channel_id), "threads", m_post, j.dump(), [this, callback](json &j, const http_request_completion_t& http) { if (callback) { auto t = thread().fill_from_json(&j); @@ -122,7 +123,7 @@ void cluster::thread_create_in_forum(const std::string& thread_name, snowflake c } callback(confirmation_callback_t(this, t, http)); } - }, msg.filename, msg.filecontent, msg.filemimetype); + }, msg.file_data); } void cluster::thread_create(const std::string& thread_name, snowflake channel_id, uint16_t auto_archive_duration, channel_type thread_type, bool invitable, uint16_t rate_limit_per_user, command_completion_event_t callback) diff --git a/src/dpp/cluster/webhook.cpp b/src/dpp/cluster/webhook.cpp index 609db9ae1b..52b895c77c 100644 --- a/src/dpp/cluster/webhook.cpp +++ b/src/dpp/cluster/webhook.cpp @@ -50,11 +50,12 @@ void cluster::edit_webhook_message(const class webhook &wh, const struct message std::string parameters = utility::make_url_parameters({ {"thread_id", thread_id}, }); + this->post_rest_multipart(API_PATH "/webhooks", std::to_string(wh.id), utility::url_encode(!wh.token.empty() ? wh.token: token) + "/messages/" + std::to_string(m.id) + parameters, m_patch, m.build_json(false), [this, callback](json &j, const http_request_completion_t& http) { if (callback) { callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } void cluster::edit_webhook_with_token(const class webhook& wh, command_completion_event_t callback) { @@ -84,11 +85,12 @@ void cluster::execute_webhook(const class webhook &wh, const struct message& m, } body = j.dump(); } + this->post_rest_multipart(API_PATH "/webhooks", std::to_string(wh.id), utility::url_encode(!wh.token.empty() ? wh.token : token) + parameters, m_post, !body.empty() ? body : m.build_json(false), [this, callback](json &j, const http_request_completion_t& http) { if (callback) { callback(confirmation_callback_t(this, message(this).fill_from_json(&j), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } void cluster::get_channel_webhooks(snowflake channel_id, command_completion_event_t callback) { diff --git a/src/dpp/dispatcher.cpp b/src/dpp/dispatcher.cpp index 7c42125dec..1d700efdec 100644 --- a/src/dpp/dispatcher.cpp +++ b/src/dpp/dispatcher.cpp @@ -162,11 +162,21 @@ void interaction_create_t::get_original_response(command_completion_event_t call } void interaction_create_t::edit_original_response(const message& m, command_completion_event_t callback) const { + std::vector file_names{}; + std::vector file_contents{}; + std::vector file_mimetypes{}; + + for(message_file_data data : m.file_data) { + file_names.push_back(data.name); + file_contents.push_back(data.content); + file_mimetypes.push_back(data.mimetype); + } + from->creator->post_rest_multipart(API_PATH "/webhooks", std::to_string(command.application_id), command.token + "/messages/@original", m_patch, m.build_json(), [creator = this->from->creator, cb = std::move(callback)](json& j, const http_request_completion_t& http) { if (cb) { cb(confirmation_callback_t(creator, message().fill_from_json(&j), http)); } - }, m.filename, m.filecontent, m.filemimetype); + }, m.file_data); } void interaction_create_t::delete_original_response(command_completion_event_t callback) const { diff --git a/src/dpp/message.cpp b/src/dpp/message.cpp index c3218c8fe3..abb2d5f8af 100644 --- a/src/dpp/message.cpp +++ b/src/dpp/message.cpp @@ -559,30 +559,39 @@ message& message::set_type(message_type t) return *this; } -message& message::set_filename(const std::string &fn) -{ - if (filename.empty()) { - filename.push_back(fn); +message& message::set_filename(const std::string &fn) { + if (file_data.empty()) { + message_file_data data; + data.name = fn; + + file_data.push_back(data); } else { - filename[filename.size() - 1] = fn; + file_data[file_data.size() - 1].name = fn; } + return *this; } -message& message::set_file_content(const std::string &fc) -{ - if (filecontent.empty()) { - filecontent.push_back(fc); +message& message::set_file_content(const std::string &fc) { + if (file_data.empty()) { + message_file_data data; + data.content = fc; + + file_data.push_back(data); } else { - filecontent[filecontent.size() - 1] = fc; + file_data[file_data.size() - 1].content = fc; } + return *this; } message& message::add_file(const std::string &fn, const std::string &fc, const std::string &fm) { - filename.push_back(fn); - filecontent.push_back(fc); - filemimetype.push_back(fm); + message_file_data data; + data.name = fn; + data.content = fc; + data.mimetype = fm; + + file_data.push_back(data); return *this; } diff --git a/src/dpp/utility.cpp b/src/dpp/utility.cpp index 947f665962..07638d1201 100644 --- a/src/dpp/utility.cpp +++ b/src/dpp/utility.cpp @@ -877,15 +877,23 @@ std::string make_url_parameters(const std::map& parameter std::string markdown_escape(const std::string& text, bool escape_code_blocks) { /** - * @brief Represents the current state of the finite state machine - * for the markdown_escape function. - */ + * @brief Represents the current state of the finite state machine + * for the markdown_escape function. + */ enum md_state { - /// normal text + /** + * @brief Normal text + */ md_normal = 0, - /// a paragraph code block, represented by three backticks + + /** + * @brief A paragraph code block, represented by three backticks. + */ md_big_code_block = 1, - /// an inline code block, represented by one backtick + + /** + * @brief An inline code block, represented by one backtick. + */ md_small_code_block = 2, }; diff --git a/src/dpp/voiceregion.cpp b/src/dpp/voiceregion.cpp index c2abf5b8d8..e3c9fc6349 100644 --- a/src/dpp/voiceregion.cpp +++ b/src/dpp/voiceregion.cpp @@ -32,20 +32,21 @@ voiceregion::voiceregion() : flags(0) } voiceregion& voiceregion::fill_from_json_impl(nlohmann::json* j) { - id = string_not_null(j, "id"); - name = string_not_null(j, "id"); + set_string_not_null(j, "id", id); + set_string_not_null(j, "name", name); + if (bool_not_null(j, "optimal")) { flags |= v_optimal; } + if (bool_not_null(j, "deprecated")) { flags |= v_deprecated; } + if (bool_not_null(j, "custom")) { flags |= v_custom; } - if (bool_not_null(j, "vip")) { - flags |= v_vip; - } + return *this; } @@ -55,8 +56,7 @@ json voiceregion::to_json_impl(bool with_id) const { { "name", name }, { "optimal", is_optimal() }, { "deprecated", is_deprecated() }, - { "custom", is_custom() }, - { "vip", is_vip() } + { "custom", is_custom() } }; } @@ -72,10 +72,5 @@ bool voiceregion::is_custom() const { return flags & v_custom; } -bool voiceregion::is_vip() const { - return flags & v_vip; -} - - } // namespace dpp diff --git a/src/dpp/voicestate.cpp b/src/dpp/voicestate.cpp index e69211dba8..e421cfbd1f 100644 --- a/src/dpp/voicestate.cpp +++ b/src/dpp/voicestate.cpp @@ -32,12 +32,12 @@ voicestate::voicestate() : shard(nullptr), guild_id(0), channel_id(0), user_id(0 } voicestate& voicestate::fill_from_json_impl(nlohmann::json* j) { - guild_id = snowflake_not_null(j, "guild_id"); - channel_id = snowflake_not_null(j, "channel_id"); - user_id = snowflake_not_null(j, "user_id"); - session_id = string_not_null(j, "session_id"); - request_to_speak = ts_not_null(j, "request_to_speak_timestamp"); - flags = 0; + set_snowflake_not_null(j, "guild_id", guild_id); + set_snowflake_not_null(j, "channel_id", channel_id); + set_snowflake_not_null(j, "user_id", user_id); + set_string_not_null(j, "session_id", session_id); + set_ts_not_null(j, "request_to_speak_timestamp", request_to_speak); + if (bool_not_null(j, "deaf")) { flags |= vs_deaf; } diff --git a/src/unittest/test.h b/src/unittest/test.h index 9058632fd8..2cdb80ac77 100644 --- a/src/unittest/test.h +++ b/src/unittest/test.h @@ -31,6 +31,8 @@ _Pragma("warning( disable : 5105 )"); // 4251 warns when we export classes or st #ifdef _WIN32 #define SHARED_OBJECT "dpp.dll" +#elif __APPLE__ +#define SHARED_OBJECT "libdpp.dylib" #else #define SHARED_OBJECT "libdpp.so" #endif