diff --git a/CMakeLists.txt b/CMakeLists.txt index ac7009a..d901687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,25 +10,22 @@ project(discord-bot VERSION 1.0 DESCRIPTION "A discord bot" LANGUAGES CXX) # Spe # Create an executable add_executable(${PROJECT_NAME} - src/main.cpp - src/ImageProcessor.cpp + main.cpp ) # Include directories for your headers and D++ headers # This tells the compiler where to find #include and #include target_include_directories(${PROJECT_NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/include # This covers ImageProcessor.h and the parent for dpp/dpp.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/stb # For stb_image.h and stb_image_write.h # Ensure this path is correct if your D++ headers are NOT directly in ${CMAKE_CURRENT_SOURCE_DIR}/include/dpp # If dpp/dpp.h is found in ${CMAKE_CURRENT_SOURCE_DIR}/include/dpp, then the line below is correct. - ${CMAKE_CURRENT_SOURCE_DIR}/include/dpp + ${CMAKE_CURRENT_SOURCE_DIR} ) # --- NEW: Direct Linker Injection using Generator Expression --- # This method tells CMake to ONLY pass the full path to the linker, # explicitly preventing it from being treated as a build target. target_link_libraries(${PROJECT_NAME} PRIVATE - "$" # Corrected 'libs' to 'lib' + "$" ) # Set C++ version diff --git a/include/dpp/appcommand.h b/include/dpp/appcommand.h deleted file mode 100644 index d43edaf..0000000 --- a/include/dpp/appcommand.h +++ /dev/null @@ -1,1669 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Discord limits the maximum number of replies to an autocomplete interaction to 25. - * This value represents that maximum. interaction_response::add_autocomplete_choice does not allow - * adding more than this number of elements to the vector. - */ -#ifndef AUTOCOMPLETE_MAX_CHOICES - #define AUTOCOMPLETE_MAX_CHOICES 25 -#endif - -/** - * @brief Represents command option types. - * These are the possible parameter value types. - */ -enum command_option_type : uint8_t { - /** - * @brief A sub-command. - */ - co_sub_command = 1, - - /** - * @brief A sub-command group. - */ - co_sub_command_group = 2, - - /** - * @brief A string value. - */ - co_string = 3, - - /** - * @brief An integer value. - */ - co_integer = 4, - - /** - * @brief A boolean value. - */ - co_boolean = 5, - - /** - * @brief A user snowflake id. - */ - co_user = 6, - - /** - * @brief A channel snowflake id. Includes all channel types and categories. - */ - co_channel = 7, - - /** - * @brief A role id (snowflake). - */ - co_role = 8, - - /** - * @brief A mentionable (users and roles). - */ - co_mentionable = 9, - - /** - * @brief Any double between -2^53 and 2^53. - */ - co_number = 10, - - /** - * @brief File attachment type. - */ - co_attachment = 11, -}; - -/** - * @brief This type is a variant that can hold any of the potential - * native data types represented by the enum dpp::command_option_type. - * It is used in interactions. - * - * std::monostate indicates an invalid parameter value, e.g. an unfilled optional parameter. - * std::int64_t will be for all integer options, double for decimal numbers and dpp::snowflake for anything ID related. - * - * You can retrieve them with std::get(). - */ -typedef std::variant command_value; - -/** - * @brief This struct represents choices in a multiple choice option - * for a command parameter. - * It has both a string name, and a value parameter which is a variant, - * meaning it can hold different potential types (see dpp::command_value) - * that you can retrieve with std::get(). - */ -struct DPP_EXPORT command_option_choice : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return command_option_choice& Reference to self - */ - command_option_choice& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief Option name (1-32 chars). - */ - std::string name; - - /** - * @brief Option value. - */ - command_value value; - - /** - * @brief Localisations of command option name. - */ - std::map name_localizations; - - /** - * @brief Construct a new command option choice object - */ - command_option_choice() = default; - - virtual ~command_option_choice() = default; - - /** - * @brief Add a localisation for this command option choice - * @see https://discord.com/developers/docs/reference#locales - * @param language Name of language, see the list of locales linked to above - * @param _name name of command option choice in the specified language - * @return command_option_choice& reference to self for fluent chaining - */ - command_option_choice& add_localization(const std::string& language, const std::string& _name); - - /** - * @brief Construct a new command option choice object - * - * @param n name to initialise with - * @param v value to initialise with - */ - command_option_choice(const std::string &n, command_value v); -}; - -/** - * @brief helper function to serialize a command_option_choice to json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param choice command_option_choice to be serialized - */ -void to_json(nlohmann::json& j, const command_option_choice& choice); - -/** - * @brief A minimum or maximum value/length for dpp::co_number, dpp::co_integer and dpp::co_string types of a dpp::command_option. - * The `int64_t` is for the integer range or string length that can be entered. The `double` is for the decimal range that can be entered - */ -typedef std::variant command_option_range; - -/** - * @brief Each command option is a command line parameter. - * It can have a type (see dpp::command_option_type), a name, - * a description, can be required or optional, and can have - * zero or more choices (for multiple choice), plus options. - * Adding options acts like sub-commands and can contain more - * options. - */ -struct DPP_EXPORT command_option : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON. Fills options recursively. - * - * @param j JSON to fill from - * @return command_option& Reference to self - */ - command_option& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief Option type (what type of value is accepted). - */ - command_option_type type; - - /** - * @brief Option name (1-32 chars). - */ - std::string name; - - /** - * @brief Option description (1-100 chars). - */ - std::string description; - - /** - * @brief Is this a mandatory parameter? - */ - bool required; - - /** - * @brief Is the user is typing in this field? - * - * @note This is sent via autocomplete. - */ - bool focused; - - /** - * @brief Set only by autocomplete when sent as part of an interaction. - */ - command_value value; - - /** - * @brief List of choices for multiple choice command. - */ - std::vector choices; - - /** - * @brief Does this option supports auto completion? - */ - bool autocomplete; - - /** - * @brief An array of sub-commands (options). - */ - std::vector options; - - /** - * @brief Allowed channel types for channel snowflake id options. - */ - std::vector channel_types; - - // Combines the `min_length` and `max_length` field by storing its value in the int64_t of the command_option_range - - /** - * @brief Minimum value/length that can be entered, for dpp::co_number, dpp::co_integer and dpp::co_string types only. - */ - command_option_range min_value; - - /** - * @brief Maximum value/length that can be entered, for dpp::co_number, dpp::co_integer and dpp::co_string types only. - */ - command_option_range max_value; - - /** - * @brief Localisations of command name. - */ - std::map name_localizations; - - /** - * @brief Localisations of command description. - */ - std::map description_localizations; - - /** - * @brief Construct a new command option object - */ - command_option() = default; - - /** - * @brief Destroy the command option object - */ - virtual ~command_option() = default; - - /** - * @brief Add a localisation for this slash command option - * @see https://discord.com/developers/docs/reference#locales - * @param language Name of language, see the list of locales linked to above - * @param _name name of slash command option in the specified language - * @param _description description of slash command option in the specified language (optional) - * @return command_option& reference to self for fluent chaining - */ - command_option& add_localization(const std::string& language, const std::string& _name, const std::string& _description = ""); - - /** - * @brief Construct a new command option object - * - * @param t Option type - * @param name Option name - * @param description Option description - * @param required True if this is a mandatory parameter - */ - command_option(command_option_type t, const std::string &name, const std::string &description, bool required = false); - - /** - * @brief Add a multiple choice option - * - * @param o choice to add - * @return command_option& returns a reference to self for chaining of calls - * @throw dpp::logic_exception command_option is an autocomplete, so choices cannot be added - */ - command_option& add_choice(const command_option_choice &o); - - /** - * @brief Set the minimum numeric value of the option. - * Only valid if the type is dpp::co_number or dpp::co_integer. - * @param min_v Minimum value - * @return command_option& returns a reference to self for chaining of calls - */ - command_option& set_min_value(command_option_range min_v); - - /** - * @brief Set the maximum numeric value of the option. - * Only valid if the type is dpp::co_number or dpp::co_integer. - * @param max_v Maximum value - * @return command_option& returns a reference to self for chaining of calls - */ - command_option& set_max_value(command_option_range max_v); - - /** - * @brief Set the minimum string length of the option. Must be between 0 and 6000 (inclusive). - * Only valid if the type is dpp::co_string - * @param min_v Minimum value - * @return command_option& returns a reference to self for chaining of calls - */ - command_option& set_min_length(command_option_range min_v); - - /** - * @brief Set the maximum string length of the option. Must be between 1 and 6000 (inclusive). - * Only valid if the type is dpp::co_string - * @param max_v Maximum value - * @return command_option& returns a reference to self for chaining of calls - */ - command_option& set_max_length(command_option_range max_v); - - /** - * @brief Add a sub-command option - * - * @param o Sub-command option to add - * @return command_option& return a reference to self for chaining of calls - */ - command_option& add_option(const command_option &o); - - /** - * @brief Add channel type for option (only for co_channel type options) - * - * @param ch type to set - * @return command_option& return a reference to self for chaining of calls - */ - command_option& add_channel_type(const channel_type ch); - - /** - * @brief Set the auto complete state - * - * @param autocomp True to enable auto completion for this option - * @return command_option& return a reference to self for chaining of calls - * @throw dpp::logic_exception You attempted to enable auto complete on a command_option that has choices added to it - */ - command_option& set_auto_complete(bool autocomp); -}; - -/** - * @brief helper function to serialize a command_option to json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param opt command_option to be serialized - */ -void to_json(nlohmann::json& j, const command_option& opt); - -/** - * @brief Response types when responding to an interaction within on_interaction_create. - */ -enum interaction_response_type { - /** - * @brief Acknowledge a Ping - */ - ir_pong = 1, - - /** - * @brief Respond to an interaction with a message. - */ - ir_channel_message_with_source = 4, - - /** - * @brief Acknowledge an interaction and edit a response later, the user sees a loading state - */ - ir_deferred_channel_message_with_source = 5, - - /** - * @brief For components, acknowledge an interaction and edit the original message later; the user does not see a loading state. - */ - ir_deferred_update_message = 6, - - /** - * @brief For components, edit the message the component was attached to. - */ - ir_update_message = 7, - - /** - * @brief Reply to autocomplete interaction. - * - * @note Be sure to do this within 500ms of the interaction! - */ - ir_autocomplete_reply = 8, - - /** - * @brief A modal dialog box - * - * @note Not available for modal submit and ping interactions. - */ - ir_modal_dialog = 9, - - /** - * @brief Acknowledge a interaction with an upgrade button, only available for apps with monetization enabled. - * - * @see https://discord.com/developers/docs/monetization/entitlements#premiumrequired-interaction-response - * @note Not available for autocomplete and ping interactions. - * @warning This response does not support using `content`, `embeds`, or `attachments`, so reply with no data when using this! - * - * @depreciated Replaced with buttons with a style of cos_premium - * This interaction type may stop working at any point - */ - ir_premium_required = 10, -}; - -/** - * @brief A response to an interaction, used to reply to a command and initiate - * a message, which can be hidden from others (ephemeral) or visible to all. - * - * The dpp::interaction_response object wraps a dpp::message object. To set the - * message as 'ephemeral' (e.g. only the command issuer can see it) you should - * add the dpp::m_ephemeral flag to the dpp::message::flags field. e.g.: - * - * `mymessage.flags |= dpp::m_ephemeral;` - */ -struct DPP_EXPORT interaction_response : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return interaction_response& Reference to self - */ - virtual interaction_response& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build json for this object - * - * @return json JSON object - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Response type from dpp::interaction_response_type. - * Should be one of ir_pong, ir_channel_message_with_source, - * or ir_deferred_channel_message_with_source. - */ - interaction_response_type type{}; - - /** - * @brief Message tied to this response. - */ - message msg{}; - - /** - * @brief Array of up to 25 autocomplete choices - */ - std::vector autocomplete_choices{}; - - /** - * @brief Construct a new interaction response object - */ - interaction_response() = default; - - /** - * @brief Construct a new interaction response object - * - * @param t Type of reply - */ - interaction_response(interaction_response_type t); - - /** - * @brief Construct a new interaction response object - * - * @param t Type of reply - * @param m Message to reply with - */ - interaction_response(interaction_response_type t, const message& m); - - /** - * @brief Construct a new interaction response object - * - * @param t Type of reply - * @param m Message to reply with - */ - interaction_response(interaction_response_type t, message&& m); - - /** - * @brief Add a command option choice - * - * @param achoice command option choice to add - * @return interaction_response& Reference to self - */ - interaction_response& add_autocomplete_choice(const command_option_choice& achoice); - - /** - * @brief Destroy the interaction response object - */ - virtual ~interaction_response() = default; - -}; - -/** - * @brief Represents a modal dialog box response to an interaction. - * - * A dialog box is a modal popup which appears to the user instead of a message. One or more - * components are displayed on a form (the same component structure as within a dpp::message). - * When the user submits the form an on_form_submit event is dispatched to any listeners. - */ -struct DPP_EXPORT interaction_modal_response : public interaction_response, public json_interface { -protected: - friend struct json_interface; - - size_t current_row; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return interaction_response& Reference to self - */ - virtual interaction_modal_response& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build a json for this object - * @param with_id include id in json output - * - * @return json JSON object - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - using json_interface::fill_from_json; - using json_interface::to_json; - using json_interface::build_json; - - /** - * @brief Custom ID for the modal form - */ - std::string custom_id; - - /** - * @brief Title of the modal form box (max 25 characters) - */ - std::string title; - - /** - * @brief List of components. All components must be placed within - * an action row, each outer vector is the action row. - */ - std::vector> components; - - /** - * @brief Construct a new interaction modal response object - */ - interaction_modal_response(); - - /** - * @brief Construct a new interaction modal response object - * - * @param _custom_id Custom ID of the modal form - * @param _title Title of the modal form. It will be truncated to the maximum length of 45 UTF-8 characters. - * @param _components Components to add to the modal form - */ - interaction_modal_response(const std::string& _custom_id, const std::string& _title, const std::vector _components = {}); - - /** - * @brief Set the custom id - * - * @param _custom_id custom id to set - * @return interaction_modal_response& Reference to self - */ - interaction_modal_response& set_custom_id(const std::string& _custom_id); - - /** - * @brief Set the title - * - * @param _title title to set - * @return interaction_modal_response& Reference to self - */ - interaction_modal_response& set_title(const std::string& _title); - - /** - * @brief Add a component to an interaction modal response - * - * @param c component to add - * @return interaction_modal_response& Reference to self - */ - interaction_modal_response& add_component(const component& c); - - /** - * @brief Add a new row to the interaction modal response. - * @note A modal response can have a maximum of five rows. - * @throw dpp::logic_exception if more than five rows are attempted to be added - * @return interaction_modal_response& Reference to self - */ - interaction_modal_response& add_row(); - - /** - * @brief Destroy the interaction modal response object - */ - virtual ~interaction_modal_response() = default; -}; - -/** - * @brief Resolved snowflake ids to users, guild members, roles and channels. You can use the `interaction::get_resolved_*` methods to easily get a resolved set - */ -struct DPP_EXPORT command_resolved { - /** - * @brief Resolved users - * @see interaction::get_resolved_user - */ - std::map users; - /** - * @brief Resolved guild members - * @see interaction::get_resolved_member - */ - std::map members; - /** - * @brief Resolved total guild member permissions including channel overwrites, permissions from roles and administrator privileges - * @see interaction::get_resolved_permission - */ - std::map member_permissions; - /** - * @brief Resolved roles - * @see interaction::get_resolved_role - */ - std::map roles; - /** - * @brief Resolved channels - * @see interaction::get_resolved_channel - */ - std::map channels; - /** - * @brief Resolved messages - * @see interaction::get_resolved_message - */ - std::map messages; - /** - * @brief Resolved attachments - * @see interaction::get_resolved_attachment - */ - std::map attachments; -}; - -/** - * @brief Values in the command interaction. - * These are the values specified by the user when actually issuing - * the command on a channel or in DM. - */ -struct DPP_EXPORT command_data_option { - /** - * @brief The name of the parameter. - */ - std::string name; - - /** - * @brief The type of option (value of ApplicationCommandOptionType). - */ - command_option_type type; - - /** - * @brief Optional: the value of the pair - */ - command_value value; - - /** - * @brief Optional: present if this option is a group or subcommand - */ - std::vector options; - - /** - * @brief Optional: true if this option is the currently focused option for autocomplete - */ - bool focused; - - /** - * @brief Check if the value variant holds std::monostate and options vector is empty (i.e. the option wasn't supplied) - * @return bool true, if value variant holds std::monostate and options vector is empty - */ - bool empty() { - return std::holds_alternative(value) && options.empty(); - } - - /** - * @brief Get an option value by index - * - * @tparam T Type to get from the parameter - * @param index index of the option - * @return T returned type - */ - template T& get_value(size_t index) { - return std::get(options.at(index).value); - } -}; - -/** - * @brief helper function to deserialize a command_data_option from json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param cdo command_data_option to be deserialized - */ -void from_json(const nlohmann::json& j, command_data_option& cdo); - -/** Types of interaction in the dpp::interaction class - */ -enum interaction_type { - /** - * @brief A ping interaction. - */ - it_ping = 1, - - /** - * @brief Application command (slash command) interaction. - */ - it_application_command = 2, - - /** - * @brief Button click or select menu chosen (component interaction) - */ - it_component_button = 3, - - /** - * @brief Autocomplete interaction. - */ - it_autocomplete = 4, - - /** - * @brief Modal form submission. - */ - it_modal_submit = 5, -}; - -/* -* @brief Context type where the interaction can be used or triggered from, e.g. guild, user etc -*/ -enum interaction_context_type { - /** - * @brief Interaction can be used within servers - */ - itc_guild = 0, - - /** - * @brief Interaction can be used within DMs with the app's bot user - */ - itc_bot_dm = 1, - - /** - * @brief Interaction can be used within Group DMs and DMs other than the app's bot user - */ - itc_private_channel = 2, -}; - -/** - * @brief Right-click context menu types - */ -enum slashcommand_contextmenu_type { - /** - * @brief Undefined context menu type - */ - ctxm_none = 0, - - /** - * @brief DEFAULT: these are the generic slash commands (e.g. /ping, /pong, etc) - */ - ctxm_chat_input = 1, - - /** - * @brief A slashcommand that goes in the user context menu. - */ - ctxm_user = 2, - - /** - * @brief A slashcommand that goes in the message context menu. - */ - ctxm_message = 3 -}; - -/** - * @brief Details of a command within an interaction. - * This subobject represents the application command associated - * with the interaction. - */ -struct DPP_EXPORT command_interaction { - /** - * @brief The ID of the invoked command. - */ - snowflake id; - - /** - * @brief The name of the invoked command. - */ - std::string name; - - /** - * @brief Optional: the params + values from the user. - */ - std::vector options; - - /** - * @brief The type of command interaction. - */ - slashcommand_contextmenu_type type; - - /** - * @brief Non-zero target ID for context menu actions (e.g. user id or message id whom clicked or tapped with the context menu). - * - * @see https://discord.com/developers/docs/interactions/application-commands#user-commands - */ - dpp::snowflake target_id; - - /** - * @brief Get an option value by index - * - * @tparam T Type to get from the parameter - * @param index index of the option - * @return T returned type - */ - template T& get_value(size_t index) { - return std::get(options.at(index).value); - } - - /** - * @brief Return a ping/mention for the slash command - * - * @return std::string mention. e.g. `` - * @note If you want a mention for a subcommand or subcommand group, you can use dpp::utility::slashcommand_mention - */ - std::string get_mention() const; -}; - -/** - * @brief helper function to deserialize a command_interaction from json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param ci command_interaction to be deserialized - */ -void from_json(const nlohmann::json& j, command_interaction& ci); - -/** - * @brief A button click for a button component - */ -struct DPP_EXPORT component_interaction { - /** - * @brief Component type (dpp::component_type) - */ - uint8_t component_type; - - /** - * @brief Custom ID set when created - */ - std::string custom_id; - - /** - * @brief Possible values for a drop down list - */ - std::vector values; -}; - -/** - * @brief An auto complete interaction - */ -struct DPP_EXPORT autocomplete_interaction : public command_interaction { -}; - -/** - * @brief helper function to deserialize a component_interaction from json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param bi button_interaction to be deserialized - */ -void from_json(const nlohmann::json& j, component_interaction& bi); - -/** - * @brief helper function to deserialize an autocomplete_interaction from json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param ai autocomplete_interaction to be deserialized - */ -void from_json(const nlohmann::json& j, autocomplete_interaction& ai); - -/** - * @brief An interaction represents a user running a command and arrives - * via the dpp::cluster::on_interaction_create event. This is further split - * into the events on_form_submit, on_slashcommand, on_user_context_menu, - * on_button_click, on_select_menu, etc. - */ -class DPP_EXPORT interaction : public managed, public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Get a resolved object from the resolved set - * - * @tparam T type of object to retrieve - * @tparam C container definition for resolved container - * @param id Snowflake ID - * @param resolved_set container for the type - * @return const T& retrieved type - * @throws dpp::logic_exception on object not found in resolved set - */ - template const T& get_resolved(snowflake id, const C& resolved_set) const { - auto i = resolved_set.find(id); - if (i == resolved_set.end()) { - throw dpp::logic_exception("ID not found in resolved properties of application command"); - } - return i->second; - } - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return interaction& Reference to self - */ - interaction& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build a json for this object - * - * @param with_id True if to include the ID in the JSON - * @return json JSON object - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Context where the interaction was triggered from - */ - std::map authorizing_integration_owners; - - /** - * @brief Context where the interaction was triggered from - */ - std::optional context; - - /** - * @brief ID of the application this interaction is for. - */ - snowflake application_id; - - /** - * @brief The type of interaction from dpp::interaction_type. - */ - uint8_t type; - - /** - * @brief Optional: the command data payload. - */ - std::variant data; - - /** - * @brief Optional: the guild it was sent from. - */ - snowflake guild_id; - - /** - * @brief Optional: the channel it was sent from - */ - snowflake channel_id; - - /** - * @brief Optional: The partial channel object where it was sent from. - */ - dpp::channel channel; - - /** - * @brief Originating message id for context menu actions. - */ - snowflake message_id; - - /** - * @brief Permissions of the bot in the channel/guild where this command was issued. - */ - permission app_permissions; - - /** - * @brief Originating message for context menu actions. - */ - message msg; - - /** - * @brief Optional: guild member data for the invoking user, including permissions. Filled when the interaction is invoked in a guild - */ - guild_member member; - - /** - * @brief User object for the invoking user. - */ - user usr; - - /** - * @brief A continuation token for responding to the interaction. - */ - std::string token; - - /** - * @brief Read-only property, always 1. - */ - uint8_t version; - - /** - * @brief Resolved data e.g. users, members, roles, channels, permissions, etc. - */ - command_resolved resolved; - - /** - * @brief User's [locale](https://discord.com/developers/docs/reference#locales) (language). - */ - std::string locale; - - /** - * @brief Guild's locale (language) - for guild interactions only. - */ - std::string guild_locale; - - /** - * @brief Cache policy from cluster. - */ - cache_policy_t cache_policy; - - /** - * @brief For monetized apps, any entitlements for the invoking user, representing access to premium SKUs. - */ - std::vector entitlements; - - /** - * @brief Construct a new interaction object. - */ - interaction(); - - /** - * @brief Destroy the interaction object - */ - virtual ~interaction() = default; - - /** - * @brief Get a user associated with the slash command from the resolved list. - * The resolved list contains associated structures for this command and does not - * use the cache or require any extra API calls. - * - * @param id User snowflake ID to find - * @return const dpp::user& user - * @throws dpp::logic_exception on object not found in resolved set - */ - const dpp::user& get_resolved_user(snowflake id) const; - - /** - * @brief Get the channel this command originated on - * - * @return const dpp::channel& channel - * @throws dpp::logic_exception Command originated from a DM or channel not in cache - */ - const dpp::channel& get_channel() const; - - /** - * @brief Get the guild this command originated on - * - * @return const dpp::guild& guild - * @throws dpp::logic_exception Command originated from a DM or guild not in cache - */ - const dpp::guild& get_guild() const; - - /** - * @brief Get the user who issued this command - * - * @return const dpp::user& user - */ - const dpp::user& get_issuing_user() const; - - /** - * @brief Get the message this action refers to if it is a context menu command - * - * @return const dpp::message& context menu message - */ - const dpp::message& get_context_message() const; - - /** - * @brief Get a role associated with the slash command from the resolved list. - * The resolved list contains associated structures for this command and does not - * use the cache or require any extra API calls. - * - * @param id Role snowflake ID to find - * @return const dpp::role& role - * @throws dpp::logic_exception on object not found in resolved set - */ - const dpp::role& get_resolved_role(snowflake id) const; - - /** - * @brief Get a channel associated with the slash command from the resolved list. - * The resolved list contains associated structures for this command and does not - * use the cache or require any extra API calls. - * - * @param id Channel snowflake ID to find - * @return const dpp::channel& channel - * @throws dpp::logic_exception on object not found in resolved set - */ - const dpp::channel& get_resolved_channel(snowflake id) const; - - /** - * @brief Get a guild member associated with the slash command from the resolved list. - * The resolved list contains associated structures for this command and does not - * use the cache or require any extra API calls. - * - * @param id User snowflake ID to find - * @return const dpp::guild_member& guild member - * @throws dpp::logic_exception on object not found in resolved set - */ - const dpp::guild_member& get_resolved_member(snowflake id) const; - - /** - * @brief Get a permission associated with the slash command from the resolved list. - * The resolved list contains associated structures for this command and does not - * use the cache or require any extra API calls. - * - * @param id User snowflake ID to find - * @return const dpp::permission& total permissions for the user including overrides on - * the channel where the command was issued. - * @throws dpp::logic_exception on object not found in resolved set - */ - const dpp::permission& get_resolved_permission(snowflake id) const; - - /** - * @brief Get a message associated with the slash command from the resolved list. - * The resolved list contains associated structures for this command and does not - * use the cache or require any extra API calls. - * - * @param id Message snowflake ID to find - * @return const dpp::message& message - * @throws dpp::logic_exception on object not found in resolved set - */ - const dpp::message& get_resolved_message(snowflake id) const; - - /** - * @brief Get an uploaded attachment associated with the slash command from the resolved list. - * The resolved list contains associated structures for this command and does not - * use the cache or require any extra API calls. - * - * @param id Attachment snowflake ID to find - * @return const dpp::attachment& file attachment - * @throws dpp::logic_exception on object not found in resolved set - */ - const dpp::attachment& get_resolved_attachment(snowflake id) const; - - /** - * @brief Get the command interaction object - * - * @throw dpp::logic_exception if the interaction is not for a command - * - * @return command_interaction object - */ - command_interaction get_command_interaction() const; - - /** - * @brief Get the component interaction object - * - * @throw dpp::logic_exception if the interaction is not for a component - * - * @return component_interaction object - */ - component_interaction get_component_interaction() const; - - /** - * @brief Get the autocomplete interaction object - * - * @throw dpp::logic_exception if the interaction is not for an autocomplete - * - * @return autocomplete_interaction object - */ - autocomplete_interaction get_autocomplete_interaction() const; - - /** - * @brief Get the command name for a command interaction - * - * @return std::string command interaction, or empty string if the interaction - * is not for a command. - */ - std::string get_command_name() const; - - /** - * @brief Get the user who installed the application for a given type. - * @param type Type of installation for the command, e.g. dpp::ait_guild_install or - * dpp::ait_user_install. - * @return The snowflake of the user. In the event this type is not allowed for the - * given command, this will return a default-initialised snowflake with value 0. - */ - dpp::snowflake get_authorizing_integration_owner(application_integration_types type) const; - - /** - * @brief Returns true if this interaction occurred as a user-app interaction, e.g. - * within a DM or group DM, added to the user not a guild. - * @return true if a user-app interaction - */ - bool is_user_app_interaction() const; - - /** - * @brief Returns true if this interaction occurred as a guild-invited interaction, e.g. - * within a guild's channel, or a DM of a user in that guild. - * @return true if a guild interaction - */ - bool is_guild_interaction() const; - -}; - -/** - * @brief helper function to deserialize an interaction from json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param i interaction to be deserialized - */ -void from_json(const nlohmann::json& j, interaction& i); - -/** - * @brief type of permission in the dpp::command_permission class - */ -enum command_permission_type { - /** - * @brief Role permission - */ - cpt_role = 1, - - /** - * @brief User permission - */ - cpt_user = 2, -}; - -/** - * @brief Application command permissions allow you to enable or - * disable commands for specific users or roles within a guild - */ -class DPP_EXPORT command_permission : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return command_permission& Reference to self - */ - command_permission &fill_from_json_impl(nlohmann::json *j); - -public: - /** - * @brief The ID of the role/user. - */ - snowflake id; - - /** - * @brief The type of permission. - */ - command_permission_type type; - - /** - * @brief True to allow, false to disallow. - */ - bool permission; - - /** - * @brief Construct a new command permission object. - */ - command_permission() = default; - - virtual ~command_permission() = default; - - /** - * @brief Construct a new command permission object - * - * @param id The ID of the role or user - * @param t The permission type - * @param permission True to allow, false, to disallow - */ - command_permission(snowflake id, const command_permission_type t, bool permission); -}; - -/** - * @brief helper function to serialize a command_permission to json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param cp command_permission to be serialized - */ -void to_json(nlohmann::json& j, const command_permission& cp); - -/** - * @brief Returned when fetching the permissions for a command in a guild. - */ -class DPP_EXPORT guild_command_permissions : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return guild_command_permissions& Reference to self - */ - guild_command_permissions &fill_from_json_impl(nlohmann::json *j); - -public: - /** - * @brief The id of the command. - */ - snowflake id; - - /** - * @brief The id of the application the command belongs to. - */ - snowflake application_id; - - /** - * @brief The id of the guild. - */ - snowflake guild_id; - - /** - * @brief The permissions for the command, in the guild. - */ - std::vector permissions; - - /** - * @brief Construct a new guild command permissions object - */ - guild_command_permissions(); - - virtual ~guild_command_permissions() = default; - -}; - -/** - * @brief helper function to serialize a guild_command_permissions to json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param gcp guild_command_permissions to be serialized - */ -void to_json(nlohmann::json& j, const guild_command_permissions& gcp); - -/** - * @brief Represents an application command, created by your bot - * either globally, or on a guild. - */ -class DPP_EXPORT slashcommand : public managed, public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return slashcommand& Reference to self - */ - slashcommand& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build a json for this object - * - * @param with_id True if to include the ID in the JSON - * @return json JSON object - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Application id (usually matches your bots id) - */ - snowflake application_id; - - /** - * @brief Context menu type, defaults to dpp::ctxm_chat_input - */ - slashcommand_contextmenu_type type; - - /** - * @brief Command name (1-32 chars) - */ - std::string name; - - /** - * @brief Command description (1-100 chars) - */ - std::string description; - - /** - * @brief Command options (parameters) - */ - std::vector options; - - /** - * @brief Whether the command is enabled by default when the app is added to a guild. - * This has no effect as the default_member_permissions value is used instead. - * @deprecated Discord discourage use of this value and instead you should use slashcommand::default_member_permissions. - */ - bool default_permission; - - /** - * @brief command permissions - * @deprecated Discord discourage use of this value and instead you should use default_member_permissions. - */ - std::vector permissions; - - /** - * @brief autoincrementing version identifier updated during substantial record changes - */ - snowflake version; - - /** - * @brief Localisations of command name - */ - std::map name_localizations; - - /** - * @brief Localisations of command description - */ - std::map description_localizations; - - /** - * @brief The default permissions of this command on a guild. - * D++ defaults this to dpp::p_use_application_commands. - * @note You can set it to 0 to disable the command for everyone except admins by default - */ - permission default_member_permissions; - - /** - * @brief Installation contexts where the command is available, only for globally-scoped commands. Defaults to your app's configured contexts - */ - std::vector integration_types; - - /** - * @brief Interaction context(s) where the command can be used, only for globally-scoped commands. By default, all interaction context types included for new commands. - */ - std::vector contexts; - - /** - * @brief True if this command should be allowed in a DM - * D++ defaults this to false. Cannot be set to true in a guild - * command, only a global command. - * @deprecated Use dpp::slashcommand_t::set_interaction_contexts instead - */ - bool dm_permission; - - /** - * @brief Indicates whether the command is [age-restricted](https://discord.com/developers/docs/interactions/application-commands#agerestricted-commands). - * Defaults to false - */ - bool nsfw; - - /** - * @brief Construct a new slashcommand object - */ - slashcommand(); - - /** - * @brief Construct a new slashcommand object - * - * @param _name Command name - * @param _description Command description - * @param _application_id Application id (usually the bot's user id) - */ - slashcommand(const std::string &_name, const std::string &_description, const dpp::snowflake _application_id); - - /** - * @brief Construct a new slashcommand object - * - * @param _name Command name - * @param _type Context menu type - * @param _application_id Application id (usually the bot's user id) - */ - slashcommand(const std::string &_name, const slashcommand_contextmenu_type _type, const dpp::snowflake _application_id); - - /** - * @brief Destroy the slashcommand object - */ - virtual ~slashcommand() = default; - - /** - * @brief Add a localisation for this slash command - * @see https://discord.com/developers/docs/reference#locales - * @param language Name of language, see the list of locales linked to above - * @param _name name of slash command in the specified language - * @param _description description of slash command in the specified language (optional) - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& add_localization(const std::string& language, const std::string& _name, const std::string& _description = ""); - - /** - * @brief Set the dm permission for the command - * - * @param dm true to allow this command in dms - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_dm_permission(bool dm); - - /** - * @brief Set whether the command should be age-restricted or not - * - * @param is_nsfw true if the command should be age-restricted - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_nsfw(bool is_nsfw); - - /** - * @brief Set the default permissions of the slash command - * - * @param defaults default permissions to set. This is a permission bitmask of bits from dpp::permissions. - * This is also an AND list, which means the user must have **all** specified permissions to use the command. - * @note You can set it to 0 to disable the command for everyone except admins by default - * - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_default_permissions(uint64_t defaults); - - /** - * @brief Add an option (parameter) - * - * @param o option (parameter) to add - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& add_option(const command_option &o); - - /** - * @brief Set the type of the slash command (only for context menu entries) - * - * @param _type Type of context menu entry this command represents - * @note If the type is dpp::ctxm_chat_input, the command name will be set to lowercase. - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_type(slashcommand_contextmenu_type _type); - - /** - * @brief Set the name of the command - * - * @param n name of command - * @note The maximum length of a command name is 32 UTF-8 codepoints. - * If your command name is longer than this, it will be truncated. - * The command name will be set to lowercase when the type is the default dpp::ctxm_chat_input. - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_name(const std::string &n); - - /** - * @brief Set the description of the command - * - * @param d description - * @note The maximum length of a command description is 100 UTF-8 codepoints. - * If your command description is longer than this, it will be truncated. - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_description(const std::string &d); - - /** - * @brief Set the application id of the command - * - * @param i application id - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_application_id(snowflake i); - - /** - * @brief Set the interaction contexts for the command - * - * @param contexts the contexts to set - * @return slashcommand& reference to self for chaining of calls - */ - slashcommand& set_interaction_contexts(std::vector contexts); - - /** - * @brief Adds a permission to the command - * - * @param p permission to add - * @return slashcommand& reference to self for chaining of calls - * @deprecated Discord discourage use of this value and instead you should use default_member_permissions. - */ - slashcommand& add_permission(const command_permission& p); - - /** - * @brief Disable default permissions, command will be unusable unless - * permissions are overridden with add_permission and - * dpp::guild_command_edit_permissions - * - * @return slashcommand& reference to self for chaining of calls - * @deprecated Discord discourage use of this value and instead you should use default_member_permissions. - */ - slashcommand& disable_default_permissions(); - - /** - * @brief Return a ping/mention for the slash command - * - * @return std::string mention. e.g. `` - * @note If you want a mention for a subcommand or subcommand group, you can use dpp::utility::slashcommand_mention - */ - std::string get_mention() const; -}; - -/** - * @brief helper function to serialize a slashcommand to json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param cmd slashcommand to be serialized - */ -void to_json(nlohmann::json& j, const slashcommand& cmd); - -/** - * @brief A group of application slash commands - */ -typedef std::unordered_map slashcommand_map; - -/** - * @brief A group of guild command permissions - */ -typedef std::unordered_map guild_command_permissions_map; - -} diff --git a/include/dpp/application.h b/include/dpp/application.h deleted file mode 100644 index 50bf5d3..0000000 --- a/include/dpp/application.h +++ /dev/null @@ -1,523 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief status of a member of a team who maintain a bot/application - */ -enum team_member_status : uint8_t { - /** - * @brief User was invited to the team. - */ - tms_invited = 1, - /** - * @brief User has accepted membership onto the team. - */ - tms_accepted = 2 -}; - -/** - * @brief Flags for a bot or application - */ -enum application_flags : uint32_t { - /** - * @brief Indicates if an app uses the Auto Moderation API - */ - apf_application_automod_rule_create_badge = (1 << 6), - - /** - * @brief Has gateway presence intent - */ - apf_gateway_presence = (1 << 12), - - /** - * @brief Has gateway presence intent for <100 guilds - */ - apf_gateway_presence_limited = (1 << 13), - - /** - * @brief Has guild members intent - */ - apf_gateway_guild_members = (1 << 14), - - /** - * @brief Has guild members intent for <100 guilds - */ - apf_gateway_guild_members_limited = (1 << 15), - - /** - * @brief Verification is pending - */ - apf_verification_pending_guild_limit = (1 << 16), - - /** - * @brief Embedded - */ - apf_embedded = (1 << 17), - - /** - * @brief Has approval for message content - */ - apf_gateway_message_content = (1 << 18), - - /** - * @brief Has message content, but <100 guilds - */ - apf_gateway_message_content_limited = (1 << 19), - - /** - * @brief Indicates if the app has registered global application commands - */ - apf_application_command_badge = (1 << 23) -}; - -/** - * @brief Represents the settings for the bot/application's in-app authorization link - */ -struct DPP_EXPORT application_install_params { - /** - * @brief A bitmask of dpp::permissions to request for the bot role. - */ - permission permissions; - - /** - * @brief The scopes as strings to add the application to the server with. - * - * @see https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes - */ - std::vector scopes; -}; - -/** - * @brief Team member role types for application team members. - * - * These are hard coded to string forms by discord. If further types are added, - * this enum will be extended to support them. - */ -enum team_member_role_t : uint8_t { - /** - * @brief Team owner. - */ - tmr_owner, - - /** - * @brief Team admin. - */ - tmr_admin, - - /** - * @brief Developer - */ - tmr_developer, - - /** - * @brief Read-Only - */ - tmr_readonly, -}; - -/** - * @brief Represents a team member on a team who maintain a bot/application - */ -class DPP_EXPORT team_member { -public: - /** - * @brief The user's membership state on the team. - */ - team_member_status membership_state; - - /** - * @brief Will always be "". - */ - std::string permissions; - - /** - * @brief The id of the parent team of which they are a member. - */ - snowflake team_id; - - /** - * @brief The avatar, discriminator, id, and username, of the user. - */ - user member_user; - - /** - * @brief The role of the user in the team. - */ - team_member_role_t member_role; -}; - -/** - * @brief Represents a team of users who maintain a bot/application - */ -class DPP_EXPORT app_team { -public: - /** - * @brief A hash of the image of the team's icon (may be empty). - */ - utility::iconhash icon; - - /** - * @brief The id of the team. - */ - snowflake id; - - /** - * @brief The members of the team. - */ - std::vector members; - - /** - * @brief The name of the team. - */ - std::string name; - - /** - * @brief The user id of the current team owner. - */ - snowflake owner_user_id; -}; - -/** - * @brief Status indicating whether event webhooks are enabled or disabled for an application. - */ -enum application_event_webhook_status: uint8_t { - /** - * @brief Webhook events are disabled by developer - */ - ews_disabled = 1, - /** - * @brief Webhook events are enabled by developer - */ - ews_enabled = 2, - /** - * @brief Webhook events are disabled by Discord, usually due to inactivity - */ - ews_disabled_by_discord = 3, -}; - -/** - * @brief Configuration object for an app installation - */ -struct DPP_EXPORT integration_configuration { - application_install_params oauth2_install_params; -}; - -/** - * @brief The application class represents details of a bot application - */ -class DPP_EXPORT application : public managed, public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - application& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief The name of the app. - */ - std::string name; - - /** - * @brief The icon hash of the app (may be empty). - */ - utility::iconhash icon; - - /** - * @brief The description of the app. - */ - std::string description; - - /** - * @brief Optional: an array of rpc origin urls, if rpc is enabled. - */ - std::vector rpc_origins; - - /** - * @brief When false, only app owner add the bot to guilds. - */ - bool bot_public; - - /** - * @brief When true, the app's bot will only join upon completion of the full oauth2 code grant flow - */ - bool bot_require_code_grant; - - /** - * @brief Optional: Partial user object for the bot user associated with the app. - */ - user bot; - - /** - * @brief Optional: the url of the app's terms of service. - */ - std::string terms_of_service_url; - - /** - * @brief Optional: the url of the app's privacy policy. - */ - std::string privacy_policy_url; - - /** - * @brief Optional: partial user object containing info on the owner of the application. - */ - user owner; - - /** - * @brief If this application is a game sold on Discord, this field will be the summary field for the store page of its primary SKU. - * - * @deprecated Will be removed in v11 - */ - std::string summary; - - /** - * @brief The hex encoded key for verification in interactions and the GameSDK's GetTicket. - */ - std::string verify_key; - - /** - * @brief If the application belongs to a team, this will be a list of the members of that team (may be empty). - */ - app_team team; - - /** - * @brief Optional: if this application is a game sold on Discord, this field will be the guild to which it has been linked. - */ - snowflake guild_id; - - /** - * @brief Partial object of the associated guild. - */ - guild guild_obj; - - /** - * @brief Optional: if this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists. - */ - snowflake primary_sku_id; - - /** - * @brief Optional: if this application is a game sold on Discord, this field will be the URL slug that links to the store page. - */ - std::string slug; - - /** - * @brief Optional: the application's default rich presence invite cover image hash - */ - utility::iconhash cover_image; - - /** - * @brief Optional: the application's public flags. - */ - uint32_t flags; - - /** - * @brief Optional: Approximate count of guilds the app has been added to. - */ - uint64_t approximate_guild_count; - - /** - * @brief Optional: Approximate count of users that have installed the app - */ - uint64_t approximate_user_install_count; - - /** - * @brief Optional: Array of redirect URIs for the app. - */ - std::vector redirect_uris; - - /** - * @brief Optional: Interactions endpoint URL for the app. - */ - std::string interactions_endpoint_url; - - /** - * @brief The application's role connection verification entry point - * which, when configured, will render the app as a verification method - * in the guild role verification configuration. - */ - std::string role_connections_verification_url; - - /** - * @brief Event webhooks URL for the app to receive webhook events - */ - std::string event_webhooks_url; - - /** - * @brief List of Webhook event types the app subscribes to. - */ - std::vector event_webhooks_types; - - /** - * If webhook events are enabled for the app. - */ - application_event_webhook_status event_webhooks_status; - - /** - * @brief Up to 5 tags describing the content and functionality of the application. - */ - std::vector tags; - - /** - * @brief Settings for the application's default in-app authorization link, if enabled. - */ - application_install_params install_params; - - /** - * @brief Default scopes and permissions for each supported installation context - */ - std::map integration_types_config; - - /** - * @brief The application's default custom authorization link, if enabled. - */ - std::string custom_install_url; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t discoverability_state; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint32_t discovery_eligibility_flags; - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t explicit_content_filter; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t creator_monetization_state; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - bool integration_public; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - bool integration_require_code_grant; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - std::vector interactions_event_types; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t interactions_version; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - bool is_monetized; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint32_t monetization_eligibility_flags; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t monetization_state; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - bool hook; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t rpc_application_state; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t store_application_state; - - /** - * @warning This variable is not documented by discord, we have no idea what it means and how it works. Use at your own risk. - */ - uint8_t verification_state; - - /** Constructor */ - application(); - - /** Destructor */ - ~application(); - - /** - * @brief Get the application's cover image url if they have one, otherwise returns an empty string - * - * @param size The size of the cover image in pixels. It can be any power of two between 16 and 4096, - * otherwise the default sized cover image is returned. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg` or `i_png`. - * @return std::string cover image url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_cover_image_url(uint16_t size = 0, const image_type format = i_png) const; - - /** - * @brief Get the application'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. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg` or `i_png`. - * @return std::string icon url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_icon_url(uint16_t size = 0, const image_type format = i_png) const; -}; - -/** - * @brief A group of applications. - * - * This is not currently ever sent by Discord API but the DPP standard setup for - * objects that can be received by REST has the possibility for this, so this exists. - * Don't ever expect to see one at present. - */ -typedef std::unordered_map application_map; - -} diff --git a/include/dpp/auditlog.h b/include/dpp/auditlog.h deleted file mode 100644 index 5af57ab..0000000 --- a/include/dpp/auditlog.h +++ /dev/null @@ -1,481 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Defines types of audit log entry - */ -enum audit_type { - /** - * @brief Guild update - */ - aut_guild_update = 1, - - /** - * @brief Channel create - */ - aut_channel_create = 10, - - /** - * @brief Channel update - */ - aut_channel_update = 11, - - /** - * @brief Channel delete - */ - aut_channel_delete = 12, - - /** - * @brief Channel overwrite create - */ - aut_channel_overwrite_create = 13, - - /** - * @brief Channel overwrite update - */ - aut_channel_overwrite_update = 14, - - /** - * @brief Channel overwrite delete - */ - aut_channel_overwrite_delete = 15, - - /** - * @brief Channel member kick - */ - aut_member_kick = 20, - - /** - * @brief Channel member prune - */ - aut_member_prune = 21, - - /** - * @brief Channel member ban add - */ - aut_member_ban_add = 22, - - /** - * @brief Channel member ban remove - */ - aut_member_ban_remove = 23, - - /** - * @brief Guild member update - */ - aut_member_update = 24, - - /** - * @brief Guild member role update - */ - aut_member_role_update = 25, - - /** - * @brief Guild member move - */ - aut_member_move = 26, - - /** - * @brief Guild member voice disconnect - */ - aut_member_disconnect = 27, - - /** - * @brief Guild bot add - */ - aut_bot_add = 28, - - /** - * @brief Guild role create - */ - aut_role_create = 30, - - /** - * @brief Guild role update - */ - aut_role_update = 31, - - /** - * @brief Guild role delete - */ - aut_role_delete = 32, - - /** - * @brief Guild invite create - */ - aut_invite_create = 40, - - /** - * @brief Guild invite update - */ - aut_invite_update = 41, - - /** - * @brief Guild invite delete - */ - aut_invite_delete = 42, - - /** - * @brief Guild webhook create - */ - aut_webhook_create = 50, - - /** - * @brief Guild webhook update - */ - aut_webhook_update = 51, - - /** - * @brief Guild webhook delete - */ - aut_webhook_delete = 52, - - /** - * @brief Guild emoji create - */ - aut_emoji_create = 60, - - /** - * @brief Guild emoji update - */ - aut_emoji_update = 61, - - /** - * @brief Guild emoji delete - */ - aut_emoji_delete = 62, - - /** - * @brief Guild message delete - */ - aut_message_delete = 72, - - /** - * @brief Guild message bulk delete - */ - aut_message_bulk_delete = 73, - - /** - * @brief Guild message pin - */ - aut_message_pin = 74, - - /** - * @brief Guild message unpin - */ - aut_message_unpin = 75, - - /** - * @brief Guild integration create - */ - aut_integration_create = 80, - - /** - * @brief Guild integration update - */ - aut_integration_update = 81, - - /** - * @brief Guild integration delete - */ - aut_integration_delete = 82, - - /** - * @brief Stage instance create - */ - aut_stage_instance_create = 83, - - /** - * @brief Stage instance update - */ - aut_stage_instance_update = 84, - - /** - * @brief stage instance delete - */ - aut_stage_instance_delete = 85, - - /** - * @brief Sticker create - */ - aut_sticker_create = 90, - - /** - * @brief Sticker update - */ - aut_sticker_update = 91, - - /** - * @brief Sticker delete - */ - aut_sticker_delete = 92, - - /** - * @brief Scheduled event creation - */ - aut_guild_scheduled_event_create = 100, - - /** - * @brief Scheduled event update - */ - aut_guild_scheduled_event_update = 101, - - /** - * @brief Scheduled event deletion - */ - aut_guild_scheduled_event_delete = 102, - - /** - * @brief Thread create - */ - aut_thread_create = 110, - - /** - * @brief Thread update - */ - aut_thread_update = 111, - - /** - * @brief Thread delete - */ - aut_thread_delete = 112, - - /** - * @brief Application command permissions update - */ - aut_appcommand_permission_update = 121, - - /** - * @brief Auto moderation rule creation - */ - aut_automod_rule_create = 140, - - /** - * @brief Auto moderation rule update - */ - aut_automod_rule_update = 141, - - /** - * @brief Auto moderation rule deletion - */ - aut_automod_rule_delete = 142, - - /** - * @brief Message was blocked by Auto Moderation - */ - aut_automod_block_message = 143, - - /** - * @brief Message was flagged by Auto Moderation - */ - aut_automod_flag_to_channel = 144, - - /** - * @brief Member was timed out by Auto Moderation - */ - aut_automod_user_communication_disabled = 145, - - /** - * @brief Creator monetization request was created - */ - aut_creator_monetization_request_created = 150, - - /** - * @brief Creator monetization terms were accepted - */ - aut_creator_monetization_terms_accepted = 151, -}; - -/** - * @brief Defines audit log changes - */ -struct DPP_EXPORT audit_change { - /** - * @brief Optional: Serialised new value of the change, e.g. for nicknames, the new nickname. - */ - std::string new_value; - - /** - * @brief Optional: Serialised old value of the change, e.g. for nicknames, the old nickname. - */ - std::string old_value; - - /** - * @brief The property name that was changed (e.g. `nick` for nickname changes). - * @note For dpp::aut_appcommand_permission_update updates the key is the id of the user, channel, role, or a permission constant that was updated instead of an actual property name. - */ - std::string key; -}; - -/** - * @brief Extra information for an audit log entry - */ -struct DPP_EXPORT audit_extra { - /** - * @brief Name of the Auto Moderation rule that was triggered. - */ - std::string automod_rule_name; - - /** - * @brief Trigger type of the Auto Moderation rule that was triggered. - */ - std::string automod_rule_trigger_type; - - /** - * @brief Number of days after which inactive members were kicked. - */ - std::string delete_member_days; - - /** - * @brief Number of members removed by the prune. - */ - std::string members_removed; - - /** - * @brief Channel in which the entities were targeted. - */ - snowflake channel_id; - - /** - * @brief ID of the message that was targeted. - */ - snowflake message_id; - - /** - * @brief Number of entities that were targeted. - */ - std::string count; - - /** - * @brief ID of the overwritten entity. - */ - snowflake id; - - /** - * @brief Type of overwritten entity - "0" for "role" or "1" for "member" - */ - std::string type; - - /** - * @brief Name of the role if type is "0" (not present if type is "1"). - */ - std::string role_name; - - /** - * @brief ID of the app whose permissions were targeted - */ - snowflake application_id; -}; - -/** - * @brief An individual audit log entry - */ -struct DPP_EXPORT audit_entry : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - audit_entry& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief ID of the entry. - */ - snowflake id; - - /** - * ID of the affected entity (webhook, user, role, etc.) (may be empty) - * @note For dpp::audit_type::aut_appcommand_permission_update updates, it's the command ID or the app ID - */ - snowflake target_id; - - /** - * @brief Optional: changes made to the target_id. - */ - std::vector changes; - - /** - * @brief The user or app that made the changes (may be empty). - */ - snowflake user_id; - - /** - * @brief Type of action that occurred. - */ - audit_type type; - - /** - * @brief Optional: additional info for certain action types. - */ - std::optional extra; - - /** - * @brief Optional: the reason for the change (1-512 characters). - */ - std::string reason; - - /** Constructor */ - audit_entry(); - - /** Destructor */ - virtual ~audit_entry() = default; -}; - -/** - * @brief The auditlog class represents the audit log entries of a guild. - */ -class DPP_EXPORT auditlog : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - auditlog& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief Audit log entries. - */ - std::vector entries; - - /** Constructor */ - auditlog() = default; - - /** Destructor */ - virtual ~auditlog() = default; -}; - -} diff --git a/include/dpp/automod.h b/include/dpp/automod.h deleted file mode 100644 index 05c194f..0000000 --- a/include/dpp/automod.h +++ /dev/null @@ -1,403 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Possible types of preset filter lists - */ -enum automod_preset_type : uint8_t { - /** - * @brief Strong swearing - */ - amod_preset_profanity = 1, - - /** - * @brief Sexual phrases and words - */ - amod_preset_sexual_content = 2, - - /** - * @brief Racial and other slurs, hate speech - */ - amod_preset_slurs = 3, -}; - -/** - * @brief Action types to perform on filtering - */ -enum automod_action_type : uint8_t { - /** - * @brief Blocks the message and prevents it from being posted. - * A custom explanation can be specified and shown to members whenever their message is blocked - */ - amod_action_block_message = 1, - - /** - * @brief Send an alert to a given channel - */ - amod_action_send_alert = 2, - - /** - * @brief timeout the user - * @note Can only be set up for rules with trigger types of dpp::amod_type_keyword and dpp::amod_type_mention_spam - */ - amod_action_timeout = 3, -}; - -/** - * @brief Event types, only message send is currently supported - */ -enum automod_event_type : uint8_t { - /** - * @brief Trigger on message send or edit - */ - amod_message_send = 1, -}; - -/** - * @brief Types of moderation to trigger - */ -enum automod_trigger_type : uint8_t { - /** - * @brief Check if content contains words from a user defined list of keywords (max 6 of this type per guild) - */ - amod_type_keyword = 1, - - /** - * @brief Harmful/malware links - * @deprecated Removed by Discord - */ - amod_type_harmful_link = 2, - - /** - * @brief Check if content represents generic spam (max 1 of this type per guild) - */ - amod_type_spam = 3, - - /** - * @brief Check if content contains words from discord pre-defined wordsets (max 1 of this type per guild) - */ - amod_type_keyword_preset = 4, - - /** - * @brief Check if content contains more mentions than allowed (max 1 of this type per guild) - */ - amod_type_mention_spam = 5, -}; - -/** - * @brief Metadata associated with an automod action. Different fields are relevant based on the value of dpp::automod_rule::trigger_type. - */ -struct DPP_EXPORT automod_metadata : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return automod_metadata& Reference to self - */ - automod_metadata& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build a json for this object - * - * @return json JSON object - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief @brief Substrings which will be searched for in content (Maximum of 1000). - * - * Each keyword can be a phrase which contains multiple words. - * All keywords are case insensitive and can be up to 60 characters. - * - * Wildcard symbols (`*`) can be used to customize how each keyword will be matched. - * - * **Examples for the `*` wildcard symbol:** - * - * Prefix - word must start with the keyword - * - * | keyword | matches | - * |----------|-------------------------------------| - * | cat* | catch, Catapult, CAttLE | - * | the mat* | the matrix | - * - * Suffix - word must end with the keyword - * - * | keyword | matches | - * |----------|--------------------------| - * | *cat | wildcat, copyCat | - * | *the mat | breathe mat | - * - * Anywhere - keyword can appear anywhere in the content - * - * | keyword | matches | - * |-----------|-----------------------------| - * | \*cat* | location, eduCation | - * | \*the mat* | breathe matter | - * - * Whole Word - keyword is a full word or phrase and must be surrounded by whitespace at the beginning and end - * - * | keyword | matches | - * |---------|-------------| - * | cat | Cat | - * | the mat | the mat | - * - */ - std::vector keywords; - - /** - * @brief Regular expression patterns which will be matched against content (Maximum of 10). - * - * Only Rust flavored regex is currently supported, which can be tested in online editors such as [Rustexp](https://rustexp.lpil.uk/). - * Each regex pattern can be up to 260 characters. - */ - std::vector regex_patterns; - - /** - * @brief Preset keyword list types to moderate - * @see automod_preset_type - */ - std::vector presets; - - /** - * @brief Substrings which should not trigger the rule (Maximum of 100 for the trigger type dpp::amod_type_keyword, Maximum of 1000 for the trigger type dpp::amod_type_keyword_preset). - * - * Each keyword can be a phrase which contains multiple words. - * All keywords are case insensitive and can be up to 60 characters. - * - * Wildcard symbols (`*`) can be used to customize how each keyword will be matched. - * - * **Examples for the `*` wildcard symbol:** - * - * Prefix - word must start with the keyword - * - * | keyword | matches | - * |----------|-------------------------------------| - * | cat* | catch, Catapult, CAttLE | - * | the mat* | the matrix | - * - * Suffix - word must end with the keyword - * - * | keyword | matches | - * |----------|--------------------------| - * | *cat | wildcat, copyCat | - * | *the mat | breathe mat | - * - * Anywhere - keyword can appear anywhere in the content - * - * | keyword | matches | - * |-----------|-----------------------------| - * | \*cat* | location, eduCation | - * | \*the mat* | breathe matter | - * - * Whole Word - keyword is a full word or phrase and must be surrounded by whitespace at the beginning and end - * - * | keyword | matches | - * |---------|-------------| - * | cat | Cat | - * | the mat | the mat | - * - */ - std::vector allow_list; - - /** - * @brief Total number of unique role and user mentions allowed per message (Maximum of 50) - */ - uint8_t mention_total_limit; - - /** - * @brief Whether to automatically detect mention raids - */ - bool mention_raid_protection_enabled; - - /** - * @brief Construct a new automod metadata object - */ - automod_metadata(); - - /** - * @brief Destroy the automod metadata object - */ - virtual ~automod_metadata(); -}; - -/** - * @brief Represents an automod action - */ -struct DPP_EXPORT automod_action : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return automod_action& Reference to self - */ - automod_action& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build a json for this object - * - * @return json JSON object - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Type of action to take - */ - automod_action_type type; - - /** - * @brief Channel ID to which user content should be logged, for type dpp::amod_action_send_alert - */ - snowflake channel_id; - - /** - * @brief Additional explanation that will be shown to members whenever their message is blocked. For type dpp::amod_action_block_message - */ - std::string custom_message; - - /** - * @brief Timeout duration in seconds (Maximum of 2419200), for dpp::amod_action_timeout - */ - uint32_t duration_seconds; - - /** - * @brief Construct a new automod action object - */ - automod_action(); - - /** - * @brief Destroy the automod action object - */ - virtual ~automod_action(); -}; - -/** - * @brief Represents an automod rule - */ -class DPP_EXPORT automod_rule : public managed, public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Fill object properties from JSON - * - * @param j JSON to fill from - * @return automod_rule& Reference to self - */ - automod_rule& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build a json string for this object - * - * @return json JSON object - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief the id of this rule - */ - snowflake id; - - /** - * @brief the guild which this rule belongs to - */ - snowflake guild_id; - - /** - * @brief the rule name - */ - std::string name; - - /** - * @brief The user which first created this rule - */ - snowflake creator_id; - - /** - * @brief The rule event type - */ - automod_event_type event_type; - - /** - * @brief The rule trigger type - */ - automod_trigger_type trigger_type; - - /** - * @brief The rule trigger metadata - */ - automod_metadata trigger_metadata; - - /** - * @brief the actions which will execute when the rule is triggered - */ - std::vector actions; - - /** - * @brief Whether the rule is enabled - */ - bool enabled; - - /** - * @brief the role ids that should not be affected by the rule (Maximum of 20) - */ - std::vector exempt_roles; - - /** - * @brief the channel ids that should not be affected by the rule (Maximum of 50) - */ - std::vector exempt_channels; - - /** - * @brief Construct a new automod rule object - */ - automod_rule(); - - /** - * @brief Destroy the automod rule object - */ - virtual ~automod_rule(); -}; - -/** A group of automod rules. - */ -typedef std::unordered_map automod_rule_map; - -} diff --git a/include/dpp/ban.h b/include/dpp/ban.h deleted file mode 100644 index 039aa90..0000000 --- a/include/dpp/ban.h +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief The ban class represents a ban on a guild. - * - */ -class DPP_EXPORT ban : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - ban& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief The ban reason. - */ - std::string reason; - - /** - * @brief User ID the ban applies to. - */ - snowflake user_id; - - /** Constructor */ - ban(); - - /** Destructor */ - virtual ~ban() = default; -}; - -/** - * @brief A group of bans. The key is the user ID. - */ -typedef std::unordered_map ban_map; - -} diff --git a/include/dpp/bignum.h b/include/dpp/bignum.h deleted file mode 100644 index 6d13f8f..0000000 --- a/include/dpp/bignum.h +++ /dev/null @@ -1,101 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include - -namespace dpp { - -/** - * @brief This contains the OpenSSL structs. It is not public, - * so that the public interface doesn't depend on OpenSSL directly. - */ -struct openssl_bignum; - -/** -* @brief An arbitrary length integer number. - * Officially, the Discord documentation says that permission values can be any arbitrary - * number of digits. At time of writing there are only 50 bits of permissions, but this is - * set to grow larger and potentially past 64 bits. They will continue to send this data - * as a huge single integer at that point, because this is obviously sensible. /s - * - * @note dpp::bignumber uses OpenSSL BN_* under the hood, as we include openssl anyway - * for HTTPS. -*/ -class DPP_EXPORT bignumber { - /** - * @brief Internal opaque struct to contain OpenSSL things - */ - std::shared_ptr ssl_bn{nullptr}; -public: - /** - * @brief Construct a new bignumber object - */ - bignumber() = default; - - /** - * @brief Parse a std::string of an arbitrary length number into - * a bignumber. - * @param number_string string representation of a number. The - * number must be an integer, and can be positive or negative. - * @note Prefixing number_string with 0x will parse it as hexadecimal. - * This is not case sensitive. - */ - bignumber(const std::string& number_string); - - /** - * @brief Build a bignumber from a vector of 64 bit values. - * The values are accepted in "reverse order", so the first vector - * entry at index 0 is the leftmost 64 bits of the bignum. - * The vector can be any arbitrary length. - * @param bits Vector of 64 bit values which represent the number - */ - bignumber(std::vector bits); - - /** - * @brief Default destructor - */ - ~bignumber() = default; - - /** - * @brief Get the string representation of the bignumber. - * @param hex If false (the default) the number is returned in - * decimal, else if this parameter is true, it will be returned - * as hex (without leading '0x') - * @return String representation of bignumber - */ - [[nodiscard]] std::string get_number(bool hex = false) const; - - /** - * @brief Get the array of 64 bit values that represents the - * bignumber. This is what we should use to store bignumbers - * in memory, not this bignumber class itself, as the bignumber - * class instantiates OpenSSL structs and takes significantly - * more ram than just a vector. - * @return Vector of 64 bit values representing the bignumber - */ - [[nodiscard]] std::vector get_binary() const; -}; - -} diff --git a/include/dpp/cache.h b/include/dpp/cache.h deleted file mode 100644 index f4bb884..0000000 --- a/include/dpp/cache.h +++ /dev/null @@ -1,274 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include -#include - -namespace dpp { - -extern DPP_EXPORT std::unordered_map deletion_queue; -extern DPP_EXPORT std::mutex deletion_mutex; - -/** forward declaration */ -class guild_member; - -/** - * @brief A cache object maintains a cache of dpp::managed objects. - * - * This is for example users, channels or guilds. You may instantiate - * your own caches, to contain any type derived from dpp::managed including - * your own types. - * - * @note This class is critical to the operation of the library and therefore - * designed with thread safety in mind. - * @tparam T class type to store, which should be derived from dpp::managed. - */ -template class cache { -private: - /** - * @brief Mutex to protect the cache - * - * This is a shared mutex so reading is cheap. - */ - std::shared_mutex cache_mutex; - - /** - * @brief Container of pointers to cached items - */ - std::unordered_map* cache_map; -public: - - /** - * @brief Construct a new cache object. - * - * @note Caches must contain classes derived from dpp::managed. - */ - cache() { - cache_map = new std::unordered_map; - } - - /** - * @brief Destroy the cache object - * - * @note This does not delete objects stored in the cache. - */ - ~cache() { - std::unique_lock l(cache_mutex); - delete cache_map; - } - - /** - * @brief Store an object in the cache. Passing a nullptr will have no effect. - * - * The object must be derived from dpp::managed and should be allocated on the heap. - * Generally this is done via `new`. Once stored in the cache the lifetime of the stored - * object is managed by the cache class unless the cache is deleted (at which point responsibility - * for deleting the object returns to its allocator). Objects stored are removed when the - * cache::remove() method is called by placing them into a garbage collection queue for deletion - * within the next 60 seconds, which are then deleted in bulk for efficiency and to aid thread - * safety. - * - * @note Adding an object to the cache with an ID which already exists replaces that entry. - * The previously entered cache item is inserted into the garbage collection queue for deletion - * similarly to if cache::remove() was called first. - * - * @param object object to store. Storing a pointer to the cache relinquishes ownership to the cache object. - */ - void store(T* object) { - if (!object) { - return; - } - std::unique_lock l(cache_mutex); - auto existing = cache_map->find(object->id); - if (existing == cache_map->end()) { - (*cache_map)[object->id] = object; - } else if (object != existing->second) { - /* Flag old pointer for deletion and replace */ - std::lock_guard delete_lock(deletion_mutex); - deletion_queue[existing->second] = time(nullptr); - (*cache_map)[object->id] = object; - } - } - - /** - * @brief Remove an object from the cache. - * - * @note The cache class takes ownership of the pointer, and calling this method will - * cause deletion of the object within the next 60 seconds by means of a garbage - * collection queue. This queue aids in efficiency by freeing memory in bulk, and - * assists in thread safety by ensuring that all deletions can be locked and freed - * at the same time. - * - * @param object object to remove. Passing a nullptr will have no effect. - */ - void remove(T* object) { - if (!object) { - return; - } - std::unique_lock l(cache_mutex); - std::lock_guard delete_lock(deletion_mutex); - auto existing = cache_map->find(object->id); - if (existing != cache_map->end()) { - cache_map->erase(existing); - deletion_queue[object] = time(nullptr); - } - } - - /** - * @brief Find an object in the cache by id. - * - * The cache is searched for the object. All dpp::managed objects have a snowflake id - * (this is the only field dpp::managed actually has). - * - * @warning Do not hang onto objects returned by cache::find() indefinitely. They may be - * deleted at a later date if cache::remove() is called. If persistence is required, - * take a copy of the object after checking its pointer is non-null. - * - * @param id Object snowflake id to find - * @return Found object or nullptr if the object with this id does not exist. - */ - T* find(snowflake id) { - std::shared_lock l(cache_mutex); - auto r = cache_map->find(id); - if (r != cache_map->end()) { - return r->second; - } - return nullptr; - } - - /** - * @brief Return a count of the number of items in the cache. - * - * This is used by the library e.g. to count guilds, users, and roles - * stored within caches. - * get - * @return uint64_t count of items in the cache - */ - uint64_t count() { - std::shared_lock l(cache_mutex); - return cache_map->size(); - } - - /** - * @brief Return the cache's locking mutex. - * - * Use this whenever you manipulate or iterate raw elements in the cache! - * - * @note If you are only reading from the cache's container, wrap this - * mutex in `std::shared_lock`, else wrap it in a `std::unique_lock`. - * Shared locks will allow for multiple readers whilst blocking writers, - * and unique locks will allow only one writer whilst blocking readers - * and writers. - * - * **Example:** - * - * ```cpp - * dpp::cache* c = dpp::get_guild_cache(); - * std::unordered_map& gc = c->get_container(); - * std::shared_lock l(c->get_mutex()); // MUST LOCK HERE - * for (auto g = gc.begin(); g != gc.end(); ++g) { - * dpp::guild* gp = (dpp::guild*)g->second; - * // Do something here with the guild* in 'gp' - * } - * ``` - * - * @return The mutex used to protect the container - */ - std::shared_mutex& get_mutex() { - return this->cache_mutex; - } - - /** - * @brief Get the container unordered map - * - * @warning Be sure to use cache::get_mutex() correctly if you - * manipulate or iterate the map returned by this method! If you do - * not, this is not thread safe and will cause crashes! - * - * @see cache::get_mutex - * - * @return A reference to the cache's container map - */ - auto & get_container() { - return *(this->cache_map); - } - - /** - * @brief "Rehash" a cache by reallocating the map and copying - * all elements into the new one. - * - * Over a long running timeframe, unordered maps can grow in size - * due to bucket allocation, this function frees that unused memory - * to keep the maps in control over time. If this is an issue which - * is apparent with your use of dpp::cache objects, you should periodically - * call this method. - * - * @warning May be time consuming! This function is O(n) in relation to the - * number of cached entries. - */ - void rehash() { - std::unique_lock l(cache_mutex); - std::unordered_map* n = new std::unordered_map; - n->reserve(cache_map->size()); - for (auto t = cache_map->begin(); t != cache_map->end(); ++t) { - n->insert(*t); - } - delete cache_map; - cache_map = n; - } - - /** - * @brief Get "real" size in RAM of the cached objects - * - * This does not include metadata used to maintain the unordered map itself. - * - * @return size_t size of cache in bytes - */ - size_t bytes() { - std::shared_lock l(cache_mutex); - return sizeof(*this) + (cache_map->bucket_count() * sizeof(size_t)); - } - -}; - -/** - * Run garbage collection across all caches removing deleted items - * that have been deleted over 60 seconds ago. - */ -void DPP_EXPORT garbage_collection(); - -#define cache_decl(type, setter, getter, counter) /** Find an object in the cache by id. @return type* Pointer to the object or nullptr when it's not found */ DPP_EXPORT class type * setter (snowflake id); DPP_EXPORT cache * getter (); /** Get the amount of cached type objects. */ DPP_EXPORT uint64_t counter (); - -/* Declare major caches */ -cache_decl(user, find_user, get_user_cache, get_user_count); -cache_decl(guild, find_guild, get_guild_cache, get_guild_count); -cache_decl(role, find_role, get_role_cache, get_role_count); -cache_decl(channel, find_channel, get_channel_cache, get_channel_count); -cache_decl(emoji, find_emoji, get_emoji_cache, get_emoji_count); - -} - diff --git a/include/dpp/channel.h b/include/dpp/channel.h deleted file mode 100644 index 2879cdd..0000000 --- a/include/dpp/channel.h +++ /dev/null @@ -1,896 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** @brief Flag integers as received from and sent to discord */ -enum channel_type : uint8_t { - /** - * @brief A text channel within a server. - */ - CHANNEL_TEXT = 0, - - /** - * @brief A direct message between users. - */ - DM = 1, - - /** - * @brief A voice channel within a server. - */ - CHANNEL_VOICE = 2, - - /** - * @brief a direct message between multiple users - * @deprecated this channel type was intended to be used with the now deprecated GameBridge SDK. - * Existing group dms with bots will continue to function, but newly created channels will be unusable. - */ - GROUP_DM = 3, - - /** - * @brief An organizational category that contains up to 50 channels. - */ - CHANNEL_CATEGORY = 4, - - /** - * @brief A channel that users can follow and cross-post into their own server. - */ - CHANNEL_ANNOUNCEMENT = 5, - - /** - * @brief A channel in which game developers can sell their game on Discord. - * @deprecated Store channels are deprecated by Discord. - */ - CHANNEL_STORE = 6, - - /** - * @brief A temporary sub-channel within a `GUILD_ANNOUNCEMENT` channel. - */ - CHANNEL_ANNOUNCEMENT_THREAD = 10, - - /** - * @brief A temporary sub-channel within a `GUILD_TEXT` or `GUILD_FORUM` channel. - */ - CHANNEL_PUBLIC_THREAD = 11, - - /** - * @brief A temporary sub-channel within a `GUILD_TEXT` channel - * that is only viewable by those invited and those with the `MANAGE_THREADS` permission. - */ - CHANNEL_PRIVATE_THREAD = 12, - - /** - * @brief A "stage" channel, like a voice channel with one authorised speaker. - */ - CHANNEL_STAGE = 13, - - /** - * @brief The channel in a hub containing the listed servers. - * - * @see https://support.discord.com/hc/en-us/articles/4406046651927-Discord-Student-Hubs-FAQ - */ - CHANNEL_DIRECTORY = 14, - - /** - * @brief Forum channel that can only contain threads. - */ - CHANNEL_FORUM = 15, - - /** - * @brief Media channel that can only contain threads, similar to forum channels. - */ - CHANNEL_MEDIA = 16, -}; - -/** @brief Our flags as stored in the object - * @note The bottom four bits of this flag are reserved to contain the channel_type values - * listed above as provided by Discord. If discord add another value > 15, we will have to - * shuffle these values upwards by one bit. - */ -enum channel_flags : uint16_t { - /* Note that bits 1 to 4 are used for the channel type mask */ - /** - * @brief NSFW Gated Channel - */ - c_nsfw = 0b0000000000010000, - - /** - * @brief Video quality forced to 720p - */ - c_video_quality_720p = 0b0000000000100000, - - /** - * @brief Lock permissions (only used when updating channel positions) - */ - c_lock_permissions = 0b0000000001000000, - - /** - * @brief Thread is pinned to the top of its parent forum or media channel - */ - c_pinned_thread = 0b0000000010000000, - - /** - * @brief Whether a tag is required to be specified when creating a thread in a forum or media channel. - * Tags are specified in the thread::applied_tags field. - */ - c_require_tag = 0b0000000100000000, - - /* Note that the 9th and 10th bit are used for the forum layout type. */ - /** - * @brief When set hides the embedded media download options. Available only for media channels - */ - c_hide_media_download_options = 0b0001000000000000, -}; - -/** - * @brief Types for sort posts in a forum channel - */ -enum default_forum_sort_order_t : uint8_t { - /** - * @brief Sort forum posts by activity (default) - */ - so_latest_activity = 0, - - /** - * @brief Sort forum posts by creation time (from most recent to oldest) - */ - so_creation_date = 1, -}; - -/** - * @brief Types of forum layout views that indicates how the threads in a forum channel will be displayed for users by default - */ -enum forum_layout_type : uint8_t { - /** - * @brief No default has been set for the forum channel - */ - fl_not_set = 0, - - /** - * @brief Display posts as a list - */ - fl_list_view = 1, - - /** - * @brief Display posts as a collection of tiles - */ - fl_gallery_view = 2, -}; - -/** - * @brief channel permission overwrite types - */ -enum overwrite_type : uint8_t { - /** - * @brief Role - */ - ot_role = 0, - - /** - * @brief Member - */ - ot_member = 1 -}; - -/** - * @brief Channel permission overwrites - */ -struct DPP_EXPORT permission_overwrite { - /** - * @brief ID of the role or the member - */ - snowflake id; - - /** - * @brief Bitmask of allowed permissions - */ - permission allow; - - /** - * @brief Bitmask of denied permissions - */ - permission deny; - - /** - * @brief Type of overwrite. See dpp::overwrite_type - */ - uint8_t type; - - /** - * @brief Construct a new permission_overwrite object - */ - permission_overwrite(); - - /** - * @brief Construct a new permission_overwrite object - * @param id ID of the role or the member to create the overwrite for - * @param allow Bitmask of allowed permissions (refer to enum dpp::permissions) for this user/role in this channel - * @param deny Bitmask of denied permissions (refer to enum dpp::permissions) for this user/role in this channel - * @param type Type of overwrite - */ - permission_overwrite(snowflake id, uint64_t allow, uint64_t deny, overwrite_type type); -}; - -/** - * @brief Auto archive duration of threads which will stop showing in the channel list after the specified period of inactivity. - * Defined as an enum to fit into 1 byte. Internally it'll be translated to minutes to match the API - */ -enum auto_archive_duration_t : uint8_t { - /** - * @brief Auto archive duration of 1 hour (60 minutes). - */ - arc_1_hour = 1, - - /** - * @brief Auto archive duration of 1 day (1440 minutes). - */ - arc_1_day = 2, - - /** - * @brief Auto archive duration of 3 days (4320 minutes). - */ - arc_3_days = 3, - - /** - * @brief Auto archive duration of 1 week (10080 minutes). - */ - arc_1_week = 4, -}; - -/** - * @brief Represents a tag that is able to be applied to a thread in a forum or media channel - */ -struct DPP_EXPORT forum_tag : public managed, public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Read struct values from a json object - * @param j json to read values from - * @return A reference to self - */ - forum_tag& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build json for this forum_tag object - * - * @param with_id include the ID in the json - * @return json JSON object - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief The name of the tag (0-20 characters). - */ - std::string name; - - /** - * @brief The emoji of the tag. - * Contains either nothing, the id of a guild's custom emoji or the unicode character of the emoji. - */ - std::variant emoji; - - /** - * @brief Whether this tag can only be added to or removed from threads - * by a member with the `MANAGE_THREADS` permission. - */ - bool moderated; - - /** Constructor */ - forum_tag(); - - /** - * @brief Constructor - * - * @param name The name of the tag. It will be truncated to the maximum length of 20 UTF-8 characters. - */ - forum_tag(const std::string& name); - - /** Destructor */ - virtual ~forum_tag() = default; - - /** - * @brief Set name of this forum_tag object - * - * @param name Name to set - * @return Reference to self, so these method calls may be chained - * - * @note name will be truncated to 20 chars, if longer - */ - forum_tag& set_name(const std::string& name); -}; - -/** - * @brief A definition of a discord channel. - * There are one of these for every channel type except threads. Threads are - * special snowflakes. Get it? A Discord pun. Hahaha. .... I'll get my coat. - */ -class DPP_EXPORT channel : public managed, public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - channel& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build json for this channel object - * - * @param with_id include the ID in the json - * @return json JSON object - */ - virtual json to_json_impl(bool with_id = false) const; - - static constexpr uint16_t CHANNEL_TYPE_MASK = 0b0000000000001111; - -public: - /** - * @brief Channel name (1-100 characters). - */ - std::string name; - - /** - * @brief Channel topic (0-4096 characters for forum and media channels, 0-1024 characters for all others). - */ - std::string topic; - - /** - * @brief Voice region if set for voice channel, otherwise empty string. - */ - std::string rtc_region; - - /** - * @brief DM recipients. - */ - std::vector recipients; - - /** - * @brief Permission overwrites to apply to base permissions. - */ - std::vector permission_overwrites; - - /** - * @brief A set of tags that can be used in a forum or media channel. - */ - std::vector available_tags; - - /** - * @brief The emoji to show as the default reaction button on a thread in a forum or media channel. - * Contains either nothing, the id of a guild's custom emoji or the unicode character of the emoji. - */ - std::variant default_reaction; - - /** - * @brief Channel icon (for group DMs). - */ - utility::iconhash icon; - - /** - * @brief User ID of the creator for group DMs or threads. - */ - snowflake owner_id; - - /** - * @brief Parent ID (for guild channels: id of the parent category, for threads: id of the text channel this thread was created). - */ - snowflake parent_id; - - /** - * @brief Guild id of the guild that owns the channel. - */ - snowflake guild_id; - - /** - * @brief ID of last message to be sent to the channel. - * - * @warning may not point to an existing or valid message/thread. - */ - snowflake last_message_id; - - /** - * @brief Timestamp of last pinned message. - */ - time_t last_pin_timestamp; - - /** - * @brief This is only filled when the channel is part of the `resolved` set - * sent within an interaction. Any other time it contains zero. When filled, - * it contains the calculated permission bitmask of the user issuing the command - * within this channel. - */ - permission permissions; - - /** - * @brief Sorting position, lower number means higher up the list - */ - uint16_t position; - - /** - * @brief The bitrate (in kilobits) of the voice channel. - */ - uint16_t bitrate; - - /** - * @brief Amount of seconds a user has to wait before sending another message (0-21600). - * Bots, as well as users with the permission manage_messages or manage_channel, are unaffected - */ - uint16_t rate_limit_per_user; - - /** - * @brief The initial `rate_limit_per_user` to set on newly created threads in a channel. - * This field is copied to the thread at creation time and does not live update. - */ - uint16_t default_thread_rate_limit_per_user; - - /** - * @brief Default duration, copied onto newly created threads. Used by the clients, not the API. - * Threads will stop showing in the channel list after the specified period of inactivity. Defaults to dpp::arc_1_day. - */ - auto_archive_duration_t default_auto_archive_duration; - - /** - * @brief The default sort order type used to order posts in forum and media channels. - */ - default_forum_sort_order_t default_sort_order; - - /** - * @brief Flags bitmap (dpp::channel_flags) - */ - uint16_t flags; - - /** - * @brief Maximum user limit for voice channels (0-99) - */ - uint8_t user_limit; - - /** Constructor */ - channel(); - - /** Destructor */ - virtual ~channel(); - - /** - * @brief Create a mentionable channel. - * @param id The ID of the channel. - * @return std::string The formatted mention of the channel. - */ - static std::string get_mention(const snowflake& id); - - /** - * @brief Set name of this channel object - * - * @param name Name to set - * @return Reference to self, so these method calls may be chained - * - * @note name will be truncated to 100 chars, if longer - * @throw dpp::length_exception if length < 1 - */ - channel& set_name(const std::string& name); - - /** - * @brief Set topic of this channel object - * - * @param topic Topic to set - * @return Reference to self, so these method calls may be chained - * - * @note topic will be truncated to 1024 chars, if longer - */ - channel& set_topic(const std::string& topic); - - /** - * @brief Set type of this channel object - * - * @param type Channel type to set - * @return Reference to self, so these method calls may be chained - */ - channel& set_type(channel_type type); - - /** - * @brief Set the default forum layout type for the forum channel - * - * @param layout_type The layout type - * @return Reference to self, so these method calls may be chained - */ - channel& set_default_forum_layout(forum_layout_type layout_type); - - /** - * @brief Set the default forum sort order for the forum channel - * - * @param sort_order The sort order - * @return Reference to self, so these method calls may be chained - */ - channel& set_default_sort_order(default_forum_sort_order_t sort_order); - - /** - * @brief Set flags for this channel object - * - * @param flags Flag bitmask to set from dpp::channel_flags - * @return Reference to self, so these method calls may be chained - */ - channel& set_flags(const uint16_t flags); - - /** - * @brief Add (bitwise OR) a flag to this channel object - * - * @param flag Flag bit to add from dpp::channel_flags - * @return Reference to self, so these method calls may be chained - */ - channel& add_flag(const channel_flags flag); - - /** - * @brief Remove (bitwise NOT AND) a flag from this channel object - * - * @param flag Flag bit to remove from dpp::channel_flags - * @return Reference to self, so these method calls may be chained - */ - channel& remove_flag(const channel_flags flag); - - /** - * @brief Set position of this channel object - * - * @param position Position to set - * @return Reference to self, so these method calls may be chained - */ - channel& set_position(const uint16_t position); - - /** - * @brief Set guild_id of this channel object - * - * @param guild_id Guild ID to set - * @return Reference to self, so these method calls may be chained - */ - channel& set_guild_id(const snowflake guild_id); - - /** - * @brief Set parent_id of this channel object - * - * @param parent_id Parent ID to set - * @return Reference to self, so these method calls may be chained - */ - channel& set_parent_id(const snowflake parent_id); - - /** - * @brief Set user_limit of this channel object - * - * @param user_limit Limit to set - * @return Reference to self, so these method calls may be chained - */ - channel& set_user_limit(const uint8_t user_limit); - - /** - * @brief Set bitrate of this channel object - * - * @param bitrate Bitrate to set (in kilobits) - * @return Reference to self, so these method calls may be chained - */ - channel& set_bitrate(const uint16_t bitrate); - - /** - * @brief Set nsfw property of this channel object - * - * @param is_nsfw true, if channel is nsfw - * @return Reference to self, so these method calls may be chained - */ - channel& set_nsfw(const bool is_nsfw); - - /** - * @brief Set lock permissions property of this channel object - * Used only with the reorder channels method - * - * @param is_lock_permissions true, if we are to inherit permissions from the category - * @return Reference to self, so these method calls may be chained - */ - channel& set_lock_permissions(const bool is_lock_permissions); - - /** - * @brief Set rate_limit_per_user of this channel object - * - * @param rate_limit_per_user rate_limit_per_user (slowmode in sec) to set - * @return Reference to self, so these method calls may be chained - */ - channel& set_rate_limit_per_user(const uint16_t rate_limit_per_user); - - /** - * @brief Add permission overwrites for a user or role. - * If the channel already has permission overwrites for the passed target, the existing ones will be adjusted by the passed permissions - * - * @param target ID of the role or the member you want to adjust overwrites for - * @param type type of overwrite - * @param allowed_permissions bitmask of dpp::permissions you want to allow for this user/role in this channel. Note: You can use the dpp::permission class - * @param denied_permissions bitmask of dpp::permissions you want to deny for this user/role in this channel. Note: You can use the dpp::permission class - * - * **Example:** - * - * ```cpp - * channel.add_permission_overwrite(388499352297406481, dpp::ot_role, dpp::p_manage_channels | dpp::p_manage_messages, 0); - * // Allows p_manage_channels and p_manage_messages permissions for the provided role. - * ``` - * - * @return Reference to self, so these method calls may be chained - */ - channel& add_permission_overwrite(const snowflake target, const overwrite_type type, const uint64_t allowed_permissions, const uint64_t denied_permissions); - /** - * @brief Set permission overwrites for a user or role on this channel object. Old permission overwrites for the target will be overwritten - * - * @param target ID of the role or the member you want to set overwrites for - * @param type type of overwrite - * @param allowed_permissions bitmask of allowed dpp::permissions for this user/role in this channel. Note: You can use the dpp::permission class - * @param denied_permissions bitmask of denied dpp::permissions for this user/role in this channel. Note: You can use the dpp::permission class - * - * **Example:** - * - * ```cpp - * channel.set_permission_overwrite(388499352297406481, dpp::ot_role, dpp::p_manage_channels | dpp::p_manage_messages, 0); - * // Sets the allowed permissions to p_manage_channels and p_manage_messages and removes all denied permission flags for the provided role. - * ``` - * - * @return Reference to self, so these method calls may be chained - * - * @note If both `allowed_permissions` and `denied_permissions` parameters are 0, the permission overwrite for the target will be removed - */ - channel& set_permission_overwrite(const snowflake target, const overwrite_type type, const uint64_t allowed_permissions, const uint64_t denied_permissions); - /** - * @brief Remove channel specific permission overwrites of a user or role - * - * @param target ID of the role or the member you want to remove permission overwrites of - * @param type type of overwrite - * - * @return Reference to self, so these method calls may be chained - */ - channel& remove_permission_overwrite(const snowflake target, const overwrite_type type); - - /** - * @brief Get the channel type - * - * @return channel_type Channel type - */ - channel_type get_type() const; - - /** - * @brief Get the default forum layout type used to display posts in forum channels - * - * @return forum_layout_types Forum layout type - */ - forum_layout_type get_default_forum_layout() const; - - /** - * @brief Get the mention ping for the channel - * - * @return std::string mention - */ - std::string get_mention() const; - - /** - * @brief Get the overall permissions for a member in this channel, including channel overwrites, role permissions and admin privileges. - * - * @param user The user to resolve the permissions for - * @return permission Permission overwrites for the member. Made of bits in dpp::permissions. - * @note Requires role cache to be enabled (it's enabled by default). - * - * @note This is an alias for guild::permission_overwrites and searches for the guild in the cache, - * so consider using guild::permission_overwrites if you already have the guild object. - * - * @warning The method will search for the guild member in the cache by the users id. - * If the guild member is not in cache, the method will always return 0. - */ - permission get_user_permissions(const class user* user) const; - - /** - * @brief Get the overall permissions for a member in this channel, including channel overwrites, role permissions and admin privileges. - * - * @param member The member to resolve the permissions for - * @return permission Permission overwrites for the member. Made of bits in dpp::permissions. - * @note Requires role cache to be enabled (it's enabled by default). - * - * @note This is an alias for guild::permission_overwrites and searches for the guild in the cache, - * so consider using guild::permission_overwrites if you already have the guild object. - */ - permission get_user_permissions(const class guild_member &member) const; - - /** - * @brief Return a map of members on the channel, built from the guild's - * member list based on which members have the VIEW_CHANNEL permission. - * Does not return reliable information for voice channels, use - * dpp::channel::get_voice_members() instead for this. - * @return A map of guild members keyed by user id. - * @note If the guild this channel belongs to is not in the cache, the function will always return 0. - */ - std::map get_members(); - - /** - * @brief Get a map of members in this channel, if it is a voice channel. - * The map is keyed by snowflake id of the user. - * - * @return std::map The voice members of the channel - */ - std::map get_voice_members(); - - /** - * @brief Get the channel's icon url (if its a group DM), 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. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg` or `i_png`. - * @return std::string icon url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_icon_url(uint16_t size = 0, const image_type format = i_png) const; - - /** - * @brief Returns string of URL to channel - * - * @return string of URL to channel - */ - std::string get_url() const; - - /** - * @brief Returns true if the channel is NSFW gated - * - * @return true if NSFW - */ - bool is_nsfw() const; - - /** - * @brief Returns true if the permissions are to be synced with the category it is in. - * Used only and set manually when using the reorder channels method. - * - * @return true if keeping permissions - */ - bool is_locked_permissions() const; - - /** - * @brief Returns true if the channel is a text channel - * - * @return true if text channel - */ - bool is_text_channel() const; - - /** - * @brief Returns true if the channel is a DM - * - * @return true if is a DM - */ - bool is_dm() const; - - /** - * @brief Returns true if the channel is a voice channel - * - * @return true if voice channel - */ - bool is_voice_channel() const; - - /** - * @brief Returns true if the channel is a group DM channel - * - * @return true if group DM - */ - bool is_group_dm() const; - - /** - * @brief Returns true if the channel is a category - * - * @return true if a category - */ - bool is_category() const; - - /** - * @brief Returns true if the channel is a forum - * - * @return true if a forum - */ - bool is_forum() const; - - /** - * @brief Returns true if the channel is a media channel - * - * @return true if media channel - */ - bool is_media_channel() const; - - /** - * @brief Returns true if the channel is an announcement channel - * - * @return true if announcement channel - */ - bool is_news_channel() const; - - /** - * @brief Returns true if the channel is a store channel - * @deprecated store channels are deprecated by Discord - * - * @return true if store channel - */ - bool is_store_channel() const; - - /** - * @brief Returns true if the channel is a stage channel - * - * @return true if stage channel - */ - bool is_stage_channel() const; - - /** - * @brief Returns true if video quality is auto - * - * @return true if video quality is auto - */ - bool is_video_auto() const; - - /** - * @brief Returns true if video quality is 720p - * - * @return true if video quality is 720p - */ - bool is_video_720p() const; - - /** - * @brief Returns true if channel is a pinned thread in forum - * - * @return true, if channel is a pinned thread in forum - */ - bool is_pinned_thread() const; - - /** - * @brief Returns true if a tag is required to be specified when creating a thread in a forum channel - * - * @return true, if a tag is required to be specified when creating a thread in a forum channel - */ - bool is_tag_required() const; - - /** - * @brief Returns true if embedded media download options are hidden in a media channel - * - * @return true, if embedded media download options are hidden in a media channel - */ - bool is_download_options_hidden() const; - -}; - -/** - * @brief Serialize a permission_overwrite object to json - * - * @param j JSON object to serialize to - * @param po object to serialize - */ -void to_json(nlohmann::json& j, const permission_overwrite& po); - -/** - * @brief A group of channels - */ -typedef std::unordered_map channel_map; - -} - diff --git a/include/dpp/cluster.h b/include/dpp/cluster.h deleted file mode 100644 index ed6573d..0000000 --- a/include/dpp/cluster.h +++ /dev/null @@ -1,4109 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Pass this value into the constructor of dpp::cluster for the shard count to create a cluster with no shards. - * A cluster with no shards does not connect to a websocket, but can still use the event loop to dispatch HTTPS API - * requests to Discord. This is useful for bots that do not need to receive websocket events as it will save a lot of - * resources. - */ -constexpr uint32_t NO_SHARDS = ~0U; - -/** - * @brief Types of startup for cluster::start() - */ -enum start_type : bool { - /** - * @brief Wait forever on a condition variable. - * The cluster will spawn threads for each shard - * and start() will not return in normal operation. - */ - st_wait = false, - - /** - * @brief Return immediately after starting shard threads. - * If you set the parameter of cluster::start() to - * this value, you will have to manage the lifetime - * and scope of your cluster object yourself. Taking it - * out of scope or deleting its pointer will terminate - * the bot. - */ - st_return = true, -}; - -/** @brief The cluster class represents a group of shards and a command queue for sending and - * receiving commands from discord via HTTP. You should usually instantiate a cluster object - * at the very least to make use of the library. - */ -class DPP_EXPORT cluster { - - friend class discord_client; - friend class discord_voice_client; - - /** - * @brief default gateway for connecting the websocket. - */ - std::string default_gateway; - - /** - * @brief queue system for commands sent to Discord, and any replies - */ - request_queue* rest; - - /** - * @brief queue system for arbitrary HTTP requests sent by the user to sites other than Discord - */ - request_queue* raw_rest; - - /** - * @brief True if to use compression on shards - */ - bool compressed; - - /** - * @brief Lock to prevent concurrent access to dm_channels - */ - std::mutex dm_list_lock; - - /** - * @brief Start time of cluster - */ - time_t start_time; - - /** - * @brief Active DM channels for the bot - */ - std::unordered_map dm_channels; - - /** - * @brief Active shards on this cluster. Shard IDs may have gaps between if there - * are multiple clusters. - */ - shard_list shards; - - /** - * @brief List of shards waiting for reconnection - */ - reconnect_list reconnections; - - /** - * @brief Ephemeral list of deleted timer ids - */ - timers_deleted_t deleted_timers; - - /** - * @brief Priority queue of of timers by time - */ - timer_next_t next_timer; - - /** - * @brief Mutex to work with named_commands and synchronize read write access - */ - std::shared_mutex named_commands_mutex; - - /** - * @brief Mutex for protection of shards list - */ - mutable std::shared_mutex shards_mutex; - - /** - * @brief Typedef for slashcommand handler type - */ - using slashcommand_handler_t = std::function; - -#ifndef DPP_NO_CORO - /** - * @brief Typedef for coroutines based slashcommand handler type - */ - using co_slashcommand_handler_t = std::function(const slashcommand_t&)>; - - /** - * @brief Typedef for variant of coroutines based slashcommand handler type and regular version of it - */ - using slashcommand_handler_variant = std::variant; - - /** - * @brief Container to store relation between command name and it's handler - */ - std::map named_commands; -#else - /** - * @brief Container to store relation between command name and it's handler - */ - std::map named_commands; -#endif - /** - * @brief Thread pool - */ - std::unique_ptr pool{nullptr}; - - /** - * @brief Used to spawn the socket engine into its own thread if - * the cluster is started with dpp::st_return. It is unused otherwise. - */ - std::thread engine_thread; - - /** - * @brief Protection mutex for timers - */ - std::mutex timer_guard; - - /** - * @brief Webhook server if enabled - */ - struct discord_webhook_server* webhook_server{nullptr}; - - /** - * @brief Mark a shard as requiring reconnection. - * Destructs the old shard in 5 seconds and creates a new one attempting to resume. - * - * @param shard_id Shard ID - */ - void add_reconnect(uint32_t shard_id); - -public: - /** - * @brief Current bot token for all shards on this cluster and all commands sent via HTTP - */ - std::string token; - - /** - * @brief Last time the bot sent an IDENTIFY - */ - time_t last_identify; - - /** - * @brief Current bitmask of gateway intents - */ - uint32_t intents; - - /** - * @brief Total number of shards across all clusters - */ - uint32_t numshards; - - /** - * @brief ID of this cluster, between 0 and MAXCLUSTERS-1 inclusive - */ - uint32_t cluster_id; - - /** - * @brief Total number of clusters that are active - */ - uint32_t maxclusters; - - /** - * @brief REST latency (HTTPS ping) in seconds - */ - double rest_ping; - - /** - * @brief The details of the bot user. This is assumed to be identical across all shards - * in the cluster. Each connecting shard updates this information. - */ - dpp::user me; - - /** - * @brief Current cache policy for the cluster - */ - cache_policy_t cache_policy; - - /** - * @brief Websocket mode for all shards in the cluster, either ws_json or ws_etf. - * Production bots should use ETF, while development bots should use JSON. - */ - websocket_protocol_t ws_mode; - - /** - * @brief Atomic bool to set to true when the cluster is terminating. - * - * D++ itself does not set this value, it is for library users to set if they want - * the cluster to terminate outside of a flow where they may have simple access to - * destruct the cluster object. - */ - std::atomic_bool terminating{false}; - - /** - * @brief The time (in seconds) that a request is allowed to take. - */ - uint16_t request_timeout = 60; - - /** - * @brief Socket engine instance - */ - std::unique_ptr socketengine; - - /** - * @brief Constructor for creating a cluster without a token. - * A cluster created without a token has no shards, and just runs the event loop. You can use this to make asynchronous - * HTTP requests via e.g. dpp::cluster::request without having to connect to a websocket to receive shard events. - * @param pool_threads The number of threads to allocate for the thread pool. This defaults to half your system concurrency and if set to a number less than 4, will default to 4. - * All callbacks and events are placed into the thread pool. The bigger you make this pool (but generally no bigger than your number of cores), the more your bot will scale. - * @throw dpp::exception Thrown on windows, if WinSock fails to initialise, or on any other system if a dpp::request_queue fails to construct - */ - explicit cluster(uint32_t pool_threads = std::thread::hardware_concurrency() / 2); - - /** - * @brief Constructor for creating a cluster. All but the token are optional. - * @param token The bot token to use for all HTTP commands and websocket connections - * @param intents A bitmask of dpd::intents values for all shards on this cluster. This is required to be sent for all bots with over 100 servers. - * @param shards The total number of shards on this bot. If there are multiple clusters, then (shards / clusters) actual shards will run on this cluster. - * If you omit this value, the library will attempt to query the Discord API for the correct number of shards to start. - * @param cluster_id The ID of this cluster, should be between 0 and MAXCLUSTERS-1 - * @param maxclusters The total number of clusters that are active, which may be on separate processes or even separate machines. - * @param compressed Whether or not to use compression for shards on this cluster. Saves a ton of bandwidth at the cost of some CPU - * @param policy Set the caching policy for the cluster, either lazy (only cache users/members when they message the bot) or aggressive (request whole member lists on seeing new guilds too) - * @param pool_threads The number of threads to allocate for the thread pool. This defaults to half your system concurrency and if set to a number less than 4, will default to 4. - * All callbacks and events are placed into the thread pool. The bigger you make this pool (but generally no bigger than your number of cores), the more your bot will scale. - * @throw dpp::exception Thrown on windows, if WinSock fails to initialise, or on any other system if a dpp::request_queue fails to construct - */ - cluster(const std::string& token, uint32_t intents = i_default_intents, uint32_t shards = 0, uint32_t cluster_id = 0, uint32_t maxclusters = 1, bool compressed = true, cache_policy_t policy = cache_policy::cpol_default, uint32_t pool_threads = std::thread::hardware_concurrency() / 2); - - /** - * @brief Create a webhook server for receiving interactions - * @note This should be considered mutually exclusive with delivery of interaction events via shards. - * @param discord_public_key Public key for the application from the application dashboard page - * @param address address to bind to, use "0.0.0.0" to bind to all local addresses - * @param port port to bind to. You should generally use a port > 1024. - * @param ssl_private_key Private key PEM file for HTTPS/SSL. If empty, a plaintext server is created - * @param ssl_public_key Public key PEM file for HTTPS/SSL. If empty, a plaintext server is created - */ - cluster& enable_webhook_server(const std::string& discord_public_key, const std::string_view address, uint16_t port, const std::string& ssl_private_key = "", const std::string& ssl_public_key = ""); - - /** - * @brief Place some arbitrary work into the thread pool for execution when time permits. - * - * Work units are fetched into threads on the thread pool from the queue in order of priority, - * lowest numeric values first. Low numeric values should be reserved for API replies from Discord, - * guild creation events, etc. - * - * @param priority Priority of the work unit - * @param task Task to queue - */ - void queue_work(int priority, work_unit task); - - /** - * @brief dpp::cluster is non-copyable - */ - cluster(const cluster&) = delete; - - /** - * @brief dpp::cluster is non-moveable - */ - cluster(const cluster&&) = delete; - - /** - * @brief dpp::cluster is non-copyable - */ - cluster& operator=(const cluster&) = delete; - - /** - * @brief dpp::cluster is non-moveable - */ - cluster& operator=(const cluster&&) = delete; - - /** - * @brief Destroy the cluster object - */ - virtual ~cluster(); - - /** - * @brief End cluster execution without destructing it. - * To restart the cluster, call cluster::start() again. - */ - void shutdown(); - - /** - * @brief Get the rest_queue object which handles HTTPS requests to Discord - * @return request_queue* pointer to request_queue object - */ - request_queue* get_rest(); - - /** - * @brief Get the raw rest_queue object which handles all HTTP(S) requests that are not directed at Discord - * @return request_queue* pointer to request_queue object - */ - request_queue* get_raw_rest(); - - /** - * @brief Set the websocket protocol for all shards on this cluster. - * You should call this method before cluster::start. - * Generally ws_etf is faster, but provides less facilities for debugging should something - * go wrong. It is recommended to use ETF in production and JSON in development. - * - * @param mode websocket protocol to use, either ws_json or ws_etf. - * @return cluster& Reference to self for chaining. - * @throw dpp::logic_exception If called after the cluster is started (this is not supported) - */ - cluster& set_websocket_protocol(websocket_protocol_t mode); - - /** - * @brief Tick active timers - */ - void tick_timers(); - - /** - * @brief Set the audit log reason for the next REST call to be made. - * This is set per-thread, so you must ensure that if you call this method, your request that - * is associated with the reason happens on the same thread where you set the reason. - * Once the next call is made, the audit log reason is cleared for this thread automatically. - * - * Example: - * ``` - * bot.set_audit_reason("Too much abusive content") - * .channel_delete(my_channel_id); - * ``` - * - * @param reason The reason to set for the next REST call on this thread - * @return cluster& Reference to self for chaining. - */ - cluster& set_audit_reason(const std::string &reason); - - /** - * @brief Clear the audit log reason for the next REST call to be made. - * This is set per-thread, so you must ensure that if you call this method, your request that - * is associated with the reason happens on the same thread where you set the reason. - * Once the next call is made, the audit log reason is cleared for this thread automatically. - * - * Example: - * ``` - * bot.set_audit_reason("Won't be sent") - * .clear_audit_reason() - * .channel_delete(my_channel_id); - * ``` - * - * @return cluster& Reference to self for chaining. - */ - cluster& clear_audit_reason(); - - /** - * @brief Get the audit reason set for the next REST call to be made on this thread. - * This is set per-thread, so you must ensure that if you call this method, your request that - * is associated with the reason happens on the same thread where you set the reason. - * Once the next call is made, the audit log reason is cleared for this thread automatically. - * - * @note This method call clears the audit reason when it returns it. - * - * @return std::string The audit reason to be used. - * - */ - std::string get_audit_reason(); - - /** - * @brief Sets the address of the default gateway, for connecting the websockets. - * - * @return cluster& Reference to self for chaining. - */ - cluster& set_default_gateway(const std::string& default_gateway); - - /** - * @brief Log a message to whatever log the user is using. - * The logged message is passed up the chain to the on_log event in user code which can then do whatever - * it wants to do with it. - * @param severity The log level from dpp::loglevel - * @param msg The log message to output - */ - void log(dpp::loglevel severity, const std::string &msg) const; - - /** - * @brief Start a timer. Every `frequency` seconds, the callback is called. - * - * @param on_tick The callback lambda to call for this timer when ticked - * @param on_stop The callback lambda to call for this timer when it is stopped - * @param frequency How often to tick the timer in seconds - * @return timer A handle to the timer, used to remove that timer later - */ - timer start_timer(timer_callback_t on_tick, uint64_t frequency, timer_callback_t on_stop = {}); - -#ifndef DPP_NO_CORO - /** - * @brief Start a coroutine timer. Every `frequency` seconds, the callback is called. - * - * @param on_tick The callback lambda to call for this timer when ticked - * @param on_stop The callback lambda to call for this timer when it is stopped - * @param frequency How often to tick the timer in seconds - * @return timer A handle to the timer, used to remove that timer later - */ - template T, std::invocable U = std::function> - requires (dpp::awaitable_type::type>) - timer start_timer(T&& on_tick, uint64_t frequency, U&& on_stop = {}) { - std::function ticker = [fun = std::forward(on_tick)](timer t) mutable -> dpp::job { - co_await std::invoke(fun, t); - }; - std::function stopper; - if constexpr (dpp::awaitable_type::type>) { - stopper = [fun = std::forward(on_stop)](timer t) mutable -> dpp::job { - co_await std::invoke(fun, t); - }; - } else { - stopper = std::forward(on_stop); - } - return start_timer(std::move(ticker), frequency, std::move(stopper)); - } -#endif - - /** - * @brief Stop a ticking timer - * - * @param t Timer handle received from cluster::start_timer - * @return bool True if the timer was stopped, false if it did not exist - * @note If the timer has an on_stop lambda, the on_stop lambda will be called. - */ - bool stop_timer(timer t); - -#ifndef DPP_NO_CORO - /** - * @brief Get an awaitable to wait a certain amount of seconds. Use the co_await keyword on its return value to suspend the coroutine until the timer ends - * - * @param seconds How long to wait for - * @return async Object that can be co_await-ed to suspend the function for a certain time - */ - [[nodiscard]] async co_sleep(uint64_t seconds); -#endif - - /** - * @brief Get the dm channel for a user id - * - * @param user_id the user id to get the dm channel for - * @return Returns 0 on failure - */ - snowflake get_dm_channel(snowflake user_id); - - /** - * @brief Set the dm channel id for a user id - * - * @param user_id user id to set the dm channel for - * @param channel_id dm channel to set - */ - void set_dm_channel(snowflake user_id, snowflake channel_id); - - /** - * @brief Returns the uptime of the cluster - * - * @return dpp::utility::uptime The uptime of the cluster - */ - dpp::utility::uptime uptime(); - - /** - * @brief Start the cluster, connecting all its shards. - * - * Returns once all shards are connected if return_after is true, - * otherwise enters an infinite loop while the shards run. - * - * @param return_after If true the bot will return to your program after starting shards, if false this function will never return. - */ - void start(start_type return_after = st_wait); - - /** - * @brief Set the presence for all shards on the cluster - * - * @param p The presence to set. Only the online status and the first activity are sent. - */ - void set_presence(const class dpp::presence &p); - - /** - * @brief Get a shard by id, returning the discord_client - * - * @param id Shard ID - * @return discord_client* shard, or null - */ - discord_client* get_shard(uint32_t id) const; - - /** - * @brief Get the list of shards - * - * @return shard_list map of shards for this cluster - */ - shard_list get_shards() const; - - /** - * @brief Sets the request timeout. - * - * @param timeout The length of time (in seconds) that requests are allowed to take. Default: 20. - * - * @return cluster& Reference to self for chaining. - */ - cluster& set_request_timeout(uint16_t timeout); - - /* Functions for attaching to event handlers */ - - /** - * @brief Register a slash command handler. - * - * @param name The name of the slash command to register - * @param handler A handler function of type `slashcommand_handler_t` - * - * @return bool Returns `true` if the command was registered successfully, or `false` if - * the command with the same name already exists - */ - bool register_command(const std::string& name, const slashcommand_handler_t handler); - - /** - * @brief Get the number of currently active HTTP(S) requests active in the cluster. - * This total includes all in-flight API requests and calls to dpp::cluster::request(). - * Note that once a request is passed to the thread pool it is no longer counted here. - * @return Total active request count - */ - size_t active_requests(); - -#ifndef DPP_NO_CORO - /** - * @brief Register a coroutine-based slash command handler. - * - * @param name The name of the slash command to register. - * @param handler A coroutine handler function of type `co_slashcommand_handler_t`. - * - * @return bool Returns `true` if the command was registered successfully, or `false` if - * the command with the same name already exists. - */ - template - std::enable_if_t, dpp::task>, bool> - register_command(const std::string& name, F&& handler){ - std::unique_lock lk(named_commands_mutex); - auto [_, inserted] = named_commands.try_emplace(name, std::forward(handler)); - return inserted; - }; -#endif - - /** - * @brief Unregister a slash command. - * - * This function unregisters (removes) a previously registered slash command by name. - * If the command is successfully removed, it returns `true`. - * - * @param name The name of the slash command to unregister. - * - * @return bool Returns `true` if the command was successfully unregistered, or `false` - * if the command was not found. - */ - bool unregister_command(const std::string& name); - - /** - * @brief on voice state update event - * - * @see https://discord.com/developers/docs/topics/gateway-events#voice-state-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_state_update_t&, and returns void. - */ - event_router_t on_voice_state_update; - - /** - * @brief on voice client platform event - * After a client connects, or on joining a vc, you will receive the platform type of each client. This is either desktop - * or mobile. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_client_disconnect_t&, and returns void. - */ - event_router_t on_voice_client_platform; - - /** - * @brief on voice client disconnect event - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_client_disconnect_t&, and returns void. - */ - event_router_t on_voice_client_disconnect; - - - /** - * @brief on voice client speaking event - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_client_speaking_t&, and returns void. - */ - event_router_t on_voice_client_speaking; - - - /** - * @brief Called when a log message is to be written to the log. - * You can attach any logging system here you wish, e.g. spdlog, or even just a simple - * use of std::cout or printf. If nothing attaches this log event, then the - * library will be silent. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type log_t&, and returns void. - */ - event_router_t on_log; - - /** - * @brief Called when a file descriptor is removed from the socket engine - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type socket_close_t&, and returns void. - */ - event_router_t on_socket_close; - - /** - * @brief on guild join request delete. - * Triggered when a user declines the membership screening questionnaire for a guild. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_join_request_delete_t&, and returns void. - */ - event_router_t on_guild_join_request_delete; - - - /** - * @brief Called when a new interaction is created. - * Interactions are created by discord when commands you have registered are issued - * by a user. For an example of this in action please see \ref slashcommands - * - * @see https://discord.com/developers/docs/topics/gateway-events#interaction-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type interaction_create_t&, and returns void. - * - * @note There are dedicated events to handle slashcommands (See dpp::cluster::on_slashcommand), - * user context menus (See dpp::cluster::on_user_context_menu) and message context menus (See dpp::cluster::on_message_context_menu) - */ - event_router_t on_interaction_create; - - /** - * @brief Called when a slash command is issued. - * Only dpp::ctxm_chat_input types of interaction are routed to this event. - * For an example of this in action please see \ref slashcommands - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type slashcommand_t&, and returns void. - */ - event_router_t on_slashcommand; - - /** - * @brief Called when a button is clicked attached to a message. - * Button clicks are triggered by discord when buttons are clicked which you have - * associated with a message using dpp::component. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type button_click_t&, and returns void. - */ - event_router_t on_button_click; - - /** - * @brief Called when an auto completed field needs suggestions to present to the user - * This is triggered by discord when option choices have auto completion enabled which you have - * associated with a dpp::slashcommand. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type autocomplete_t&, and returns void. - */ - event_router_t on_autocomplete; - - - /** - * @brief Called when a select menu is clicked attached to a message. - * Select menu clicks are triggered by discord when select menus are clicked which you have - * associated with a message using dpp::component. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type select_click_t&, and returns void. - */ - event_router_t on_select_click; - - /** - * @brief Called when a user right-clicks or long-presses on a message, - * where a slash command is bound to the dpp::ctxm_message command type. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_context_menu_t&, and returns void. - */ - event_router_t on_message_context_menu; - - /** - * @brief Called when a user right-clicks or long-presses on a user, - * where a slash command is bound to the dpp::ctxm_user command type. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type user_context_menu_t&, and returns void. - */ - event_router_t on_user_context_menu; - - /** - * @brief Called when a modal dialog is submitted. - * Form submits are triggered by discord when modal dialogs are submitted which you have - * associated with a slash command using dpp::interaction_modal_response. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type form_submit_t&, and returns void. - */ - event_router_t on_form_submit; - - - /** - * @brief Called when a guild is deleted. - * A guild can be deleted via the bot being kicked, the bot leaving the guild - * explicitly with dpp::cluster::guild_delete, or via the guild being unavailable due to - * an outage. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_delete_t&, and returns void. - */ - event_router_t on_guild_delete; - - - /** - * @brief Called when a channel is deleted from a guild. - * The channel will still be temporarily available in the cache. Pointers to the - * channel should not be retained long-term as they will be deleted by the garbage - * collector. - * - * @see https://discord.com/developers/docs/topics/gateway-events#channel-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type channel_delete_t&, and returns void. - */ - event_router_t on_channel_delete; - - - /** - * @brief Called when a channel is edited on a guild. - * The new channel details have already been applied to the guild when you - * receive this event. - * - * @see https://discord.com/developers/docs/topics/gateway-events#channel-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type channel_update_t&, and returns void. - */ - event_router_t on_channel_update; - - - /** - * @brief Called when a shard is connected and ready. - * A set of cluster::on_guild_create events will follow this event. - * - * @see https://discord.com/developers/docs/topics/gateway-events#ready - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type ready_t&, and returns void. - */ - event_router_t on_ready; - - - /** - * @brief Called when a message is deleted. - * The message has already been deleted from Discord when you - * receive this event. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_delete_t&, and returns void. - */ - event_router_t on_message_delete; - - - /** - * @brief Called when a user leaves a guild (either through being kicked, or choosing to leave) - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-member-remove - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_member_remove_t&, and returns void. - */ - event_router_t on_guild_member_remove; - - - /** - * @brief Called when a connection to a shard successfully resumes. - * A resumed session does not need to re-synchronise guilds, members, etc. - * This is generally non-fatal and informational only. - * - * @see https://discord.com/developers/docs/topics/gateway-events#resumed - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type resumed_t&, and returns void. - */ - event_router_t on_resumed; - - - /** - * @brief Called when a new role is created on a guild. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-role-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_role_create_t&, and returns void. - */ - event_router_t on_guild_role_create; - - - /** - * @brief Called when a user is typing on a channel. - * - * @see https://discord.com/developers/docs/topics/gateway-events#typing-start - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type typing_start_t&, and returns void. - */ - event_router_t on_typing_start; - - - /** - * @brief Called when a new reaction is added to a message. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-reaction-add - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_reaction_add_t&, and returns void. - */ - event_router_t on_message_reaction_add; - - - /** - * @brief Called when a set of members is received for a guild. - * D++ will request these for all new guilds if needed, after the cluster::on_guild_create - * events. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-members-chunk - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_members_chunk_t&, and returns void. - */ - event_router_t on_guild_members_chunk; - - - /** - * @brief Called when a single reaction is removed from a message. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-reaction-remove - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_reaction_remove_t&, and returns void. - */ - event_router_t on_message_reaction_remove; - - - /** - * @brief Called when a new guild is created. - * D++ will request members for the guild for its cache using guild_members_chunk. - * - * @warning If the cache policy has disabled guild caching, the pointer in this event will become invalid after the - * event ends. You should make a copy of any data you wish to preserve beyond this. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_create_t&, and returns void. - */ - event_router_t on_guild_create; - - - /** - * @brief Called when a new channel is created on a guild. - * - * @warning If the cache policy has disabled channel caching, the pointer in this event will become invalid after the - * event ends. You should make a copy of any data you wish to preserve beyond this. - * - * @see https://discord.com/developers/docs/topics/gateway-events#channel-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type channel_create_t&, and returns void. - */ - event_router_t on_channel_create; - - - /** - * @brief Called when all reactions for a particular emoji are removed from a message. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-reaction-remove-emoji - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_reaction_remove_emoji_t&, and returns void. - */ - event_router_t on_message_reaction_remove_emoji; - - - /** - * @brief Called when multiple messages are deleted from a channel or DM. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-delete-bulk - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_delete_bulk_t&, and returns void. - */ - event_router_t on_message_delete_bulk; - - - /** - * @brief Called when an existing role is updated on a guild. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-role-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_role_update_t&, and returns void. - */ - event_router_t on_guild_role_update; - - - /** - * @brief Called when a role is deleted in a guild. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-role-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_role_delete_t&, and returns void. - */ - event_router_t on_guild_role_delete; - - - /** - * @brief Called when a message is pinned. - * Note that the pinned message is not returned to this event, just the timestamp - * of the last pinned message. - * - * @see https://discord.com/developers/docs/topics/gateway-events#channel-pins-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type channel_pins_update_t&, and returns void. - */ - event_router_t on_channel_pins_update; - - - /** - * @brief Called when all reactions are removed from a message. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-reaction-remove-all - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_reaction_remove_all_t&, and returns void. - */ - event_router_t on_message_reaction_remove_all; - - - /** - * @brief Called when we are told which voice server we can use. - * This will be sent either when we establish a new voice channel connection, - * or as discord rearrange their infrastructure. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_server_update_t&, and returns void. - */ - event_router_t on_voice_server_update; - - - /** - * @brief Called when new emojis are added to a guild. - * The complete set of emojis is sent every time. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-emojis-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_emojis_update_t&, and returns void. - */ - event_router_t on_guild_emojis_update; - - - /** - * @brief Called when new stickers are added to a guild. - * The complete set of stickers is sent every time. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-stickers-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_stickers_update_t&, and returns void. - */ - event_router_t on_guild_stickers_update; - - - /** - * @brief Called when a user's presence is updated. - * To receive these you will need the GUILD_PRESENCES privileged intent. - * You will receive many of these, very often, and receiving them will significantly - * increase your bot's CPU usage. If you don't need them it is recommended to not ask - * for them. - * - * @see https://discord.com/developers/docs/topics/gateway-events#presence-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type presence_update_t&, and returns void. - */ - event_router_t on_presence_update; - - - /** - * @brief Called when the webhooks for a guild are updated. - * - * @see https://discord.com/developers/docs/topics/gateway-events#webhooks-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type webhooks_update_t&, and returns void. - */ - event_router_t on_webhooks_update; - - /** - * @brief Called when a new automod rule is created. - * - * @see https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type automod_rule_create_t&, and returns void. - */ - event_router_t on_automod_rule_create; - - - /** - * @brief Called when an automod rule is updated. - * - * @see https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type automod_rule_update_t&, and returns void. - */ - event_router_t on_automod_rule_update; - - /** - * @brief Called when an automod rule is deleted. - * - * @see https://discord.com/developers/docs/topics/gateway-events#auto-moderation-rule-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type automod_rule_delete_t&, and returns void. - */ - event_router_t on_automod_rule_delete; - - /** - * @brief Called when an automod rule is triggered/executed. - * - * @see https://discord.com/developers/docs/topics/gateway-events#auto-moderation-action-execution - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type automod_rule_execute_t&, and returns void. - */ - event_router_t on_automod_rule_execute; - - /** - * @brief Called when a new member joins a guild. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-member-add - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_member_add_t&, and returns void. - */ - event_router_t on_guild_member_add; - - - /** - * @brief Called when an invite is deleted from a guild. - * - * @see https://discord.com/developers/docs/topics/gateway-events#invite-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type invite_delete_t&, and returns void. - */ - event_router_t on_invite_delete; - - - /** - * @brief Called when details of a guild are updated. - * - * @warning If the cache policy has disabled guild caching, the pointer in this event will become invalid after the - * event ends. You should make a copy of any data you wish to preserve beyond this. If the guild cache is disabled, - * only changed elements in the updated guild object will be set. all other values will be empty or defaults. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_update_t&, and returns void. - */ - event_router_t on_guild_update; - - - /** - * @brief Called when an integration is updated for a guild. - * This returns the complete list. - * An integration is a connection to a guild of a user's associated accounts, - * e.g. youtube or twitch, for automatic assignment of roles etc. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-integrations-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_integrations_update_t&, and returns void. - */ - event_router_t on_guild_integrations_update; - - - /** - * @brief Called when details of a guild member (e.g. their roles or nickname) are updated. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-member-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_member_update_t&, and returns void. - */ - event_router_t on_guild_member_update; - - - /** - * @brief Called when a new invite is created for a guild. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#invite-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type invite_create_t&, and returns void. - */ - event_router_t on_invite_create; - - - /** - * @brief Called when a message is updated (edited). - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_update_t&, and returns void. - */ - event_router_t on_message_update; - - - /** - * @brief Called when a user is updated. - * This is separate to cluster::on_guild_member_update and includes things such as an avatar change, - * username change, discriminator change or change in subscription status for nitro. - * - * @see https://discord.com/developers/docs/topics/gateway-events#user-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type user_update_t&, and returns void. - */ - event_router_t on_user_update; - - - /** - * @brief Called when a new message arrives from discord. - * Note that D++ does not cache messages. If you want to cache these objects you - * should create something yourself within your bot. Caching of messages is not on - * the roadmap to be supported as it consumes excessive amounts of RAM. - * For an example for caching of messages, please see \ref caching-messages - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_create_t&, and returns void. - */ - event_router_t on_message_create; - - /** - * @brief Called when a vote is added to a message poll. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-poll-vote-add - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_poll_vote_add_t&, and returns void. - */ - event_router_t on_message_poll_vote_add; - - /** - * @brief Called when a vote is removed from a message poll. - * - * @see https://discord.com/developers/docs/topics/gateway-events#message-poll-vote-remove - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type message_poll_vote_remove_t&, and returns void. - */ - event_router_t on_message_poll_vote_remove; - - /** - * @brief Called when a guild audit log entry is created. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-audit-log-entry-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_audit_log_entry_create_t&, and returns void. - */ - event_router_t on_guild_audit_log_entry_create; - - /** - * @brief Called when a ban is added to a guild. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-ban-add - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_ban_add_t&, and returns void. - */ - event_router_t on_guild_ban_add; - - - /** - * @brief Called when a ban is removed from a guild. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-ban-remove - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_ban_remove_t&, and returns void. - */ - event_router_t on_guild_ban_remove; - - - /** - * @brief Called when a new integration is attached to a guild by a user. - * An integration is a connection to a guild of a user's associated accounts, - * e.g. youtube or twitch, for automatic assignment of roles etc. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#integration-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type integration_create_t&, and returns void. - */ - event_router_t on_integration_create; - - - /** - * @brief Called when an integration is updated by a user. - * This returns details of just the single integration that has changed. - * An integration is a connection to a guild of a user's associated accounts, - * e.g. youtube or twitch, for automatic assignment of roles etc. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#integration-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type integration_update_t&, and returns void. - */ - event_router_t on_integration_update; - - - /** - * @brief Called when an integration is removed by a user. - * An integration is a connection to a guild of a user's associated accounts, - * e.g. youtube or twitch, for automatic assignment of roles etc. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#integration-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type integration_delete_t&, and returns void. - */ - event_router_t on_integration_delete; - - - /** - * @brief Called when a thread is created. - * Note that threads are not cached by D++, but a list of thread IDs is accessible in a guild object - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#thread-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type thread_create_t&, and returns void. - */ - event_router_t on_thread_create; - - - /** - * @brief Called when a thread is updated - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#thread-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type thread_update_t&, and returns void. - */ - event_router_t on_thread_update; - - - /** - * @brief Called when a thread is deleted - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#thread-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type thread_delete_t&, and returns void. - */ - event_router_t on_thread_delete; - - - /** - * @brief Called when thread list is synced (upon gaining access to a channel). - * Note that threads are not cached by D++, but a list of thread IDs is accessible in a guild object - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#thread-list-sync - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type thread_list_sync_t&, and returns void. - */ - event_router_t on_thread_list_sync; - - - /** - * @brief Called when current user's thread member object is updated - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#thread-member-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type thread_member_update_t&, and returns void. - */ - event_router_t on_thread_member_update; - - - /** - * @brief Called when a thread's member list is updated (without GUILD_MEMBERS intent, is only called for current user) - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#thread-members-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type thread_members_update_t&, and returns void. - */ - event_router_t on_thread_members_update; - - - /** - * @brief Called when a new scheduled event is created - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_scheduled_event_create_t&, and returns void. - */ - event_router_t on_guild_scheduled_event_create; - - - /** - * @brief Called when a new scheduled event is updated - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_scheduled_event_update_t&, and returns void. - */ - event_router_t on_guild_scheduled_event_update; - - - /** - * @brief Called when a new scheduled event is deleted - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_scheduled_event_delete_t&, and returns void. - */ - event_router_t on_guild_scheduled_event_delete; - - - /** - * @brief Called when a user is added to a scheduled event - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-add - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_scheduled_event_user_add_t&, and returns void. - */ - event_router_t on_guild_scheduled_event_user_add; - - - /** - * @brief Called when a user is removed from a scheduled event - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#guild-scheduled-event-user-remove - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type guild_scheduled_event_user_remove_t&, and returns void. - */ - event_router_t on_guild_scheduled_event_user_remove; - - - /** - * @brief Called when packets are sent from the voice buffer. - * The voice buffer contains packets that are already encoded with Opus and encrypted - * with XChaCha20-Poly1305, and merged into packets by the repacketizer, which is done in the - * dpp::discord_voice_client::send_audio method. You should use the buffer size properties - * of dpp::voice_buffer_send_t to determine if you should fill the buffer with more - * content. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_buffer_send_t&, and returns void. - */ - event_router_t on_voice_buffer_send; - - - /** - * @brief Called when a voice channel is connected and ready to send audio. - * Note that this is not directly attached to the READY event of the websocket, - * as there is further connection that needs to be done before audio is ready to send. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_ready_t&, and returns void. - */ - event_router_t on_voice_ready; - - - /** - * @brief Called when new audio data is received. - * Each separate user's audio from the voice channel will arrive tagged with - * their user id in the event, if a user can be attributed to the received audio. - * - * @note Receiving audio for bots is not officially supported by discord. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_receive_t&, and returns void. - */ - event_router_t on_voice_receive; - - /** - * @brief Called when new audio data is received, combined and mixed for all speaking users. - * - * @note Receiving audio for bots is not officially supported by discord. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_receive_t&, and returns void. - */ - event_router_t on_voice_receive_combined; - - /** - * @brief Called when sending of audio passes over a track marker. - * Track markers are arbitrarily placed "bookmarks" in the audio buffer, placed - * by the bot developer. Each track marker can have a string value associated with it - * which is specified in dpp::discord_voice_client::insert_marker and returned to this - * event. - * - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type voice_track_marker_t&, and returns void. - */ - event_router_t on_voice_track_marker; - - - /** - * @brief Called when a new stage instance is created on a stage channel. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#stage-instance-create - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type stage_instance_create_t&, and returns void. - */ - event_router_t on_stage_instance_create; - - - /** - * @brief Called when a stage instance is updated. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#stage-instance-update - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type stage_instance_update_t&, and returns void. - */ - event_router_t on_stage_instance_update; - - - /** - * @brief Called when an existing stage instance is deleted from a stage channel. - * - * @warning If the cache policy has disabled guild caching, the pointer to the guild in this event may be nullptr. - * - * @see https://discord.com/developers/docs/topics/gateway-events#stage-instance-delete - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type stage_instance_delete_t&, and returns void. - */ - event_router_t on_stage_instance_delete; - - /** - * @brief Called when a user subscribes to an SKU. - * - * @see https://discord.com/developers/docs/monetization/entitlements#new-entitlement - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type channel_delete_t&, and returns void. - */ - event_router_t on_entitlement_create; - - - /** - * @brief Called when a user's subscription renews for the next billing period. - * The `ends_at` field will have an updated value with the new expiration date. - * - * @see https://discord.com/developers/docs/monetization/entitlements#updated-entitlement - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type channel_update_t&, and returns void. - */ - event_router_t on_entitlement_update; - - /** - * @brief Called when a user's entitlement is deleted. - * These events are infrequent and only occur if Discord issues a refund, or Discord removes an entitlement via "internal tooling". - * Entitlements **are not deleted** when they expire. - * - * @see https://discord.com/developers/docs/monetization/entitlements#deleted-entitlement - * @note Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. - * The function signature for this event takes a single `const` reference of type channel_update_t&, and returns void. - */ - event_router_t on_entitlement_delete; - - /** - * @brief Post a REST request. Where possible use a helper method instead like message_create - * - * @param endpoint Endpoint to post to, e.g. /api/guilds - * @param major_parameters Major parameters for the endpoint e.g. a guild id - * @param parameters Minor parameters for the API request - * @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 Filename to post for POST requests (for uploading files) - * @param filecontent File content to post for POST requests (for uploading files) - * @param filemimetype File content to post for POST requests (for uploading files) - * @param protocol HTTP protocol to use (1.0 and 1.1 are supported) - */ - void post_rest(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::string &filename = "", const std::string &filecontent = "", const std::string &filemimetype = "", const std::string& protocol = "1.1"); - - /** - * @brief Post a multipart REST request. Where possible use a helper method instead like message_create - * - * @param endpoint Endpoint to post to, e.g. /api/guilds - * @param major_parameters Major parameters for the endpoint e.g. a guild id - * @param parameters Minor parameters for the API request - * @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 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 &file_data = {}); - - /** - * @brief Make a HTTP(S) request. For use when wanting asynchronous access to HTTP APIs outside of Discord. - * - * @param url Full URL to post to, e.g. https://api.somewhere.com/v1/foo/ - * @param method Method, e.g. GET, POST - * @param callback Function to call when the HTTP call completes. No processing is done on the returned data. - * @param postdata POST data - * @param mimetype MIME type of POST data - * @param headers Headers to send with the request - * @param protocol HTTP protocol to use (1.1 and 1.0 are supported) - */ - void request(const std::string &url, http_method method, http_completion_event callback, const std::string &postdata = "", const std::string &mimetype = "text/plain", const std::multimap &headers = {}, const std::string &protocol = "1.1"); - - /** - * @brief Respond to a slash command - * - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response - * @param interaction_id Interaction id to respond to - * @param token Token for the interaction webhook - * @param r Response to send - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_response_create(snowflake interaction_id, const std::string &token, const interaction_response &r, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit response to a slash command - * - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response - * @param token Token for the interaction webhook - * @param m Message to send - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_response_edit(const std::string &token, const message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the original response to a slash command - * - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#get-original-interaction-response - * @param token Token for the interaction webhook - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_response_get_original(const std::string &token, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create a followup message to a slash command - * - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response - * @param token Token for the interaction webhook - * @param m followup message to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_followup_create(const std::string &token, const message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit original followup message to a slash command - * This is an alias for cluster::interaction_response_edit - * @see cluster::interaction_response_edit - * - * @param token Token for the interaction webhook - * @param m message to edit, the ID should be set - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_followup_edit_original(const std::string &token, const message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete the initial interaction response - * - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#delete-original-interaction-response - * @param token Token for the interaction webhook - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_followup_delete(const std::string &token, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit followup message to a slash command - * The message ID in the message you pass should be correctly set to that of a followup message you previously sent - * - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message - * @param token Token for the interaction webhook - * @param m message to edit, the ID should be set - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_followup_edit(const std::string &token, const message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the followup message to a slash command - * - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#get-followup-message - * @param token Token for the interaction webhook - * @param message_id message to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_followup_get(const std::string &token, snowflake message_id, command_completion_event_t callback); - - /** - * @brief Get the original followup message to a slash command - * This is an alias for cluster::interaction_response_get_original - * @see cluster::interaction_response_get_original - * - * @param token Token for the interaction webhook - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void interaction_followup_get_original(const std::string &token, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create a global slash command (a bot can have a maximum of 100 of these). - * - * @see https://discord.com/developers/docs/interactions/application-commands#create-global-application-command - * @param s Slash command to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void global_command_create(const slashcommand &s, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a global slash command - * - * @see https://discord.com/developers/docs/interactions/application-commands#get-global-application-command - * @param id The ID of the slash command - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void global_command_get(snowflake id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the audit log for a guild - * - * @see https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log - * @param guild_id Guild to get the audit log of - * @param user_id Entries from a specific user ID. Set this to `0` will fetch any user - * @param action_type Entries for a specific dpp::audit_type. Set this to `0` will fetch any type - * @param before Entries with ID less than a specific audit log entry ID. Used for paginating - * @param after Entries with ID greater than a specific audit log entry ID. Used for paginating - * @param limit Maximum number of entries (between 1-100) to return - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::auditlog object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_auditlog_get(snowflake guild_id, snowflake user_id, uint32_t action_type, snowflake before, snowflake after, uint32_t limit, command_completion_event_t callback); - - /** - * @brief Create a slash command local to a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#create-guild-application-command - * @note Creating a command with the same name as an existing command for your application will overwrite the old command. - * @param s Slash command to create - * @param guild_id Guild ID to create the slash command in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_command_create(const slashcommand &s, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create/overwrite guild slash commands. - * Any existing guild slash commands on this guild will be deleted and replaced with these. - * - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-guild-application-commands - * @param commands Vector of slash commands to create/update. - * New guild commands will be available in the guild immediately. If the command did not already exist, it will count toward daily application command create limits. - * @param guild_id Guild ID to create/update the slash commands in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_bulk_command_create(const std::vector &commands, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete all existing guild slash commands. - * - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands - * @param guild_id Guild ID to delete the slash commands in. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand_map object in confirmation_callback_t::value **which will be empty, meaning there are no commands**. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_bulk_command_delete(snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create/overwrite global slash commands. - * Any existing global slash commands will be deleted and replaced with these. - * - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands - * @param commands Vector of slash commands to create/update. - * overwriting existing commands that are registered globally for this application. - * Commands that do not already exist will count toward daily application command create limits. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void global_bulk_command_create(const std::vector &commands, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete all existing global slash commands. - * - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand_map object in confirmation_callback_t::value **which will be empty, meaning there are no commands**. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void global_bulk_command_delete(command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a global slash command (a bot can have a maximum of 100 of these) - * - * @see https://discord.com/developers/docs/interactions/application-commands#edit-global-application-command - * @param s Slash command to change - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void global_command_edit(const slashcommand &s, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a slash command of a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#get-guild-application-command - * @note The returned slash commands will not have permissions set, you need to use a permissions getter e.g. dpp::guild_commands_get_permissions to get the guild command permissions - * @param id The ID of the slash command - * @param guild_id Guild ID to get the slash command from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_command_get(snowflake id, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a slash command local to a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#edit-guild-application-command - * @param s Slash command to edit - * @param guild_id Guild ID to edit the slash command in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_command_edit(const slashcommand &s, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit slash command permissions of a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions - * @note You can only add up to 10 permission overwrites for a command - * @param s Slash command to edit the permissions for - * @param guild_id Guild ID to edit the slash command in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_command_edit_permissions(const slashcommand &s, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the permissions for a slash command of a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#get-application-command-permissions - * @param id The ID of the slash command to get the permissions for - * @param guild_id Guild ID to get the permissions of - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_command_permissions object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_command_get_permissions(snowflake id, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit/Overwrite the permissions of all existing slash commands in a guild - * - * @note You can only add up to 10 permission overwrites for a command - * - * @see https://discord.com/developers/docs/interactions/application-commands#batch-edit-application-command-permissions - * @warning The endpoint will overwrite all existing permissions for all commands of the application in a guild, including slash commands, user commands, and message commands. Meaning that if you forgot to pass a slash command, the permissions of it might be removed. - * @param commands A vector of slash commands to edit/overwrite the permissions for - * @param guild_id Guild ID to edit permissions of the slash commands in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_command_permissions_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @deprecated This has been disabled with updates to Permissions v2. You can use guild_command_edit_permissions instead - */ - void guild_bulk_command_edit_permissions(const std::vector &commands, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a global slash command (a bot can have a maximum of 100 of these) - * - * @see https://discord.com/developers/docs/interactions/application-commands#delete-global-application-command - * @param id Slash command to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void global_command_delete(snowflake id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a slash command local to a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#delete-guild-application-command - * @param id Slash command to delete - * @param guild_id Guild ID to delete the slash command in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_command_delete(snowflake id, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the application's slash commands for a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#get-guild-application-commands - * @note The returned slash commands will not have permissions set, you need to use a permissions getter e.g. dpp::guild_commands_get_permissions to get the guild command permissions - * @param guild_id Guild ID to get the slash commands for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_commands_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get all slash command permissions of a guild - * - * @see https://discord.com/developers/docs/interactions/application-commands#get-application-command-permissions - * @param guild_id Guild ID to get the slash commands permissions for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_command_permissions_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_commands_get_permissions(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get the application's global slash commands - * - * @see https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::slashcommand_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void global_commands_get(command_completion_event_t callback); - - /** - * @brief Create a direct message, also create the channel for the direct message if needed - * - * @see https://discord.com/developers/docs/resources/user#create-dm - * @see https://discord.com/developers/docs/resources/channel#create-message - * @param user_id User ID of user to send message to - * @param m Message object - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void direct_message_create(snowflake user_id, const message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a message - * - * @see https://discord.com/developers/docs/resources/channel#get-channel-message - * @param message_id Message ID - * @param channel_id Channel ID - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_get(snowflake message_id, snowflake channel_id, command_completion_event_t callback); - - /** - * @brief Get multiple messages. - * - * This function will attempt to fetch as many messages as possible using multiple API calls if needed. - * - * @see https://discord.com/developers/docs/resources/channel#get-channel-messages - * @param channel_id Channel ID to retrieve messages for - * @param around Messages should be retrieved around this ID if this is set to non-zero - * @param before Messages before this ID should be retrieved if this is set to non-zero - * @param after Messages after this ID should be retrieved if this is set to non-zero - * @param limit This number of messages maximum should be returned, up to a maximum of 100. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void messages_get(snowflake channel_id, snowflake around, snowflake before, snowflake after, uint64_t limit, command_completion_event_t callback); - - /** - * @brief Send a message to a channel. The callback function is called when the message has been sent - * - * @see https://discord.com/developers/docs/resources/channel#create-message - * @param m Message to send - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_create(const struct message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Crosspost a message. The callback function is called when the message has been sent - * - * @see https://discord.com/developers/docs/resources/channel#crosspost-message - * @param message_id Message to crosspost - * @param channel_id Channel ID to crosspost from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_crosspost(snowflake message_id, snowflake channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a message on a channel. The callback function is called when the message has been edited - * - * @see https://discord.com/developers/docs/resources/channel#edit-message - * @param m Message to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_edit(const struct message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit the flags of a message on a channel. The callback function is called when the message has been edited - * - * @param m Message to edit the flags of - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_edit_flags(const struct message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Add a reaction to a message. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see https://discord.com/developers/docs/resources/channel#create-reaction - * @param m Message to add a reaction to - * @param reaction Reaction to add. Emojis should be in the form emojiname:id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_add_reaction(const struct message &m, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete own reaction from a message. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see https://discord.com/developers/docs/resources/channel#delete-own-reaction - * @param m Message to delete own reaction from - * @param reaction Reaction to delete. The reaction should be in the form emojiname:id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_own_reaction(const struct message &m, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a user's reaction from a message. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see https://discord.com/developers/docs/resources/channel#delete-user-reaction - * @param m Message to delete a user's reaction from - * @param user_id User ID who's reaction you want to remove - * @param reaction Reaction to remove. Reactions should be in the form emojiname:id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_reaction(const struct message &m, snowflake user_id, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get reactions on a message for a particular emoji. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see https://discord.com/developers/docs/resources/channel#get-reactions - * @param m Message to get reactions for - * @param reaction Reaction should be in the form emojiname:id or a unicode character - * @param before Reactions before this ID should be retrieved if this is set to non-zero - * @param after Reactions before this ID should be retrieved if this is set to non-zero - * @param limit This number of reactions maximum should be returned - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::user_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_get_reactions(const struct message &m, const std::string &reaction, snowflake before, snowflake after, snowflake limit, command_completion_event_t callback); - - /** - * @brief Delete all reactions on a message - * - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions - * @param m Message to delete reactions from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_all_reactions(const struct message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete all reactions on a message using a particular emoji. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji - * @param m Message to delete reactions from - * @param reaction Reaction to delete, in the form emojiname:id or a unicode character - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_reaction_emoji(const struct message &m, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Add a reaction to a message by id. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see https://discord.com/developers/docs/topics/gateway#message-reaction-add - * @param message_id Message to add reactions to - * @param channel_id Channel to add reactions to - * @param reaction Reaction to add. Emojis should be in the form emojiname:id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_add_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete own reaction from a message by id. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see https://discord.com/developers/docs/resources/channel#delete-own-reaction - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @param reaction Reaction to delete. The reaction should be in the form emojiname:id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_own_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a user's reaction from a message by id. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see https://discord.com/developers/docs/resources/channel#delete-user-reaction - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @param user_id User ID who's reaction you want to remove - * @param reaction Reaction to remove. Reactions should be in the form emojiname:id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_reaction(snowflake message_id, snowflake channel_id, snowflake user_id, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get reactions on a message for a particular emoji by id. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see https://discord.com/developers/docs/resources/channel#get-reactions - * @param message_id Message to get reactions for - * @param channel_id Channel to get reactions for - * @param reaction Reaction should be in the form emojiname:id or a unicode character - * @param before Reactions before this ID should be retrieved if this is set to non-zero - * @param after Reactions before this ID should be retrieved if this is set to non-zero - * @param limit This number of reactions maximum should be returned - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::user_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_get_reactions(snowflake message_id, snowflake channel_id, const std::string &reaction, snowflake before, snowflake after, snowflake limit, command_completion_event_t callback); - - /** - * @brief Delete all reactions on a message by id - * - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_all_reactions(snowflake message_id, snowflake channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete all reactions on a message using a particular emoji by id. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @param reaction Reaction to delete, in the form emojiname:id or a unicode character - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_reaction_emoji(snowflake message_id, snowflake channel_id, const std::string &reaction, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a message from a channel. The callback function is called when the message has been edited - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see https://discord.com/developers/docs/resources/channel#delete-message - * @param message_id Message ID to delete - * @param channel_id Channel to delete from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete(snowflake message_id, snowflake channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Bulk delete messages from a channel. The callback function is called when the message has been edited - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @note If any message provided older than 2 weeks or any duplicate message ID, it will fail. - * - * @see https://discord.com/developers/docs/resources/channel#bulk-delete-messages - * @param message_ids List of message IDs to delete (at least 2 and at most 100 message IDs) - * @param channel_id Channel to delete from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_delete_bulk(const std::vector &message_ids, snowflake channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a list of users that voted for this specific answer. - * - * @param m Message that contains the poll to retrieve the answers from - * @param answer_id ID of the answer to retrieve votes from (see poll_answer::answer_id) - * @param after Users after this ID should be retrieved if this is set to non-zero - * @param limit This number of users maximum should be returned, up to 100 - * @param callback Function to call when the API call completes. - * @see https://discord.com/developers/docs/resources/poll#get-answer-voters - * On success the callback will contain a dpp::user_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void poll_get_answer_voters(const message& m, uint32_t answer_id, snowflake after, uint64_t limit, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a list of users that voted for this specific answer. - * - * @param message_id ID of the message with the poll to retrieve the answers from - * @param channel_id ID of the channel with the poll to retrieve the answers from - * @param answer_id ID of the answer to retrieve votes from (see poll_answer::answer_id) - * @param after Users after this ID should be retrieved if this is set to non-zero - * @param limit This number of users maximum should be returned, up to 100 - * @param callback Function to call when the API call completes. - * @see https://discord.com/developers/docs/resources/poll#get-answer-voters - * On success the callback will contain a dpp::user_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void poll_get_answer_voters(snowflake message_id, snowflake channel_id, uint32_t answer_id, snowflake after, uint64_t limit, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Immediately end a poll. - * - * @param m Message that contains the poll - * @param callback Function to call when the API call completes. - * @see https://discord.com/developers/docs/resources/poll#end-poll - * On success the callback will contain a dpp::message object representing the message containing the poll in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void poll_end(const message &m, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Immediately end a poll. - * - * @param message_id ID of the message with the poll to end - * @param channel_id ID of the channel with the poll to end - * @param callback Function to call when the API call completes. - * @see https://discord.com/developers/docs/resources/poll#end-poll - * On success the callback will contain a dpp::message object representing the message containing the poll in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void poll_end(snowflake message_id, snowflake channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a channel - * - * @see https://discord.com/developers/docs/resources/channel#get-channel - * @param c Channel ID to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::channel object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_get(snowflake c, command_completion_event_t callback); - - /** - * @brief Get all channels for a guild - * - * @see https://discord.com/developers/docs/resources/channel#get-channels - * @param guild_id Guild ID to retrieve channels for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::channel_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channels_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Create a channel - * - * Create a new channel object for the guild. Requires the `MANAGE_CHANNELS` permission. If setting permission overwrites, - * only permissions your bot has in the guild can be allowed/denied. Setting `MANAGE_ROLES` permission in channels is only possible - * for guild administrators. Returns the new channel object on success. Fires a `Channel Create Gateway` event. - * - * All parameters to this endpoint are optional excluding `name` - * - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/channel#create-channel - * @param c Channel to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::channel object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_create(const class channel &c, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/channel#modify-channel - * @param c Channel to edit/update - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::channel object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_edit(const class channel &c, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit multiple channels positions - * - * Modify the positions of a set of channel objects for the guild. - * Requires `MANAGE_CHANNELS` permission. Fires multiple `Channel Update Gateway` events. - * Only channels to be modified are required. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions - * @param c Channel to change the position for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_edit_positions(const std::vector &c, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a channel's permissions - * - * @see https://discord.com/developers/docs/resources/channel#edit-channel-permissions - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param c Channel to set permissions for - * @param overwrite_id Overwrite to change (a user or role ID) - * @param allow Bitmask of allowed permissions (refer to enum dpp::permissions) - * @param deny Bitmask of denied permissions (refer to enum dpp::permissions) - * @param member true if the overwrite_id is a user id, false if it is a channel id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_edit_permissions(const class channel &c, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a channel's permissions - * - * @see https://discord.com/developers/docs/resources/channel#edit-channel-permissions - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param channel_id ID of the channel to set permissions for - * @param overwrite_id Overwrite to change (a user or role ID) - * @param allow Bitmask of allowed permissions (refer to enum dpp::permissions) - * @param deny Bitmask of denied permissions (refer to enum dpp::permissions) - * @param member true if the overwrite_id is a user id, false if it is a channel id - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_edit_permissions(const snowflake channel_id, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/channel#deleteclose-channel - * @param channel_id Channel id to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_delete(snowflake channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get details about an invite - * - * @see https://discord.com/developers/docs/resources/invite#get-invite - * @param invite_code Invite code to get information on - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::invite object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void invite_get(const std::string &invite_code, command_completion_event_t callback); - - /** - * @brief Delete an invite - * - * @see https://discord.com/developers/docs/resources/invite#delete-invite - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param invite Invite code to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::invite object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void invite_delete(const std::string &invite, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get invites for a channel - * - * @see https://discord.com/developers/docs/resources/invite#get-invites - * @param c Channel to get invites for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::invite_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_invites_get(const class channel &c, command_completion_event_t callback); - - /** - * @brief Create invite for a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/channel#create-channel-invite - * @param c Channel to create an invite on - * @param i Invite to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::invite object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_invite_create(const class channel &c, const class invite &i, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a channel's pins - * @see https://discord.com/developers/docs/resources/channel#get-pinned-messages - * @param channel_id Channel ID to get pins for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_pins_get(snowflake channel_id, command_completion_event_t callback); - - /** - * @brief Adds a recipient to a Group DM using their access token - * @see https://discord.com/developers/docs/resources/channel#group-dm-add-recipient - * @param channel_id Channel id to add group DM recipients to - * @param user_id User ID to add - * @param access_token Access token from OAuth2 - * @param nick Nickname of user to apply to the chat - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void gdm_add(snowflake channel_id, snowflake user_id, const std::string &access_token, const std::string &nick, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Removes a recipient from a Group DM - * @see https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient - * @param channel_id Channel ID of group DM - * @param user_id User ID to remove from group DM - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void gdm_remove(snowflake channel_id, snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Remove a permission from a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/channel#delete-channel-permission - * @param c Channel to remove permission from - * @param overwrite_id Overwrite to remove, user or channel ID - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_delete_permission(const class channel &c, snowflake overwrite_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Follow an announcement (news) channel - * @see https://discord.com/developers/docs/resources/channel#follow-news-channel - * @param c Channel id to follow - * @param target_channel_id Channel to subscribe the channel to - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_follow_news(const class channel &c, snowflake target_channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Trigger channel typing indicator - * @see https://discord.com/developers/docs/resources/channel#trigger-typing-indicator - * @param c Channel to set as typing on - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_typing(const class channel &c, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Trigger channel typing indicator - * @see https://discord.com/developers/docs/resources/channel#trigger-typing-indicator - * @param cid Channel ID to set as typing on - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_typing(snowflake cid, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Pin a message - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/channel#pin-message - * @param channel_id Channel id to pin message on - * @param message_id Message id to pin message on - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_pin(snowflake channel_id, snowflake message_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Unpin a message - * @see https://discord.com/developers/docs/resources/channel#unpin-message - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param channel_id Channel id to unpin message on - * @param message_id Message id to unpin message on - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void message_unpin(snowflake channel_id, snowflake message_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a guild - * - * Returns the guild object for the given id. This endpoint will also return approximate_member_count and approximate_presence_count - * for the guild. - * @see https://discord.com/developers/docs/resources/guild#get-guild - * @param g Guild ID to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get(snowflake g, command_completion_event_t callback); - - /** - * @brief Get a guild preview. Returns a guild object but only a subset of the fields will be populated. - * - * Returns the guild preview object for the given id `g`. If the user is not in the guild, then the guild - * must be lurkable (it must be Discoverable or have a live public stage). - * @see https://discord.com/developers/docs/resources/guild#get-guild-preview - * @param g Guild ID to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_preview(snowflake g, command_completion_event_t callback); - - /** - * @brief Get a guild member - * @see https://discord.com/developers/docs/resources/guild#get-guild-member - * @param guild_id Guild ID to get member for - * @param user_id User ID of member to get - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_member object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_member(snowflake guild_id, snowflake user_id, command_completion_event_t callback); - - /** - * @brief Search for guild members based on whether their username or nickname starts with the given string. - * - * @note This endpoint is restricted according to whether the `GUILD_MEMBERS` Privileged Intent is enabled for your application. - * @see https://discord.com/developers/docs/resources/guild#search-guild-members - * @param guild_id Guild ID to search in - * @param query Query string to match username(s) and nickname(s) against - * @param limit max number of members to return (1-1000) - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_member_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_search_members(snowflake guild_id, const std::string& query, uint16_t limit, command_completion_event_t callback); - - /** - * @brief Get all guild members - * - * @note This endpoint is restricted according to whether the `GUILD_MEMBERS` Privileged Intent is enabled for your application. - * @see https://discord.com/developers/docs/resources/guild#get-guild-members - * @param guild_id Guild ID to get all members for - * @param limit max number of members to return (1-1000) - * @param after the highest user id in the previous page - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_member_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_members(snowflake guild_id, uint16_t limit, snowflake after, command_completion_event_t callback); - - /** - * @brief Add guild member. Needs a specific oauth2 scope, from which you get the access_token. - * - * Adds a user to the guild, provided you have a valid oauth2 access token for the user with the guilds.join scope. - * Returns the guild_member, which is defaulted if the user is already a member of the guild. Fires a `Guild Member Add` Gateway event. - * - * For guilds with Membership Screening enabled, this endpoint will default to adding new members as pending in the guild member object. - * Members that are pending will have to complete membership screening before they become full members that can talk. - * - * @note All parameters to this endpoint except for access_token are optional. - * The bot must be a member of the guild with `CREATE_INSTANT_INVITE` permission. - * @see https://discord.com/developers/docs/resources/guild#add-guild-member - * @param gm Guild member to add - * @param access_token Access token from Oauth2 scope - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_member object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_add_member(const guild_member& gm, const std::string &access_token, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit the properties of an existing guild member - * - * Modify attributes of a guild member. Returns the guild_member. Fires a `Guild Member Update` Gateway event. - * To remove a timeout, set the `communication_disabled_until` to a non-zero time in the past, e.g. 1. - * When moving members to channels, the API user must have permissions to both connect to the channel and have the `MOVE_MEMBERS` permission. - * For moving and disconnecting users from voice, use dpp::cluster::guild_member_move. - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param gm Guild member to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_member object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_edit_member(const guild_member& gm, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Moves the guild member to a other voice channel, if member is connected to one. - * Set the `channel_id` to `0` to disconnect the user. - * - * Fires a `Guild Member Update` Gateway event. - * @note When moving members to channels, the API user __must__ have permissions to both connect to the channel and have the `MOVE_MEMBERS` permission. - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @param channel_id Id of the channel to which the user is used. Set to `0` to disconnect the user - * @param guild_id Guild id to which the user is connected - * @param user_id User id, who should be moved - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_member object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_member_move(const snowflake channel_id, const snowflake guild_id, const snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Change current user nickname - * - * Modifies the nickname of the current user in a guild. - * Fires a `Guild Member Update` Gateway event. - * - * @deprecated Deprecated in favor of Modify Current Member. Will be replaced by dpp::cluster::guild_current_member_edit - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/guild#modify-current-user-nick - * @param guild_id Guild ID to change nickname on - * @param nickname New nickname, or empty string to clear nickname - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_set_nickname(snowflake guild_id, const std::string &nickname, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Add role to guild member - * - * Adds a role to a guild member. Requires the `MANAGE_ROLES` permission. - * Fires a `Guild Member Update` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#add-guild-member-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to add a role to - * @param user_id User ID to add role to - * @param role_id Role ID to add to the user - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_member_add_role(snowflake guild_id, snowflake user_id, snowflake role_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Remove role from guild member - * - * Removes a role from a guild member. Requires the `MANAGE_ROLES` permission. - * Fires a `Guild Member Update` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to remove role from user on - * @param user_id User ID to remove role from - * @param role_id Role to remove - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @deprecated Use dpp::cluster::guild_member_remove_role instead - */ - void guild_member_delete_role(snowflake guild_id, snowflake user_id, snowflake role_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Remove role from guild member - * - * Removes a role from a guild member. Requires the `MANAGE_ROLES` permission. - * Fires a `Guild Member Update` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to remove role from user on - * @param user_id User ID to remove role from - * @param role_id Role to remove - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_member_remove_role(snowflake guild_id, snowflake user_id, snowflake role_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Remove (kick) a guild member - * - * Remove a member from a guild. Requires `KICK_MEMBERS` permission. - * Fires a `Guild Member Remove` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @deprecated Replaced by dpp::cluster::guild_member_kick - * @param guild_id Guild ID to kick member from - * @param user_id User ID to kick - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_member_delete(snowflake guild_id, snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Remove (kick) a guild member - * - * Remove a member from a guild. Requires `KICK_MEMBERS` permission. - * Fires a `Guild Member Remove` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to kick member from - * @param user_id User ID to kick - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_member_kick(snowflake guild_id, snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Set the timeout of a guild member - * - * Fires a `Guild Member Update` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to timeout the member in - * @param user_id User ID to set the timeout for - * @param communication_disabled_until The timestamp when the user's timeout will expire (up to 28 days in the future). Set to 0 to remove the timeout - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_member_timeout(snowflake guild_id, snowflake user_id, time_t communication_disabled_until, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Remove the timeout of a guild member. - * A shortcut for guild_member_timeout(guild_id, user_id, 0, callback) - * Fires a `Guild Member Update` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to remove the member timeout from - * @param user_id User ID to remove the timeout for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_member_timeout_remove(snowflake guild_id, snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Add guild ban - * - * Create a guild ban, and optionally delete previous messages sent by the banned user. - * Requires the `BAN_MEMBERS` permission. Fires a `Guild Ban Add` Gateway event. - * @see https://discord.com/developers/docs/resources/guild#create-guild-ban - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to add ban to - * @param user_id User ID to ban - * @param delete_message_seconds How many seconds to delete messages for, between 0 and 604800 (7 days). Defaults to 0 - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_ban_add(snowflake guild_id, snowflake user_id, uint32_t delete_message_seconds = 0, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete guild ban - * - * Remove the ban for a user. Requires the `BAN_MEMBERS` permissions. - * Fires a Guild Ban Remove Gateway event. - * @see https://discord.com/developers/docs/resources/guild#remove-guild-ban - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild to delete ban from - * @param user_id User ID to delete ban for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_ban_delete(snowflake guild_id, snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get guild ban list - * - * Requires the `BAN_MEMBERS` permission. - * @see https://discord.com/developers/docs/resources/guild#get-guild-bans - * @note Provide a user ID to `before` and `after` for pagination. Users will always be returned in ascending order by the user ID. If both before and after are provided, only before is respected. - * @param guild_id Guild ID to get bans for - * @param before If non-zero, all bans for user ids before this user id will be returned up to the limit - * @param after if non-zero, all bans for user ids after this user id will be returned up to the limit - * @param limit the maximum number of bans to retrieve in this call up to a maximum of 1000 - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::ban_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_bans(snowflake guild_id, snowflake before, snowflake after, snowflake limit, command_completion_event_t callback); - - /** - * @brief Get single guild ban - * - * Requires the `BAN_MEMBERS` permission. - * @see https://discord.com/developers/docs/resources/guild#get-guild-ban - * @param guild_id Guild ID to get ban for - * @param user_id User ID of ban to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::ban object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_ban(snowflake guild_id, snowflake user_id, command_completion_event_t callback); - - /** - * @brief Get a template - * @see https://discord.com/developers/docs/resources/guild-template#get-guild-template - * @param code Template code - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::dtemplate object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void template_get(const std::string &code, command_completion_event_t callback); - - /** - * @brief Create a new guild based on a template. - * @note This endpoint can be used only by bots in less than 10 guilds. - * @see https://discord.com/developers/docs/resources/guild-template#create-guild-from-guild-template - * @param code Template code to create guild from - * @param name Guild name to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_create_from_template(const std::string &code, const std::string &name, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get guild templates - * - * @see https://discord.com/developers/docs/resources/guild-template#get-guild-templates - * @param guild_id Guild ID to get templates for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::dtemplate_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_templates_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Creates a template for the guild - * - * @see https://discord.com/developers/docs/resources/guild-template#create-guild-template - * @param guild_id Guild to create template from - * @param name Template name to create - * @param description Description of template to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::dtemplate object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_template_create(snowflake guild_id, const std::string &name, const std::string &description, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Syncs the template to the guild's current state. - * - * @see https://discord.com/developers/docs/resources/guild-template#sync-guild-template - * @param guild_id Guild to synchronise template for - * @param code Code of template to synchronise - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::dtemplate object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_template_sync(snowflake guild_id, const std::string &code, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Modifies the template's metadata. - * - * @see https://discord.com/developers/docs/resources/guild-template#modify-guild-template - * @param guild_id Guild ID of template to modify - * @param code Template code to modify - * @param name New name of template - * @param description New description of template - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::dtemplate object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_template_modify(snowflake guild_id, const std::string &code, const std::string &name, const std::string &description, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Deletes the template - * - * @see https://discord.com/developers/docs/resources/guild-template#delete-guild-template - * @param guild_id Guild ID of template to delete - * @param code Template code to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_template_delete(snowflake guild_id, const std::string &code, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create a guild - * - * Create a new guild. Returns a guild object on success. `Fires a Guild Create Gateway` event. - * - * When using the roles parameter, the first member of the array is used to change properties of the guild's everyone role. - * If you are trying to bootstrap a guild with additional roles, keep this in mind. The required id field within each role object is an - * integer placeholder, and will be replaced by the API upon consumption. Its purpose is to allow you to overwrite a role's permissions - * in a channel when also passing in channels with the channels array. - * When using the channels parameter, the position field is ignored, and none of the default channels are created. The id field within - * each channel object may be set to an integer placeholder, and will be replaced by the API upon consumption. Its purpose is to - * allow you to create `GUILD_CATEGORY` channels by setting the `parent_id` field on any children to the category's id field. - * Category channels must be listed before any children. - * - * @see https://discord.com/developers/docs/resources/guild#create-guild - * @note The region field is deprecated and is replaced by channel.rtc_region. This endpoint can be used only by bots in less than 10 guilds. - * @param g Guild to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_create(const class guild &g, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a guild - * - * Modify a guild's settings. Requires the `MANAGE_GUILD` permission. Returns the updated guild object on success. - * Fires a `Guild Update Gateway` event. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param g Guild to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_edit(const class guild &g, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a guild - * - * Delete a guild permanently. User must be owner. Fires a `Guild Delete Gateway` event. - * - * @see https://discord.com/developers/docs/resources/guild#delete-guild - * @param guild_id Guild ID to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_delete(snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get all emojis for a guild - * - * @see https://discord.com/developers/docs/resources/emoji#list-guild-emojis - * @param guild_id Guild ID to get emojis for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_emojis_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get a single emoji - * - * @see https://discord.com/developers/docs/resources/emoji#get-guild-emoji - * @param guild_id Guild ID to get emoji for - * @param emoji_id Emoji ID to get - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_emoji_get(snowflake guild_id, snowflake emoji_id, command_completion_event_t callback); - - /** - * @brief Create single emoji. - * You must ensure that the emoji passed contained image data using the emoji::load_image() method. - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see https://discord.com/developers/docs/resources/emoji#create-guild-emoji - * @param guild_id Guild ID to create emoji om - * @param newemoji Emoji to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_emoji_create(snowflake guild_id, const class emoji& newemoji, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a single emoji. - * - * You must ensure that the emoji passed contained image data using the emoji::load_image() method. - * @see https://discord.com/developers/docs/resources/emoji#modify-guild-emoji - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to edit emoji on - * @param newemoji Emoji to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_emoji_edit(snowflake guild_id, const class emoji& newemoji, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a guild emoji - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see https://discord.com/developers/docs/resources/emoji#delete-guild-emoji - * @param guild_id Guild ID to delete emoji on - * @param emoji_id Emoji ID to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_emoji_delete(snowflake guild_id, snowflake emoji_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief List all Application Emojis - * - * @see https://discord.com/developers/docs/resources/emoji#list-application-emojis - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void application_emojis_get(command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get an Application Emoji - * - * @see https://discord.com/developers/docs/resources/emoji#get-application-emoji - * @param emoji_id The ID of the Emoji to get. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void application_emoji_get(snowflake emoji_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create an Application Emoji - * - * @see https://discord.com/developers/docs/resources/emoji#create-application-emoji - * @param newemoji The emoji to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void application_emoji_create(const class emoji& newemoji, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit an Application Emoji - * - * @see https://discord.com/developers/docs/resources/emoji#modify-application-emoji - * @param newemoji The emoji to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void application_emoji_edit(const class emoji& newemoji, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete an Application Emoji - * - * @see https://discord.com/developers/docs/resources/emoji#delete-application-emoji - * @param emoji_id The emoji's ID to delete. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void application_emoji_delete(snowflake emoji_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get prune counts - * - * Returns a prune object indicating the number of members that would be removed in a prune operation. Requires the `KICK_MEMBERS` - * permission. By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the - * include_roles parameter. Any inactive user that has a subset of the provided role(s) will be counted in the prune and users with additional - * roles will not. - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-prune-count - * @param guild_id Guild ID to count for pruning - * @param pruneinfo Pruning info - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::prune object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_prune_counts(snowflake guild_id, const struct prune& pruneinfo, command_completion_event_t callback); - - /** - * @brief Begin guild prune - * - * Begin a prune operation. Requires the `KICK_MEMBERS` permission. Returns a prune object indicating the number of members - * that were removed in the prune operation. For large guilds it's recommended to set the `compute_prune_count` option to false, forcing - * 'pruned' to 0. Fires multiple `Guild Member Remove` Gateway events. - * By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the `include_roles` - * parameter. Any inactive user that has a subset of the provided role(s) will be included in the prune and users with additional roles will not. - * - * @see https://discord.com/developers/docs/resources/guild#begin-guild-prune - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to prune - * @param pruneinfo Pruning info - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::prune object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_begin_prune(snowflake guild_id, const struct prune& pruneinfo, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get guild voice regions. - * - * Voice regions per guild are somewhat deprecated in preference of per-channel voice regions. - * Returns a list of voice region objects for the guild. Unlike the similar /voice route, this returns VIP servers when - * the guild is VIP-enabled. - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-voice-regions - * @param guild_id Guild ID to get voice regions for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::voiceregion_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_voice_regions(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get guild invites - * - * Returns a list of invite objects (with invite metadata) for the guild. Requires the `MANAGE_GUILD` permission. - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-invites - * @param guild_id Guild ID to get invites for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::invite_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_invites(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get guild integrations - * - * Requires the `MANAGE_GUILD` permission. - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-integrations - * @param guild_id Guild ID to get integrations for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::integration_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * - * @note This endpoint returns a maximum of 50 integrations. If a guild has more integrations, they cannot be accessed. - */ - void guild_get_integrations(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Modify guild integration - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild-integration - * @param guild_id Guild ID to modify integration for - * @param i Integration to modify - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::integration object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_modify_integration(snowflake guild_id, const class integration &i, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete guild integration - * - * Delete the attached integration object for the guild. Deletes any associated webhooks and kicks the associated bot if there is one. - * Requires the `MANAGE_GUILD` permission. Fires a Guild Integrations Update Gateway event. - * - * @see https://discord.com/developers/docs/resources/guild#delete-guild-integration - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to delete integration for - * @param integration_id Integration ID to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_delete_integration(snowflake guild_id, snowflake integration_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Sync guild integration - * - * @see https://discord.com/developers/docs/resources/guild#sync-guild-integration - * @param guild_id Guild ID to sync integration on - * @param integration_id Integration ID to synchronise - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_sync_integration(snowflake guild_id, snowflake integration_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get guild widget - * - * Requires the `MANAGE_GUILD` permission. - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-widget - * @param guild_id Guild ID to get widget for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_widget object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_widget(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Edit guild widget - * - * Requires the `MANAGE_GUILD` permission. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild-widget - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to edit widget for - * @param gw New guild widget information - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_widget object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_edit_widget(snowflake guild_id, const class guild_widget &gw, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get guild vanity url, if enabled - * - * Returns a partial dpp::invite object for guilds with that feature enabled. Requires the `MANAGE_GUILD` permission. code will be null if a vanity url for the guild is not set. - * @see https://discord.com/developers/docs/resources/guild#get-guild-vanity-url - * @param guild_id Guild to get vanity URL for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::invite object in confirmation_callback_t::value filled to match the vanity url. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_vanity(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get the guild's onboarding configuration - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-onboarding - * @param guild_id The guild to pull the onboarding configuration from. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::onboarding object in confirmation_callback_t::value filled to match the vanity url. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_onboarding(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Edit the guild's onboarding configuration - * - * Requires the `MANAGE_GUILD` and `MANAGE_ROLES` permissions. - * - * @note Onboarding enforces constraints when enabled. These constraints are that there must be at least 7 Default Channels and at least 5 of them must allow sending messages to the \@everyone role. The `onboarding::mode` field modifies what is considered when enforcing these constraints. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild-onboarding - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param o The onboarding object - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::onboarding object in confirmation_callback_t::value filled to match the vanity url. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_edit_onboarding(const struct onboarding& o, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the guild's welcome screen - * - * If the welcome screen is not enabled, the `MANAGE_GUILD` permission is required. - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen - * @param guild_id The guild ID to get the welcome screen from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::welcome_screen object in confirmation_callback_t::value filled to match the vanity url. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_get_welcome_screen(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Edit the guild's welcome screen - * - * Requires the `MANAGE_GUILD` permission. May fire a `Guild Update` Gateway event. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen - * @param guild_id The guild ID to edit the welcome screen for - * @param welcome_screen The welcome screen - * @param enabled Whether the welcome screen should be enabled or disabled - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::welcome_screen object in confirmation_callback_t::value filled to match the vanity url. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_edit_welcome_screen(snowflake guild_id, const struct welcome_screen& welcome_screen, bool enabled, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create a webhook - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/webhook#create-webhook - * @param w Webhook to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::webhook object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void create_webhook(const class webhook &w, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get guild webhooks - * @see https://discord.com/developers/docs/resources/webhook#get-guild-webhooks - * @param guild_id Guild ID to get webhooks for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::webhook_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_guild_webhooks(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get channel webhooks - * @see https://discord.com/developers/docs/resources/webhook#get-guild-webhooks - * @param channel_id Channel ID to get webhooks for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::webhook_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_channel_webhooks(snowflake channel_id, command_completion_event_t callback); - - /** - * @brief Get webhook - * @see https://discord.com/developers/docs/resources/webhook#get-webhook - * @param webhook_id Webhook ID to get - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::webhook object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_webhook(snowflake webhook_id, command_completion_event_t callback); - - /** - * @brief Get webhook using token - * @see https://discord.com/developers/docs/resources/webhook#get-webhook-with-token - * @param webhook_id Webhook ID to retrieve - * @param token Token of webhook - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::webhook object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_webhook_with_token(snowflake webhook_id, const std::string &token, command_completion_event_t callback); - - /** - * @brief Edit webhook - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/webhook#modify-webhook - * @param wh Webhook to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::webhook object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void edit_webhook(const class webhook& wh, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit webhook with token (token is encapsulated in the webhook object) - * @see https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token - * @param wh Webhook to edit (should include token) - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::webhook object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void edit_webhook_with_token(const class webhook& wh, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a webhook - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/webhook#delete-webhook - * @param webhook_id Webhook ID to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void delete_webhook(snowflake webhook_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete webhook with token - * @see https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token - * @param webhook_id Webhook ID to delete - * @param token Token of webhook to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void delete_webhook_with_token(snowflake webhook_id, const std::string &token, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Execute webhook - * - * @see https://discord.com/developers/docs/resources/webhook#execute-webhook - * @param wh Webhook to execute - * @param m Message to send - * @param wait waits for server confirmation of message send before response, and returns the created message body - * @param thread_id Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived - * @param thread_name Name of thread to create (requires the webhook channel to be a forum channel) - * @param callback Function to call when the API call completes. - * @note If the webhook channel is a forum channel, you must provide either `thread_id` or `thread_name`. If `thread_id` is provided, the message will send in that thread. If `thread_name` is provided, a thread with that name will be created in the forum channel. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void execute_webhook(const class webhook &wh, const struct message &m, bool wait = false, snowflake thread_id = 0, const std::string& thread_name = "", command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get webhook message - * - * @see https://discord.com/developers/docs/resources/webhook#get-webhook-message - * @param wh Webhook to get the original message for - * @param message_id The message ID - * @param thread_id ID of the thread the message is in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id = 0, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit webhook message - * - * When the content field is edited, the mentions array in the message object will be reconstructed from scratch based on - * the new content. The allowed_mentions field of the edit request controls how this happens. If there is no explicit - * allowed_mentions in the edit request, the content will be parsed with default allowances, that is, without regard to - * whether or not an allowed_mentions was present in the request that originally created the message. - * - * @see https://discord.com/developers/docs/resources/webhook#edit-webhook-message - * @note the attachments array must contain all attachments that should be present after edit, including retained and new attachments provided in the request body. - * @param wh Webhook to edit message for - * @param m New message - * @param thread_id ID of the thread the message is in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void edit_webhook_message(const class webhook &wh, const struct message &m, snowflake thread_id = 0, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete webhook message - * - * @see https://discord.com/developers/docs/resources/webhook#delete-webhook-message - * @param wh Webhook to delete message for - * @param message_id Message ID to delete - * @param thread_id ID of the thread the message is in - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void delete_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id = 0, command_completion_event_t callback = utility::log_error()); - - - /** - * @brief Get a role for a guild - * - * @see https://discord.com/developers/docs/resources/guild#get-guild-roles - * @param guild_id Guild ID to get role for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::role_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void roles_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Create a role on a guild - * - * Create a new role for the guild. Requires the `MANAGE_ROLES` permission. Returns the new role object on success. - * Fires a `Guild Role Create` Gateway event. - * - * @see https://discord.com/developers/docs/resources/guild#create-guild-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param r Role to create (guild ID is encapsulated in the role object) - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::role object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void role_create(const class role &r, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit a role on a guild - * - * Requires the `MANAGE_ROLES` permission. Returns the updated role on success. Fires a `Guild Role Update` Gateway event. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param r Role to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::role object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void role_edit(const class role &r, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit multiple role's position in a guild. Returns a list of all roles of the guild on success. - * - * Modify the positions of a set of role objects for the guild. Requires the `MANAGE_ROLES` permission. - * Fires multiple `Guild Role Update` Gateway events. - * - * @see https://discord.com/developers/docs/resources/guild#modify-guild-role-positions - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to change the roles position on - * @param roles Vector of roles to change the positions of - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::role_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void roles_edit_position(snowflake guild_id, const std::vector &roles, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a role - * - * Requires the `MANAGE_ROLES` permission. Fires a `Guild Role Delete` Gateway event. - * - * @see https://discord.com/developers/docs/resources/guild#delete-guild-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to delete the role on - * @param role_id Role ID to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void role_delete(snowflake guild_id, snowflake role_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the application's role connection metadata records - * - * @see https://discord.com/developers/docs/resources/application-role-connection-metadata#get-application-role-connection-metadata-records - * @param application_id The application ID - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::application_role_connection_metadata_list object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void application_role_connection_get(snowflake application_id, command_completion_event_t callback); - - /** - * @brief Update the application's role connection metadata records - * - * @see https://discord.com/developers/docs/resources/application-role-connection-metadata#update-application-role-connection-metadata-records - * @param application_id The application ID - * @param connection_metadata The application role connection metadata to update - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::application_role_connection_metadata_list object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @note An application can have a maximum of 5 metadata records. - */ - void application_role_connection_update(snowflake application_id, const std::vector &connection_metadata, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get user application role connection - * - * @see https://discord.com/developers/docs/resources/user#get-user-application-role-connection - * @param application_id The application ID - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::application_role_connection object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void user_application_role_connection_get(snowflake application_id, command_completion_event_t callback); - - /** - * @brief Update user application role connection - * - * @see https://discord.com/developers/docs/resources/user#update-user-application-role-connection - * @param application_id The application ID - * @param connection The application role connection to update - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::application_role_connection object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void user_application_role_connection_update(snowflake application_id, const application_role_connection &connection, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a user by id, without using the cache - * - * @see https://discord.com/developers/docs/resources/user#get-user - * @param user_id User ID to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::user_identified object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes. - * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`. - * @note unless you want something special from `dpp::user_identified` or you've turned off caching, you have no need to call this. - * Call `dpp::find_user` instead that looks up the user in the cache rather than a REST call. - */ - void user_get(snowflake user_id, command_completion_event_t callback); - - /** - * @brief Get a user by id, checking in the cache first - * - * @see https://discord.com/developers/docs/resources/user#get-user - * @param user_id User ID to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::user_identified object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes. - * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`. - * @note If the user is found in the cache, special values set in `dpp::user_identified` will be undefined. This call should be used - * where you want to for example resolve a user who may no longer be in the bot's guilds, for something like a ban log message. - */ - void user_get_cached(snowflake user_id, command_completion_event_t callback); - - /** - * @brief Get current (bot) user - * - * @see https://discord.com/developers/docs/resources/user#get-current-user - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::user_identified object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes. - * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`. - */ - void current_user_get(command_completion_event_t callback); - - /** - * @brief Get current (bot) application - * - * @see https://discord.com/developers/docs/topics/oauth2#get-current-bot-application-information - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::application object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_application_get(command_completion_event_t callback); - - /** - * @brief Modify current member - * - * Modifies the current member in a guild. - * Fires a `Guild Member Update` Gateway event. - * - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/guild#modify-current-member - * @param guild_id Guild ID to change on - * @param nickname New nickname, or empty string to clear nickname - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_current_member_edit(snowflake guild_id, const std::string &nickname, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get current user's connections (linked accounts, e.g. steam, xbox). - * This call requires the oauth2 `connections` scope and cannot be executed - * against a bot token. - * @see https://discord.com/developers/docs/resources/user#get-user-connections - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::connection_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_user_connections_get(command_completion_event_t callback); - - /** - * @brief Get current (bot) user guilds - * @see https://discord.com/developers/docs/resources/user#get-current-user-guilds - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::guild_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_user_get_guilds(command_completion_event_t callback); - - /** - * @brief Edit current (bot) user. - * - * Modify the requester's user account settings. Returns a dpp::user object on success. - * Fires a User Update Gateway event. - * - * @note There appears to be no limit to the image size, however, if your image cannot be processed/uploaded in time, you will receive a malformed http request. - * - * @see https://discord.com/developers/docs/resources/user#modify-current-user - * @param nickname Nickname to set - * @param avatar_blob Avatar data to upload - * @param avatar_type Type of image for avatar. It can be one of `i_gif`, `i_jpg` or `i_png`. - * @param banner_blob Banner data to upload - * @param banner_type Type of image for Banner. It can be one of `i_gif`, `i_jpg` or `i_png`. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::user object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @throw dpp::length_exception Image data is larger than the maximum size of 256 kilobytes - */ - void current_user_edit(const std::string &nickname, const std::string& avatar_blob = "", const image_type avatar_type = i_png, const std::string& banner_blob = "", const image_type banner_type = i_png, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get current user DM channels - * - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::channel_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_user_get_dms(command_completion_event_t callback); - - /** - * @brief Create a dm channel - * @see https://discord.com/developers/docs/resources/user#create-dm - * @param user_id User ID to create DM channel with - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::channel object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void create_dm_channel(snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Leave a guild - * @see https://discord.com/developers/docs/resources/user#leave-guild - * @param guild_id Guild ID to leave - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_user_leave_guild(snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create a thread in a forum or media channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel - * @param thread_name Name of the forum thread - * @param channel_id Forum channel in which thread to create - * @param msg The message to start the thread with - * @param auto_archive_duration Duration to automatically archive the thread after recent activity - * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected - * @param applied_tags List of IDs of forum tags (dpp::forum_tag) to apply to this thread - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::thread object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_create_in_forum(const std::string& thread_name, snowflake channel_id, const message& msg, auto_archive_duration_t auto_archive_duration, uint16_t rate_limit_per_user, std::vector applied_tags = {}, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create a thread - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see https://discord.com/developers/docs/resources/channel#start-thread-without-message - * @param thread_name Name of the thread - * @param channel_id Channel in which thread to create - * @param auto_archive_duration Duration after which thread auto-archives. Can be set to - 60, 1440 (for boosted guilds can also be: 4320, 10080) - * @param thread_type Type of thread - CHANNEL_PUBLIC_THREAD, CHANNEL_ANNOUNCEMENT_THREAD, CHANNEL_PRIVATE_THREAD - * @param invitable whether non-moderators can add other non-moderators to a thread; only available when creating a private thread - * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::thread object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void 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 = utility::log_error()); - - /** - * @brief Edit a thread - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see https://discord.com/developers/docs/topics/threads#editing-deleting-threads - * @param t Thread to edit - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::thread object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_edit(const thread &t, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Create a thread with a message (Discord: ID of a thread is same as message ID) - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/channel#start-thread-from-message - * @param thread_name Name of the thread - * @param channel_id Channel in which thread to create - * @param message_id message to start thread with - * @param auto_archive_duration Duration after which thread auto-archives. Can be set to - 60, 1440 (for boosted guilds can also be: 4320, 10080) - * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::thread object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_create_with_message(const std::string& thread_name, snowflake channel_id, snowflake message_id, uint16_t auto_archive_duration, uint16_t rate_limit_per_user, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Join a thread - * @see https://discord.com/developers/docs/resources/channel#join-thread - * @param thread_id Thread ID to join - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_user_join_thread(snowflake thread_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Leave a thread - * @see https://discord.com/developers/docs/resources/channel#leave-thread - * @param thread_id Thread ID to leave - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_user_leave_thread(snowflake thread_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Add a member to a thread - * @see https://discord.com/developers/docs/resources/channel#add-thread-member - * @param thread_id Thread ID to add to - * @param user_id Member ID to add - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_member_add(snowflake thread_id, snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Remove a member from a thread - * @see https://discord.com/developers/docs/resources/channel#remove-thread-member - * @param thread_id Thread ID to remove from - * @param user_id Member ID to remove - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_member_remove(snowflake thread_id, snowflake user_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a thread member - * @see https://discord.com/developers/docs/resources/channel#get-thread-member - * @param thread_id Thread to get member for - * @param user_id ID of the user to get - * @param callback Function to call when the API call completes - * On success the callback will contain a dpp::thread_member object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_member_get(const snowflake thread_id, const snowflake user_id, command_completion_event_t callback); - - /** - * @brief Get members of a thread - * @see https://discord.com/developers/docs/resources/channel#list-thread-members - * @param thread_id Thread to get members for - * @param callback Function to call when the API call completes - * On success the callback will contain a dpp::thread_member_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_members_get(snowflake thread_id, command_completion_event_t callback); - - /** - * @brief Get all active threads in the guild, including public and private threads. Threads are ordered by their id, in descending order. - * @see https://discord.com/developers/docs/resources/guild#list-active-guild-threads - * @param guild_id Guild to get active threads for - * @param callback Function to call when the API call completes - * On success the callback will contain a dpp::active_threads object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void threads_get_active(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get public archived threads in a channel (Sorted by archive_timestamp in descending order) - * @see https://discord.com/developers/docs/resources/channel#list-public-archived-threads - * @param channel_id Channel to get public archived threads for - * @param before_timestamp Get threads archived before this timestamp - * @param limit Number of threads to get - * @param callback Function to call when the API call completes - * On success the callback will contain a dpp::thread_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void threads_get_public_archived(snowflake channel_id, time_t before_timestamp, uint16_t limit, command_completion_event_t callback); - - /** - * @brief Get private archived threads in a channel (Sorted by archive_timestamp in descending order) - * @see https://discord.com/developers/docs/resources/channel#list-private-archived-threads - * @param channel_id Channel to get public archived threads for - * @param before_timestamp Get threads archived before this timestamp - * @param limit Number of threads to get - * @param callback Function to call when the API call completes - * On success the callback will contain a dpp::thread_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void threads_get_private_archived(snowflake channel_id, time_t before_timestamp, uint16_t limit, command_completion_event_t callback); - - /** - * @brief Get private archived threads in a channel which current user has joined (Sorted by ID in descending order) - * @see https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads - * @param channel_id Channel to get public archived threads for - * @param before_id Get threads before this id - * @param limit Number of threads to get - * @param callback Function to call when the API call completes - * On success the callback will contain a dpp::thread_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void threads_get_joined_private_archived(snowflake channel_id, snowflake before_id, uint16_t limit, command_completion_event_t callback); - - /** - * @brief Get the thread specified by thread_id. This uses the same call as dpp::cluster::channel_get but returns a thread object. - * @see https://discord.com/developers/docs/resources/channel#get-channel - * @param thread_id The id of the thread to obtain. - * @param callback Function to call when the API call completes - * On success the callback will contain a dpp::thread object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thread_get(snowflake thread_id, command_completion_event_t callback); - - /** - * @brief Create a sticker in a guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/sticker#create-guild-sticker - * @param s Sticker to create. Must have its guild ID set. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::sticker object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_sticker_create(const sticker &s, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Modify a sticker in a guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/sticker#modify-guild-sticker - * @param s Sticker to modify. Must have its guild ID and sticker ID set. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::sticker object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_sticker_modify(const sticker &s, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a sticker from a guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see https://discord.com/developers/docs/resources/sticker#delete-guild-sticker - * @param sticker_id sticker ID to delete - * @param guild_id guild ID to delete from - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::sticker object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_sticker_delete(snowflake sticker_id, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a nitro sticker - * @see https://discord.com/developers/docs/resources/sticker#get-sticker - * @param id Id of sticker to get. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::sticker object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void nitro_sticker_get(snowflake id, command_completion_event_t callback); - - /** - * @brief Get a guild sticker - * @see https://discord.com/developers/docs/resources/sticker#get-guild-sticker - * @param id Id of sticker to get. - * @param guild_id Guild ID of the guild where the sticker is - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::sticker object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_sticker_get(snowflake id, snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get all guild stickers - * @see https://discord.com/developers/docs/resources/sticker#list-guild-stickers - * @param guild_id Guild ID of the guild where the sticker is - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::sticker_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_stickers_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get a list of available sticker packs - * @see https://discord.com/developers/docs/resources/sticker#list-sticker-packs - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::sticker_pack_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void sticker_packs_get(command_completion_event_t callback); - - /** - * @brief Create a stage instance on a stage channel. - * @see https://discord.com/developers/docs/resources/stage-instance#create-stage-instance - * @param instance Stage instance to create - * @param callback User function to execute when the api call completes - * On success the callback will contain a dpp::stage_instance object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - */ - void stage_instance_create(const stage_instance& instance, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the stage instance associated with the channel id, if it exists. - * @see https://discord.com/developers/docs/resources/stage-instance#get-stage-instance - * @param channel_id ID of the associated channel - * @param callback User function to execute when the api call completes - * On success the callback will contain a dpp::stage_instance object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void stage_instance_get(const snowflake channel_id, command_completion_event_t callback); - - /** - * @brief Edit a stage instance. - * @see https://discord.com/developers/docs/resources/stage-instance#modify-stage-instance - * @param instance Stage instance to edit - * @param callback User function to execute when the api call completes - * On success the callback will contain a dpp::stage_instance object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - */ - void stage_instance_edit(const stage_instance& instance, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a stage instance. - * @see https://discord.com/developers/docs/resources/stage-instance#delete-stage-instance - * @param channel_id ID of the associated channel - * @param callback User function to execute when the api call completes - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - */ - void stage_instance_delete(const snowflake channel_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get all voice regions - * @see https://discord.com/developers/docs/resources/voice#list-voice-regions - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::voiceregion_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_voice_regions(command_completion_event_t callback); - - /** - * @brief Get the gateway information for the bot using the token - * @see https://discord.com/developers/docs/topics/gateway#get-gateway-bot - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::gateway object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_gateway_bot(command_completion_event_t callback); - - /** - * @brief Get all scheduled events for a guild - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#list-scheduled-events-for-guild - * @param guild_id Guild to get events for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::scheduled_event_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_events_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get users RSVP'd to an event - * - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event-users - * @param guild_id Guild to get user list for - * @param event_id Guild to get user list for - * @param limit Maximum number of results to return - * @param before Return user IDs that fall before this ID, if provided - * @param after Return user IDs that fall after this ID, if provided - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::event_member_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_event_users_get(snowflake guild_id, snowflake event_id, command_completion_event_t callback, uint8_t limit = 100, snowflake before = 0, snowflake after = 0); - - /** - * @brief Create a scheduled event on a guild - * - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event - * @param event Event to create (guild ID must be populated) - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::scheduled_event_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_event_create(const scheduled_event& event, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete a scheduled event from a guild - * - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#delete-guild-scheduled-event - * @param event_id Event ID to delete - * @param guild_id Guild ID of event to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_event_delete(snowflake event_id, snowflake guild_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit/modify a scheduled event on a guild - * - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#modify-guild-scheduled-event - * @param event Event to create (event ID and guild ID must be populated) - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::scheduled_event_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_event_edit(const scheduled_event& event, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a scheduled event for a guild - * - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event - * @param guild_id Guild to get event for - * @param event_id Event ID to get - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::scheduled_event object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void guild_event_get(snowflake guild_id, snowflake event_id, command_completion_event_t callback); - - /** - * @brief Set the bot's voice state on a stage channel - * - * **Caveats** - * - * There are currently several caveats for this endpoint: - * - * - `channel_id` must currently point to a stage channel. - * - current user must already have joined `channel_id`. - * - You must have the `MUTE_MEMBERS` permission to unsuppress yourself. You can always suppress yourself. - * - You must have the `REQUEST_TO_SPEAK` permission to request to speak. You can always clear your own request to speak. - * - You are able to set `request_to_speak_timestamp` to any present or future time. - * - * @see https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state - * @param guild_id Guild to set voice state on - * @param channel_id Stage channel to set voice state on - * @param callback Function to call when the API call completes. - * @param suppress True if the user's audio should be suppressed, false if it should not - * @param request_to_speak_timestamp The time at which we requested to speak, or 0 to clear the request. The time set here must be the current time or in the future. - * On success the callback will contain a dpp::scheduled_event object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - * @throw std::logic_exception You attempted to set a request_to_speak_timestamp in the past which is not the value of 0. - */ - void current_user_set_voice_state(snowflake guild_id, snowflake channel_id, bool suppress = false, time_t request_to_speak_timestamp = 0, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get the bot's voice state in a guild without a Gateway connection - * - * @see https://discord.com/developers/docs/resources/voice#get-current-user-voice-state - * @param guild_id Guild to get the voice state for - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::voicestate object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void current_user_get_voice_state(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Set a user's voice state on a stage channel - * - * **Caveats** - * - * There are currently several caveats for this endpoint: - * - * - `channel_id` must currently point to a stage channel. - * - User must already have joined `channel_id`. - * - You must have the `MUTE_MEMBERS` permission. (Since suppression is the only thing that is available currently) - * - When unsuppressed, non-bot users will have their `request_to_speak_timestamp` set to the current time. Bot users will not. - * - When suppressed, the user will have their `request_to_speak_timestamp` removed. - * - * @see https://discord.com/developers/docs/resources/guild#modify-user-voice-state - * @param user_id The user to set the voice state of - * @param guild_id Guild to set voice state on - * @param channel_id Stage channel to set voice state on - * @param callback Function to call when the API call completes. - * @param suppress True if the user's audio should be suppressed, false if it should not - * On success the callback will contain a dpp::scheduled_event object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void user_set_voice_state(snowflake user_id, snowflake guild_id, snowflake channel_id, bool suppress = false, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Get a user's voice state in a guild without a Gateway connection - * - * @see https://discord.com/developers/docs/resources/voice#get-user-voice-state - * @param guild_id Guild to get the voice state for - * @param user_id The user to get the voice state of - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::voicestate object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void user_get_voice_state(snowflake guild_id, snowflake user_id, command_completion_event_t callback); - - /** - * @brief Get all auto moderation rules for a guild - * - * @param guild_id Guild id of the auto moderation rule - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::automod_rule_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void automod_rules_get(snowflake guild_id, command_completion_event_t callback); - - /** - * @brief Get a single auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param rule_id Rule id to retrieve - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::automod_rule object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void automod_rule_get(snowflake guild_id, snowflake rule_id, command_completion_event_t callback); - - /** - * @brief Create an auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param r Auto moderation rule to create - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::automod_rule object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void automod_rule_create(snowflake guild_id, const automod_rule& r, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Edit an auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param r Auto moderation rule to edit. The rule's id must be set. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::automod_rule object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void automod_rule_edit(snowflake guild_id, const automod_rule& r, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Delete an auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param rule_id Auto moderation rule id to delete - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void automod_rule_delete(snowflake guild_id, snowflake rule_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Returns all entitlements for a given app, active and expired. - * - * @see https://discord.com/developers/docs/monetization/entitlements#list-entitlements - * @param user_id User ID to look up entitlements for. - * @param sku_ids List of SKU IDs to check entitlements for. - * @param before_id Retrieve entitlements before this entitlement ID. - * @param after_id Retrieve entitlements after this entitlement ID. - * @param limit Number of entitlements to return, 1-100 (default 100). - * @param guild_id Guild ID to look up entitlements for. - * @param exclude_ended Whether ended entitlements should be excluded from the search. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::emoji_map object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void entitlements_get(snowflake user_id = 0, const std::vector& sku_ids = {}, snowflake before_id = 0, snowflake after_id = 0, uint8_t limit = 100, snowflake guild_id = 0, bool exclude_ended = false, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Creates a test entitlement to a given SKU for a given guild or user. - * Discord will act as though that user or guild has entitlement to your premium offering. - * - * @see https://discord.com/developers/docs/monetization/entitlements#create-test-entitlement - * @param new_entitlement The entitlement to create. - * Make sure your dpp::entitlement_type (inside your dpp::entitlement object) matches the type of the owner_id - * (if type is guild, owner_id is a guild id), otherwise it won't work! - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::entitlement object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void entitlement_test_create(const class entitlement& new_entitlement, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Deletes a currently-active test entitlement. - * Discord will act as though that user or guild no longer has entitlement to your premium offering. - * - * @see https://discord.com/developers/docs/monetization/entitlements#delete-test-entitlement - * @param entitlement_id The test entitlement to delete. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void entitlement_test_delete(snowflake entitlement_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed. - * - * @see https://discord.com/developers/docs/monetization/entitlements#consume-an-entitlement - * @param entitlement_id The entitlement to mark as consumed. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void entitlement_consume(snowflake entitlement_id, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Returns all SKUs for a given application. - * @note Because of how Discord's SKU and subscription systems work, you will see two SKUs for your premium offering. - * For integration and testing entitlements, you should use the SKU with type: 5. - * - * @see https://discord.com/developers/docs/monetization/skus#list-skus - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void skus_get(command_completion_event_t callback = utility::log_error()); - - /** - * @brief Set the status of a voice channel. - * - * @see https://github.com/discord/discord-api-docs/pull/6400 (please replace soon). - * @param channel_id The channel to update. - * @param status The new status for the channel. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void channel_set_voice_status(snowflake channel_id, const std::string& status, command_completion_event_t callback = utility::log_error()); - -#ifndef DPP_NO_CORO - #include -#endif - -}; - -} diff --git a/include/dpp/cluster_coro_calls.h b/include/dpp/cluster_coro_calls.h deleted file mode 100644 index f7d44dc..0000000 --- a/include/dpp/cluster_coro_calls.h +++ /dev/null @@ -1,2652 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - - -/* Auto @generated by buildtools/make_coro_struct.php. - * - * DO NOT EDIT BY HAND! - * - * To re-generate this header file re-run the script! - */ -/** - * @brief Create/overwrite global slash commands. - * Any existing global slash commands will be deleted and replaced with these. - * - * @see dpp::cluster::global_bulk_command_create - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands - * @param commands Vector of slash commands to create/update. - * overwriting existing commands that are registered globally for this application. - * Commands that do not already exist will count toward daily application command create limits. - * @return slashcommand_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_global_bulk_command_create(const std::vector &commands); - -/** - * @brief Delete all existing global slash commands. - * - * @see dpp::cluster::global_bulk_command_delete - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands - * @return slashcommand_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_global_bulk_command_delete(); - -/** - * @brief Create a global slash command (a bot can have a maximum of 100 of these). - * - * @see dpp::cluster::global_command_create - * @see https://discord.com/developers/docs/interactions/application-commands#create-global-application-command - * @param s Slash command to create - * @return slashcommand returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_global_command_create(const slashcommand &s); - -/** - * @brief Get a global slash command - * - * @see dpp::cluster::global_command_get - * @see https://discord.com/developers/docs/interactions/application-commands#get-global-application-command - * @param id The ID of the slash command - * @return slashcommand returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_global_command_get(snowflake id); - -/** - * @brief Delete a global slash command (a bot can have a maximum of 100 of these) - * - * @see dpp::cluster::global_command_delete - * @see https://discord.com/developers/docs/interactions/application-commands#delete-global-application-command - * @param id Slash command to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_global_command_delete(snowflake id); - -/** - * @brief Edit a global slash command (a bot can have a maximum of 100 of these) - * - * @see dpp::cluster::global_command_edit - * @see https://discord.com/developers/docs/interactions/application-commands#edit-global-application-command - * @param s Slash command to change - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_global_command_edit(const slashcommand &s); - -/** - * @brief Get the application's global slash commands - * - * @see dpp::cluster::global_commands_get - * @see https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands - * @return slashcommand_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_global_commands_get(); - -/** - * @brief Create/overwrite guild slash commands. - * Any existing guild slash commands on this guild will be deleted and replaced with these. - * - * @see dpp::cluster::guild_bulk_command_create - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-guild-application-commands - * @param commands Vector of slash commands to create/update. - * New guild commands will be available in the guild immediately. If the command did not already exist, it will count toward daily application command create limits. - * @param guild_id Guild ID to create/update the slash commands in - * @return slashcommand_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_bulk_command_create(const std::vector &commands, snowflake guild_id); - -/** - * @brief Delete all existing guild slash commands. - * - * @see dpp::cluster::guild_bulk_command_delete - * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands - * @param guild_id Guild ID to delete the slash commands in. - * @return slashcommand_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_bulk_command_delete(snowflake guild_id); - -/** - * @brief Get all slash command permissions of a guild - * - * @see dpp::cluster::guild_commands_get_permissions - * @see https://discord.com/developers/docs/interactions/application-commands#get-application-command-permissions - * @param guild_id Guild ID to get the slash commands permissions for - * @return guild_command_permissions_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_commands_get_permissions(snowflake guild_id); - -/** - * @brief Edit/Overwrite the permissions of all existing slash commands in a guild - * - * @note You can only add up to 10 permission overwrites for a command - * - * @see dpp::cluster::guild_bulk_command_edit_permissions - * @see https://discord.com/developers/docs/interactions/application-commands#batch-edit-application-command-permissions - * @warning The endpoint will overwrite all existing permissions for all commands of the application in a guild, including slash commands, user commands, and message commands. Meaning that if you forgot to pass a slash command, the permissions of it might be removed. - * @param commands A vector of slash commands to edit/overwrite the permissions for - * @param guild_id Guild ID to edit permissions of the slash commands in - * @return guild_command_permissions_map returned object on completion - * @deprecated This has been disabled with updates to Permissions v2. You can use guild_command_edit_permissions instead - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_bulk_command_edit_permissions(const std::vector &commands, snowflake guild_id); - -/** - * @brief Create a slash command local to a guild - * - * @see dpp::cluster::guild_command_create - * @see https://discord.com/developers/docs/interactions/application-commands#create-guild-application-command - * @note Creating a command with the same name as an existing command for your application will overwrite the old command. - * @param s Slash command to create - * @param guild_id Guild ID to create the slash command in - * @return slashcommand returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_command_create(const slashcommand &s, snowflake guild_id); - -/** - * @brief Delete a slash command local to a guild - * - * @see dpp::cluster::guild_command_delete - * @see https://discord.com/developers/docs/interactions/application-commands#delete-guild-application-command - * @param id Slash command to delete - * @param guild_id Guild ID to delete the slash command in - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_command_delete(snowflake id, snowflake guild_id); - -/** - * @brief Edit slash command permissions of a guild - * - * @see dpp::cluster::guild_command_edit_permissions - * @see https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions - * @note You can only add up to 10 permission overwrites for a command - * @param s Slash command to edit the permissions for - * @param guild_id Guild ID to edit the slash command in - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_command_edit_permissions(const slashcommand &s, snowflake guild_id); - -/** - * @brief Get a slash command of a guild - * - * @see dpp::cluster::guild_command_get - * @see https://discord.com/developers/docs/interactions/application-commands#get-guild-application-command - * @note The returned slash commands will not have permissions set, you need to use a permissions getter e.g. dpp::guild_commands_get_permissions to get the guild command permissions - * @param id The ID of the slash command - * @param guild_id Guild ID to get the slash command from - * @return slashcommand returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_command_get(snowflake id, snowflake guild_id); - -/** - * @brief Get the permissions for a slash command of a guild - * - * @see dpp::cluster::guild_command_get_permissions - * @see https://discord.com/developers/docs/interactions/application-commands#get-application-command-permissions - * @param id The ID of the slash command to get the permissions for - * @param guild_id Guild ID to get the permissions of - * @return guild_command_permissions returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_command_get_permissions(snowflake id, snowflake guild_id); - -/** - * @brief Edit a slash command local to a guild - * - * @see dpp::cluster::guild_command_edit - * @see https://discord.com/developers/docs/interactions/application-commands#edit-guild-application-command - * @param s Slash command to edit - * @param guild_id Guild ID to edit the slash command in - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_command_edit(const slashcommand &s, snowflake guild_id); - -/** - * @brief Get the application's slash commands for a guild - * - * @see dpp::cluster::guild_commands_get - * @see https://discord.com/developers/docs/interactions/application-commands#get-guild-application-commands - * @note The returned slash commands will not have permissions set, you need to use a permissions getter e.g. dpp::guild_commands_get_permissions to get the guild command permissions - * @param guild_id Guild ID to get the slash commands for - * @return slashcommand_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_commands_get(snowflake guild_id); - -/** - * @brief Respond to a slash command - * - * @see dpp::cluster::interaction_response_create - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response - * @param interaction_id Interaction id to respond to - * @param token Token for the interaction webhook - * @param r Response to send - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_response_create(snowflake interaction_id, const std::string &token, const interaction_response &r); - -/** - * @brief Edit response to a slash command - * - * @see dpp::cluster::interaction_response_edit - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response - * @param token Token for the interaction webhook - * @param m Message to send - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_response_edit(const std::string &token, const message &m); - -/** - * @brief Get the original response to a slash command - * - * @see dpp::cluster::interaction_response_get_original - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#get-original-interaction-response - * @param token Token for the interaction webhook - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_response_get_original(const std::string &token); - -/** - * @brief Create a followup message to a slash command - * - * @see dpp::cluster::interaction_followup_create - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response - * @param token Token for the interaction webhook - * @param m followup message to create - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_followup_create(const std::string &token, const message &m); - -/** - * @brief Edit original followup message to a slash command - * This is an alias for cluster::interaction_response_edit - * @see dpp::cluster::interaction_followup_edit_original - * @see cluster::interaction_response_edit - * - * @param token Token for the interaction webhook - * @param m message to edit, the ID should be set - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_followup_edit_original(const std::string &token, const message &m); - -/** - * @brief Delete the initial interaction response - * - * @see dpp::cluster::interaction_followup_delete - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#delete-original-interaction-response - * @param token Token for the interaction webhook - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_followup_delete(const std::string &token); - -/** - * @brief Edit followup message to a slash command - * The message ID in the message you pass should be correctly set to that of a followup message you previously sent - * - * @see dpp::cluster::interaction_followup_edit - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message - * @param token Token for the interaction webhook - * @param m message to edit, the ID should be set - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_followup_edit(const std::string &token, const message &m); - -/** - * @brief Get the followup message to a slash command - * - * @see dpp::cluster::interaction_followup_get - * @see https://discord.com/developers/docs/interactions/receiving-and-responding#get-followup-message - * @param token Token for the interaction webhook - * @param message_id message to retrieve - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_followup_get(const std::string &token, snowflake message_id); - -/** - * @brief Get the original followup message to a slash command - * This is an alias for cluster::interaction_response_get_original - * @see dpp::cluster::interaction_followup_get_original - * @see cluster::interaction_response_get_original - * - * @param token Token for the interaction webhook - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_interaction_followup_get_original(const std::string &token); - -/** - * @brief Get all auto moderation rules for a guild - * - * @param guild_id Guild id of the auto moderation rule - * @return automod_rule_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_automod_rules_get(snowflake guild_id); - -/** - * @brief Get a single auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param rule_id Rule id to retrieve - * @return automod_rule returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_automod_rule_get(snowflake guild_id, snowflake rule_id); - -/** - * @brief Create an auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param r Auto moderation rule to create - * @return automod_rule returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_automod_rule_create(snowflake guild_id, const automod_rule& r); - -/** - * @brief Edit an auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param r Auto moderation rule to edit. The rule's id must be set. - * @return automod_rule returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_automod_rule_edit(snowflake guild_id, const automod_rule& r); - -/** - * @brief Delete an auto moderation rule - * - * @param guild_id Guild id of the auto moderation rule - * @param rule_id Auto moderation rule id to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_automod_rule_delete(snowflake guild_id, snowflake rule_id); - -/** - * @brief Create a channel - * - * Create a new channel object for the guild. Requires the `MANAGE_CHANNELS` permission. If setting permission overwrites, - * only permissions your bot has in the guild can be allowed/denied. Setting `MANAGE_ROLES` permission in channels is only possible - * for guild administrators. Returns the new channel object on success. Fires a `Channel Create Gateway` event. - * - * All parameters to this endpoint are optional excluding `name` - * - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::channel_create - * @see https://discord.com/developers/docs/resources/channel#create-channel - * @param c Channel to create - * @return channel returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_create(const class channel &c); - -/** - * @brief Remove a permission from a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::channel_delete_permission - * @see https://discord.com/developers/docs/resources/channel#delete-channel-permission - * @param c Channel to remove permission from - * @param overwrite_id Overwrite to remove, user or channel ID - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_delete_permission(const class channel &c, snowflake overwrite_id); - -/** - * @brief Delete a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::channel_delete - * @see https://discord.com/developers/docs/resources/channel#deleteclose-channel - * @param channel_id Channel id to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_delete(snowflake channel_id); - -/** - * @brief Edit a channel's permissions - * - * @see dpp::cluster::channel_edit_permissions - * @see https://discord.com/developers/docs/resources/channel#edit-channel-permissions - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param c Channel to set permissions for - * @param overwrite_id Overwrite to change (a user or role ID) - * @param allow Bitmask of allowed permissions (refer to enum dpp::permissions) - * @param deny Bitmask of denied permissions (refer to enum dpp::permissions) - * @param member true if the overwrite_id is a user id, false if it is a channel id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_edit_permissions(const class channel &c, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member); - -/** - * @brief Edit a channel's permissions - * - * @see dpp::cluster::channel_edit_permissions - * @see https://discord.com/developers/docs/resources/channel#edit-channel-permissions - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param channel_id ID of the channel to set permissions for - * @param overwrite_id Overwrite to change (a user or role ID) - * @param allow Bitmask of allowed permissions (refer to enum dpp::permissions) - * @param deny Bitmask of denied permissions (refer to enum dpp::permissions) - * @param member true if the overwrite_id is a user id, false if it is a channel id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_edit_permissions(const snowflake channel_id, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member); - -/** - * @brief Edit multiple channels positions - * - * Modify the positions of a set of channel objects for the guild. - * Requires `MANAGE_CHANNELS` permission. Fires multiple `Channel Update Gateway` events. - * Only channels to be modified are required. - * - * @see dpp::cluster::channel_edit_positions - * @see https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions - * @param c Channel to change the position for - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_edit_positions(const std::vector &c); - -/** - * @brief Edit a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::channel_edit - * @see https://discord.com/developers/docs/resources/channel#modify-channel - * @param c Channel to edit/update - * @return channel returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_edit(const class channel &c); - -/** - * @brief Follow an announcement (news) channel - * @see dpp::cluster::channel_follow_news - * @see https://discord.com/developers/docs/resources/channel#follow-news-channel - * @param c Channel id to follow - * @param target_channel_id Channel to subscribe the channel to - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_follow_news(const class channel &c, snowflake target_channel_id); - -/** - * @brief Get a channel - * - * @see dpp::cluster::channel_get - * @see https://discord.com/developers/docs/resources/channel#get-channel - * @param c Channel ID to retrieve - * @return channel returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_get(snowflake c); - -/** - * @brief Create invite for a channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::channel_invite_create - * @see https://discord.com/developers/docs/resources/channel#create-channel-invite - * @param c Channel to create an invite on - * @param i Invite to create - * @return invite returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_invite_create(const class channel &c, const class invite &i); - -/** - * @brief Get invites for a channel - * - * @see dpp::cluster::channel_invites_get - * @see https://discord.com/developers/docs/resources/invite#get-invites - * @param c Channel to get invites for - * @return invite_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_invites_get(const class channel &c); - -/** - * @brief Trigger channel typing indicator - * @see dpp::cluster::channel_typing - * @see https://discord.com/developers/docs/resources/channel#trigger-typing-indicator - * @param c Channel to set as typing on - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_typing(const class channel &c); - -/** - * @brief Trigger channel typing indicator - * @see dpp::cluster::channel_typing - * @see https://discord.com/developers/docs/resources/channel#trigger-typing-indicator - * @param cid Channel ID to set as typing on - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_typing(snowflake cid); - -/** - * @brief Get all channels for a guild - * - * @see dpp::cluster::channels_get - * @see https://discord.com/developers/docs/resources/channel#get-channels - * @param guild_id Guild ID to retrieve channels for - * @return channel_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channels_get(snowflake guild_id); - -/** - * @brief Set the status of a voice channel. - * - * @see dpp::cluster::channel_set_voice_status - * @see https://github.com/discord/discord-api-docs/pull/6400 (please replace soon). - * @param channel_id The channel to update. - * @param status The new status for the channel. - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_set_voice_status(snowflake channel_id, const std::string& status); - -/** - * @brief Create a dm channel - * @see dpp::cluster::create_dm_channel - * @see https://discord.com/developers/docs/resources/user#create-dm - * @param user_id User ID to create DM channel with - * @return channel returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_create_dm_channel(snowflake user_id); - -/** - * @brief Get current user DM channels - * - * @return channel_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_get_dms(); - -/** - * @brief Create a direct message, also create the channel for the direct message if needed - * - * @see dpp::cluster::direct_message_create - * @see https://discord.com/developers/docs/resources/user#create-dm - * @see dpp::cluster::direct_message_create - * @see https://discord.com/developers/docs/resources/channel#create-message - * @param user_id User ID of user to send message to - * @param m Message object - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_direct_message_create(snowflake user_id, const message &m); - -/** - * @brief Adds a recipient to a Group DM using their access token - * @see dpp::cluster::gdm_add - * @see https://discord.com/developers/docs/resources/channel#group-dm-add-recipient - * @param channel_id Channel id to add group DM recipients to - * @param user_id User ID to add - * @param access_token Access token from OAuth2 - * @param nick Nickname of user to apply to the chat - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_gdm_add(snowflake channel_id, snowflake user_id, const std::string &access_token, const std::string &nick); - -/** - * @brief Removes a recipient from a Group DM - * @see dpp::cluster::gdm_remove - * @see https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient - * @param channel_id Channel ID of group DM - * @param user_id User ID to remove from group DM - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_gdm_remove(snowflake channel_id, snowflake user_id); - -/** - * @brief Create single emoji. - * You must ensure that the emoji passed contained image data using the emoji::load_image() method. - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see dpp::cluster::guild_emoji_create - * @see https://discord.com/developers/docs/resources/emoji#create-guild-emoji - * @param guild_id Guild ID to create emoji om - * @param newemoji Emoji to create - * @return emoji returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_emoji_create(snowflake guild_id, const class emoji& newemoji); - -/** - * @brief Delete a guild emoji - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see dpp::cluster::guild_emoji_delete - * @see https://discord.com/developers/docs/resources/emoji#delete-guild-emoji - * @param guild_id Guild ID to delete emoji on - * @param emoji_id Emoji ID to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_emoji_delete(snowflake guild_id, snowflake emoji_id); - -/** - * @brief Edit a single emoji. - * - * You must ensure that the emoji passed contained image data using the emoji::load_image() method. - * @see dpp::cluster::guild_emoji_edit - * @see https://discord.com/developers/docs/resources/emoji#modify-guild-emoji - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to edit emoji on - * @param newemoji Emoji to edit - * @return emoji returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_emoji_edit(snowflake guild_id, const class emoji& newemoji); - -/** - * @brief Get a single emoji - * - * @see dpp::cluster::guild_emoji_get - * @see https://discord.com/developers/docs/resources/emoji#get-guild-emoji - * @param guild_id Guild ID to get emoji for - * @param emoji_id Emoji ID to get - * @return emoji returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_emoji_get(snowflake guild_id, snowflake emoji_id); - -/** - * @brief Get all emojis for a guild - * - * @see dpp::cluster::guild_emojis_get - * @see https://discord.com/developers/docs/resources/emoji#list-guild-emojis - * @param guild_id Guild ID to get emojis for - * @return emoji_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_emojis_get(snowflake guild_id); - -/** - * @brief List all Application Emojis - * - * @see dpp::cluster::application_emojis_get - * @see https://discord.com/developers/docs/resources/emoji#list-application-emojis - * @return emoji_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_application_emojis_get(); - -/** - * @brief Get an Application Emoji - * - * @see dpp::cluster::application_emoji_get - * @see https://discord.com/developers/docs/resources/emoji#get-application-emoji - * @param emoji_id The ID of the Emoji to get. - * @return emoji returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_application_emoji_get(snowflake emoji_id); - -/** - * @brief Create an Application Emoji - * - * @see dpp::cluster::application_emoji_create - * @see https://discord.com/developers/docs/resources/emoji#create-application-emoji - * @param newemoji The emoji to create - * @return emoji returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_application_emoji_create(const class emoji& newemoji); - -/** - * @brief Edit an Application Emoji - * - * @see dpp::cluster::application_emoji_edit - * @see https://discord.com/developers/docs/resources/emoji#modify-application-emoji - * @param newemoji The emoji to edit - * @return emoji returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_application_emoji_edit(const class emoji& newemoji); - -/** - * @brief Delete an Application Emoji - * - * @see dpp::cluster::application_emoji_delete - * @see https://discord.com/developers/docs/resources/emoji#delete-application-emoji - * @param emoji_id The emoji's ID to delete. - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_application_emoji_delete(snowflake emoji_id); - -/** - * @brief Returns all entitlements for a given app, active and expired. - * - * @see dpp::cluster::entitlements_get - * @see https://discord.com/developers/docs/monetization/entitlements#list-entitlements - * @param user_id User ID to look up entitlements for. - * @param sku_ids List of SKU IDs to check entitlements for. - * @param before_id Retrieve entitlements before this entitlement ID. - * @param after_id Retrieve entitlements after this entitlement ID. - * @param limit Number of entitlements to return, 1-100 (default 100). - * @param guild_id Guild ID to look up entitlements for. - * @param exclude_ended Whether ended entitlements should be excluded from the search. - * @return entitlement_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_entitlements_get(snowflake user_id = 0, const std::vector& sku_ids = {}, snowflake before_id = 0, snowflake after_id = 0, uint8_t limit = 100, snowflake guild_id = 0, bool exclude_ended = false); - -/** - * @brief Creates a test entitlement to a given SKU for a given guild or user. - * Discord will act as though that user or guild has entitlement to your premium offering. - * - * @see dpp::cluster::entitlement_test_create - * @see https://discord.com/developers/docs/monetization/entitlements#create-test-entitlement - * @param new_entitlement The entitlement to create. - * Make sure your dpp::entitlement_type (inside your dpp::entitlement object) matches the type of the owner_id - * (if type is guild, owner_id is a guild id), otherwise it won't work! - * @return entitlement returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_entitlement_test_create(const class entitlement& new_entitlement); - -/** - * @brief Deletes a currently-active test entitlement. - * Discord will act as though that user or guild no longer has entitlement to your premium offering. - * - * @see dpp::cluster::entitlement_test_delete - * @see https://discord.com/developers/docs/monetization/entitlements#delete-test-entitlement - * @param entitlement_id The test entitlement to delete. - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_entitlement_test_delete(snowflake entitlement_id); - -/** - * @brief For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed. - * - * @see dpp::cluster::entitlement_consume - * @see https://discord.com/developers/docs/monetization/entitlements#consume-an-entitlement - * @param entitlement_id The entitlement to mark as consumed. - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_entitlement_consume(snowflake entitlement_id); - -/** - * @brief Get the gateway information for the bot using the token - * @see dpp::cluster::get_gateway_bot - * @see https://discord.com/developers/docs/topics/gateway#get-gateway-bot - * @return gateway returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_get_gateway_bot(); - -/** - * @brief Modify current member - * - * Modifies the current member in a guild. - * Fires a `Guild Member Update` Gateway event. - * - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::guild_current_member_edit - * @see https://discord.com/developers/docs/resources/guild#modify-current-member - * @param guild_id Guild ID to change on - * @param nickname New nickname, or empty string to clear nickname - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_current_member_edit(snowflake guild_id, const std::string &nickname); - -/** - * @brief Get the audit log for a guild - * - * @see dpp::cluster::guild_auditlog_get - * @see https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log - * @param guild_id Guild to get the audit log of - * @param user_id Entries from a specific user ID. Set this to `0` will fetch any user - * @param action_type Entries for a specific dpp::audit_type. Set this to `0` will fetch any type - * @param before Entries with ID less than a specific audit log entry ID. Used for paginating - * @param after Entries with ID greater than a specific audit log entry ID. Used for paginating - * @param limit Maximum number of entries (between 1-100) to return - * @return auditlog returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_auditlog_get(snowflake guild_id, snowflake user_id, uint32_t action_type, snowflake before, snowflake after, uint32_t limit); - -/** - * @brief Add guild ban - * - * Create a guild ban, and optionally delete previous messages sent by the banned user. - * Requires the `BAN_MEMBERS` permission. Fires a `Guild Ban Add` Gateway event. - * @see dpp::cluster::guild_ban_add - * @see https://discord.com/developers/docs/resources/guild#create-guild-ban - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to add ban to - * @param user_id User ID to ban - * @param delete_message_seconds How many seconds to delete messages for, between 0 and 604800 (7 days). Defaults to 0 - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_ban_add(snowflake guild_id, snowflake user_id, uint32_t delete_message_seconds = 0); - -/** - * @brief Delete guild ban - * - * Remove the ban for a user. Requires the `BAN_MEMBERS` permissions. - * Fires a Guild Ban Remove Gateway event. - * @see dpp::cluster::guild_ban_delete - * @see https://discord.com/developers/docs/resources/guild#remove-guild-ban - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild to delete ban from - * @param user_id User ID to delete ban for - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_ban_delete(snowflake guild_id, snowflake user_id); - -/** - * @brief Create a guild - * - * Create a new guild. Returns a guild object on success. `Fires a Guild Create Gateway` event. - * - * When using the roles parameter, the first member of the array is used to change properties of the guild's everyone role. - * If you are trying to bootstrap a guild with additional roles, keep this in mind. The required id field within each role object is an - * integer placeholder, and will be replaced by the API upon consumption. Its purpose is to allow you to overwrite a role's permissions - * in a channel when also passing in channels with the channels array. - * When using the channels parameter, the position field is ignored, and none of the default channels are created. The id field within - * each channel object may be set to an integer placeholder, and will be replaced by the API upon consumption. Its purpose is to - * allow you to create `GUILD_CATEGORY` channels by setting the `parent_id` field on any children to the category's id field. - * Category channels must be listed before any children. - * - * @see dpp::cluster::guild_create - * @see https://discord.com/developers/docs/resources/guild#create-guild - * @note The region field is deprecated and is replaced by channel.rtc_region. This endpoint can be used only by bots in less than 10 guilds. - * @param g Guild to create - * @return guild returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_create(const class guild &g); - -/** - * @brief Delete a guild - * - * Delete a guild permanently. User must be owner. Fires a `Guild Delete Gateway` event. - * - * @see dpp::cluster::guild_delete - * @see https://discord.com/developers/docs/resources/guild#delete-guild - * @param guild_id Guild ID to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_delete(snowflake guild_id); - -/** - * @brief Delete guild integration - * - * Delete the attached integration object for the guild. Deletes any associated webhooks and kicks the associated bot if there is one. - * Requires the `MANAGE_GUILD` permission. Fires a Guild Integrations Update Gateway event. - * - * @see dpp::cluster::guild_delete_integration - * @see https://discord.com/developers/docs/resources/guild#delete-guild-integration - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to delete integration for - * @param integration_id Integration ID to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_delete_integration(snowflake guild_id, snowflake integration_id); - -/** - * @brief Edit a guild - * - * Modify a guild's settings. Requires the `MANAGE_GUILD` permission. Returns the updated guild object on success. - * Fires a `Guild Update Gateway` event. - * - * @see dpp::cluster::guild_edit - * @see https://discord.com/developers/docs/resources/guild#modify-guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param g Guild to edit - * @return guild returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_edit(const class guild &g); - -/** - * @brief Edit guild widget - * - * Requires the `MANAGE_GUILD` permission. - * - * @see dpp::cluster::guild_edit_widget - * @see https://discord.com/developers/docs/resources/guild#modify-guild-widget - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to edit widget for - * @param gw New guild widget information - * @return guild_widget returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_edit_widget(snowflake guild_id, const class guild_widget &gw); - -/** - * @brief Get single guild ban - * - * Requires the `BAN_MEMBERS` permission. - * @see dpp::cluster::guild_get_ban - * @see https://discord.com/developers/docs/resources/guild#get-guild-ban - * @param guild_id Guild ID to get ban for - * @param user_id User ID of ban to retrieve - * @return ban returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_ban(snowflake guild_id, snowflake user_id); - -/** - * @brief Get guild ban list - * - * Requires the `BAN_MEMBERS` permission. - * @see dpp::cluster::guild_get_bans - * @see https://discord.com/developers/docs/resources/guild#get-guild-bans - * @note Provide a user ID to `before` and `after` for pagination. Users will always be returned in ascending order by the user ID. If both before and after are provided, only before is respected. - * @param guild_id Guild ID to get bans for - * @param before If non-zero, all bans for user ids before this user id will be returned up to the limit - * @param after if non-zero, all bans for user ids after this user id will be returned up to the limit - * @param limit the maximum number of bans to retrieve in this call up to a maximum of 1000 - * @return ban_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_bans(snowflake guild_id, snowflake before, snowflake after, snowflake limit); - - -[[nodiscard]] async co_guild_get(snowflake guild_id); - -/** - * @brief Get guild integrations - * - * Requires the `MANAGE_GUILD` permission. - * - * @see dpp::cluster::guild_get_integrations - * @see https://discord.com/developers/docs/resources/guild#get-guild-integrations - * @param guild_id Guild ID to get integrations for - * @return integration_map returned object on completion - * - * @note This endpoint returns a maximum of 50 integrations. If a guild has more integrations, they cannot be accessed. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_integrations(snowflake guild_id); - - -[[nodiscard]] async co_guild_get_preview(snowflake guild_id); - -/** - * @brief Get guild vanity url, if enabled - * - * Returns a partial dpp::invite object for guilds with that feature enabled. Requires the `MANAGE_GUILD` permission. code will be null if a vanity url for the guild is not set. - * @see dpp::cluster::guild_get_vanity - * @see https://discord.com/developers/docs/resources/guild#get-guild-vanity-url - * @param guild_id Guild to get vanity URL for - * @return invite returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_vanity(snowflake guild_id); - -/** - * @brief Get guild widget - * - * Requires the `MANAGE_GUILD` permission. - * - * @see dpp::cluster::guild_get_widget - * @see https://discord.com/developers/docs/resources/guild#get-guild-widget - * @param guild_id Guild ID to get widget for - * @return guild_widget returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_widget(snowflake guild_id); - -/** - * @brief Modify guild integration - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see dpp::cluster::guild_modify_integration - * @see https://discord.com/developers/docs/resources/guild#modify-guild-integration - * @param guild_id Guild ID to modify integration for - * @param i Integration to modify - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_modify_integration(snowflake guild_id, const class integration &i); - -/** - * @brief Get prune counts - * - * Returns a prune object indicating the number of members that would be removed in a prune operation. Requires the `KICK_MEMBERS` - * permission. By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the - * include_roles parameter. Any inactive user that has a subset of the provided role(s) will be counted in the prune and users with additional - * roles will not. - * - * @see dpp::cluster::guild_get_prune_counts - * @see https://discord.com/developers/docs/resources/guild#get-guild-prune-count - * @param guild_id Guild ID to count for pruning - * @param pruneinfo Pruning info - * @return prune returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_prune_counts(snowflake guild_id, const struct prune& pruneinfo); - -/** - * @brief Begin guild prune - * - * Begin a prune operation. Requires the `KICK_MEMBERS` permission. Returns a prune object indicating the number of members - * that were removed in the prune operation. For large guilds it's recommended to set the `compute_prune_count` option to false, forcing - * 'pruned' to 0. Fires multiple `Guild Member Remove` Gateway events. - * By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the `include_roles` - * parameter. Any inactive user that has a subset of the provided role(s) will be included in the prune and users with additional roles will not. - * - * @see dpp::cluster::guild_begin_prune - * @see https://discord.com/developers/docs/resources/guild#begin-guild-prune - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to prune - * @param pruneinfo Pruning info - * @return prune returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_begin_prune(snowflake guild_id, const struct prune& pruneinfo); - -/** - * @brief Change current user nickname - * - * Modifies the nickname of the current user in a guild. - * Fires a `Guild Member Update` Gateway event. - * - * @deprecated Deprecated in favor of Modify Current Member. Will be replaced by dpp::cluster::guild_current_member_edit - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::guild_set_nickname - * @see https://discord.com/developers/docs/resources/guild#modify-current-user-nick - * @param guild_id Guild ID to change nickname on - * @param nickname New nickname, or empty string to clear nickname - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_set_nickname(snowflake guild_id, const std::string &nickname); - -/** - * @brief Sync guild integration - * - * @see dpp::cluster::guild_sync_integration - * @see https://discord.com/developers/docs/resources/guild#sync-guild-integration - * @param guild_id Guild ID to sync integration on - * @param integration_id Integration ID to synchronise - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_sync_integration(snowflake guild_id, snowflake integration_id); - -/** - * @brief Get the guild's onboarding configuration - * - * @see dpp::cluster::guild_get_onboarding - * @see https://discord.com/developers/docs/resources/guild#get-guild-onboarding - * @param guild_id The guild to pull the onboarding configuration from. - * @return onboarding returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_onboarding(snowflake guild_id); - -/** - * @brief Edit the guild's onboarding configuration - * - * Requires the `MANAGE_GUILD` and `MANAGE_ROLES` permissions. - * - * @note Onboarding enforces constraints when enabled. These constraints are that there must be at least 7 Default Channels and at least 5 of them must allow sending messages to the \@everyone role. The `onboarding::mode` field modifies what is considered when enforcing these constraints. - * - * @see dpp::cluster::guild_edit_onboarding - * @see https://discord.com/developers/docs/resources/guild#modify-guild-onboarding - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param o The onboarding object - * @return onboarding returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_edit_onboarding(const struct onboarding& o); - -/** - * @brief Get the guild's welcome screen - * - * If the welcome screen is not enabled, the `MANAGE_GUILD` permission is required. - * - * @see dpp::cluster::guild_get_welcome_screen - * @see https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen - * @param guild_id The guild ID to get the welcome screen from - * @return dpp::welcome_screen returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_welcome_screen(snowflake guild_id); - -/** - * @brief Edit the guild's welcome screen - * - * Requires the `MANAGE_GUILD` permission. May fire a `Guild Update` Gateway event. - * - * @see dpp::cluster::guild_edit_welcome_screen - * @see https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen - * @param guild_id The guild ID to edit the welcome screen for - * @param welcome_screen The welcome screen - * @param enabled Whether the welcome screen should be enabled or disabled - * @return dpp::welcome_screen returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_edit_welcome_screen(snowflake guild_id, const struct welcome_screen& welcome_screen, bool enabled); - -/** - * @brief Add guild member. Needs a specific oauth2 scope, from which you get the access_token. - * - * Adds a user to the guild, provided you have a valid oauth2 access token for the user with the guilds.join scope. - * Returns the guild_member, which is defaulted if the user is already a member of the guild. Fires a `Guild Member Add` Gateway event. - * - * For guilds with Membership Screening enabled, this endpoint will default to adding new members as pending in the guild member object. - * Members that are pending will have to complete membership screening before they become full members that can talk. - * - * @note All parameters to this endpoint except for access_token are optional. - * The bot must be a member of the guild with `CREATE_INSTANT_INVITE` permission. - * @see dpp::cluster::guild_add_member - * @see https://discord.com/developers/docs/resources/guild#add-guild-member - * @param gm Guild member to add - * @param access_token Access token from Oauth2 scope - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_add_member(const guild_member& gm, const std::string &access_token); - -/** - * @brief Edit the properties of an existing guild member - * - * Modify attributes of a guild member. Returns the guild_member. Fires a `Guild Member Update` Gateway event. - * To remove a timeout, set the `communication_disabled_until` to a non-zero time in the past, e.g. 1. - * When moving members to channels, the API user must have permissions to both connect to the channel and have the `MOVE_MEMBERS` permission. - * For moving and disconnecting users from voice, use dpp::cluster::guild_member_move. - * @see dpp::cluster::guild_edit_member - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param gm Guild member to edit - * @return guild_member returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_edit_member(const guild_member& gm); - -/** - * @brief Get a guild member - * @see dpp::cluster::guild_get_member - * @see https://discord.com/developers/docs/resources/guild#get-guild-member - * @param guild_id Guild ID to get member for - * @param user_id User ID of member to get - * @return guild_member returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_member(snowflake guild_id, snowflake user_id); - -/** - * @brief Get all guild members - * - * @note This endpoint is restricted according to whether the `GUILD_MEMBERS` Privileged Intent is enabled for your application. - * @see dpp::cluster::guild_get_members - * @see https://discord.com/developers/docs/resources/guild#get-guild-members - * @param guild_id Guild ID to get all members for - * @param limit max number of members to return (1-1000) - * @param after the highest user id in the previous page - * @return guild_member_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_members(snowflake guild_id, uint16_t limit, snowflake after); - -/** - * @brief Add role to guild member - * - * Adds a role to a guild member. Requires the `MANAGE_ROLES` permission. - * Fires a `Guild Member Update` Gateway event. - * @see dpp::cluster::guild_member_add_role - * @see https://discord.com/developers/docs/resources/guild#add-guild-member-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to add a role to - * @param user_id User ID to add role to - * @param role_id Role ID to add to the user - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_add_role(snowflake guild_id, snowflake user_id, snowflake role_id); - -/** - * @brief Remove (kick) a guild member - * - * Remove a member from a guild. Requires `KICK_MEMBERS` permission. - * Fires a `Guild Member Remove` Gateway event. - * @see dpp::cluster::guild_member_delete - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @deprecated Replaced by dpp::cluster::guild_member_kick - * @param guild_id Guild ID to kick member from - * @param user_id User ID to kick - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_delete(snowflake guild_id, snowflake user_id); - -/** - * @brief Remove (kick) a guild member - * - * Remove a member from a guild. Requires `KICK_MEMBERS` permission. - * Fires a `Guild Member Remove` Gateway event. - * @see dpp::cluster::guild_member_kick - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to kick member from - * @param user_id User ID to kick - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_kick(snowflake guild_id, snowflake user_id); - -/** - * @brief Set the timeout of a guild member - * - * Fires a `Guild Member Update` Gateway event. - * @see dpp::cluster::guild_member_timeout - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to timeout the member in - * @param user_id User ID to set the timeout for - * @param communication_disabled_until The timestamp when the user's timeout will expire (up to 28 days in the future). Set to 0 to remove the timeout - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_timeout(snowflake guild_id, snowflake user_id, time_t communication_disabled_until); - -/** - * @brief Remove the timeout of a guild member. - * A shortcut for guild_member_timeout(guild_id, user_id, 0, callback) - * Fires a `Guild Member Update` Gateway event. - * @see dpp::cluster::guild_member_timeout_remove - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to remove the member timeout from - * @param user_id User ID to remove the timeout for - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_timeout_remove(snowflake guild_id, snowflake user_id); - -/** - * @brief Remove role from guild member - * - * Removes a role from a guild member. Requires the `MANAGE_ROLES` permission. - * Fires a `Guild Member Update` Gateway event. - * @see dpp::cluster::guild_member_delete_role - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to remove role from user on - * @param user_id User ID to remove role from - * @param role_id Role to remove - * @return confirmation returned object on completion - * @deprecated Use dpp::cluster::guild_member_remove_role instead - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_delete_role(snowflake guild_id, snowflake user_id, snowflake role_id); - -/** - * @brief Remove role from guild member - * - * Removes a role from a guild member. Requires the `MANAGE_ROLES` permission. - * Fires a `Guild Member Update` Gateway event. - * @see dpp::cluster::guild_member_remove_role - * @see https://discord.com/developers/docs/resources/guild#remove-guild-member-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to remove role from user on - * @param user_id User ID to remove role from - * @param role_id Role to remove - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_remove_role(snowflake guild_id, snowflake user_id, snowflake role_id); - -/** - * @brief Moves the guild member to a other voice channel, if member is connected to one. - * Set the `channel_id` to `0` to disconnect the user. - * - * Fires a `Guild Member Update` Gateway event. - * @note When moving members to channels, the API user __must__ have permissions to both connect to the channel and have the `MOVE_MEMBERS` permission. - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::guild_member_move - * @see https://discord.com/developers/docs/resources/guild#modify-guild-member - * @param channel_id Id of the channel to which the user is used. Set to `0` to disconnect the user - * @param guild_id Guild id to which the user is connected - * @param user_id User id, who should be moved - * @return guild_member returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_member_move(const snowflake channel_id, const snowflake guild_id, const snowflake user_id); - -/** - * @brief Search for guild members based on whether their username or nickname starts with the given string. - * - * @note This endpoint is restricted according to whether the `GUILD_MEMBERS` Privileged Intent is enabled for your application. - * @see dpp::cluster::guild_search_members - * @see https://discord.com/developers/docs/resources/guild#search-guild-members - * @param guild_id Guild ID to search in - * @param query Query string to match username(s) and nickname(s) against - * @param limit max number of members to return (1-1000) - * @return guild_member_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_search_members(snowflake guild_id, const std::string& query, uint16_t limit); - -/** - * @brief Get guild invites - * - * Returns a list of invite objects (with invite metadata) for the guild. Requires the `MANAGE_GUILD` permission. - * - * @see dpp::cluster::guild_get_invites - * @see https://discord.com/developers/docs/resources/guild#get-guild-invites - * @param guild_id Guild ID to get invites for - * @return invite_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_invites(snowflake guild_id); - - -[[nodiscard]] async co_invite_delete(const std::string &invitecode); - -/** - * @brief Get details about an invite - * - * @see dpp::cluster::invite_get - * @see https://discord.com/developers/docs/resources/invite#get-invite - * @param invite_code Invite code to get information on - * @return invite returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_invite_get(const std::string &invite_code); - -/** - * @brief Add a reaction to a message. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see dpp::cluster::message_add_reaction - * @see https://discord.com/developers/docs/resources/channel#create-reaction - * @param m Message to add a reaction to - * @param reaction Reaction to add. Emojis should be in the form emojiname:id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_add_reaction(const struct message &m, const std::string &reaction); - -/** - * @brief Add a reaction to a message by id. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see dpp::cluster::message_add_reaction - * @see https://discord.com/developers/docs/topics/gateway#message-reaction-add - * @param message_id Message to add reactions to - * @param channel_id Channel to add reactions to - * @param reaction Reaction to add. Emojis should be in the form emojiname:id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_add_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction); - -/** - * @brief Send a message to a channel. The callback function is called when the message has been sent - * - * @see dpp::cluster::message_create - * @see https://discord.com/developers/docs/resources/channel#create-message - * @param m Message to send - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_create(const struct message &m); - -/** - * @brief Crosspost a message. The callback function is called when the message has been sent - * - * @see dpp::cluster::message_crosspost - * @see https://discord.com/developers/docs/resources/channel#crosspost-message - * @param message_id Message to crosspost - * @param channel_id Channel ID to crosspost from - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_crosspost(snowflake message_id, snowflake channel_id); - -/** - * @brief Delete all reactions on a message - * - * @see dpp::cluster::message_delete_all_reactions - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions - * @param m Message to delete reactions from - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_all_reactions(const struct message &m); - -/** - * @brief Delete all reactions on a message by id - * - * @see dpp::cluster::message_delete_all_reactions - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_all_reactions(snowflake message_id, snowflake channel_id); - -/** - * @brief Bulk delete messages from a channel. The callback function is called when the message has been edited - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @note If any message provided older than 2 weeks or any duplicate message ID, it will fail. - * - * @see dpp::cluster::message_delete_bulk - * @see https://discord.com/developers/docs/resources/channel#bulk-delete-messages - * @param message_ids List of message IDs to delete (at least 2 and at most 100 message IDs) - * @param channel_id Channel to delete from - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_bulk(const std::vector &message_ids, snowflake channel_id); - -/** - * @brief Delete a message from a channel. The callback function is called when the message has been edited - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see dpp::cluster::message_delete - * @see https://discord.com/developers/docs/resources/channel#delete-message - * @param message_id Message ID to delete - * @param channel_id Channel to delete from - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete(snowflake message_id, snowflake channel_id); - -/** - * @brief Delete own reaction from a message. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see dpp::cluster::message_delete_own_reaction - * @see https://discord.com/developers/docs/resources/channel#delete-own-reaction - * @param m Message to delete own reaction from - * @param reaction Reaction to delete. The reaction should be in the form emojiname:id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_own_reaction(const struct message &m, const std::string &reaction); - -/** - * @brief Delete own reaction from a message by id. The reaction string must be either an `emojiname:id` or a unicode character. - * - * @see dpp::cluster::message_delete_own_reaction - * @see https://discord.com/developers/docs/resources/channel#delete-own-reaction - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @param reaction Reaction to delete. The reaction should be in the form emojiname:id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_own_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction); - -/** - * @brief Delete a user's reaction from a message. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see dpp::cluster::message_delete_reaction - * @see https://discord.com/developers/docs/resources/channel#delete-user-reaction - * @param m Message to delete a user's reaction from - * @param user_id User ID who's reaction you want to remove - * @param reaction Reaction to remove. Reactions should be in the form emojiname:id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_reaction(const struct message &m, snowflake user_id, const std::string &reaction); - -/** - * @brief Delete a user's reaction from a message by id. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see dpp::cluster::message_delete_reaction - * @see https://discord.com/developers/docs/resources/channel#delete-user-reaction - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @param user_id User ID who's reaction you want to remove - * @param reaction Reaction to remove. Reactions should be in the form emojiname:id - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_reaction(snowflake message_id, snowflake channel_id, snowflake user_id, const std::string &reaction); - -/** - * @brief Delete all reactions on a message using a particular emoji. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see dpp::cluster::message_delete_reaction_emoji - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji - * @param m Message to delete reactions from - * @param reaction Reaction to delete, in the form emojiname:id or a unicode character - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_reaction_emoji(const struct message &m, const std::string &reaction); - -/** - * @brief Delete all reactions on a message using a particular emoji by id. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see dpp::cluster::message_delete_reaction_emoji - * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji - * @param message_id Message to delete reactions from - * @param channel_id Channel to delete reactions from - * @param reaction Reaction to delete, in the form emojiname:id or a unicode character - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_delete_reaction_emoji(snowflake message_id, snowflake channel_id, const std::string &reaction); - -/** - * @brief Edit a message on a channel. The callback function is called when the message has been edited - * - * @see dpp::cluster::message_edit - * @see https://discord.com/developers/docs/resources/channel#edit-message - * @param m Message to edit - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_edit(const struct message &m); - -/** - * @brief Edit the flags of a message on a channel. The callback function is called when the message has been edited - * - * @param m Message to edit the flags of - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_edit_flags(const struct message &m); - -/** - * @brief Get a message - * - * @see dpp::cluster::message_get - * @see https://discord.com/developers/docs/resources/channel#get-channel-message - * @param message_id Message ID - * @param channel_id Channel ID - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_get(snowflake message_id, snowflake channel_id); - -/** - * @brief Get reactions on a message for a particular emoji. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see dpp::cluster::message_get_reactions - * @see https://discord.com/developers/docs/resources/channel#get-reactions - * @param m Message to get reactions for - * @param reaction Reaction should be in the form emojiname:id or a unicode character - * @param before Reactions before this ID should be retrieved if this is set to non-zero - * @param after Reactions before this ID should be retrieved if this is set to non-zero - * @param limit This number of reactions maximum should be returned - * @return user_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_get_reactions(const struct message &m, const std::string &reaction, snowflake before, snowflake after, snowflake limit); - -/** - * @brief Get reactions on a message for a particular emoji by id. The reaction string must be either an `emojiname:id` or a unicode character - * - * @see dpp::cluster::message_get_reactions - * @see https://discord.com/developers/docs/resources/channel#get-reactions - * @param message_id Message to get reactions for - * @param channel_id Channel to get reactions for - * @param reaction Reaction should be in the form emojiname:id or a unicode character - * @param before Reactions before this ID should be retrieved if this is set to non-zero - * @param after Reactions before this ID should be retrieved if this is set to non-zero - * @param limit This number of reactions maximum should be returned - * @return emoji_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_get_reactions(snowflake message_id, snowflake channel_id, const std::string &reaction, snowflake before, snowflake after, snowflake limit); - -/** - * @brief Pin a message - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::message_pin - * @see https://discord.com/developers/docs/resources/channel#pin-message - * @param channel_id Channel id to pin message on - * @param message_id Message id to pin message on - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_pin(snowflake channel_id, snowflake message_id); - -/** - * @brief Get multiple messages. - * - * This function will attempt to fetch as many messages as possible using multiple API calls if needed. - * - * @see dpp::cluster::messages_get - * @see https://discord.com/developers/docs/resources/channel#get-channel-messages - * @param channel_id Channel ID to retrieve messages for - * @param around Messages should be retrieved around this ID if this is set to non-zero - * @param before Messages before this ID should be retrieved if this is set to non-zero - * @param after Messages after this ID should be retrieved if this is set to non-zero - * @param limit This number of messages maximum should be returned, up to a maximum of 100. - * @return message_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_messages_get(snowflake channel_id, snowflake around, snowflake before, snowflake after, uint64_t limit); - -/** - * @brief Unpin a message - * @see dpp::cluster::message_unpin - * @see https://discord.com/developers/docs/resources/channel#unpin-message - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param channel_id Channel id to unpin message on - * @param message_id Message id to unpin message on - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_message_unpin(snowflake channel_id, snowflake message_id); - -/** - * @brief Get a list of users that voted for this specific answer. - * - * @param m Message that contains the poll to retrieve the answers from - * @param answer_id ID of the answer to retrieve votes from (see poll_answer::answer_id) - * @param after Users after this ID should be retrieved if this is set to non-zero - * @param limit This number of users maximum should be returned, up to 100 - * @return user_map returned object on completion - * @see dpp::cluster::poll_get_answer_voters - * @see https://discord.com/developers/docs/resources/poll#get-answer-voters - * \memberof dpp::cluster - */ -[[nodiscard]] async co_poll_get_answer_voters(const message& m, uint32_t answer_id, snowflake after, uint64_t limit); - -/** - * @brief Get a list of users that voted for this specific answer. - * - * @param message_id ID of the message with the poll to retrieve the answers from - * @param channel_id ID of the channel with the poll to retrieve the answers from - * @param answer_id ID of the answer to retrieve votes from (see poll_answer::answer_id) - * @param after Users after this ID should be retrieved if this is set to non-zero - * @param limit This number of users maximum should be returned, up to 100 - * @return user_map returned object on completion - * @see dpp::cluster::poll_get_answer_voters - * @see https://discord.com/developers/docs/resources/poll#get-answer-voters - * \memberof dpp::cluster - */ -[[nodiscard]] async co_poll_get_answer_voters(snowflake message_id, snowflake channel_id, uint32_t answer_id, snowflake after, uint64_t limit); - -/** - * @brief Immediately end a poll. - * - * @param m Message that contains the poll - * @return message returned object on completion - * @see dpp::cluster::poll_end - * @see https://discord.com/developers/docs/resources/poll#end-poll - * \memberof dpp::cluster - */ -[[nodiscard]] async co_poll_end(const message &m); - -/** - * @brief Immediately end a poll. - * - * @param message_id ID of the message with the poll to end - * @param channel_id ID of the channel with the poll to end - * @return message returned object on completion - * @see dpp::cluster::poll_end - * @see https://discord.com/developers/docs/resources/poll#end-poll - * \memberof dpp::cluster - */ -[[nodiscard]] async co_poll_end(snowflake message_id, snowflake channel_id); - -/** - * @brief Get a channel's pins - * @see dpp::cluster::channel_pins_get - * @see https://discord.com/developers/docs/resources/channel#get-pinned-messages - * @param channel_id Channel ID to get pins for - * @return message_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_channel_pins_get(snowflake channel_id); - -/** - * @brief Create a role on a guild - * - * Create a new role for the guild. Requires the `MANAGE_ROLES` permission. Returns the new role object on success. - * Fires a `Guild Role Create` Gateway event. - * - * @see dpp::cluster::role_create - * @see https://discord.com/developers/docs/resources/guild#create-guild-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param r Role to create (guild ID is encapsulated in the role object) - * @return role returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_role_create(const class role &r); - -/** - * @brief Delete a role - * - * Requires the `MANAGE_ROLES` permission. Fires a `Guild Role Delete` Gateway event. - * - * @see dpp::cluster::role_delete - * @see https://discord.com/developers/docs/resources/guild#delete-guild-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to delete the role on - * @param role_id Role ID to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_role_delete(snowflake guild_id, snowflake role_id); - -/** - * @brief Edit a role on a guild - * - * Requires the `MANAGE_ROLES` permission. Returns the updated role on success. Fires a `Guild Role Update` Gateway event. - * - * @see dpp::cluster::role_edit - * @see https://discord.com/developers/docs/resources/guild#modify-guild-role - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param r Role to edit - * @return role returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_role_edit(const class role &r); - -/** - * @brief Edit multiple role's position in a guild. Returns a list of all roles of the guild on success. - * - * Modify the positions of a set of role objects for the guild. Requires the `MANAGE_ROLES` permission. - * Fires multiple `Guild Role Update` Gateway events. - * - * @see dpp::cluster::roles_edit_position - * @see https://discord.com/developers/docs/resources/guild#modify-guild-role-positions - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @param guild_id Guild ID to change the roles position on - * @param roles Vector of roles to change the positions of - * @return role_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_roles_edit_position(snowflake guild_id, const std::vector &roles); - -/** - * @brief Get a role for a guild - * - * @see dpp::cluster::roles_get - * @see https://discord.com/developers/docs/resources/guild#get-guild-roles - * @param guild_id Guild ID to get role for - * @return role_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_roles_get(snowflake guild_id); - -/** - * @brief Get the application's role connection metadata records - * - * @see dpp::cluster::application_role_connection_get - * @see https://discord.com/developers/docs/resources/application-role-connection-metadata#get-application-role-connection-metadata-records - * @param application_id The application ID - * @return application_role_connection returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_application_role_connection_get(snowflake application_id); - -/** - * @brief Update the application's role connection metadata records - * - * @see dpp::cluster::application_role_connection_update - * @see https://discord.com/developers/docs/resources/application-role-connection-metadata#update-application-role-connection-metadata-records - * @param application_id The application ID - * @param connection_metadata The application role connection metadata to update - * @return application_role_connection returned object on completion - * @note An application can have a maximum of 5 metadata records. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_application_role_connection_update(snowflake application_id, const std::vector &connection_metadata); - -/** - * @brief Get user application role connection - * - * @see dpp::cluster::user_application_role_connection_get - * @see https://discord.com/developers/docs/resources/user#get-user-application-role-connection - * @param application_id The application ID - * @return application_role_connection returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_user_application_role_connection_get(snowflake application_id); - -/** - * @brief Update user application role connection - * - * @see dpp::cluster::user_application_role_connection_update - * @see https://discord.com/developers/docs/resources/user#update-user-application-role-connection - * @param application_id The application ID - * @param connection The application role connection to update - * @return application_role_connection returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_user_application_role_connection_update(snowflake application_id, const application_role_connection &connection); - -/** - * @brief Get all scheduled events for a guild - * @see dpp::cluster::guild_events_get - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#list-scheduled-events-for-guild - * @param guild_id Guild to get events for - * @return scheduled_event_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_events_get(snowflake guild_id); - -/** - * @brief Create a scheduled event on a guild - * - * @see dpp::cluster::guild_event_create - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event - * @param event Event to create (guild ID must be populated) - * @return scheduled_event returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_event_create(const scheduled_event& event); - -/** - * @brief Delete a scheduled event from a guild - * - * @see dpp::cluster::guild_event_delete - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#delete-guild-scheduled-event - * @param event_id Event ID to delete - * @param guild_id Guild ID of event to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_event_delete(snowflake event_id, snowflake guild_id); - -/** - * @brief Edit/modify a scheduled event on a guild - * - * @see dpp::cluster::guild_event_edit - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#modify-guild-scheduled-event - * @param event Event to create (event ID and guild ID must be populated) - * @return scheduled_event returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_event_edit(const scheduled_event& event); - -/** - * @brief Get a scheduled event for a guild - * - * @see dpp::cluster::guild_event_get - * @see https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event - * @param guild_id Guild to get event for - * @param event_id Event ID to get - * @return scheduled_event returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_event_get(snowflake guild_id, snowflake event_id); - -/** - * @brief Returns all SKUs for a given application. - * @note Because of how Discord's SKU and subscription systems work, you will see two SKUs for your premium offering. - * For integration and testing entitlements, you should use the SKU with type: 5. - * - * @see dpp::cluster::skus_get - * @see https://discord.com/developers/docs/monetization/skus#list-skus - * @return sku_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_skus_get(); - - -[[nodiscard]] async co_stage_instance_create(const stage_instance& si); - -/** - * @brief Get the stage instance associated with the channel id, if it exists. - * @see dpp::cluster::stage_instance_get - * @see https://discord.com/developers/docs/resources/stage-instance#get-stage-instance - * @param channel_id ID of the associated channel - * @return stage_instance returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_stage_instance_get(const snowflake channel_id); - - -[[nodiscard]] async co_stage_instance_edit(const stage_instance& si); - -/** - * @brief Delete a stage instance. - * @see dpp::cluster::stage_instance_delete - * @see https://discord.com/developers/docs/resources/stage-instance#delete-stage-instance - * @param channel_id ID of the associated channel - * @return confirmation returned object on completion - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_stage_instance_delete(const snowflake channel_id); - -/** - * @brief Create a sticker in a guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::guild_sticker_create - * @see https://discord.com/developers/docs/resources/sticker#create-guild-sticker - * @param s Sticker to create. Must have its guild ID set. - * @return sticker returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_sticker_create(const sticker &s); - -/** - * @brief Delete a sticker from a guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::guild_sticker_delete - * @see https://discord.com/developers/docs/resources/sticker#delete-guild-sticker - * @param sticker_id sticker ID to delete - * @param guild_id guild ID to delete from - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_sticker_delete(snowflake sticker_id, snowflake guild_id); - -/** - * @brief Get a guild sticker - * @see dpp::cluster::guild_sticker_get - * @see https://discord.com/developers/docs/resources/sticker#get-guild-sticker - * @param id Id of sticker to get. - * @param guild_id Guild ID of the guild where the sticker is - * @return sticker returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_sticker_get(snowflake id, snowflake guild_id); - -/** - * @brief Modify a sticker in a guild - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::guild_sticker_modify - * @see https://discord.com/developers/docs/resources/sticker#modify-guild-sticker - * @param s Sticker to modify. Must have its guild ID and sticker ID set. - * @return sticker returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_sticker_modify(const sticker &s); - -/** - * @brief Get all guild stickers - * @see dpp::cluster::guild_stickers_get - * @see https://discord.com/developers/docs/resources/sticker#list-guild-stickers - * @param guild_id Guild ID of the guild where the sticker is - * @return sticker_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_stickers_get(snowflake guild_id); - -/** - * @brief Get a nitro sticker - * @see dpp::cluster::nitro_sticker_get - * @see https://discord.com/developers/docs/resources/sticker#get-sticker - * @param id Id of sticker to get. - * @return sticker returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_nitro_sticker_get(snowflake id); - -/** - * @brief Get a list of available sticker packs - * @see dpp::cluster::sticker_packs_get - * @see https://discord.com/developers/docs/resources/sticker#list-sticker-packs - * @return sticker_pack_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_sticker_packs_get(); - -/** - * @brief Create a new guild based on a template. - * @note This endpoint can be used only by bots in less than 10 guilds. - * @see dpp::cluster::guild_create_from_template - * @see https://discord.com/developers/docs/resources/guild-template#create-guild-from-guild-template - * @param code Template code to create guild from - * @param name Guild name to create - * @return guild returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_create_from_template(const std::string &code, const std::string &name); - -/** - * @brief Creates a template for the guild - * - * @see dpp::cluster::guild_template_create - * @see https://discord.com/developers/docs/resources/guild-template#create-guild-template - * @param guild_id Guild to create template from - * @param name Template name to create - * @param description Description of template to create - * @return dtemplate returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_template_create(snowflake guild_id, const std::string &name, const std::string &description); - -/** - * @brief Deletes the template - * - * @see dpp::cluster::guild_template_delete - * @see https://discord.com/developers/docs/resources/guild-template#delete-guild-template - * @param guild_id Guild ID of template to delete - * @param code Template code to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_template_delete(snowflake guild_id, const std::string &code); - -/** - * @brief Modifies the template's metadata. - * - * @see dpp::cluster::guild_template_modify - * @see https://discord.com/developers/docs/resources/guild-template#modify-guild-template - * @param guild_id Guild ID of template to modify - * @param code Template code to modify - * @param name New name of template - * @param description New description of template - * @return dtemplate returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_template_modify(snowflake guild_id, const std::string &code, const std::string &name, const std::string &description); - -/** - * @brief Get guild templates - * - * @see dpp::cluster::guild_templates_get - * @see https://discord.com/developers/docs/resources/guild-template#get-guild-templates - * @param guild_id Guild ID to get templates for - * @return dtemplate_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_templates_get(snowflake guild_id); - -/** - * @brief Syncs the template to the guild's current state. - * - * @see dpp::cluster::guild_template_sync - * @see https://discord.com/developers/docs/resources/guild-template#sync-guild-template - * @param guild_id Guild to synchronise template for - * @param code Code of template to synchronise - * @return dtemplate returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_template_sync(snowflake guild_id, const std::string &code); - -/** - * @brief Get a template - * @see dpp::cluster::template_get - * @see https://discord.com/developers/docs/resources/guild-template#get-guild-template - * @param code Template code - * @return dtemplate returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_template_get(const std::string &code); - -/** - * @brief Join a thread - * @see dpp::cluster::current_user_join_thread - * @see https://discord.com/developers/docs/resources/channel#join-thread - * @param thread_id Thread ID to join - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_join_thread(snowflake thread_id); - -/** - * @brief Leave a thread - * @see dpp::cluster::current_user_leave_thread - * @see https://discord.com/developers/docs/resources/channel#leave-thread - * @param thread_id Thread ID to leave - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_leave_thread(snowflake thread_id); - -/** - * @brief Get all active threads in the guild, including public and private threads. Threads are ordered by their id, in descending order. - * @see dpp::cluster::threads_get_active - * @see https://discord.com/developers/docs/resources/guild#list-active-guild-threads - * @param guild_id Guild to get active threads for - * @return active_threads returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_threads_get_active(snowflake guild_id); - -/** - * @brief Get private archived threads in a channel which current user has joined (Sorted by ID in descending order) - * @see dpp::cluster::threads_get_joined_private_archived - * @see https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads - * @param channel_id Channel to get public archived threads for - * @param before_id Get threads before this id - * @param limit Number of threads to get - * @return thread_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_threads_get_joined_private_archived(snowflake channel_id, snowflake before_id, uint16_t limit); - -/** - * @brief Get private archived threads in a channel (Sorted by archive_timestamp in descending order) - * @see dpp::cluster::threads_get_private_archived - * @see https://discord.com/developers/docs/resources/channel#list-private-archived-threads - * @param channel_id Channel to get public archived threads for - * @param before_timestamp Get threads archived before this timestamp - * @param limit Number of threads to get - * @return thread_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_threads_get_private_archived(snowflake channel_id, time_t before_timestamp, uint16_t limit); - -/** - * @brief Get public archived threads in a channel (Sorted by archive_timestamp in descending order) - * @see dpp::cluster::threads_get_public_archived - * @see https://discord.com/developers/docs/resources/channel#list-public-archived-threads - * @param channel_id Channel to get public archived threads for - * @param before_timestamp Get threads archived before this timestamp - * @param limit Number of threads to get - * @return thread_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_threads_get_public_archived(snowflake channel_id, time_t before_timestamp, uint16_t limit); - -/** - * @brief Get a thread member - * @see dpp::cluster::thread_member_get - * @see https://discord.com/developers/docs/resources/channel#get-thread-member - * @param thread_id Thread to get member for - * @param user_id ID of the user to get - * @return thread_member returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_member_get(const snowflake thread_id, const snowflake user_id); - -/** - * @brief Get members of a thread - * @see dpp::cluster::thread_members_get - * @see https://discord.com/developers/docs/resources/channel#list-thread-members - * @param thread_id Thread to get members for - * @return thread_member_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_members_get(snowflake thread_id); - -/** - * @brief Create a thread in a forum or media channel - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see dpp::cluster::thread_create_in_forum - * @see https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel - * @param thread_name Name of the forum thread - * @param channel_id Forum channel in which thread to create - * @param msg The message to start the thread with - * @param auto_archive_duration Duration to automatically archive the thread after recent activity - * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected - * @param applied_tags List of IDs of forum tags (dpp::forum_tag) to apply to this thread - * @return thread returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_create_in_forum(const std::string& thread_name, snowflake channel_id, const message& msg, auto_archive_duration_t auto_archive_duration, uint16_t rate_limit_per_user, std::vector applied_tags = {}); - -/** - * @brief Create a thread - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see dpp::cluster::thread_create - * @see https://discord.com/developers/docs/resources/channel#start-thread-without-message - * @param thread_name Name of the thread - * @param channel_id Channel in which thread to create - * @param auto_archive_duration Duration after which thread auto-archives. Can be set to - 60, 1440 (for boosted guilds can also be: 4320, 10080) - * @param thread_type Type of thread - CHANNEL_PUBLIC_THREAD, CHANNEL_ANNOUNCEMENT_THREAD, CHANNEL_PRIVATE_THREAD - * @param invitable whether non-moderators can add other non-moderators to a thread; only available when creating a private thread - * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected - * @return thread returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_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); - -/** - * @brief Edit a thread - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * - * @see dpp::cluster::thread_edit - * @see https://discord.com/developers/docs/topics/threads#editing-deleting-threads - * @param t Thread to edit - * @return thread returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_edit(const thread &t); - -/** - * @brief Create a thread with a message (Discord: ID of a thread is same as message ID) - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::thread_create_with_message - * @see https://discord.com/developers/docs/resources/channel#start-thread-from-message - * @param thread_name Name of the thread - * @param channel_id Channel in which thread to create - * @param message_id message to start thread with - * @param auto_archive_duration Duration after which thread auto-archives. Can be set to - 60, 1440 (for boosted guilds can also be: 4320, 10080) - * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected - * @return thread returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_create_with_message(const std::string& thread_name, snowflake channel_id, snowflake message_id, uint16_t auto_archive_duration, uint16_t rate_limit_per_user); - -/** - * @brief Add a member to a thread - * @see dpp::cluster::thread_member_add - * @see https://discord.com/developers/docs/resources/channel#add-thread-member - * @param thread_id Thread ID to add to - * @param user_id Member ID to add - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_member_add(snowflake thread_id, snowflake user_id); - -/** - * @brief Remove a member from a thread - * @see dpp::cluster::thread_member_remove - * @see https://discord.com/developers/docs/resources/channel#remove-thread-member - * @param thread_id Thread ID to remove from - * @param user_id Member ID to remove - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_member_remove(snowflake thread_id, snowflake user_id); - -/** - * @brief Get the thread specified by thread_id. This uses the same call as dpp::cluster::channel_get but returns a thread object. - * @see dpp::cluster::thread_get - * @see https://discord.com/developers/docs/resources/channel#get-channel - * @param thread_id The id of the thread to obtain. - * @return thread returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_thread_get(snowflake thread_id); - -/** - * @brief Edit current (bot) user. - * - * Modify the requester's user account settings. Returns a dpp::user object on success. - * Fires a User Update Gateway event. - * - * @note There appears to be no limit to the image size, however, if your image cannot be processed/uploaded in time, you will receive a malformed http request. - * - * @see dpp::cluster::current_user_edit - * @see https://discord.com/developers/docs/resources/user#modify-current-user - * @param nickname Nickname to set - * @param avatar_blob Avatar data to upload - * @param avatar_type Type of image for avatar. It can be one of `i_gif`, `i_jpg` or `i_png`. - * @param banner_blob Banner data to upload - * @param banner_type Type of image for Banner. It can be one of `i_gif`, `i_jpg` or `i_png`. - * @return user returned object on completion - * @throw dpp::length_exception Image data is larger than the maximum size of 256 kilobytes - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_edit(const std::string &nickname, const std::string& avatar_blob = "", const image_type avatar_type = i_png, const std::string& banner_blob = "", const image_type banner_type = i_png); - -/** - * @brief Get current (bot) application - * - * @see dpp::cluster::current_application_get - * @see https://discord.com/developers/docs/topics/oauth2#get-current-bot-application-information - * @return application returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_application_get(); - -/** - * @brief Get current (bot) user - * - * @see dpp::cluster::current_user_get - * @see https://discord.com/developers/docs/resources/user#get-current-user - * @return user_identified returned object on completion - * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes. - * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_get(); - -/** - * @brief Set the bot's voice state on a stage channel - * - * **Caveats** - * - * There are currently several caveats for this endpoint: - * - * - `channel_id` must currently point to a stage channel. - * - current user must already have joined `channel_id`. - * - You must have the `MUTE_MEMBERS` permission to unsuppress yourself. You can always suppress yourself. - * - You must have the `REQUEST_TO_SPEAK` permission to request to speak. You can always clear your own request to speak. - * - You are able to set `request_to_speak_timestamp` to any present or future time. - * - * @see dpp::cluster::current_user_set_voice_state - * @see https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state - * @param guild_id Guild to set voice state on - * @param channel_id Stage channel to set voice state on - * @return confirmation returned object on completion - * @param suppress True if the user's audio should be suppressed, false if it should not - * @param request_to_speak_timestamp The time at which we requested to speak, or 0 to clear the request. The time set here must be the current time or in the future. - * @throw std::logic_exception You attempted to set a request_to_speak_timestamp in the past which is not the value of 0. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_set_voice_state(snowflake guild_id, snowflake channel_id, bool suppress = false, time_t request_to_speak_timestamp = 0); - -/** - * @brief Get the bot's voice state in a guild without a Gateway connection - * - * @see dpp::cluster::current_user_get_voice_state - * @see https://discord.com/developers/docs/resources/voice#get-current-user-voice-state - * @param guild_id Guild to get the voice state for - * @return voicestate returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_get_voice_state(snowflake guild_id); - -/** - * @brief Set a user's voice state on a stage channel - * - * **Caveats** - * - * There are currently several caveats for this endpoint: - * - * - `channel_id` must currently point to a stage channel. - * - User must already have joined `channel_id`. - * - You must have the `MUTE_MEMBERS` permission. (Since suppression is the only thing that is available currently) - * - When unsuppressed, non-bot users will have their `request_to_speak_timestamp` set to the current time. Bot users will not. - * - When suppressed, the user will have their `request_to_speak_timestamp` removed. - * - * @see dpp::cluster::user_set_voice_state - * @see https://discord.com/developers/docs/resources/guild#modify-user-voice-state - * @param user_id The user to set the voice state of - * @param guild_id Guild to set voice state on - * @param channel_id Stage channel to set voice state on - * @return confirmation returned object on completion - * @param suppress True if the user's audio should be suppressed, false if it should not - * \memberof dpp::cluster - */ -[[nodiscard]] async co_user_set_voice_state(snowflake user_id, snowflake guild_id, snowflake channel_id, bool suppress = false); - -/** - * @brief Get a user's voice state in a guild without a Gateway connection - * - * @see dpp::cluster::user_get_voice_state - * @see https://discord.com/developers/docs/resources/voice#get-user-voice-state - * @param guild_id Guild to get the voice state for - * @param user_id The user to get the voice state of - * @return voicestate returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_user_get_voice_state(snowflake guild_id, snowflake user_id); - -/** - * @brief Get current user's connections (linked accounts, e.g. steam, xbox). - * This call requires the oauth2 `connections` scope and cannot be executed - * against a bot token. - * @see dpp::cluster::current_user_connections_get - * @see https://discord.com/developers/docs/resources/user#get-user-connections - * @return connection_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_connections_get(); - -/** - * @brief Get current (bot) user guilds - * @see dpp::cluster::current_user_get_guilds - * @see https://discord.com/developers/docs/resources/user#get-current-user-guilds - * @return guild_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_get_guilds(); - -/** - * @brief Leave a guild - * @see dpp::cluster::current_user_leave_guild - * @see https://discord.com/developers/docs/resources/user#leave-guild - * @param guild_id Guild ID to leave - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_current_user_leave_guild(snowflake guild_id); - -/** - * @brief Get a user by id, without using the cache - * - * @see dpp::cluster::user_get - * @see https://discord.com/developers/docs/resources/user#get-user - * @param user_id User ID to retrieve - * @return user_identified returned object on completion - * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes. - * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`. - * @note unless you want something special from `dpp::user_identified` or you've turned off caching, you have no need to call this. - * Call `dpp::find_user` instead that looks up the user in the cache rather than a REST call. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_user_get(snowflake user_id); - -/** - * @brief Get a user by id, checking in the cache first - * - * @see dpp::cluster::user_get_cached - * @see https://discord.com/developers/docs/resources/user#get-user - * @param user_id User ID to retrieve - * @return user_identified returned object on completion - * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes. - * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`. - * @note If the user is found in the cache, special values set in `dpp::user_identified` will be undefined. This call should be used - * where you want to for example resolve a user who may no longer be in the bot's guilds, for something like a ban log message. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_user_get_cached(snowflake user_id); - -/** - * @brief Get all voice regions - * @see dpp::cluster::get_voice_regions - * @see https://discord.com/developers/docs/resources/voice#list-voice-regions - * @return voiceregion_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_get_voice_regions(); - -/** - * @brief Get guild voice regions. - * - * Voice regions per guild are somewhat deprecated in preference of per-channel voice regions. - * Returns a list of voice region objects for the guild. Unlike the similar /voice route, this returns VIP servers when - * the guild is VIP-enabled. - * - * @see dpp::cluster::guild_get_voice_regions - * @see https://discord.com/developers/docs/resources/guild#get-guild-voice-regions - * @param guild_id Guild ID to get voice regions for - * @return voiceregion_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_guild_get_voice_regions(snowflake guild_id); - - -[[nodiscard]] async co_create_webhook(const class webhook &wh); - -/** - * @brief Delete a webhook - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::delete_webhook - * @see https://discord.com/developers/docs/resources/webhook#delete-webhook - * @param webhook_id Webhook ID to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_delete_webhook(snowflake webhook_id); - -/** - * @brief Delete webhook message - * - * @see dpp::cluster::delete_webhook_message - * @see https://discord.com/developers/docs/resources/webhook#delete-webhook-message - * @param wh Webhook to delete message for - * @param message_id Message ID to delete - * @param thread_id ID of the thread the message is in - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_delete_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id = 0); - -/** - * @brief Delete webhook with token - * @see dpp::cluster::delete_webhook_with_token - * @see https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token - * @param webhook_id Webhook ID to delete - * @param token Token of webhook to delete - * @return confirmation returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_delete_webhook_with_token(snowflake webhook_id, const std::string &token); - -/** - * @brief Edit webhook - * @note This method supports audit log reasons set by the cluster::set_audit_reason() method. - * @see dpp::cluster::edit_webhook - * @see https://discord.com/developers/docs/resources/webhook#modify-webhook - * @param wh Webhook to edit - * @return webhook returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_edit_webhook(const class webhook& wh); - -/** - * @brief Edit webhook message - * - * When the content field is edited, the mentions array in the message object will be reconstructed from scratch based on - * the new content. The allowed_mentions field of the edit request controls how this happens. If there is no explicit - * allowed_mentions in the edit request, the content will be parsed with default allowances, that is, without regard to - * whether or not an allowed_mentions was present in the request that originally created the message. - * - * @see dpp::cluster::edit_webhook_message - * @see https://discord.com/developers/docs/resources/webhook#edit-webhook-message - * @note the attachments array must contain all attachments that should be present after edit, including retained and new attachments provided in the request body. - * @param wh Webhook to edit message for - * @param m New message - * @param thread_id ID of the thread the message is in - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_edit_webhook_message(const class webhook &wh, const struct message &m, snowflake thread_id = 0); - -/** - * @brief Edit webhook with token (token is encapsulated in the webhook object) - * @see dpp::cluster::edit_webhook_with_token - * @see https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token - * @param wh Webhook to edit (should include token) - * @return webhook returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_edit_webhook_with_token(const class webhook& wh); - -/** - * @brief Execute webhook - * - * @see dpp::cluster::execute_webhook - * @see https://discord.com/developers/docs/resources/webhook#execute-webhook - * @param wh Webhook to execute - * @param m Message to send - * @param wait waits for server confirmation of message send before response, and returns the created message body - * @param thread_id Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived - * @param thread_name Name of thread to create (requires the webhook channel to be a forum channel) - * @return message returned object on completion - * @note If the webhook channel is a forum channel, you must provide either `thread_id` or `thread_name`. If `thread_id` is provided, the message will send in that thread. If `thread_name` is provided, a thread with that name will be created in the forum channel. - * \memberof dpp::cluster - */ -[[nodiscard]] async co_execute_webhook(const class webhook &wh, const struct message &m, bool wait = false, snowflake thread_id = 0, const std::string& thread_name = ""); - -/** - * @brief Get channel webhooks - * @see dpp::cluster::get_channel_webhooks - * @see https://discord.com/developers/docs/resources/webhook#get-guild-webhooks - * @param channel_id Channel ID to get webhooks for - * @return webhook_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_get_channel_webhooks(snowflake channel_id); - -/** - * @brief Get guild webhooks - * @see dpp::cluster::get_guild_webhooks - * @see https://discord.com/developers/docs/resources/webhook#get-guild-webhooks - * @param guild_id Guild ID to get webhooks for - * @return webhook_map returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_get_guild_webhooks(snowflake guild_id); - -/** - * @brief Get webhook - * @see dpp::cluster::get_webhook - * @see https://discord.com/developers/docs/resources/webhook#get-webhook - * @param webhook_id Webhook ID to get - * @return webhook returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_get_webhook(snowflake webhook_id); - -/** - * @brief Get webhook message - * - * @see dpp::cluster::get_webhook_message - * @see https://discord.com/developers/docs/resources/webhook#get-webhook-message - * @param wh Webhook to get the original message for - * @param message_id The message ID - * @param thread_id ID of the thread the message is in - * @return message returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_get_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id = 0); - -/** - * @brief Get webhook using token - * @see dpp::cluster::get_webhook_with_token - * @see https://discord.com/developers/docs/resources/webhook#get-webhook-with-token - * @param webhook_id Webhook ID to retrieve - * @param token Token of webhook - * @return webhook returned object on completion - * \memberof dpp::cluster - */ -[[nodiscard]] async co_get_webhook_with_token(snowflake webhook_id, const std::string &token); - - -/* End of auto-generated definitions */ -[[nodiscard]] async co_request(const std::string &url, http_method method, const std::string &postdata = "", const std::string &mimetype = "text/plain", const std::multimap &headers = {}, const std::string &protocol = "1.1"); - diff --git a/include/dpp/collector.h b/include/dpp/collector.h deleted file mode 100644 index 715a640..0000000 --- a/include/dpp/collector.h +++ /dev/null @@ -1,473 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Collects objects from events during a specified time period. - * - * This template must be specialised. There are premade specialisations which you can use - * such as dpp::reaction_collector and dpp::message_collector. For these specialised instances - * all you need to do is derive a simple class from them which implements collector::completed(). - * - * A collector will run for the specified number of seconds, attaching itself to the - * given event. During this time any events pass through the collector and collector::filter(). - * This function can return a pointer to an object to allow a copy of that object to be stored - * to a vector, or it can return nullptr to do nothing with that object. For example a collector - * attached to on_message_create would receive an event with the type message_create_t, and from - * this may decide to extract the message_create_t::msg structure, returning a pointer to it, or - * instead may choose to return a nullptr. - * - * When either the predetermined timeout is reached, or the collector::cancel() method is called, - * or the collector is destroyed, the collector::completed() method is called, which will be - * passed a list of collected objects in the order they were collected. - * - * @tparam T parameter type of the event this collector will monitor - * @tparam C object type this collector will store - */ -template class collector -{ -protected: - /** - * @brief Owning cluster. - */ - class cluster* owner; -private: - /** - * @brief Timed listener. - */ - timed_listener, std::function>* tl; - - /** - * @brief Stored list. - */ - std::vector stored; - - /** - * @brief Trigger flag. - */ - bool triggered; -public: - /** - * @brief Construct a new collector object. - * - * The timer for the collector begins immediately on construction of the object. - * - * @param cl Pointer to cluster which manages this collector - * @param duration Duration in seconds to run the collector for - * @param event Event to attach to, e.g. cluster::on_message_create - */ - collector(class cluster* cl, uint64_t duration, event_router_t & event) : owner(cl), triggered(false) { - std::function f = [this](const T& event) { - const C* v = filter(event); - if (v) { - stored.push_back(*v); - } - }; - tl = new dpp::timed_listener, std::function>(cl, duration, event, f, [this]([[maybe_unused]] dpp::timer timer_handle) { - if (!triggered) { - triggered = true; - completed(stored); - } - }); - } - - /** - * @brief You must implement this function to receive the completed list of - * captured objects. - * @param list The list of captured objects in captured order - */ - virtual void completed(const std::vector& list) = 0; - - /** - * @brief Filter the list of elements. - * - * Every time an event is fired on the collector, this method wil be called - * to determine if we should add an object to the list or not. This function - * can then process the `element` value, extract the parts which are to be - * saved to a list (e.g. a dpp::message out of a dpp::message_create_t) and - * return it as the return value. Returning a value of nullptr causes no - * object to be stored. - * - * Here is an example of how to filter messages which have specific text in them. - * This should be used with the specialised type dpp::message_collector - * - * ```cpp - * virtual const dpp::message* filter(const dpp::message_create_t& m) { - * if (m.msg.content.find("something i want") != std::string::npos) { - * return &m.msg; - * } else { - * return nullptr; - * } - * } - * ``` - * - * @param element The event data to filter - * @return const C* Returned object or nullptr - */ - virtual const C* filter(const T& element) = 0; - - /** - * @brief Immediately cancels the collector. - * - * Use this if you have met the conditions for which you are collecting objects - * early, e.g. you were watching for a message containing 'yes' or 'no' and have - * received it before the time is up. - * - * @note Causes calling of the completed() method if it has not yet been called. - */ - virtual void cancel() { - delete tl; - tl = nullptr; - } - - /** - * @brief Destroy the collector object. - * @note Causes calling of the completed() method if it has not yet been called. - */ - virtual ~collector() { - delete tl; - } -}; - -/** - * @brief Represents a reaction. - * Can be filled for use in a collector - */ -class collected_reaction : public managed { -public: - /** - * @brief Reacting user. - */ - user react_user{}; - - /** - * @brief Reacting guild. - */ - guild react_guild{}; - - /** - * @brief Reacting guild member. - */ - guild_member react_member{}; - - /** - * @brief Reacting channel. - */ - channel react_channel{}; - - /** - * @brief Reacted emoji. - */ - emoji react_emoji{}; - - /** - * @brief Optional: ID of the user who authored the message which was reacted to. - */ - snowflake message_author_id{}; -}; - -/** - * @brief Template type for base class of channel collector - */ -typedef dpp::collector channel_collector_t; - -/** - * @brief Template type for base class of thread collector - */ -typedef dpp::collector thread_collector_t; - -/** - * @brief Template type for base class of role collector - */ -typedef dpp::collector role_collector_t; - -/** - * @brief Template type for base class of scheduled event collector - */ -typedef dpp::collector scheduled_event_collector_t; - -/** - * @brief Template type for base class of message collector - */ -typedef dpp::collector message_collector_t; - -/** - * @brief Template type for base class of message reaction collector - */ -typedef dpp::collector reaction_collector_t; - -/** - * @brief Message collector. - * Collects messages during a set timeframe and returns them in a list via the completed() method. - */ -class message_collector : public message_collector_t { -public: - /** - * @brief Construct a new message collector object - * - * @param cl cluster to associate the collector with - * @param duration Duration of time to run the collector for in seconds - */ - message_collector(cluster* cl, uint64_t duration) : message_collector_t::collector(cl, duration, cl->on_message_create) { } - - /** - * @brief Return the completed collection - * - * @param list items collected during the timeframe specified - */ - virtual void completed(const std::vector& list) = 0; - - /** - * @brief Select and filter the items which are to appear in the list - * This is called every time a new event is fired, to filter the event and determine which - * of the items is sent to the list. Returning nullptr excludes the item from the list. - * - * @param element element to filter - * @return Returned item to add to the list, or nullptr to skip adding this element - */ - virtual const dpp::message* filter(const dpp::message_create_t& element) { return &element.msg; } - - /** - * @brief Destroy the message collector object - */ - virtual ~message_collector() = default; -}; - -/** - * @brief Reaction collector. - * Collects message reactions during a set timeframe and returns them in a list via the completed() method. - */ -class reaction_collector : public reaction_collector_t { - /** - * @brief The ID of the message. - */ - snowflake message_id; - - /** - * @brief The reaction. - */ - collected_reaction react; -public: - /** - * @brief Construct a new reaction collector object - * - * @param cl cluster to associate the collector with - * @param duration Duration of time to run the collector for in seconds - * @param msg_id Optional message ID. If specified, only collects reactions for the given message - */ - reaction_collector(cluster* cl, uint64_t duration, snowflake msg_id = 0) : reaction_collector_t::collector(cl, duration, cl->on_message_reaction_add), message_id(msg_id) { } - - /** - * @brief Return the completed collection - * - * @param list items collected during the timeframe specified - */ - virtual void completed(const std::vector& list) = 0; - - /** - * @brief Select and filter the items which are to appear in the list - * This is called every time a new event is fired, to filter the event and determine which - * of the items is sent to the list. Returning nullptr excludes the item from the list. - * - * @param element element to filter - * @return Returned item to add to the list, or nullptr to skip adding this element - */ - virtual const dpp::collected_reaction* filter(const dpp::message_reaction_add_t& element) { - /* Capture reactions for given message ID only */ - if (message_id.empty() || element.message_id == message_id) { - react.id = element.message_id; - react.react_user = element.reacting_user; - react.react_guild = element.reacting_guild; - react.react_member = element.reacting_member; - react.react_channel = element.reacting_channel; - react.react_emoji = element.reacting_emoji; - react.message_author_id = element.message_author_id; - return &react; - } else { - return nullptr; - } - } - - /** - * @brief Destroy the reaction collector object - */ - virtual ~reaction_collector() = default; -}; - -/** - * @brief Channel collector. - * Collects channels during a set timeframe and returns them in a list via the completed() method. - */ -class channel_collector : public channel_collector_t { -public: - /** - * @brief Construct a new channel collector object - * - * @param cl cluster to associate the collector with - * @param duration Duration of time to run the collector for in seconds - */ - channel_collector(cluster* cl, uint64_t duration) : channel_collector_t::collector(cl, duration, cl->on_channel_create) { } - - /** - * @brief Return the completed collection - * - * @param list items collected during the timeframe specified - */ - virtual void completed(const std::vector& list) = 0; - - /** - * @brief Select and filter the items which are to appear in the list - * This is called every time a new event is fired, to filter the event and determine which - * of the items is sent to the list. Returning nullptr excludes the item from the list. - * - * @param element element to filter - * @return Returned item to add to the list, or nullptr to skip adding this element - */ - virtual const dpp::channel* filter(const dpp::channel_create_t& element) { return &element.created; } - - /** - * @brief Destroy the channel collector object - */ - virtual ~channel_collector() = default; -}; - -/** - * @brief Thread collector. - * Collects threads during a set timeframe and returns them in a list via the completed() method. - */ -class thread_collector : public thread_collector_t { -public: - /** - * @brief Construct a new thread collector object - * - * @param cl cluster to associate the collector with - * @param duration Duration of time to run the collector for in seconds - */ - thread_collector(cluster* cl, uint64_t duration) : thread_collector_t::collector(cl, duration, cl->on_thread_create) { } - - /** - * @brief Return the completed collection - * - * @param list items collected during the timeframe specified - */ - virtual void completed(const std::vector& list) = 0; - - /** - * @brief Select and filter the items which are to appear in the list - * This is called every time a new event is fired, to filter the event and determine which - * of the items is sent to the list. Returning nullptr excludes the item from the list. - * - * @param element element to filter - * @return Returned item to add to the list, or nullptr to skip adding this element - */ - virtual const dpp::thread* filter(const dpp::thread_create_t& element) { return &element.created; } - - /** - * @brief Destroy the thread collector object - */ - virtual ~thread_collector() = default; -}; - -/** - * @brief Role collector. - * Collects guild roles during a set timeframe and returns them in a list via the completed() method. - */ -class role_collector : public role_collector_t { -public: - /** - * @brief Construct a new role collector object - * - * @param cl cluster to associate the collector with - * @param duration Duration of time to run the collector for in seconds - */ - role_collector(cluster* cl, uint64_t duration) : role_collector_t::collector(cl, duration, cl->on_guild_role_create) { } - - /** - * @brief Return the completed collection - * - * @param list items collected during the timeframe specified - */ - virtual void completed(const std::vector& list) = 0; - - /** - * @brief Select and filter the items which are to appear in the list - * This is called every time a new event is fired, to filter the event and determine which - * of the items is sent to the list. Returning nullptr excludes the item from the list. - * - * @param element element to filter - * @return Returned item to add to the list, or nullptr to skip adding this element - */ - virtual const dpp::role* filter(const dpp::guild_role_create_t& element) { return &element.created; } - - /** - * @brief Destroy the role collector object - */ - virtual ~role_collector() = default; -}; - -/** - * @brief Scheduled event collector. - * Collects messages during a set timeframe and returns them in a list via the completed() method. - */ -class scheduled_event_collector : public scheduled_event_collector_t { -public: - /** - * @brief Construct a new scheduled event collector object - * - * @param cl cluster to associate the collector with - * @param duration Duration of time to run the collector for in seconds - */ - scheduled_event_collector(cluster* cl, uint64_t duration) : scheduled_event_collector_t::collector(cl, duration, cl->on_guild_scheduled_event_create) { } - - /** - * @brief Return the completed collection - * - * @param list items collected during the timeframe specified - */ - virtual void completed(const std::vector& list) = 0; - - /** - * @brief Select and filter the items which are to appear in the list - * This is called every time a new event is fired, to filter the event and determine which - * of the items is sent to the list. Returning nullptr excludes the item from the list. - * - * @param element element to filter - * @return Returned item to add to the list, or nullptr to skip adding this element - */ - virtual const dpp::scheduled_event* filter(const dpp::guild_scheduled_event_create_t& element) { return &element.created; } - - /** - * @brief Destroy the scheduled event collector object - */ - virtual ~scheduled_event_collector() = default; -}; - -} diff --git a/include/dpp/colors.h b/include/dpp/colors.h deleted file mode 100644 index 7a2c90b..0000000 --- a/include/dpp/colors.h +++ /dev/null @@ -1,745 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include - -/** - * @brief The main namespace for D++ functions. classes and types - */ -namespace dpp { - -/** - * @brief predefined color constants. - */ -namespace colors { - const uint32_t - white = 0xFFFFFF, - discord_white = 0xFFFFFE, - light_gray = 0xC0C0C0, - gray = 0x808080, - dark_gray = 0x404040, - black = 0x000000, - discord_black = 0x000001, - red = 0xFF0000, - pink = 0xFFAFAF, - orange = 0xFFC800, - yellow = 0xFFFF00, - green = 0x00FF00, - magenta = 0xFF00FF, - cyan = 0x00FFFF, - blue = 0x0000FF, - light_sea_green = 0x1ABC9C, - medium_sea_green = 0x2ECC71, - summer_sky = 0x3498DB, - deep_lilac = 0x9B59B6, - ruby = 0xE91E63, - moon_yellow = 0xF1C40F, - tahiti_gold = 0xE67E22, - cinnabar = 0xE74C3C, - submarine = 0x95A5A6, - blue_aquamarine = 0x607D8B, - deep_sea = 0x11806A, - sea_green = 0x1F8B4C, - endeavour = 0x206694, - vivid_violet = 0x71368A, - jazzberry_jam = 0xAD1457, - dark_goldenrod = 0xC27C0E, - rust = 0xA84300, - brown = 0x992D22, - gray_chateau = 0x979C9F, - bismark = 0x546E7A, - sti_blue = 0x0E4BEF, - wrx_blue = 0x00247D, - rallyart_crimson = 0xE60012, - lime = 0x00FF00, - forest_green = 0x228B22, - cadmium_green = 0x097969, - aquamarine = 0x7FFFD4, - blue_green = 0x088F8F, - raspberry = 0xE30B5C, - scarlet_red = 0xFF2400, - night = 0x0C090A, - charcoal = 0x34282C, - oil = 0x3B3131, - light_black = 0x454545, - black_cat = 0x413839, - iridium = 0x3D3C3A, - black_eel = 0x463E3F, - black_cow = 0x4C4646, - gray_wolf = 0x504A4B, - grey_wolf = 0x504A4B, - vampire_gray = 0x565051, - vampire_grey = 0x565051, - iron_gray = 0x52595D, - iron_grey = 0x52595D, - gray_dolphin = 0x5C5858, - grey_dolphin = 0x5C5858, - carbon_gray = 0x625D5D, - carbon_grey = 0x625D5D, - ash_gray = 0x666362, - ash_grey = 0x666362, - dim_gray = 0x696969, - dim_grey = 0x696969, - nardo_gray = 0x686A6C, - nardo_grey = 0x686A6C, - cloudy_gray = 0x6D6968, - cloudy_grey = 0x6D6968, - smokey_gray = 0x726E6D, - smokey_grey = 0x726E6D, - alien_gray = 0x736F6E, - alien_grey = 0x736F6E, - sonic_silver = 0x757575, - platinum_gray = 0x797979, - platinum_grey = 0x797979, - granite = 0x837E7C, - battleship_gray = 0x848482, - battleship_grey = 0x848482, - gunmetal_gray = 0x8D918D, - gunmetal_grey = 0x8D918D, - gray_cloud = 0xB6B6B4, - grey_cloud = 0xB6B6B4, - silver = 0xC0C0C0, - pale_silver = 0xC9C0BB, - gray_goose = 0xD1D0CE, - grey_goose = 0xD1D0CE, - platinum_silver = 0xCECECE, - silver_white = 0xDADBDD, - gainsboro = 0xDCDCDC, - platinum = 0xE5E4E2, - metallic_silver = 0xBCC6CC, - blue_gray = 0x98AFC7, - blue_grey = 0x98AFC7, - roman_silver = 0x838996, - light_slate_gray = 0x778899, - light_slate_grey = 0x778899, - slate_gray = 0x708090, - slate_grey = 0x708090, - rat_gray = 0x6D7B8D, - slate_granite_gray = 0x657383, - slate_granite_grey = 0x657383, - jet_gray = 0x616D7E, - jet_grey = 0x616D7E, - mist_blue = 0x646D7E, - marble_blue = 0x566D7E, - slate_blue_grey = 0x737CA1, - slate_blue_gray = 0x737CA1, - light_purple_blue = 0x728FCE, - azure_blue = 0x4863A0, - blue_jay = 0x2B547E, - charcoal_blue = 0x36454F, - dark_blue_grey = 0x29465B, - dark_slate = 0x2B3856, - deep_sea_blue = 0x123456, - night_blue = 0x151B54, - midnight_blue = 0x191970, - navy = 0x000080, - denim_dark_blue = 0x151B8D, - dark_blue = 0x00008B, - lapis_blue = 0x15317E, - new_midnight_blue = 0x0000A0, - earth_blue = 0x0000A5, - cobalt_blue = 0x0020C2, - medium_blue = 0x0000CD, - blueberry_blue = 0x0041C2, - canary_blue = 0x2916F5, - samco_blue = 0x0002FF, - bright_blue = 0x0909FF, - blue_orchid = 0x1F45FC, - sapphire_blue = 0x2554C7, - blue_eyes = 0x1569C7, - bright_navy_blue = 0x1974D2, - balloon_blue = 0x2B60DE, - royal_blue = 0x4169E1, - ocean_blue = 0x2B65EC, - blue_ribbon = 0x306EFF, - blue_dress = 0x157DEC, - neon_blue = 0x1589FF, - dodger_blue = 0x1E90FF, - glacial_blue_ice = 0x368BC1, - steel_blue = 0x4682B4, - silk_blue = 0x488AC7, - windows_blue = 0x357EC7, - blue_ivy = 0x3090C7, - blue_koi = 0x659EC7, - columbia_blue = 0x87AFC7, - baby_blue = 0x95B9C7, - cornflower_blue = 0x6495ED, - sky_blue_dress = 0x6698FF, - iceberg = 0x56A5EC, - butterfly_blue = 0x38ACEC, - deep_sky_blue = 0x00BFFF, - midday_blue = 0x3BB9FF, - crystal_blue = 0x5CB3FF, - denim_blue = 0x79BAEC, - day_sky_blue = 0x82CAFF, - light_sky_blue = 0x87CEFA, - sky_blue = 0x87CEEB, - jeans_blue = 0xA0CFEC, - blue_angel = 0xB7CEEC, - pastel_blue = 0xB4CFEC, - light_day_blue = 0xADDFFF, - sea_blue = 0xC2DFFF, - heavenly_blue = 0xC6DEFF, - robin_egg_blue = 0xBDEDFF, - powder_blue = 0xB0E0E6, - coral_blue = 0xAFDCEC, - light_blue = 0xADD8E6, - light_steel_blue = 0xB0CFDE, - gulf_blue = 0xC9DFEC, - pastel_light_blue = 0xD5D6EA, - lavender_blue = 0xE3E4FA, - white_blue = 0xDBE9FA, - lavender = 0xE6E6FA, - water = 0xEBF4FA, - alice_blue = 0xF0F8FF, - ghost_white = 0xF8F8FF, - azure = 0xF0FFFF, - light_cyan = 0xE0FFFF, - light_slate = 0xCCFFFF, - electric_blue = 0x9AFEFF, - tron_blue = 0x7DFDFE, - blue_zircon = 0x57FEFF, - aqua = 0x00FFFF, - bright_cyan = 0x0AFFFF, - celeste = 0x50EBEC, - blue_diamond = 0x4EE2EC, - bright_turquoise = 0x16E2F5, - blue_lagoon = 0x8EEBEC, - pale_turquoise = 0xAFEEEE, - pale_blue_lily = 0xCFECEC, - light_teal = 0xB3D9D9, - tiffany_blue = 0x81D8D0, - blue_hosta = 0x77BFC7, - cyan_opaque = 0x92C7C7, - northern_lights_blue = 0x78C7C7, - medium_aquamarine = 0x66CDAA, - magic_mint = 0xAAF0D1, - light_aquamarine = 0x93FFE8, - bright_teal = 0x01F9C6, - turquoise = 0x40E0D0, - medium_turquoise = 0x48D1CC, - deep_turquoise = 0x48CCCD, - jellyfish = 0x46C7C7, - blue_turquoise = 0x43C6DB, - dark_turquoise = 0x00CED1, - macaw_blue_green = 0x43BFC7, - seafoam_green = 0x3EA99F, - cadet_blue = 0x5F9EA0, - blue_chill = 0x3B9C9C, - dark_cyan = 0x008B8B, - teal_green = 0x00827F, - teal = 0x008080, - teal_blue = 0x007C80, - medium_teal = 0x045F5F, - dark_teal = 0x045D5D, - deep_teal = 0x033E3E, - dark_slate_gray = 0x25383C, - dark_slate_grey = 0x25383C, - gunmetal = 0x2C3539, - blue_moss_green = 0x3C565B, - beetle_green = 0x4C787E, - grayish_turquoise = 0x5E7D7E, - greenish_blue = 0x307D7E, - aquamarine_stone = 0x348781, - sea_turtle_green = 0x438D80, - dull_sea_green = 0x4E8975, - dark_green_blue = 0x1F6357, - deep_sea_green = 0x306754, - bottle_green = 0x006A4E, - elf_green = 0x1B8A6B, - dark_mint = 0x31906E, - jade = 0x00A36C, - earth_green = 0x34A56F, - chrome_green = 0x1AA260, - emerald = 0x50C878, - mint = 0x3EB489, - metallic_green = 0x7C9D8E, - camouflage_green = 0x78866B, - sage_green = 0x848B79, - hazel_green = 0x617C58, - venom_green = 0x728C00, - olive_drab = 0x6B8E23, - olive = 0x808000, - dark_olive_green = 0x556B2F, - military_green = 0x4E5B31, - green_leaves = 0x3A5F0B, - army_green = 0x4B5320, - fern_green = 0x667C26, - fall_forest_green = 0x4E9258, - irish_green = 0x08A04B, - pine_green = 0x387C44, - medium_forest_green = 0x347235, - jungle_green = 0x347C2C, - cactus_green = 0x227442, - dark_green = 0x006400, - deep_green = 0x056608, - deep_emerald_green = 0x046307, - hunter_green = 0x355E3B, - dark_forest_green = 0x254117, - lotus_green = 0x004225, - seaweed_green = 0x437C17, - shamrock_green = 0x347C17, - green_onion = 0x6AA121, - moss_green = 0x8A9A5B, - grass_green = 0x3F9B0B, - green_pepper = 0x4AA02C, - dark_lime_green = 0x41A317, - parrot_green = 0x12AD2B, - clover_green = 0x3EA055, - dinosaur_green = 0x73A16C, - green_snake = 0x6CBB3C, - alien_green = 0x6CC417, - green_apple = 0x4CC417, - lime_green = 0x32CD32, - pea_green = 0x52D017, - kelly_green = 0x4CC552, - zombie_green = 0x54C571, - green_peas = 0x89C35C, - dollar_bill_green = 0x85BB65, - frog_green = 0x99C68E, - turquoise_green = 0xA0D6B4, - dark_sea_green = 0x8FBC8F, - basil_green = 0x829F82, - gray_green = 0xA2AD9C, - iguana_green = 0x9CB071, - citron_green = 0x8FB31D, - acid_green = 0xB0BF1A, - avocado_green = 0xB2C248, - pistachio_green = 0x9DC209, - salad_green = 0xA1C935, - yellow_green = 0x9ACD32, - pastel_green = 0x77DD77, - hummingbird_green = 0x7FE817, - nebula_green = 0x59E817, - stoplight_go_green = 0x57E964, - neon_green = 0x16F529, - jade_green = 0x5EFB6E, - lime_mint_green = 0x36F57F, - spring_green = 0x00FF7F, - medium_spring_green = 0x00FA9A, - emerald_green = 0x5FFB17, - lawn_green = 0x7CFC00, - bright_green = 0x66FF00, - chartreuse = 0x7FFF00, - yellow_lawn_green = 0x87F717, - aloe_vera_green = 0x98F516, - dull_green_yellow = 0xB1FB17, - lemon_green = 0xADF802, - green_yellow = 0xADFF2F, - chameleon_green = 0xBDF516, - neon_yellow_green = 0xDAEE01, - yellow_green_grosbeak = 0xE2F516, - tea_green = 0xCCFB5D, - slime_green = 0xBCE954, - algae_green = 0x64E986, - light_green = 0x90EE90, - dragon_green = 0x6AFB92, - pale_green = 0x98FB98, - mint_green = 0x98FF98, - green_thumb = 0xB5EAAA, - organic_brown = 0xE3F9A6, - light_jade = 0xC3FDB8, - light_mint_green = 0xC2E5D3, - light_rose_green = 0xDBF9DB, - chrome_white = 0xE8F1D4, - honeydew = 0xF0FFF0, - mint_cream = 0xF5FFFA, - lemon_chiffon = 0xFFFACD, - parchment = 0xFFFFC2, - cream = 0xFFFFCC, - cream_white = 0xFFFDD0, - light_goldenrod_yellow = 0xFAFAD2, - light_yellow = 0xFFFFE0, - beige = 0xF5F5DC, - cornsilk = 0xFFF8DC, - blonde = 0xFBF6D9, - champagne = 0xF7E7CE, - antique_white = 0xFAEBD7, - papaya_whip = 0xFFEFD5, - blanched_almond = 0xFFEBCD, - bisque = 0xFFE4C4, - wheat = 0xF5DEB3, - moccasin = 0xFFE4B5, - peach = 0xFFE5B4, - light_orange = 0xFED8B1, - peach_puff = 0xFFDAB9, - coral_peach = 0xFBD5AB, - navajo_white = 0xFFDEAD, - golden_blonde = 0xFBE7A1, - golden_silk = 0xF3E3C3, - dark_blonde = 0xF0E2B6, - light_gold = 0xF1E5AC, - vanilla = 0xF3E5AB, - tan_brown = 0xECE5B6, - dirty_white = 0xE8E4C9, - pale_goldenrod = 0xEEE8AA, - khaki = 0xF0E68C, - cardboard_brown = 0xEDDA74, - harvest_gold = 0xEDE275, - sun_yellow = 0xFFE87C, - corn_yellow = 0xFFF380, - pastel_yellow = 0xFAF884, - neon_yellow = 0xFFFF33, - canary_yellow = 0xFFEF00, - banana_yellow = 0xF5E216, - mustard_yellow = 0xFFDB58, - golden_yellow = 0xFFDF00, - bold_yellow = 0xF9DB24, - rubber_ducky_yellow = 0xFFD801, - gold = 0xFFD700, - bright_gold = 0xFDD017, - chrome_gold = 0xFFCE44, - golden_brown = 0xEAC117, - deep_yellow = 0xF6BE00, - macaroni_and_cheese = 0xF2BB66, - saffron = 0xFBB917, - neon_gold = 0xFDBD01, - beer = 0xFBB117, - yellow_orange = 0xFFAE42, - orange_yellow = 0xFFAE42, - cantaloupe = 0xFFA62F, - cheese_orange = 0xFFA600, - brown_sand = 0xEE9A4D, - sandy_brown = 0xF4A460, - brown_sugar = 0xE2A76F, - camel_brown = 0xC19A6B, - deer_brown = 0xE6BF83, - burly_wood = 0xDEB887, - tan = 0xD2B48C, - light_french_beige = 0xC8AD7F, - sand = 0xC2B280, - sage = 0xBCB88A, - fall_leaf_brown = 0xC8B560, - ginger_brown = 0xC9BE62, - bronze_gold = 0xC9AE5D, - dark_khaki = 0xBDB76B, - olive_green = 0xBAB86C, - brass = 0xB5A642, - cookie_brown = 0xC7A317, - metallic_gold = 0xD4AF37, - bee_yellow = 0xE9AB17, - school_bus_yellow = 0xE8A317, - goldenrod = 0xDAA520, - orange_gold = 0xD4A017, - caramel = 0xC68E17, - cinnamon = 0xC58917, - peru = 0xCD853F, - bronze = 0xCD7F32, - tiger_orange = 0xC88141, - copper = 0xB87333, - dark_gold = 0xAA6C39, - metallic_bronze = 0xA97142, - dark_almond = 0xAB784E, - wood = 0x966F33, - oak_brown = 0x806517, - antique_bronze = 0x665D1E, - hazel = 0x8E7618, - dark_yellow = 0x8B8000, - dark_moccasin = 0x827839, - khaki_green = 0x8A865D, - millennium_jade = 0x93917C, - dark_beige = 0x9F8C76, - bullet_shell = 0xAF9B60, - army_brown = 0x827B60, - sandstone = 0x786D5F, - taupe = 0x483C32, - mocha = 0x493D26, - milk_chocolate = 0x513B1C, - gray_brown = 0x3D3635, - dark_coffee = 0x3B2F2F, - old_burgundy = 0x43302E, - western_charcoal = 0x49413F, - bakers_brown = 0x5C3317, - dark_brown = 0x654321, - sepia_brown = 0x704214, - dark_bronze = 0x804A00, - coffee = 0x6F4E37, - brown_bear = 0x835C3B, - red_dirt = 0x7F5217, - sepia = 0x7F462C, - sienna = 0xA0522D, - saddle_brown = 0x8B4513, - dark_sienna = 0x8A4117, - sangria = 0x7E3817, - blood_red = 0x7E3517, - chestnut = 0x954535, - coral_brown = 0x9E4638, - chestnut_red = 0xC34A2C, - mahogany = 0xC04000, - red_gold = 0xEB5406, - red_fox = 0xC35817, - dark_bisque = 0xB86500, - light_brown = 0xB5651D, - petra_gold = 0xB76734, - copper_red = 0xCB6D51, - orange_salmon = 0xC47451, - chocolate = 0xD2691E, - sedona = 0xCC6600, - papaya_orange = 0xE56717, - halloween_orange = 0xE66C2C, - neon_orange = 0xFF6700, - bright_orange = 0xFF5F1F, - pumpkin_orange = 0xF87217, - carrot_orange = 0xF88017, - dark_orange = 0xFF8C00, - construction_cone_orange = 0xF87431, - indian_saffron = 0xFF7722, - sunrise_orange = 0xE67451, - mango_orange = 0xFF8040, - coral = 0xFF7F50, - basket_ball_orange = 0xF88158, - light_salmon_rose = 0xF9966B, - light_salmon = 0xFFA07A, - dark_salmon = 0xE9967A, - tangerine = 0xE78A61, - light_copper = 0xDA8A67, - salmon_pink = 0xFF8674, - salmon = 0xFA8072, - peach_pink = 0xF98B88, - light_coral = 0xF08080, - pastel_red = 0xF67280, - pink_coral = 0xE77471, - bean_red = 0xF75D59, - valentine_red = 0xE55451, - indian_red = 0xCD5C5C, - tomato = 0xFF6347, - shocking_orange = 0xE55B3C, - orange_red = 0xFF4500, - neon_red = 0xFD1C03, - ruby_red = 0xF62217, - ferrari_red = 0xF70D1A, - fire_engine_red = 0xF62817, - lava_red = 0xE42217, - love_red = 0xE41B17, - grapefruit = 0xDC381F, - cherry_red = 0xC24641, - chilli_pepper = 0xC11B17, - fire_brick = 0xB22222, - tomato_sauce_red = 0xB21807, - carbon_red = 0xA70D2A, - cranberry = 0x9F000F, - saffron_red = 0x931314, - crimson_red = 0x990000, - red_wine = 0x990012, - wine_red = 0x990012, - dark_red = 0x8B0000, - maroon = 0x800000, - burgundy = 0x8C001A, - vermilion = 0x7E191B, - deep_red = 0x800517, - red_blood = 0x660000, - blood_night = 0x551606, - dark_scarlet = 0x560319, - black_bean = 0x3D0C02, - chocolate_brown = 0x3F000F, - midnight = 0x2B1B17, - purple_lily = 0x550A35, - purple_maroon = 0x810541, - plum_pie = 0x7D0541, - plum_velvet = 0x7D0552, - dark_raspberry = 0x872657, - velvet_maroon = 0x7E354D, - rosy_finch = 0x7F4E52, - dull_purple = 0x7F525D, - puce = 0x7F5A58, - rose_dust = 0x997070, - pastel_brown = 0xB1907F, - rosy_pink = 0xB38481, - rosy_brown = 0xBC8F8F, - khaki_rose = 0xC5908E, - lipstick_pink = 0xC48793, - pink_brown = 0xC48189, - old_rose = 0xC08081, - dusty_pink = 0xD58A94, - pink_daisy = 0xE799A3, - rose = 0xE8ADAA, - dusty_rose = 0xC9A9A6, - silver_pink = 0xC4AEAD, - gold_pink = 0xE6C7C2, - rose_gold = 0xECC5C0, - deep_peach = 0xFFCBA4, - pastel_orange = 0xF8B88B, - desert_sand = 0xEDC9AF, - unbleached_silk = 0xFFDDCA, - pig_pink = 0xFDD7E4, - pale_pink = 0xF2D4D7, - blush = 0xFFE6E8, - misty_rose = 0xFFE4E1, - pink_bubble_gum = 0xFFDFDD, - light_rose = 0xFBCFCD, - light_red = 0xFFCCCB, - warm_pink = 0xF6C6BD, - deep_rose = 0xFBBBB9, - light_pink = 0xFFB6C1, - soft_pink = 0xFFB8BF, - donut_pink = 0xFAAFBE, - baby_pink = 0xFAAFBA, - flamingo_pink = 0xF9A7B0, - pastel_pink = 0xFEA3AA, - rose_pink = 0xE7A1B0, - pink_rose = 0xE7A1B0, - cadillac_pink = 0xE38AAE, - carnation_pink = 0xF778A1, - pastel_rose = 0xE5788F, - blush_red = 0xE56E94, - pale_violet_red = 0xDB7093, - purple_pink = 0xD16587, - tulip_pink = 0xC25A7C, - bashful_pink = 0xC25283, - dark_pink = 0xE75480, - dark_hot_pink = 0xF660AB, - hot_pink = 0xFF69B4, - watermelon_pink = 0xFC6C85, - violet_red = 0xF6358A, - hot_deep_pink = 0xF52887, - bright_pink = 0xFF007F, - deep_pink = 0xFF1493, - neon_pink = 0xF535AA, - chrome_pink = 0xFF33AA, - neon_hot_pink = 0xFD349C, - pink_cupcake = 0xE45E9D, - royal_pink = 0xE759AC, - dimorphotheca_magenta = 0xE3319D, - pink_lemonade = 0xE4287C, - red_pink = 0xFA2A55, - crimson = 0xDC143C, - bright_maroon = 0xC32148, - rose_red = 0xC21E56, - rogue_pink = 0xC12869, - burnt_pink = 0xC12267, - pink_violet = 0xCA226B, - magenta_pink = 0xCC338B, - medium_violet_red = 0xC71585, - dark_carnation_pink = 0xC12283, - raspberry_purple = 0xB3446C, - pink_plum = 0xB93B8F, - orchid = 0xDA70D6, - deep_mauve = 0xDF73D4, - violet = 0xEE82EE, - fuchsia_pink = 0xFF77FF, - bright_neon_pink = 0xF433FF, - fuchsia = 0xFF00FF, - crimson_purple = 0xE238EC, - heliotrope_purple = 0xD462FF, - tyrian_purple = 0xC45AEC, - medium_orchid = 0xBA55D3, - purple_flower = 0xA74AC7, - orchid_purple = 0xB048B5, - rich_lilac = 0xB666D2, - pastel_violet = 0xD291BC, - mauve_taupe = 0x915F6D, - viola_purple = 0x7E587E, - eggplant = 0x614051, - plum_purple = 0x583759, - grape = 0x5E5A80, - purple_navy = 0x4E5180, - slate_blue = 0x6A5ACD, - blue_lotus = 0x6960EC, - blurple = 0x5865F2, - light_slate_blue = 0x736AFF, - medium_slate_blue = 0x7B68EE, - periwinkle_purple = 0x7575CF, - very_peri = 0x6667AB, - bright_grape = 0x6F2DA8, - purple_amethyst = 0x6C2DC7, - bright_purple = 0x6A0DAD, - deep_periwinkle = 0x5453A6, - dark_slate_blue = 0x483D8B, - purple_haze = 0x4E387E, - purple_iris = 0x571B7E, - dark_purple = 0x4B0150, - deep_purple = 0x36013F, - midnight_purple = 0x2E1A47, - purple_monster = 0x461B7E, - indigo = 0x4B0082, - blue_whale = 0x342D7E, - rebecca_purple = 0x663399, - purple_jam = 0x6A287E, - dark_magenta = 0x8B008B, - purple = 0x800080, - french_lilac = 0x86608E, - dark_orchid = 0x9932CC, - dark_violet = 0x9400D3, - purple_violet = 0x8D38C9, - jasmine_purple = 0xA23BEC, - purple_daffodil = 0xB041FF, - clematis_violet = 0x842DCE, - blue_violet = 0x8A2BE2, - purple_sage_bush = 0x7A5DC7, - lovely_purple = 0x7F38EC, - neon_purple = 0x9D00FF, - purple_plum = 0x8E35EF, - aztech_purple = 0x893BFF, - medium_purple = 0x9370DB, - light_purple = 0x8467D7, - crocus_purple = 0x9172EC, - purple_mimosa = 0x9E7BFF, - periwinkle = 0xCCCCFF, - pale_lilac = 0xDCD0FF, - lavender_purple = 0x967BB6, - rose_purple = 0xB09FCA, - lilac = 0xC8A2C8, - mauve = 0xE0B0FF, - bright_lilac = 0xD891EF, - purple_dragon = 0xC38EC7, - plum = 0xDDA0DD, - blush_pink = 0xE6A9EC, - pastel_purple = 0xF2A2E8, - blossom_pink = 0xF9B7FF, - wisteria_purple = 0xC6AEC7, - purple_thistle = 0xD2B9D3, - thistle = 0xD8BFD8, - purple_white = 0xDFD3E3, - periwinkle_pink = 0xE9CFEC, - cotton_candy = 0xFCDFFF, - lavender_pinocchio = 0xEBDDE2, - dark_white = 0xE1D9D1, - ash_white = 0xE9E4D4, - white_chocolate = 0xEDE6D6, - soft_ivory = 0xFAF0DD, - off_white = 0xF8F0E3, - pearl_white = 0xF8F6F0, - red_white = 0xF3E8EA, - lavender_blush = 0xFFF0F5, - pearl = 0xFDEEF4, - egg_shell = 0xFFF9E3, - old_lace = 0xFEF0E3, - linen = 0xFAF0E6, - sea_shell = 0xFFF5EE, - bone_white = 0xF9F6EE, - rice = 0xFAF5EF, - floral_white = 0xFFFAF0, - ivory = 0xFFFFF0, - white_gold = 0xFFFFF4, - light_white = 0xFFFFF7, - white_smoke = 0xF5F5F5, - cotton = 0xFBFBF9, - snow = 0xFFFAFA, - milk_white = 0xFEFCFF, - half_white = 0xFFFEFA; -} // namespace colors - -/** - * @brief Predefined colour constants, same as colors but for the british. - */ -namespace colours = colors; -} // namespace dpp diff --git a/include/dpp/commandhandler.h b/include/dpp/commandhandler.h deleted file mode 100644 index c8be5c9..0000000 --- a/include/dpp/commandhandler.h +++ /dev/null @@ -1,428 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief dpp::resolved_user contains both a dpp::guild_member and a dpp::user. - * The user can be used to obtain in-depth user details such as if they are nitro, - * and the guild member information to check their roles on a guild etc. - * The Discord API provides both if a parameter is a user ping, - * so we offer both in a combined structure. - */ -struct DPP_EXPORT resolved_user { - /** - * @brief Holds user information - */ - dpp::user user; - - /** - * @brief Holds member information - */ - dpp::guild_member member; -}; - -/** - * @brief Represents a received parameter. - * We use variant so that multiple non-related types can be contained within. - */ -typedef std::variant command_parameter; - -/** - * @brief Parameter types when registering a command. - * We don't pass these in when triggering the command in the handler, because it is - * expected the developer added the command so they know what types to expect for each named - * parameter. - */ -enum parameter_type { - /** - * @brief String parameter. - */ - pt_string, - - /** - * @brief Role object parameter. - */ - pt_role, - - /** - * @brief Channel object parameter. - */ - pt_channel, - - /** - * @brief User object parameter. - */ - pt_user, - - /** - * @brief 64 bit signed integer parameter. - */ - pt_integer, - - /** - * @brief double floating point parameter. - */ - pt_double, - - /** - * @brief Boolean parameter. - */ - pt_boolean -}; - -/** - * @brief Details of a command parameter used in registration. - * Note that for non-slash commands optional parameters can only be at the end of - * the list of parameters. - */ -struct DPP_EXPORT param_info { - /** - * @brief Type of parameter - */ - parameter_type type; - - /** - * @brief True if the parameter is optional. - * For non-slash commands optional parameters may only be on the end of the list. - */ - bool optional; - - /** - * @brief Description of command. Displayed only for slash commands - */ - std::string description; - - /** - * @brief Allowed multiple choice options. - * The key name is the string passed to the command handler - * and the key value is its description displayed to the user. - */ - std::map choices; - - /** - * @brief Construct a new param_info object - * - * @param t Type of parameter - * @param o True if parameter is optional - * @param description The parameter description - * @param opts The options for a multiple choice parameter - */ - param_info(parameter_type t, bool o, const std::string &description, const std::map &opts = {}); -}; - -/** - * @brief Parameter list used during registration. - * Note that use of vector/pair is important here to preserve parameter order, - * as opposed to unordered_map (which doesn't guarantee any order at all) and - * std::map, which reorders keys alphabetically. - */ -typedef std::vector> parameter_registration_t; - -/** - * @brief Parameter list for a called command. - * See dpp::parameter_registration_t for an explanation as to why vector is used. - */ -typedef std::vector> parameter_list_t; - -/** - * @brief Represents the sending source of a command. - * This is passed to any command handler and should be passed back to - * commandhandler::reply(), allowing the reply method to route any replies back - * to the origin, which may be a slash command or a message. Both require different - * response facilities but we want this to be transparent if you use the command - * handler class. - * @deprecated commandhandler and message commands are deprecated and dpp::slashcommand is encouraged as a replacement. - */ -struct DPP_EXPORT command_source { - /** - * @brief Sending guild id - */ - snowflake guild_id; - - /** - * @brief Source channel id - */ - snowflake channel_id; - - /** - * @brief Command ID of a slash command - */ - snowflake command_id; - - /** - * @brief Token for sending a slash command reply - */ - std::string command_token; - - /** - * @brief The user who issued the command - */ - user issuer; - - /** - * @brief Copy of the underlying message_create_t event, if it was a message create event - */ - std::optional message_event; - - /** - * @brief Copy of the underlying interaction_create_t event, if it was an interaction create event - */ - std::optional interaction_event; - - /** - * @brief Construct a command_source object from a message_create_t event - */ - command_source(const struct message_create_t& event); - - /** - * @brief Construct a command_source object from an interaction_create_t event - */ - command_source(const struct interaction_create_t& event); -}; - -/** - * @brief The function definition for a command handler. Expects a command name string, - * and a list of command parameters. - * @deprecated commandhandler and message commands are deprecated and dpp::slashcommand is encouraged as a replacement. - */ -typedef std::function command_handler; - -/** - * @brief Represents the details of a command added to the command handler class. - * @deprecated commandhandler and message commands are deprecated and dpp::slashcommand is encouraged as a replacement. - */ -struct DPP_EXPORT command_info_t { - /** - * @brief Function reference for the handler. This is std::function so it can represent - * a class member, a lambda or a raw C function pointer. - */ - command_handler func; - - /** - * @brief Parameters requested for the command, with their types - */ - parameter_registration_t parameters; - - /** - * @brief Guild ID the command exists on, or 0 to be present on all guilds - */ - snowflake guild_id; -}; - - -/** - * @brief The commandhandler class represents a group of commands, prefixed or slash commands with handling functions. - * - * It can automatically register slash commands, and handle routing of messages and interactions to separated command handler - * functions. - * @deprecated commandhandler and message commands are deprecated and dpp::slashcommand is encouraged as a replacement. - */ -class DPP_EXPORT DPP_DEPRECATED("commandhandler should not be used. Please consider using dpp::cluster::register_command instead.") commandhandler { -private: - /** - * @brief List of guild commands to bulk register - */ - std::map> bulk_registration_list_guild; - - /** - * @brief List of global commands to bulk register - */ - std::vector bulk_registration_list_global; -public: - /** - * @brief Commands in the handler - */ - std::unordered_map commands; - - /** - * @brief Valid prefixes - */ - std::vector prefixes; - - /** - * @brief Set to true automatically if one of the prefixes added is "/" - */ - bool slash_commands_enabled; - - /** - * @brief Cluster we are attached to for issuing REST calls - */ - class cluster* owner; - - /** - * @brief Application ID - */ - snowflake app_id; - - /** - * @brief Interaction event handle - */ - event_handle interactions; - - /** - * @brief Message event handle - */ - event_handle messages; - - /** - * @brief Returns true if the string has a known prefix on the start. - * Modifies string to remove prefix if it returns true. - * - * @param str String to check and modify - * @return true string contained a prefix, prefix removed from string - * @return false string did not contain a prefix - */ - bool string_has_prefix(std::string &str); - -public: - - /** - * @brief Construct a new commandhandler object - * - * @param o Owning cluster to attach to - * @param auto_hook_events Set to true to automatically hook the on_slashcommand - * and on_message events. You should not need to set this to false unless you have a specific - * use case, as D++ supports multiple listeners to an event, so will allow the commandhandler - * to hook to your command events without disrupting other uses for the events you may have. - * @param application_id The application id of the bot. If not specified, the class will - * look within the cluster object and use cluster::me::id instead. - */ - commandhandler(class cluster* o, bool auto_hook_events = true, snowflake application_id = 0); - - /** - * @brief Destroy the commandhandler object - */ - ~commandhandler(); - - /** - * @brief Set the application id after construction - * - * @param o Owning cluster to attach to - */ - commandhandler& set_owner(class cluster* o); - - /** - * @brief Add a prefix to the command handler - * - * @param prefix Prefix to be handled by the command handler - * @return commandhandler& reference to self - */ - commandhandler& add_prefix(const std::string &prefix); - - /** - * @brief Add a command to the command handler - * - * @param command Command to be handled. - * Note that if any one of your prefixes is "/" this will attempt to register - * a global command using the API and you will receive notification of this command - * via an interaction event. - * @param handler Handler function - * @param parameters Parameters to use for the command - * @param description The description of the command, shown for slash commands - * @param guild_id The guild ID to restrict the command to. For slash commands causes registration of a guild command as opposed to a global command. - * @return commandhandler& reference to self - * @throw dpp::logic_exception if application ID cannot be determined - */ - commandhandler& add_command(const std::string &command, const parameter_registration_t ¶meters, command_handler handler, const std::string &description = "", snowflake guild_id = 0); - - /** - * @brief Register all slash commands with Discord - * This method must be called at least once if you are using the "/" prefix to mark the - * end of commands being added to the handler. Note that this uses bulk registration and will replace any - * existing slash commands. - * - * Note that if you have previously registered your commands and they have not changed, you do - * not need to call this again. Discord retains a cache of previously added commands. - * - * @return commandhandler& Reference to self for chaining method calls - */ - commandhandler& register_commands(); - - /** - * @brief Route a command from the on_message_create function. - * Call this method from within your on_message_create with the received - * dpp::message object if you have disabled automatic registration of events. - * - * @param event message create event to parse - */ - void route(const struct dpp::message_create_t& event); - - /** - * @brief Route a command from the on_slashcommand function. - * Call this method from your on_slashcommand with the received - * dpp::interaction_create_t object if you have disabled automatic registration of events. - * - * @param event command interaction event to parse - */ - void route(const struct slashcommand_t & event); - - /** - * @brief Reply to a command. - * You should use this method rather than cluster::message_create as - * the way you reply varies between slash commands and message commands. - * Note you should ALWAYS reply. Slash commands will emit an ugly error - * to the user if you do not emit some form of reply within 3 seconds. - * - * @param m message to reply with. - * @param source source of the command - * @param callback User function to execute when the api call completes. - */ - void reply(const dpp::message &m, command_source source, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Reply to a command without a message, causing the discord client - * to display "Bot name is thinking...". - * The "thinking" message will persist for a maximum of 15 minutes. - * This counts as a reply for a slash command. Slash commands will emit an - * ugly error to the user if you do not emit some form of reply within 3 - * seconds. - * - * @param source source of the command - * @param callback User function to execute when the api call completes. - */ - void thinking(command_source source, command_completion_event_t callback = utility::log_error()); - - /** - * @brief Easter egg (redefinition of dpp::commandhandler::thinking). - */ - void thonk(command_source source, command_completion_event_t callback = utility::log_error()); - -}; - -} diff --git a/include/dpp/coro.h b/include/dpp/coro.h deleted file mode 100644 index 03d3181..0000000 --- a/include/dpp/coro.h +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once - -#include "coro/awaitable.h" -#include "coro/async.h" -#include "coro/coroutine.h" -#include "coro/job.h" -#include "coro/task.h" -#include "coro/when_any.h" diff --git a/include/dpp/coro/async.h b/include/dpp/coro/async.h deleted file mode 100644 index 6f42259..0000000 --- a/include/dpp/coro/async.h +++ /dev/null @@ -1,189 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include - -#include - -namespace dpp { - -struct async_dummy : awaitable_dummy { - std::shared_ptr dummy_shared_state = nullptr; -}; - -} - -#ifndef DPP_NO_CORO - -#include "coro.h" - -#include -#include -#include -#include -#include - -namespace dpp { - -namespace detail { - -namespace async { - -/** - * @brief Shared state of the async and its callback, to be used across threads. - */ -template -struct callback { - /** - * @brief Promise object to set the result into - */ - std::shared_ptr> promise{nullptr}; - - /** - * @brief Call operator, sets the value in the promise and notifies any awaiter - * - * @param v Callback value - */ - template - void operator()(const U& v) const requires (std::convertible_to) { - promise->set_value(v); - } - - /** - * @brief Call operator, sets the value in the promise and notifies any awaiter - * - * @param v Callback value - */ - template - void operator()(U&& v) const requires (std::convertible_to) { - promise->set_value(std::move(v)); - } - - /** - * @brief Call operator, sets the value in the promise and notifies any awaiter - */ - void operator()() const requires (std::is_void_v) - { - promise->set_value(); - } -}; - -} // namespace async - -} // namespace detail - -struct confirmation_callback_t; - -/** - * @class async async.h coro/async.h - * @brief A co_await-able object handling an API call in parallel with the caller. - * - * This class is the return type of the dpp::cluster::co_* methods, but it can also be created manually to wrap any async call. - * - * @remark - The coroutine may be resumed in another thread, do not rely on thread_local variables. - * @warning - This feature is EXPERIMENTAL. The API may change at any time and there may be bugs. Please report any to GitHub issues or to the D++ Discord server. - * @tparam R The return type of the API call. Defaults to confirmation_callback_t - */ -template -class async : public awaitable { - /** - * @brief Callable object to pass to API calls - */ - detail::async::callback api_callback{}; - - /** - * @brief Internal promise constructor, grabs a promise object for the callback to use - */ - explicit async(std::shared_ptr> &&promise) : awaitable{promise.get()}, api_callback{std::move(promise)} {} - -public: - using awaitable::awaitable; // use awaitable's constructors - using awaitable::operator=; // use async_base's assignment operator - using awaitable::await_ready; // expose await_ready as public - - /** - * @brief The return type of the API call. Defaults to confirmation_callback_t - */ - using result_type = R; - - /** - * @brief Construct an async object wrapping an object method, the call is made immediately by forwarding to std::invoke and can be awaited later to retrieve the result. - * - * @param obj The object to call the method on - * @param fun The method of the object to call. Its last parameter must be a callback taking a parameter of type R - * @param args Parameters to pass to the method, excluding the callback - */ - template -#ifndef _DOXYGEN_ - requires std::invocable> -#endif - explicit async(Obj &&obj, Fun &&fun, Args&&... args) : async{std::make_shared>()} { - std::invoke(std::forward(fun), std::forward(obj), std::forward(args)..., api_callback); - } - - /** - * @brief Construct an async object wrapping an invokeable object, the call is made immediately by forwarding to std::invoke and can be awaited later to retrieve the result. - * - * @param fun The object to call using std::invoke. Its last parameter must be a callable taking a parameter of type R - * @param args Parameters to pass to the object, excluding the callback - */ - template -#ifndef _DOXYGEN_ - requires std::invocable> -#endif - explicit async(Fun &&fun, Args&&... args) : async{std::make_shared>()} { - std::invoke(std::forward(fun), std::forward(args)..., api_callback); - } - - /** - * @brief Copy constructor is disabled. - */ - async(const async&) = delete; - - /** - * @brief Move constructor, moves the awaitable async object - */ - async(async&&) = default; - - /** - * @brief Copy assignment operator is disabled. - */ - async& operator=(const async&) = delete; - - /** - * @brief Move assignment operator, moves the awaitable async object - */ - async& operator=(async&&) = default; - - /** - * @brief Destructor, signals to the callback that the async object is gone and shouldn't be notified of the result - */ - ~async() { - this->abandon(); - } -}; - -DPP_CHECK_ABI_COMPAT(async<>, async_dummy); - -} - -#endif /* DPP_NO_CORO */ diff --git a/include/dpp/coro/awaitable.h b/include/dpp/coro/awaitable.h deleted file mode 100644 index 488bcd1..0000000 --- a/include/dpp/coro/awaitable.h +++ /dev/null @@ -1,735 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once - -#include - -#include - -namespace dpp { - -struct awaitable_dummy { - int *promise_dummy = nullptr; -}; - -} - -#ifndef DPP_NO_CORO - -#include - -// Do not include as coro.h includes or depending on clang version -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -namespace detail::promise { - -/** - * @brief State of a promise - */ -enum state_flags { - /** - * @brief Promise is empty - */ - sf_none = 0b0000000, - - /** - * @brief Promise has spawned an awaitable - */ - sf_has_awaitable = 0b00000001, - - /** - * @brief Promise is being awaited - */ - sf_awaited = 0b00000010, - - /** - * @brief Promise has a result - */ - sf_ready = 0b00000100, - - /** - * @brief Promise has completed, no more results are expected - */ - sf_done = 0b00001000, - - /** - * @brief Promise was broken - future or promise is gone - */ - sf_broken = 0b0010000 -}; - -template -class promise_base; - -/** - * @brief Empty result from void-returning awaitable - */ -struct empty{}; - -/** - * @brief Variant for the 3 conceptual values of a coroutine: - */ -template -using result_t = std::variant, empty, T>, std::exception_ptr>; - -template -void spawn_sync_wait_job(auto* awaitable, std::condition_variable &cv, auto&& result); - -} /* namespace detail::promise */ - -template -class basic_awaitable { -protected: - /** - * @brief Implementation for sync_wait. This is code used by sync_wait, sync_wait_for, sync_wait_until. - * - * @tparam Timed Whether the wait function times out or not - * @param do_wait Function to do the actual wait on the cv - * @return If T is void, returns a boolean for which true means the awaitable completed, false means it timed out. - * @return If T is non-void, returns a std::optional for which an absence of value means timed out. - */ - template - auto sync_wait_impl(auto&& do_wait) { - using result_type = decltype(detail::co_await_resolve(std::declval()).await_resume()); - using variant_type = detail::promise::result_t; - variant_type result; - std::condition_variable cv; - - detail::promise::spawn_sync_wait_job(static_cast(this), cv, result); - do_wait(cv, result); - /* - * Note: we use .index() here to support dpp::promise & dpp::promise :D - */ - if (result.index() == 2) { - std::rethrow_exception(std::get<2>(result)); - } - if constexpr (!Timed) { // no timeout - if constexpr (!std::is_void_v) { - return std::get<1>(result); - } - } else { // timeout - if constexpr (std::is_void_v) { - return result.index() == 1 ? true : false; - } else { - return result.index() == 1 ? std::optional{std::get<1>(result)} : std::nullopt; - } - } - } - -public: - /** - * @brief Blocks this thread and waits for the awaitable to finish. - * - * @attention This will BLOCK THE THREAD. It is likely you want to use co_await instead. - * @return If T is void, returns a boolean for which true means the awaitable completed, false means it timed out. - * @return If T is non-void, returns a std::optional for which an absence of value means timed out. - */ - auto sync_wait() { - return sync_wait_impl([](std::condition_variable &cv, auto&& result) { - std::mutex m{}; - std::unique_lock lock{m}; - cv.wait(lock, [&result] { return result.index() != 0; }); - }); - } - - /** - * @brief Blocks this thread and waits for the awaitable to finish. - * - * @attention This will BLOCK THE THREAD. It is likely you want to use co_await instead. - * @param duration Maximum duration to wait for - * @return If T is void, returns a boolean for which true means the awaitable completed, false means it timed out. - * @return If T is non-void, returns a std::optional for which an absence of value means timed out. - */ - template - auto sync_wait_for(const std::chrono::duration& duration) { - return sync_wait_impl([duration](std::condition_variable &cv, auto&& result) { - std::mutex m{}; - std::unique_lock lock{m}; - cv.wait_for(lock, duration, [&result] { return result.index() != 0; }); - }); - } - - /** - * @brief Blocks this thread and waits for the awaitable to finish. - * - * @attention This will BLOCK THE THREAD. It is likely you want to use co_await instead. - * @param time Maximum time point to wait for - * @return If T is void, returns a boolean for which true means the awaitable completed, false means it timed out. - * @return If T is non-void, returns a std::optional for which an absence of value means timed out. - */ - template - auto sync_wait_until(const std::chrono::time_point &time) { - return sync_wait_impl([time](std::condition_variable &cv, auto&& result) { - std::mutex m{}; - std::unique_lock lock{m}; - cv.wait_until(lock, time, [&result] { return result.index() != 0; }); - }); - } -}; - -/** - * @brief Generic awaitable class, represents a future value that can be co_await-ed on. - * - * Roughly equivalent of std::future for coroutines, with the crucial distinction that the future does not own a reference to a "shared state". - * It holds a non-owning reference to the promise, which must be kept alive for the entire lifetime of the awaitable. - * - * @tparam T Type of the asynchronous value - * @see promise - */ -template -class awaitable : public basic_awaitable> { -protected: - friend class detail::promise::promise_base; - - using shared_state = detail::promise::promise_base; - using state_flags = detail::promise::state_flags; - - /** - * @brief The type of the result produced by this task. - */ - using result_type = T; - - /** - * @brief Non-owning pointer to the promise, which must be kept alive for the entire lifetime of the awaitable. - */ - shared_state *state_ptr = nullptr; - - /** - * @brief Construct from a promise. - * - * @param promise The promise to refer to. - */ - awaitable(shared_state *promise) noexcept : state_ptr{promise} {} - - /** - * @brief Abandons the promise. - * - * Set the promise's state to broken and unlinks this awaitable. - * - * @return uint8_t Flags previously held before setting them to broken - */ - uint8_t abandon(); - /** - * @brief Awaiter returned by co_await. - * - * Contains the await_ready, await_suspend and await_resume functions required by the C++ standard. - * This class is CRTP-like, in that it will refer to an object derived from awaitable. - * - * @tparam Derived Type of reference to refer to the awaitable. - */ - template - struct awaiter { - Derived awaitable_obj; - - /** - * @brief First function called by the standard library when co_await-ing this object. - * - * @throws dpp::logic_exception If the awaitable's valid() would return false. - * @return bool Whether the result is ready, in which case we don't need to suspend - */ - bool await_ready() const; - - /** - * @brief Second function called by the standard library when co_await-ing this object. - * - * @throws dpp::logic_exception If the awaitable's valid() would return false. - * At this point the coroutine frame was allocated and suspended. - * - * @return bool Whether we do need to suspend or not - */ - bool await_suspend(detail::std_coroutine::coroutine_handle<> handle); - - /** - * @brief Third and final function called by the standard library when co_await-ing this object, after resuming. - * - * @throw ? Any exception that occured during the retrieval of the value will be thrown - * @return T The result. - */ - T await_resume(); - }; - -public: - /** - * @brief Construct an empty awaitable. - * - * Such an awaitable must be assigned a promise before it can be awaited. - */ - awaitable() = default; - - /** - * @brief Copy construction is disabled. - */ - awaitable(const awaitable&) = delete; - - /** - * @brief Move from another awaitable. - * - * @param rhs The awaitable to move from, left in an unspecified state after this. - */ - awaitable(awaitable&& rhs) noexcept : state_ptr(std::exchange(rhs.state_ptr, nullptr)) { - } - - /** - * @brief Title :) - * - * We use this in the destructor - */ - void if_this_causes_an_invalid_read_your_promise_was_destroyed_before_your_awaitable____check_your_promise_lifetime() { - abandon(); - } - - /** - * @brief Destructor. - * - * May signal to the promise that it was destroyed. - */ - ~awaitable(); - - /** - * @brief Copy assignment is disabled. - */ - awaitable& operator=(const awaitable&) = delete; - - /** - * @brief Move from another awaitable. - * - * @param rhs The awaitable to move from, left in an unspecified state after this. - * @return *this - */ - awaitable& operator=(awaitable&& rhs) noexcept { - abandon(); - state_ptr = std::exchange(rhs.state_ptr, nullptr); - return *this; - } - - /** - * @brief Check whether this awaitable refers to a valid promise. - * - * @return bool Whether this awaitable refers to a valid promise or not - */ - bool valid() const noexcept; - - /** - * @brief Check whether or not co_await-ing this would suspend the caller, i.e. if we have the result or not - * - * @return bool Whether we already have the result or not - */ - bool await_ready() const; - - /** - * @brief Overload of the co_await operator. - * - * @return Returns an @ref awaiter referencing this awaitable. - */ - template - requires (std::is_base_of_v>) - friend awaiter operator co_await(Derived& obj) noexcept { - return {obj}; - } - - /** - * @brief Overload of the co_await operator. Returns an @ref awaiter referencing this awaitable. - * - * @return Returns an @ref awaiter referencing this awaitable. - */ - template - requires (std::is_base_of_v>) - friend awaiter operator co_await(Derived&& obj) noexcept { - return {std::move(obj)}; - } -}; - -namespace detail::promise { - -/** - * @brief Base class defining logic common to all promise types, aka the "write" end of an awaitable. - */ -template -class promise_base { -protected: - friend class awaitable; - - /** - * @brief Variant representing one of either 3 states of the result value : empty, result, exception. - */ - using storage_type = result_t; - - /** - * @brief State of the result value. - * - * @see storage_type - * - * @note use .index() instead of std::holds_alternative to support promise_base and promise_base :) - */ - storage_type value = std::monostate{}; - - /** - * @brief State of the awaitable tied to this promise. - */ - std::atomic state = sf_none; - - /** - * @brief Coroutine handle currently awaiting the completion of this promise. - */ - std_coroutine::coroutine_handle<> awaiter = nullptr; - - /** - * @brief Check if the result is empty, throws otherwise. - * - * @throw dpp::logic_exception if the result isn't empty. - */ - void throw_if_not_empty() { - if (value.index() != 0) [[unlikely]] { - throw dpp::logic_exception("cannot set a value on a promise that already has one"); - } - } - - /** - * @brief Unlinks this promise from its currently linked awaiter and returns it. - * - * At the time of writing this is only used in the case of a serious internal error in dpp::task. - * Avoid using this as this will crash if the promise is used after this. - */ - std_coroutine::coroutine_handle<> release_awaiter() { - return std::exchange(awaiter, nullptr); - } - - /** - * @brief Construct a new promise, with empty result. - */ - promise_base() = default; - - /** - * @brief Copy construction is disabled. - */ - promise_base(const promise_base&) = delete; - - /** - * @brief Move construction is disabled. - * - * awaitable hold a pointer to this object so moving is not possible. - */ - promise_base(promise_base&& rhs) = delete; - -public: - /** - * @brief Copy assignment is disabled. - */ - promise_base &operator=(const promise_base&) = delete; - - /** - * @brief Move assignment is disabled. - */ - promise_base &operator=(promise_base&& rhs) = delete; - - /** - * @brief Set this promise to an exception and resume any awaiter. - * - * @tparam Notify Whether to resume any awaiter or not. - * @throws dpp::logic_exception if the promise is not empty. - * @throws ? Any exception thrown by the coroutine if resumed will propagate - */ - template - void set_exception(std::exception_ptr ptr) { - throw_if_not_empty(); - value.template emplace<2>(std::move(ptr)); - [[maybe_unused]] auto previous_value = this->state.fetch_or(sf_ready, std::memory_order_acq_rel); - if constexpr (Notify) { - if ((previous_value & sf_awaited) != 0) { - this->awaiter.resume(); - } - } - } - - /** - * @brief Notify a currently awaiting coroutine that the result is ready. - * - * @note This may resume the coroutine on the current thread. - * @throws ? Any exception thrown by the coroutine if resumed will propagate - */ - void notify_awaiter() { - if ((state.load(std::memory_order_acquire) & sf_awaited) != 0) { - awaiter.resume(); - } - } - - /** - * @brief Get an awaitable object for this promise. - * - * @throws dpp::logic_exception if get_awaitable has already been called on this object. - * @return awaitable An object that can be co_await-ed to retrieve the value of this promise. - */ - awaitable get_awaitable() { - uint8_t previous_flags = state.fetch_or(sf_has_awaitable, std::memory_order_relaxed); - if (previous_flags & sf_has_awaitable) [[unlikely]] { - throw dpp::logic_exception{"an awaitable was already created from this promise"}; - } - return { this }; - } -}; - -} - -/** - * @brief Generic promise class, represents the owning potion of an asynchronous value. - * - * This class is roughly equivalent to std::promise, with the crucial distinction that the promise *IS* the shared state. - * As such, the promise needs to be kept alive for the entire time a value can be retrieved. - * - * @tparam T Type of the asynchronous value - * @see awaitable - */ -template -class basic_promise : public detail::promise::promise_base { -public: - using detail::promise::promise_base::promise_base; - using detail::promise::promise_base::operator=; - - /** - * @brief Construct the result in place by forwarding the arguments, and by default resume any awaiter. - * - * @tparam Notify Whether to resume any awaiter or not. - * @throws dpp::logic_exception if the promise is not empty. - */ - template - requires (std::constructible_from) - void emplace_value(Args&&... args) { - this->throw_if_not_empty(); - try { - this->value.template emplace<1>(std::forward(args)...); - } catch (...) { - this->value.template emplace<2>(std::current_exception()); - } - [[maybe_unused]] auto previous_value = this->state.fetch_or(detail::promise::sf_ready, std::memory_order_acq_rel); - if constexpr (Notify) { - if (previous_value & detail::promise::sf_awaited) { - this->awaiter.resume(); - } - } - } - - /** - * @brief Construct the result by forwarding reference, and resume any awaiter. - * - * @tparam Notify Whether to resume any awaiter or not. - * @throws dpp::logic_exception if the promise is not empty. - */ - template - requires (std::convertible_to) - void set_value(U&& v) { - emplace_value(std::forward(v)); - } - - /** - * @brief Construct a void result, and resume any awaiter. - * - * @tparam Notify Whether to resume any awaiter or not. - * @throws dpp::logic_exception if the promise is not empty. - */ - template - requires (std::is_void_v) - void set_value() { - this->throw_if_not_empty(); - this->value.template emplace<1>(); - [[maybe_unused]] auto previous_value = this->state.fetch_or(detail::promise::sf_ready, std::memory_order_acq_rel); - if constexpr (Notify) { - if (previous_value & detail::promise::sf_awaited) { - this->awaiter.resume(); - } - } - } -}; - -/** - * @brief Generic promise class, represents the owning potion of an asynchronous value. - * - * This class is roughly equivalent to std::promise, with the crucial distinction that the promise *IS* the shared state. - * As such, the promise needs to be kept alive for the entire time a value can be retrieved. - * - * The difference between basic_promise and this object is that this one is moveable as it wraps an underlying basic_promise in a std::unique_ptr. - * - * @see awaitable - */ -template -class moveable_promise { - /** - * @brief Shared state, wrapped in a unique_ptr to allow move without disturbing an awaitable's promise pointer. - */ - std::unique_ptr> shared_state = std::make_unique>(); - -public: - /** - * @copydoc basic_promise::emplace_value - */ - template - requires (std::constructible_from) - void emplace_value(Args&&... args) { - shared_state->template emplace_value(std::forward(args)...); - } - - /** - * @copydoc basic_promise::set_value(U&&) - */ - template - void set_value(U&& v) requires (std::convertible_to) { - shared_state->template set_value(std::forward(v)); - } - - /** - * @copydoc basic_promise::set_value() - */ - template - void set_value() requires (std::is_void_v) { - shared_state->template set_value(); - } - - /** - * @copydoc basic_promise::set_value(T&&) - */ - template - void set_exception(std::exception_ptr ptr) { - shared_state->template set_exception(std::move(ptr)); - } - - /** - * @copydoc basic_promise::notify_awaiter - */ - void notify_awaiter() { - shared_state->notify_awaiter(); - } - - /** - * @copydoc basic_promise::get_awaitable - */ - awaitable get_awaitable() { - return shared_state->get_awaitable(); - } -}; - -template -using promise = moveable_promise; - -template -auto awaitable::abandon() -> uint8_t { - uint8_t previous_state = state_flags::sf_broken; - if (state_ptr) { - previous_state = state_ptr->state.fetch_or(state_flags::sf_broken, std::memory_order_acq_rel); - state_ptr = nullptr; - } - return previous_state; -} - -template -awaitable::~awaitable() { - if_this_causes_an_invalid_read_your_promise_was_destroyed_before_your_awaitable____check_your_promise_lifetime(); -} - -template -bool awaitable::valid() const noexcept { - return state_ptr != nullptr; -} - -template -bool awaitable::await_ready() const { - if (!this->valid()) { - throw dpp::logic_exception("cannot co_await an empty awaitable"); - } - uint8_t state = this->state_ptr->state.load(std::memory_order_relaxed); - return state & detail::promise::sf_ready; -} - -template -template -bool awaitable::awaiter::await_suspend(detail::std_coroutine::coroutine_handle<> handle) { - auto &promise = *awaitable_obj.state_ptr; - - promise.awaiter = handle; - auto previous_flags = promise.state.fetch_or(detail::promise::sf_awaited, std::memory_order_relaxed); - if (previous_flags & detail::promise::sf_awaited) { - throw dpp::logic_exception("awaitable is already being awaited"); - } - return !(previous_flags & detail::promise::sf_ready); -} - -template -template -T awaitable::awaiter::await_resume() { - auto &promise = *awaitable_obj.state_ptr; - - promise.state.fetch_and(static_cast(~detail::promise::sf_awaited), std::memory_order_acq_rel); - if (std::holds_alternative(promise.value)) { - std::rethrow_exception(std::get<2>(promise.value)); - } - if constexpr (!std::is_void_v) { - return std::get<1>(std::move(promise.value)); - } else { - return; - } -} - - - -template -template -bool awaitable::awaiter::await_ready() const { - return static_cast(awaitable_obj).await_ready(); -} - -} - -#include - -namespace dpp { - -namespace detail::promise { - -template -void spawn_sync_wait_job(auto* awaitable, std::condition_variable &cv, auto&& result) { - [](auto* awaitable_, std::condition_variable &cv_, auto&& result_) -> dpp::job { - try { - if constexpr (std::is_void_v) { - co_await *awaitable_; - result_.template emplace<1>(); - } else { - result_.template emplace<1>(co_await *awaitable_); - } - } catch (...) { - result_.template emplace<2>(std::current_exception()); - } - cv_.notify_all(); - }(awaitable, cv, std::forward(result)); -} - -} - -} - -#endif /* DPP_NO_CORO */ diff --git a/include/dpp/coro/coro.h b/include/dpp/coro/coro.h deleted file mode 100644 index 13aa5ef..0000000 --- a/include/dpp/coro/coro.h +++ /dev/null @@ -1,205 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once - -#include - -#ifndef DPP_NO_CORO - -#if (defined(_LIBCPP_VERSION) and !defined(__cpp_impl_coroutine)) // if libc++ experimental implementation (LLVM < 14) -# define STDCORO_EXPERIMENTAL_HEADER -# define STDCORO_EXPERIMENTAL_NAMESPACE -#endif - -#ifdef STDCORO_GLIBCXX_COMPAT -# define __cpp_impl_coroutine 1 -namespace std { - namespace experimental { - using namespace std; - } -} -#endif - -#ifdef STDCORO_EXPERIMENTAL_HEADER -# include -#else -# include -#endif - -namespace dpp { - -/** - * @brief Implementation details for internal use only. - * - * @attention This is only meant to be used by D++ internally. Support will not be given regarding the facilities in this namespace. - */ -namespace detail { -#ifdef _DOXYGEN_ -/** - * @brief Alias for either std or std::experimental depending on compiler and library. Used by coroutine implementation. - * - * @todo Remove and use std when all supported libraries have coroutines in it - */ -namespace std_coroutine {} -#else -# ifdef STDCORO_EXPERIMENTAL_NAMESPACE -namespace std_coroutine = std::experimental; -# else -namespace std_coroutine = std; -# endif -#endif - -#ifndef _DOXYGEN_ -/** - * @brief Concept to check if a type has a useable `operator co_await()` member - */ -template -concept has_co_await_member = requires (T expr) { expr.operator co_await(); }; - -/** - * @brief Concept to check if a type has a useable overload of the free function `operator co_await(expr)` - */ -template -concept has_free_co_await = requires (T expr) { operator co_await(expr); }; - -/** - * @brief Concept to check if a type has useable `await_ready()`, `await_suspend()` and `await_resume()` member functions. - */ -template -concept has_await_members = requires (T expr) { expr.await_ready(); expr.await_suspend(); expr.await_resume(); }; - -/** - * @brief Mimics the compiler's behavior of using co_await. That is, it returns whichever works first, in order : `expr.operator co_await();` > `operator co_await(expr)` > `expr` - */ -template -requires (has_co_await_member) -decltype(auto) co_await_resolve(T&& expr) noexcept(noexcept(expr.operator co_await())) { - decltype(auto) awaiter = expr.operator co_await(); - return awaiter; -} - -/** - * @brief Mimics the compiler's behavior of using co_await. That is, it returns whichever works first, in order : `expr.operator co_await();` > `operator co_await(expr)` > `expr` - */ -template -requires (!has_co_await_member && has_free_co_await) -decltype(auto) co_await_resolve(T&& expr) noexcept(noexcept(operator co_await(expr))) { - decltype(auto) awaiter = operator co_await(static_cast(expr)); - return awaiter; -} - -/** - * @brief Mimics the compiler's behavior of using co_await. That is, it returns whichever works first, in order : `expr.operator co_await();` > `operator co_await(expr)` > `expr` - */ -template -requires (!has_co_await_member && !has_free_co_await) -decltype(auto) co_await_resolve(T&& expr) noexcept { - return static_cast(expr); -} - -#else - -/** - * @brief Concept to check if a type has a useable `operator co_await()` member - * - * @note This is actually a C++20 concept but Doxygen doesn't do well with them - */ -template -inline constexpr bool has_co_await_member; - -/** - * @brief Concept to check if a type has a useable overload of the free function `operator co_await(expr)` - * - * @note This is actually a C++20 concept but Doxygen doesn't do well with them - */ -template -inline constexpr bool has_free_co_await; - -/** - * @brief Concept to check if a type has useable `await_ready()`, `await_suspend()` and `await_resume()` member functions. - * - * @note This is actually a C++20 concept but Doxygen doesn't do well with them - */ -template -inline constexpr bool has_await_members; - -/** - * @brief Concept to check if a type can be used with co_await - * - * @note This is actually a C++20 concept but Doxygen doesn't do well with them - */ -template -inline constexpr bool awaitable_type; - -/** - * @brief Mimics the compiler's behavior of using co_await. That is, it returns whichever works first, in order : `expr.operator co_await();` > `operator co_await(expr)` > `expr` - * - * This function is conditionally noexcept, if the returned expression also is. - */ -decltype(auto) co_await_resolve(auto&& expr) {} - -#endif - -/** - * @brief Convenience alias for the result of a certain awaitable's await_resume. - */ -template -using awaitable_result = decltype(co_await_resolve(std::declval()).await_resume()); - -} // namespace detail - -/** - * @brief Concept to check if a type can be used with co_await - */ -template -concept awaitable_type = requires (T expr) { detail::co_await_resolve(expr).await_ready(); }; - -struct confirmation_callback_t; - -template -class async; - -template -#ifndef _DOXYGEN_ -requires (!std::is_reference_v) -#endif -class task; - -template -class coroutine; - -struct job; - -#ifdef DPP_CORO_TEST -/** - * @brief Allocation count of a certain type, for testing purposes. - * - * @todo Remove when coro is stable - */ -template -inline int coro_alloc_count = 0; -#endif - -} // namespace dpp - -#endif /* DPP_NO_CORO */ - diff --git a/include/dpp/coro/coroutine.h b/include/dpp/coro/coroutine.h deleted file mode 100644 index a2f541c..0000000 --- a/include/dpp/coro/coroutine.h +++ /dev/null @@ -1,406 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include - -namespace dpp { - -struct coroutine_dummy { - int *handle_dummy = nullptr; -}; - -} - -#ifndef DPP_NO_CORO - -#include -#include - -#include -#include -#include -#include -#include - -namespace dpp { - -namespace detail { - -namespace coroutine { - -template -struct promise_t; - -template -/** - * @brief Alias for the handle_t of a coroutine. - */ -using handle_t = std_coroutine::coroutine_handle>; - -} // namespace coroutine - -} // namespace detail - -/** - * @class coroutine coroutine.h coro/coroutine.h - * @brief Base type for a coroutine, starts on co_await. - * - * @warning - This feature is EXPERIMENTAL. The API may change at any time and there may be bugs. - * Please report any to GitHub Issues or to our Discord Server. - * @warning - Using co_await on this object more than once is undefined behavior. - * @tparam R Return type of the coroutine. Can be void, or a complete object that supports move construction and move assignment. - */ -template -class [[nodiscard("dpp::coroutine only starts when it is awaited, it will do nothing if discarded")]] coroutine : public basic_awaitable> { - /** - * @brief Promise has friend access for the constructor - */ - friend struct detail::coroutine::promise_t; - - /** - * @brief Coroutine handle. - */ - detail::coroutine::handle_t handle{nullptr}; - - /** - * @brief Construct from a handle. Internal use only. - */ - coroutine(detail::coroutine::handle_t h) : handle{h} {} - - struct awaiter { - /** - * @brief Reference to the coroutine object being awaited. - */ - coroutine &coro; - - /** - * @brief First function called by the standard library when the coroutine is co_await-ed. - * - * @remark Do not call this manually, use the co_await keyword instead. - * @throws invalid_operation_exception if the coroutine is empty or finished. - * @return bool Whether the coroutine is done - */ - [[nodiscard]] bool await_ready() const { - if (!coro.handle) { - throw dpp::logic_exception("cannot co_await an empty coroutine"); - } - return coro.handle.done(); - } - - /** - * @brief Second function called by the standard library when the coroutine is co_await-ed. - * - * Stores the calling coroutine in the promise to resume when this coroutine suspends. - * - * @remark Do not call this manually, use the co_await keyword instead. - * @param caller The calling coroutine, now suspended - */ - template - [[nodiscard]] detail::coroutine::handle_t await_suspend(detail::std_coroutine::coroutine_handle caller) noexcept { - coro.handle.promise().parent = caller; - return coro.handle; - } - - /** - * @brief Final function called by the standard library when the coroutine is co_await-ed. - * - * Pops the coroutine's result and returns it. - * @remark Do not call this manually, use the co_await keyword instead. - */ - R await_resume() { - detail::coroutine::promise_t &promise = coro.handle.promise(); - if (promise.exception) { - std::rethrow_exception(promise.exception); - } - if constexpr (!std::is_void_v) { - return *std::exchange(promise.result, std::nullopt); - } else { - return; // unnecessary but makes lsp happy - } - } - }; - -public: - /** - * @brief The type of the result produced by this coroutine. - */ - using result_type = R; - - /** - * @brief Default constructor, creates an empty coroutine. - */ - coroutine() = default; - - /** - * @brief Copy constructor is disabled - */ - coroutine(const coroutine &) = delete; - - /** - * @brief Move constructor, grabs another coroutine's handle - * - * @param other Coroutine to move the handle from - */ - coroutine(coroutine &&other) noexcept : handle(std::exchange(other.handle, nullptr)) {} - - /** - * @brief Destructor, destroys the handle. - */ - ~coroutine() { - if (handle) { - handle.destroy(); - } - } - - /** - * @brief Copy assignment is disabled - */ - coroutine &operator=(const coroutine &) = delete; - - /** - * @brief Move assignment, grabs another coroutine's handle - * - * @param other Coroutine to move the handle from - */ - coroutine &operator=(coroutine &&other) noexcept { - handle = std::exchange(other.handle, nullptr); - return *this; - } - - [[nodiscard]] auto operator co_await() { - return awaiter{*this}; - } -}; - -namespace detail::coroutine { - template - struct final_awaiter; - -#ifdef DPP_CORO_TEST - struct promise_t_base{}; -#endif - - /** - * @brief Promise type for coroutine. - */ - template - struct promise_t { - /** - * @brief Handle of the coroutine co_await-ing this coroutine. - */ - std_coroutine::coroutine_handle<> parent{nullptr}; - - /** - * @brief Return value of the coroutine - */ - std::optional result{}; - - /** - * @brief Pointer to an uncaught exception thrown by the coroutine - */ - std::exception_ptr exception{nullptr}; - -#ifdef DPP_CORO_TEST - promise_t() { - ++coro_alloc_count; - } - - ~promise_t() { - --coro_alloc_count; - } -#endif - - /** - * @brief Function called by the standard library when reaching the end of a coroutine - * - * @return final_awaiter Resumes any coroutine co_await-ing on this - */ - [[nodiscard]] final_awaiter final_suspend() const noexcept; - - /** - * @brief Function called by the standard library when the coroutine start - * - * @return @return std::suspend_always Always suspend at the start, for a lazy start - */ - [[nodiscard]] std_coroutine::suspend_always initial_suspend() const noexcept { - return {}; - } - - /** - * @brief Function called when an exception escapes the coroutine - * - * Stores the exception to throw to the co_await-er - */ - void unhandled_exception() noexcept { - exception = std::current_exception(); - } - - /** - * @brief Function called by the standard library when the coroutine co_returns a value. - * - * Stores the value internally to hand to the caller when it resumes. - * - * @param expr The value given to co_return - */ - void return_value(R&& expr) noexcept(std::is_nothrow_move_constructible_v) requires std::move_constructible { - result = static_cast(expr); - } - - /** - * @brief Function called by the standard library when the coroutine co_returns a value. - * - * Stores the value internally to hand to the caller when it resumes. - * - * @param expr The value given to co_return - */ - void return_value(const R &expr) noexcept(std::is_nothrow_copy_constructible_v) requires std::copy_constructible { - result = expr; - } - - /** - * @brief Function called by the standard library when the coroutine co_returns a value. - * - * Stores the value internally to hand to the caller when it resumes. - * - * @param expr The value given to co_return - */ - template - requires (!std::is_same_v> && std::convertible_to) - void return_value(T&& expr) noexcept (std::is_nothrow_convertible_v) { - result = std::forward(expr); - } - - /** - * @brief Function called to get the coroutine object - */ - dpp::coroutine get_return_object() { - return dpp::coroutine{handle_t::from_promise(*this)}; - } - }; - - /** - * @brief Struct returned by a coroutine's final_suspend, resumes the continuation - */ - template - struct final_awaiter { - /** - * @brief First function called by the standard library when reaching the end of a coroutine - * - * @return false Always return false, we need to suspend to resume the parent - */ - [[nodiscard]] bool await_ready() const noexcept { - return false; - } - - /** - * @brief Second function called by the standard library when reaching the end of a coroutine. - * - * @return std::handle_t<> Coroutine handle to resume, this is either the parent if present or std::noop_coroutine() - */ - [[nodiscard]] std_coroutine::coroutine_handle<> await_suspend(std_coroutine::coroutine_handle> handle) const noexcept { - auto parent = handle.promise().parent; - - return parent ? parent : std_coroutine::noop_coroutine(); - } - - /** - * @brief Function called by the standard library when this object is resumed - */ - void await_resume() const noexcept {} - }; - - template - final_awaiter promise_t::final_suspend() const noexcept { - return {}; - } - - /** - * @brief Struct returned by a coroutine's final_suspend, resumes the continuation - */ - template <> - struct promise_t { - /** - * @brief Handle of the coroutine co_await-ing this coroutine. - */ - std_coroutine::coroutine_handle<> parent{nullptr}; - - /** - * @brief Pointer to an uncaught exception thrown by the coroutine - */ - std::exception_ptr exception{nullptr}; - - /** - * @brief Function called by the standard library when reaching the end of a coroutine - * - * @return final_awaiter Resumes any coroutine co_await-ing on this - */ - [[nodiscard]] final_awaiter final_suspend() const noexcept { - return {}; - } - - /** - * @brief Function called by the standard library when the coroutine start - * - * @return @return std::suspend_always Always suspend at the start, for a lazy start - */ - [[nodiscard]] std_coroutine::suspend_always initial_suspend() const noexcept { - return {}; - } - - /** - * @brief Function called when an exception escapes the coroutine - * - * Stores the exception to throw to the co_await-er - */ - void unhandled_exception() noexcept { - exception = std::current_exception(); - } - - /** - * @brief Function called when co_return is used - */ - void return_void() const noexcept {} - - /** - * @brief Function called to get the coroutine object - */ - [[nodiscard]] dpp::coroutine get_return_object() { - return dpp::coroutine{handle_t::from_promise(*this)}; - } - }; - -} // namespace detail - -DPP_CHECK_ABI_COMPAT(coroutine, coroutine_dummy) -DPP_CHECK_ABI_COMPAT(coroutine, coroutine_dummy) - -} - -/** - * @brief Specialization of std::coroutine_traits, helps the standard library figure out a promise type from a coroutine function. - */ -template -struct dpp::detail::std_coroutine::coroutine_traits, Args...> { - using promise_type = dpp::detail::coroutine::promise_t; -}; - -#endif /* DPP_NO_CORO */ diff --git a/include/dpp/coro/job.h b/include/dpp/coro/job.h deleted file mode 100644 index 4b3ef50..0000000 --- a/include/dpp/coro/job.h +++ /dev/null @@ -1,145 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include - -namespace dpp { - -struct job_dummy { -}; - -} - -#ifndef DPP_NO_CORO - -#include "coro.h" - -#include -#include - -namespace dpp { - -/** - * @class job job.h coro/job.h - * @brief Extremely light coroutine object designed to send off a coroutine to execute on its own. - * Can be used in conjunction with coroutine events via @ref dpp::event_router_t::operator()(F&&) "event routers", or on its own. - * - * This object stores no state and is the recommended way to use coroutines if you do not need to co_await the result. - * - * @warning - This feature is EXPERIMENTAL. The API may change at any time and there may be bugs. - * Please report any to GitHub Issues or to our Discord Server. - * @warning - It cannot be co_awaited, which means the second it co_awaits something, the program jumps back to the calling function, which continues executing. - * At this point, if the function returns, every object declared in the function including its parameters are destroyed, which causes @ref lambdas-and-locals "dangling references". - * For this reason, `co_await` will error if any parameters are passed by reference. - * If you must pass a reference, pass it as a pointer or with std::ref, but you must fully understand the reason behind this warning, and what to avoid. - * If you prefer a safer type, use `coroutine` for synchronous execution, or `task` for parallel tasks, and co_await them. - */ -struct job {}; - -namespace detail { - -namespace job { - -#ifdef DPP_CORO_TEST - struct promise{}; -#endif - -/** - * @brief Coroutine promise type for a job - */ -template -struct promise { - -#ifdef DPP_CORO_TEST - promise() { - ++coro_alloc_count; - } - - ~promise() { - --coro_alloc_count; - } -#endif - - /** - * @brief Function called when the job is done. - * - * @return std::suspend_never Do not suspend at the end, destroying the handle immediately - */ - std_coroutine::suspend_never final_suspend() const noexcept { - return {}; - } - - /** - * @brief Function called when the job is started. - * - * @return std::suspend_never Do not suspend at the start, starting the job immediately - */ - std_coroutine::suspend_never initial_suspend() const noexcept { - return {}; - } - - /** - * @brief Function called to get the job object - * - * @return job - */ - dpp::job get_return_object() const noexcept { - return {}; - } - - /** - * @brief Function called when an exception is thrown and not caught. - * - * @throw Immediately rethrows the exception to the caller / resumer - */ - void unhandled_exception() const { - throw; - } - - /** - * @brief Function called when the job returns. Does nothing. - */ - void return_void() const noexcept {} -}; - -} // namespace job - -} // namespace detail - -DPP_CHECK_ABI_COMPAT(job, job_dummy) -} // namespace dpp - -/** - * @brief Specialization of std::coroutine_traits, helps the standard library figure out a promise type from a coroutine function. - */ -template -struct dpp::detail::std_coroutine::coroutine_traits { - /** - * @brief Promise type for this coroutine signature. - * - * When the coroutine is created from a lambda, that lambda is passed as a first parameter. - * Not ideal but we'll allow any callable that takes the rest of the arguments passed - */ - using promise_type = dpp::detail::job::promise; -}; - -#endif /* DPP_NO_CORO */ diff --git a/include/dpp/coro/task.h b/include/dpp/coro/task.h deleted file mode 100644 index 2bc8a6c..0000000 --- a/include/dpp/coro/task.h +++ /dev/null @@ -1,446 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include -#include - -namespace dpp { - -struct task_dummy : awaitable_dummy { - int* handle_dummy = nullptr; -}; - -} - -#ifndef DPP_NO_CORO - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include // std::cerr in final_suspend - -namespace dpp { - -namespace detail { - -/* Internal cogwheels for dpp::task */ -namespace task { - -/** - * @brief A @ref dpp::task "task"'s promise_t type, with special logic for handling nested tasks. - * - * @tparam R Return type of the task - */ -template -struct promise_t; - -/** - * @brief The object automatically co_await-ed at the end of a @ref dpp::task "task". Ensures nested coroutine chains are resolved, and the promise_t cleans up if it needs to. - * - * @tparam R Return type of the task - */ -template -struct final_awaiter; - -/** - * @brief Alias for for a @ref dpp::task "task"'s @ref promise_t. - * - * @tparam R Return type of the task - */ -template -using handle_t = std_coroutine::coroutine_handle>; - -} // namespace task - -} // namespace detail - -/** - * @class task task.h coro/task.h - * @brief A coroutine task. It starts immediately on construction and can be co_await-ed, making it perfect for parallel coroutines returning a value. - * - * @warning - This feature is EXPERIMENTAL. The API may change at any time and there may be bugs. - * Please report any to GitHub Issues or to our Discord Server. - * @tparam R Return type of the task. Cannot be a reference but can be void. - */ -template -#ifndef _DOXYGEN_ -requires (!std::is_reference_v) -#endif -class [[nodiscard("dpp::task cancels itself on destruction. use co_await on it, or its sync_wait method")]] task : public awaitable { - friend struct detail::task::promise_t; - - using handle_t = detail::task::handle_t; - using state_flags = detail::promise::state_flags; - - handle_t handle{}; - -protected: - /** - * @brief Construct from a coroutine handle. Internal use only - */ - explicit task(handle_t handle_) : awaitable(&handle_.promise()), handle(handle_) {} - - /** - * @brief Clean up our handle, cancelling any running task - */ - void cleanup() { - if (handle && this->valid()) { - if (this->abandon() & state_flags::sf_done) { - handle.destroy(); - } else { - cancel(); - } - handle = nullptr; - } - } - -public: - /** - * @brief Default constructor, creates a task not bound to a coroutine. - */ - task() = default; - - /** - * @brief Copy constructor is disabled - */ - task(const task &) = delete; - - /** - * @brief Move constructor, grabs another task's coroutine handle - * - * @param other Task to move the handle from - */ - task(task &&other) noexcept : awaitable(std::move(other)), handle(std::exchange(other.handle, nullptr)) {} - - /** - * @brief Copy assignment is disabled - */ - task &operator=(const task &) = delete; - - /** - * @brief Move assignment, grabs another task's coroutine handle - * - * @param other Task to move the handle from - */ - task &operator=(task &&other) noexcept { - cleanup(); - handle = std::exchange(other.handle, nullptr); - awaitable::operator=(std::move(other)); - return *this; - } - - /** - * @brief Destructor. - * - * Destroys the handle. If the task is still running, it will be cancelled. - */ - ~task() { - cleanup(); - } - - /** - * @brief Function to check if the task has finished its execution entirely - * - * @return bool Whether the task is finished. - */ - [[nodiscard]] bool done() const noexcept { - return handle && (!this->valid() || handle.promise().state.load(std::memory_order_acq_rel) == state_flags::sf_done); - } - - /** - * @brief Cancel the task, it will stop the next time it uses co_await. On co_await-ing this task, throws dpp::task_cancelled_exception. - * - * @return *this - */ - task& cancel() & noexcept { - handle.promise().cancelled.exchange(true, std::memory_order_relaxed); - return *this; - } - - /** - * @brief Cancel the task, it will stop the next time it uses co_await. On co_await-ing this task, throws dpp::task_cancelled_exception. - * - * @return *this - */ - task&& cancel() && noexcept { - handle.promise().cancelled.exchange(true, std::memory_order_relaxed); - return *this; - } -}; - -namespace detail::task { -/** - * @brief Awaitable returned from task::promise_t's final_suspend. Resumes the parent and cleans up its handle if needed - */ -template -struct final_awaiter { - /** - * @brief Always suspend at the end of the task. This allows us to clean up and resume the parent - */ - [[nodiscard]] bool await_ready() const noexcept { - return (false); - } - - /** - * @brief The suspension logic of the coroutine when it finishes. Always suspend the caller, meaning cleaning up the handle is on us - * - * @param handle The handle of this coroutine - * @return std::coroutine_handle<> Handle to resume, which is either the parent if present or std::noop_coroutine() otherwise - */ - [[nodiscard]] std_coroutine::coroutine_handle<> await_suspend(handle_t handle) const noexcept; - - /** - * @brief Function called when this object is co_awaited by the standard library at the end of final_suspend. Do nothing, return nothing - */ - void await_resume() const noexcept {} -}; - -/** - * @brief Base implementation of task::promise_t, without the logic that would depend on the return type. Meant to be inherited from - */ -template -struct promise_base : basic_promise { - /** - * @brief Whether the task is cancelled or not. - */ - std::atomic cancelled = false; - -#ifdef DPP_CORO_TEST - promise_base() { - ++coro_alloc_count; - } - - ~promise_base() { - --coro_alloc_count; - } -#endif - - /** - * @brief Function called by the standard library when the coroutine is created. - * - * @return std::suspend_never Don't suspend, the coroutine starts immediately. - */ - std_coroutine::suspend_never initial_suspend() const noexcept { - return {}; - } - - /** - * @brief Function called by the standard library when an exception is thrown and not caught in the coroutine. - * - * Stores the exception pointer to rethrow on co_await. If the task object is destroyed and was not cancelled, throw instead - */ - void unhandled_exception() { - if ((this->state.load() & promise::state_flags::sf_broken) && !cancelled) { - throw; - } - this->template set_exception(std::current_exception()); - } - - /** - * @brief Proxy awaitable that wraps any co_await inside the task and checks for cancellation on resumption - * - * @see await_transform - */ - template - struct proxy_awaiter { - /** @brief The promise_t object bound to this proxy */ - const promise_base &promise; - - /** @brief The inner awaitable being awaited */ - A awaitable; - - /** @brief Wrapper for the awaitable's await_ready */ - [[nodiscard]] bool await_ready() noexcept(noexcept(awaitable.await_ready())) { - return awaitable.await_ready(); - } - - /** @brief Wrapper for the awaitable's await_suspend */ - template - [[nodiscard]] decltype(auto) await_suspend(T&& handle) noexcept(noexcept(awaitable.await_suspend(std::forward(handle)))) { - return awaitable.await_suspend(std::forward(handle)); - } - - /** - * @brief Wrapper for the awaitable's await_resume, throws if the task is cancelled - * - * @throw dpp::task_cancelled_exception If the task was cancelled - */ - decltype(auto) await_resume() { - if (promise.cancelled.load()) { - throw dpp::task_cancelled_exception{"task was cancelled"}; - } - return awaitable.await_resume(); - } - }; - - /** - * @brief Function called whenever co_await is used inside of the task - * - * @throw dpp::task_cancelled_exception On resumption if the task was cancelled - * - * @return @ref proxy_awaiter Returns a proxy awaiter that will check for cancellation on resumption - */ - template - [[nodiscard]] auto await_transform(T&& expr) const noexcept(noexcept(co_await_resolve(std::forward(expr)))) { - using awaitable_t = decltype(co_await_resolve(std::forward(expr))); - return proxy_awaiter{*this, co_await_resolve(std::forward(expr))}; - } -}; - -/** - * @brief Implementation of task::promise_t for non-void return type - */ -template -struct promise_t : promise_base { - friend struct final_awaiter; - - /** - * @brief Function called by the standard library when the coroutine co_returns a value. - * - * Stores the value internally to hand to the caller when it resumes. - * - * @param expr The value given to co_return - */ - void return_value(R&& expr) noexcept(std::is_nothrow_move_constructible_v) requires std::move_constructible { - this->template set_value(std::move(expr)); - } - - /** - * @brief Function called by the standard library when the coroutine co_returns a value. - * - * Stores the value internally to hand to the caller when it resumes. - * - * @param expr The value given to co_return - */ - void return_value(const R &expr) noexcept(std::is_nothrow_copy_constructible_v) requires std::copy_constructible { - this->template set_value(expr); - } - - /** - * @brief Function called by the standard library when the coroutine co_returns a value. - * - * Stores the value internally to hand to the caller when it resumes. - * - * @param expr The value given to co_return - */ - template - requires (!std::is_same_v> && std::convertible_to) - void return_value(T&& expr) noexcept (std::is_nothrow_convertible_v) { - this->template emplace_value(std::forward(expr)); - } - - /** - * @brief Function called by the standard library when the coroutine is created. - * - * @return dpp::task The coroutine object - */ - [[nodiscard]] dpp::task get_return_object() noexcept { - return dpp::task{handle_t::from_promise(*this)}; - } - - /** - * @brief Function called by the standard library when the coroutine reaches its last suspension point - * - * @return final_awaiter Special object containing the chain resolution and clean-up logic. - */ - [[nodiscard]] final_awaiter final_suspend() const noexcept { - return {}; - } -}; - -/** - * @brief Implementation of task::promise_t for void return type - */ -template <> -struct promise_t : promise_base { - friend struct final_awaiter; - - /** - * @brief Function called by the standard library when the coroutine co_returns - * - * Sets the promise state to finished. - */ - void return_void() noexcept { - set_value(); - } - - /** - * @brief Function called by the standard library when the coroutine is created. - * - * @return task The coroutine object - */ - [[nodiscard]] dpp::task get_return_object() noexcept { - return dpp::task{handle_t::from_promise(*this)}; - } - - /** - * @brief Function called by the standard library when the coroutine reaches its last suspension point - * - * @return final_awaiter Special object containing the chain resolution and clean-up logic. - */ - [[nodiscard]] final_awaiter final_suspend() const noexcept { - return {}; - } -}; - -template -std_coroutine::coroutine_handle<> final_awaiter::await_suspend(handle_t handle) const noexcept { - using state_flags = promise::state_flags; - promise_t &promise = handle.promise(); - uint8_t previous_state = promise.state.fetch_or(state_flags::sf_done); - - if ((previous_state & state_flags::sf_awaited) != 0) { // co_await-ed, resume parent - if ((previous_state & state_flags::sf_broken) != 0) { // major bug, these should never be set together - // we don't have a cluster so just log it on cerr - std::cerr << "dpp: task promise ended in both an awaited and dangling state. this is a bug and a memory leak, please report it to us!" << std::endl; - } - return promise.release_awaiter(); - } - if ((previous_state & state_flags::sf_broken) != 0) { // task object is gone, free the handle - handle.destroy(); - } - return std_coroutine::noop_coroutine(); -} - -} // namespace detail::task - -DPP_CHECK_ABI_COMPAT(task, task_dummy) -DPP_CHECK_ABI_COMPAT(task, task_dummy) - -} - -/** - * @brief Specialization of std::coroutine_traits, helps the standard library figure out a promise_t type from a coroutine function. - */ -template -struct dpp::detail::std_coroutine::coroutine_traits, Args...> { - using promise_type = dpp::detail::task::promise_t; -}; - -#endif /* DPP_NO_CORO */ diff --git a/include/dpp/coro/when_any.h b/include/dpp/coro/when_any.h deleted file mode 100644 index f3b04e2..0000000 --- a/include/dpp/coro/when_any.h +++ /dev/null @@ -1,536 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#ifndef DPP_NO_CORO -#pragma once - -#include "coro.h" -#include "job.h" - -#include -#include -#include -#include -#include - -namespace dpp { - -template -class event_router_t; - -namespace detail { - -namespace event_router { - -template -class awaitable; - -} - -/** - * @brief Internal cogwheels for dpp::when_any - */ -namespace when_any { - -/** - * @brief Current state of a when_any object - */ -enum await_state : uint8_t { - /** - * @brief Object is being awaited - */ - waiting = 1 << 0, - /** - * @brief Object was resumed - */ - done = 1 << 1, - /** - * @brief Result is ready to retrieve - */ - ready = 1 << 2, - /** - * @brief Object was destroyed - */ - dangling = 1 << 3 -}; - -/** - * @brief Type trait helper to obtain the actual type that will be used by a when_any when a type is passed as a parameter. - * May specialize for certain types for specific behavior, e.g. for an event_router, store the awaitable directly - */ -template -struct arg_helper_s { - /** Raw type of the awaitable */ - using type = T; - - /** Helper static method to get the awaitable from a variable */ - static decltype(auto) get(auto&& v) { - return static_cast(v); - } -}; - -template -struct arg_helper_s> { - using type = event_router::awaitable; - - template -#ifndef _DOXYGEN - requires (std::same_as, dpp::event_router_t>) -#endif - static event_router::awaitable get(U&& v) { - return static_cast(v).operator co_await(); - } -}; - -/** - * @brief Alias for the actual type that an awaitable will be stored as in a when_any. - * For example if given an event_router, store the awaitable, not the event_router. - */ -template -using awaitable_type = typename arg_helper_s::type; - -/** - * @brief Helper struct with a method to convert an awaitable parameter to the actual value it will be stored as. - * For example if given an event_router, store the awaitable, not the event_router. - */ -template -using arg_helper = arg_helper_s>; - -/** - * @brief Empty result from void-returning awaitable - */ -struct empty{}; - -/** - * @brief Actual type a result will be stores as in when_any - */ -template -using storage_type = std::conditional_t, empty, T>; - -/** - * @brief Concept satisfied if a stored result is void - */ -template -concept void_result = std::same_as; - -} - -} // namespace detail - -/** - * @class when_any when_any.h coro/when_any.h - * @brief Experimental class to co_await on a bunch of awaitable objects, resuming when the first one completes. - * On completion, returns a @ref result object that contains the index of the awaitable that finished first. - * A user can call @ref result::index() and @ref result::get() on the result object to get the result, similar to std::variant. - * - * @see when_any::result - * @tparam Args... Type of each awaitable to await on - */ -template -#ifndef _DOXYGEN_ -requires (sizeof...(Args) >= 1) -#endif -class when_any { - /** - * @brief Alias for the type of the result variant - */ - using variant_type = std::variant>>...>; - - /** - * @brief Alias for the result type of the Nth arg. - * - * @tparam N index of the argument to fetch - */ - template - using result_t = std::variant_alternative_t; - - /** - * @brief State shared between all the jobs to spawn - */ - struct state_t { - /** - * @brief Constructor for the internal state. Its arguments are used to construct each awaitable - */ - template - state_t(Args_&&... args) : awaitables{std::forward(args)...} {} - - /** - * @brief Awaitable objects to handle. - */ - std::tuple awaitables; - - /** - * @brief Result or exception, as a variant. This will contain the result of the first awaitable to finish - */ - variant_type result{}; - - /** - * @brief Coroutine handle to resume after finishing an awaitable - */ - detail::std_coroutine::coroutine_handle<> handle{}; - - /** - * @brief Index of the awaitable that finished. Initialized to the maximum value of std::size_t. - */ - size_t index_finished = std::numeric_limits::max(); - - /** - * @brief State of the when_any object. - * - * @see detail::when_any::await_state - */ - std::atomic owner_state{}; - }; - - /** - * @brief Shared pointer to the state shared between the jobs spawned. Contains the awaitable objects and the result. - */ - std::shared_ptr my_state{nullptr}; - - /** - * @brief Spawn a dpp::job handling the Nth argument. - * - * @tparam N Index of the argument to handle - * @return dpp::job Job handling the Nth argument - */ - template - static job make_job(std::shared_ptr shared_state) { - using namespace detail::when_any; - - /** - * Any exceptions from the awaitable's await_suspend should be thrown to the caller (the coroutine creating the when_any object) - * If the co_await passes, and it is the first one to complete, try construct the result, catch any exceptions to rethrow at resumption, and resume. - */ - if constexpr (!std::same_as, empty>) { - decltype(auto) result = co_await std::get(shared_state->awaitables); - - if (auto s = shared_state->owner_state.fetch_or(await_state::done, std::memory_order_relaxed); (s & (await_state::done | await_state::dangling)) != 0) { - co_return; - } - - using result_t = decltype(result); - - /* Try construct, prefer move if possible, store any exception to rethrow */ - try { - if constexpr (std::is_lvalue_reference_v && !std::is_const_v && std::is_move_constructible_v>) { - shared_state->result.template emplace(std::move(result)); - } else { - shared_state->result.template emplace(result); - } - } catch (...) { - shared_state->result.template emplace<0>(std::current_exception()); - } - } else { - co_await std::get(shared_state->awaitables); - - if (auto s = shared_state->owner_state.fetch_or(await_state::done, std::memory_order_relaxed); (s & (await_state::done | await_state::dangling)) != 0) { - co_return; - } - - shared_state->result.template emplace(); - } - - shared_state->index_finished = N; - if (auto s = shared_state->owner_state.fetch_or(await_state::ready, std::memory_order_acq_rel); (s & (await_state::waiting)) != 0) { - assert(shared_state->handle); - shared_state->handle.resume(); - } - } - - /** - * @brief Spawn a dpp::job to handle each awaitable. - * Each of them will co_await the awaitable and set the result if they are the first to finish - */ - void make_jobs() { - constexpr auto impl = [](when_any *self, std::index_sequence) { - // We create an array to guarantee evaluation order here - // https://eel.is/c++draft/dcl.init.aggr#7 - [[maybe_unused]] dpp::job jobs[] = { make_job(self->my_state)... }; - }; - impl(this, std::index_sequence_for{}); - } - -public: - /** - * @brief Object returned by \ref operator co_await() on resumption. Can be moved but not copied. - */ - class result { - friend class when_any; - - /** - * @brief Reference to the shared state to pull the data from - */ - std::shared_ptr shared_state; - - /** - * @brief Default construction is deleted - */ - result() = delete; - - /** - * @brief Internal constructor taking the shared state - */ - result(std::shared_ptr state) : shared_state{state} {} - - public: - /** - * @brief Move constructor - */ - result(result&&) = default; - - /** - * @brief This object is not copyable. - */ - result(const result &) = delete; - - /** - * @brief Move assignment operator - */ - result &operator=(result&&) = default; - - /** - * @brief This object is not copyable. - */ - result &operator=(const result&) = delete; - - /** - * @brief Retrieve the index of the awaitable that finished first. - * - * @return size_t Index of the awaitable that finished first, relative to the template arguments of when_any - */ - size_t index() const noexcept { - return shared_state->index_finished; - } - - /** - * @brief Retrieve the non-void result of an awaitable. - * - * @tparam N Index of the result to retrieve. Must correspond to index(). - * @throw ??? Throws any exception triggered at construction, or std::bad_variant_access if N does not correspond to index() - * @return Result of the awaitable as a reference. - */ - template -#ifndef _DOXYGEN_ - requires (!detail::when_any::void_result>) -#endif - result_t& get() & { - if (is_exception()) { - std::rethrow_exception(std::get<0>(shared_state->result)); - } - return std::get(shared_state->result); - } - - /** - * @brief Retrieve the non-void result of an awaitable. - * - * @tparam N Index of the result to retrieve. Must correspond to index(). - * @throw ??? Throws any exception triggered at construction, or std::bad_variant_access if N does not correspond to index() - * @return Result of the awaitable as a cpnst reference. - */ - template -#ifndef _DOXYGEN_ - requires (!detail::when_any::void_result>) -#endif - const result_t& get() const& { - if (is_exception()) { - std::rethrow_exception(std::get<0>(shared_state->result)); - } - return std::get(shared_state->result); - } - - /** - * @brief Retrieve the non-void result of an awaitable. - * - * @tparam N Index of the result to retrieve. Must correspond to index(). - * @throw ??? Throws any exception triggered at construction, or std::bad_variant_access if N does not correspond to index() - * @return Result of the awaitable as an rvalue reference. - */ - template -#ifndef _DOXYGEN_ - requires (!detail::when_any::void_result>) -#endif - result_t&& get() && { - if (is_exception()) { - std::rethrow_exception(std::get<0>(shared_state->result)); - } - return std::get(shared_state->result); - } - - /** - * @brief Cannot retrieve a void result. - */ - template -#ifndef _DOXYGEN - requires (detail::when_any::void_result>) -#endif - [[deprecated("cannot retrieve a void result")]] void get() = delete; - - /** - * @brief Checks whether the return of the first awaitable triggered an exception, that is, a call to get() will rethrow. - * - * @return Whether or not the result is an exception - */ - [[nodiscard]] bool is_exception() const noexcept { - return shared_state->result.index() == 0; - } - }; - - /** - * @brief Object returned by \ref operator co_await(). Meant to be used by the standard library, not by a user. - * - * @see result - */ - struct awaiter { - /** - * @brief Pointer to the when_any object - */ - when_any *self; - - /** - * @brief First function called by the standard library when using co_await. - * - * @return bool Whether the result is ready - */ - [[nodiscard]] bool await_ready() const noexcept { - return self->await_ready(); - } - - /** - * @brief Second function called by the standard library when using co_await. - * - * @return bool Returns false if we want to resume immediately. - */ - bool await_suspend(detail::std_coroutine::coroutine_handle<> caller) noexcept { - using namespace detail::when_any; - - self->my_state->handle = caller; - auto prev = self->my_state->owner_state.fetch_or(await_state::waiting, std::memory_order_acq_rel); - return (prev & await_state::ready) == 0; // true (suspend) if the state was not `ready` -- false (resume) if it was - } - - /** - * @brief Third and final function called by the standard library when using co_await. Returns the result object. - * - * @see result - */ - result await_resume() const noexcept { - return { self->my_state }; - } - }; - - /** - * @brief Default constructor. - * A when_any object created this way holds no state - */ - when_any() = default; - - /** - * @brief Constructor from awaitable objects. Each awaitable is executed immediately and the when_any object can then be co_await-ed later. - * - * @throw ??? Any exception thrown by the start of each awaitable will propagate to the caller. - * @param args Arguments to construct each awaitable from. The when_any object will construct an awaitable for each, it is recommended to pass rvalues or std::move. - */ - template -#ifndef _DOXYGEN_ - requires (sizeof...(Args_) == sizeof...(Args)) -#endif /* _DOXYGEN_ */ - when_any(Args_&&... args) : my_state{ std::make_shared(detail::when_any::arg_helper::get(std::forward(args))...) } { - make_jobs(); - } - - /** - * @brief This object is not copyable. - */ - when_any(const when_any &) = delete; - - /** - * @brief Move constructor. - */ - when_any(when_any &&) noexcept = default; - - /** - * @brief On destruction the when_any will try to call @ref dpp::task::cancel() cancel() on each of its awaitable if they have such a method. - * - * @note If you are looking to use a custom type with when_any and want it to cancel on its destruction, - * make sure it has a cancel() method, which will trigger an await_resume() throwing a dpp::task_cancelled_exception. - * This object will swallow the exception and return cleanly. Any other exception will be thrown back to the resumer. - */ - ~when_any() { - if (!my_state) - return; - - my_state->owner_state = detail::when_any::await_state::dangling; - - [](when_any *self, std::index_sequence) constexpr { - constexpr auto cancel = [](when_any *self) constexpr { - if constexpr (requires { std::get(self->my_state->awaitables).cancel(); }) { - try { - std::get(self->my_state->awaitables).cancel(); - } catch (...) { - // swallow any exception. no choice here, we're in a destructor - } - } - }; - (cancel.template operator()(self), ...); - }(this, std::index_sequence_for()); - } - - /** - * @brief This object is not copyable. - */ - when_any &operator=(const when_any &) = delete; - - /** - * @brief Move assignment operator. - */ - when_any &operator=(when_any &&) noexcept = default; - - /** - * @brief Check whether a call to co_await would suspend. - * - * @note This can change from false to true at any point, but not the other way around. - * @return bool Whether co_await would suspend - */ - [[nodiscard]] bool await_ready() const noexcept { - return (my_state->owner_state.load(std::memory_order_acquire) & detail::when_any::await_state::ready) != 0; - } - - /** - * @brief Suspend the caller until any of the awaitables completes. - * - * @see result - * @throw ??? On resumption, throws any exception caused by the construction of the result. - * @return result On resumption, this object returns an object that allows to retrieve the index and result of the awaitable. - */ - [[nodiscard]] awaiter operator co_await() noexcept { - return { this }; - } -}; - -template -#ifndef _DOXYGEN_ -requires (sizeof...(Args) >= 1) -#endif /* _DOXYGEN_ */ -when_any(Args...) -> when_any...>; - -} /* namespace dpp */ - -#endif \ No newline at end of file diff --git a/include/dpp/discord_webhook_server.h b/include/dpp/discord_webhook_server.h deleted file mode 100644 index e115e9e..0000000 --- a/include/dpp/discord_webhook_server.h +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include -#include -#include - -namespace dpp { - -/** - * @brief Creates a HTTP server which listens for incoming - * Discord interactions, and if verified as valid, raises them - * as cluster events, returning the response back. - * Note that Discord requires all interaction endpoints to - * have a valid SSL certificate (not self signed) so in most - * cases you should put this port behind a reverse proxy, e.g. - * nginx, apache, etc. - */ -struct discord_webhook_server : public http_server { - - /** - * @brief Verifier for signed requests - */ - signature_verifier verifier; - - /** - * @brief Public key from application dashboard - */ - std::string public_key_hex; - - /** - * @brief Constructor for creation of a HTTP(S) server - * @param creator Cluster creator - * @param discord_public_key Public key for the application from the application dashboard page - * @param address address to bind to, use "0.0.0.0" to bind to all local addresses - * @param port port to bind to. You should generally use a port > 1024. - * @param ssl_private_key Private key PEM file for HTTPS/SSL. If empty, a plaintext server is created - * @param ssl_public_key Public key PEM file for HTTPS/SSL. If empty, a plaintext server is created - */ - discord_webhook_server(cluster* creator, const std::string& discord_public_key, const std::string_view address, uint16_t port, const std::string& ssl_private_key = "", const std::string& ssl_public_key = ""); - - /** - * @brief Handle Discord outbound webhook - * @param request Request from discord - */ - void handle_request(http_server_request* request); - - /** - * @brief Virtual dtor - */ - virtual ~discord_webhook_server() = default; -}; - -} diff --git a/include/dpp/discordclient.h b/include/dpp/discordclient.h deleted file mode 100644 index b73ae0c..0000000 --- a/include/dpp/discordclient.h +++ /dev/null @@ -1,624 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Discord API version for shard websockets and HTTPS API requests - */ -#define DISCORD_API_VERSION "10" - -/** - * @brief HTTPS Request base path for API calls - */ -#define API_PATH "/api/v" DISCORD_API_VERSION - -/* Forward declarations */ -class cluster; - -/** - * @brief How many seconds to wait between (re)connections. DO NOT change this. - * It is mandated by the Discord API spec! - */ -constexpr time_t RECONNECT_INTERVAL = 5; - -/** - * @brief Represents different event opcodes sent and received on a shard websocket - * - * These are used internally to route frames. - */ -enum shard_frame_type : int { - - /** - * @brief An event was dispatched. - * @note Receive only - */ - ft_dispatch = 0, - - /** - * @brief Fired periodically by the client to keep the connection alive. - * @note Send/Receive - */ - ft_heartbeat = 1, - - /** - * @brief Starts a new session during the initial handshake. - * @note Send only - */ - ft_identify = 2, - - /** - * @brief Update the client's presence. - * @note Send only - */ - ft_presence = 3, - - /** - * @brief Used to join/leave or move between voice channels. - * @note Send only - */ - ft_voice_state_update = 4, - - /** - * @brief Resume a previous session that was disconnected. - * @note Send only - */ - ft_resume = 6, - - /** - * @brief You should attempt to reconnect and resume immediately. - * @note Receive only - */ - ft_reconnect = 7, - - /** - * @brief Request information about offline guild members in a large guild. - * @note Send only - */ - ft_request_guild_members = 8, - - /** - * @brief The session has been invalidated. You should reconnect and identify/resume accordingly. - * @note Receive only - */ - ft_invalid_session = 9, - - /** - * @brief Sent immediately after connecting, contains the heartbeat interval to use. - * @note Receive only - */ - ft_hello = 10, - - /** - * @brief Sent in response to receiving a heartbeat to acknowledge that it has been received. - * @note Receive only - */ - ft_heartbeat_ack = 11, - - /** - * @brief Request information about soundboard sounds in a set of guilds. - * @note Send only - */ - ft_request_soundboard_sounds = 31, -}; - -/** - * @brief Represents a connection to a voice channel. - * A client can only connect to one voice channel per guild at a time, so these are stored in a map - * in the dpp::discord_client keyed by guild_id. - */ -class DPP_EXPORT voiceconn { - /** - * @brief Owning dpp::discord_client instance - */ - class discord_client* creator; -public: - /** - * @brief Voice Channel ID - */ - snowflake channel_id; - - /** - * @brief Websocket hostname for status - */ - std::string websocket_hostname; - - /** - * @brief Voice Voice session ID - */ - std::string session_id; - - /** - * @brief Voice websocket token - */ - std::string token; - - /** - * @brief voice websocket client - */ - class discord_voice_client* voiceclient; - - /** - * @brief True to enable DAVE E2EE - * @warning This is an EXPERIMENTAL feature! - */ - bool dave; - - /** - * @brief Construct a new voiceconn object - */ - voiceconn() = default; - - /** - * @brief Construct a new voiceconn object - * - * @param o owner - * @param _channel_id voice channel id - * @param enable_dave True to enable DAVE E2EE - * @warn DAVE is an EXPERIMENTAL feature! - */ - voiceconn(class discord_client* o, snowflake _channel_id, bool enable_dave); - - /** - * @brief Destroy the voiceconn object - */ - ~voiceconn(); - - /** - * @brief return true if the connection is ready to connect - * (has hostname, token and session id) - * - * @return true if ready to connect - */ - bool is_ready() const; - - /** - * @brief return true if the connection is active (websocket exists) - * - * @return true if has an active websocket - */ - bool is_active() const; - - /** - * @brief Create websocket object and connect it. - * Needs hostname, token and session_id to be set or does nothing. - * - * @param guild_id Guild to connect to the voice channel on - * @return reference to self - * @note It can spawn a thread to establish the connection, so this is NOT a synchronous blocking call! - * You shouldn't call this directly. Use a wrapper function instead. e.g. dpp::guild::connect_member_voice - */ - voiceconn& connect(snowflake guild_id); - - /** - * @brief Disconnect from the currently connected voice channel - * @return reference to self - */ - voiceconn& disconnect(); - - /** - * @brief Reassigns the owner to the given discord_client. - */ - void reassign_owner(class discord_client* o); -}; - -/** @brief Implements a discord client. Each discord_client connects to one shard and derives from a websocket client. */ -class DPP_EXPORT discord_client : public websocket_client -{ -protected: - /** - * @brief Needed so that voice_state_update can call dpp::discord_client::disconnect_voice_internal - */ - friend class dpp::events::voice_state_update; - - /** - * @brief Needed so that guild_create can request member chunks if you have the correct intents - */ - friend class dpp::events::guild_create; - - /** - * @brief Needed to allow cluster::set_presence to use the ETF functions - */ - friend class dpp::cluster; - - /** - * @brief Disconnect from the connected voice channel on a guild - * - * @param guild_id The guild who's voice channel you wish to disconnect from - * @param send_json True if we should send a json message confirming we are leaving the VC - * Should be set to false if we already receive this message in an event. - */ - void disconnect_voice_internal(snowflake guild_id, bool send_json = true); - - /** - * @brief Start connecting the websocket - * - * Called from the constructor, or during reconnection - */ - void start_connecting(); - - /** - * @brief Stores the most recent ping message on this shard, which we check - * for to monitor latency - */ - std::string last_ping_message; - -private: - - /** - * @brief Mutex for message queue - */ - std::shared_mutex queue_mutex; - - /** - * @brief Mutex for zlib pointer - */ - std::mutex zlib_mutex; - - /** - * @brief Queue of outbound messages - */ - std::deque message_queue; - - /** - * @brief If true, stream compression is enabled - */ - bool compressed; - - /** - * @brief Decompressed string - */ - std::string decompressed; - - /** - * @brief This object contains the various zlib structs which - * are not usable by the user of the library directly. They - * are wrapped within this opaque object so that this header - * file does not bring in a dependency on zlib.h. - */ - std::unique_ptr zlib{}; - - /** - * @brief Last connect time of cluster - */ - time_t connect_time; - - /** - * @brief Time last ping sent to websocket, in fractional seconds - */ - double ping_start; - - /** - * @brief ETF parser for when in ws_etf mode - */ - std::unique_ptr etf; - - /** - * @brief Convert a JSON object to string. - * In JSON protocol mode, call json.dump(), and in ETF mode, - * call etf::build(). - * - * @param json nlohmann::json object to convert - * @return std::string string output in the correct format - */ - std::string jsonobj_to_string(const nlohmann::json& json); - - /** - * @brief Update the websocket hostname with the resume url - * from the last READY event - */ - void set_resume_hostname(); - - /** - * @brief Clean up resources - */ - void cleanup(); -public: - /** - * @brief Owning cluster - */ - class dpp::cluster* creator; - - /** - * @brief Heartbeat interval for sending heartbeat keepalive - * @note value in milliseconds - */ - uint32_t heartbeat_interval; - - /** - * @brief Last heartbeat - */ - time_t last_heartbeat; - - /** - * @brief Shard ID of this client - */ - uint32_t shard_id; - - /** - * @brief Total number of shards - */ - uint32_t max_shards; - - /** - * @brief Last sequence number received, for resumes and pings - */ - uint64_t last_seq; - - /** - * @brief Discord bot token - */ - std::string token; - - /** - * @brief Privileged gateway intents - * @see dpp::intents - */ - uint32_t intents; - - /** - * @brief Discord session id - */ - std::string sessionid; - - /** - * @brief Mutex for voice connections map - */ - std::shared_mutex voice_mutex; - - /** - * @brief Resume count - */ - uint32_t resumes; - - /** - * @brief Reconnection count - */ - uint32_t reconnects; - - /** - * @brief Websocket latency in fractional seconds - */ - double websocket_ping; - - /** - * @brief True if READY or RESUMED has been received - */ - bool ready; - - /** - * @brief Last heartbeat ACK (opcode 11) - */ - time_t last_heartbeat_ack; - - /** - * @brief Current websocket protocol, currently either ETF or JSON - */ - websocket_protocol_t protocol; - - /** - * @brief List of voice channels we are connecting to keyed by guild id - */ - std::unordered_map> connecting_voice_channels; - - /** - * @brief The gateway address we reconnect to when we resume a session - */ - std::string resume_gateway_url; - - /** - * @brief Log a message to whatever log the user is using. - * The logged message is passed up the chain to the on_log event in user code which can then do whatever - * it wants to do with it. - * @param severity The log level from dpp::loglevel - * @param msg The log message to output - */ - virtual void log(dpp::loglevel severity, const std::string &msg) const override; - - /** - * @brief Handle an event (opcode 0) - * @param event Event name, e.g. MESSAGE_CREATE - * @param j JSON object for the event content - * @param raw Raw JSON event string - */ - virtual void handle_event(const std::string &event, json &j, const std::string &raw); - - /** - * @brief Get the Guild Count for this shard - * - * @return uint64_t guild count - */ - uint64_t get_guild_count(); - - /** - * @brief Get the Member Count for this shard - * - * @return uint64_t member count - */ - uint64_t get_member_count(); - - /** - * @brief Get the Channel Count for this shard - * - * @return uint64_t channel count - */ - uint64_t get_channel_count(); - - /** - * @brief Fires every second from the underlying socket I/O loop, used for sending heartbeats - * and any queued outbound websocket frames. - */ - virtual void one_second_timer() override; - - /** - * @brief Queue a message to be sent via the websocket - * - * @param j The JSON data of the message to be sent - * @param to_front If set to true, will place the message at the front of the queue not the back - * (this is for urgent messages such as heartbeat, presence, so they can take precedence over - * chunk requests etc) - */ - void queue_message(const std::string &j, bool to_front = false); - - /** - * @brief Clear the outbound message queue - * @return reference to self - */ - discord_client& clear_queue(); - - /** - * @brief Get the size of the outbound message queue - * - * @return The size of the queue - */ - size_t get_queue_size(); - - /** - * @brief Returns true if the shard is connected - * - * @return True if connected - */ - bool is_connected(); - - /** - * @brief Returns the connection time of the shard - * - * @return dpp::utility::uptime Detail of how long the shard has been connected for - */ - dpp::utility::uptime get_uptime(); - - /** - * @brief Construct a new discord_client object - * - * @param _cluster The owning cluster for this shard - * @param _shard_id The ID of the shard to start - * @param _max_shards The total number of shards across all clusters - * @param _token The bot token to use for identifying to the websocket - * @param intents Privileged intents to use, a bitmask of values from dpp::intents - * @param compressed True if the received data will be gzip compressed - * @param ws_protocol Websocket protocol to use for the connection, JSON or ETF - * - * @throws std::bad_alloc Passed up to the caller if any internal objects fail to allocate, after cleanup has completed - */ - discord_client(dpp::cluster* _cluster, uint32_t _shard_id, uint32_t _max_shards, const std::string &_token, uint32_t intents = 0, bool compressed = true, websocket_protocol_t ws_protocol = ws_json); - - /** - * @brief Construct a discord_client object from another discord_client object - * Used when resuming, the url to connect to will be taken from the resume url of the - * other object, along with the seq number. - * - * @param old Previous connection to resume from - * @param sequence Sequence number of previous session - * @param session_id Session ID of previous session - */ - explicit discord_client(discord_client& old, uint64_t sequence, const std::string& session_id); - - /** - * @brief Destroy the discord client object - */ - virtual ~discord_client() = default; - - /** - * @brief Get decompressed total bytes received - * - * This will always return 0 if the connection is not compressed - * @return uint64_t compressed bytes received - */ - uint64_t get_decompressed_bytes_in(); - - /** - * @brief Handle JSON from the websocket. - * @param buffer The entire buffer content from the websocket client - * @param opcode The type of frame, e.g. text or binary - * @returns True if a frame has been handled - */ - virtual bool handle_frame(const std::string &buffer, ws_opcode opcode) override; - - /** - * @brief Handle a websocket error. - * @param errorcode The error returned from the websocket - */ - virtual void error(uint32_t errorcode) override; - - /** - * @brief Start and monitor I/O loop. - */ - void run(); - - /** - * @brief Called when the HTTP socket is closed - */ - virtual void on_disconnect() override; - - /** - * @brief Connect to a voice channel - * - * @param guild_id Guild where the voice channel is - * @param channel_id Channel ID of the voice channel - * @param self_mute True if the bot should mute itself - * @param self_deaf True if the bot should deafen itself - * @param enable_dave True to enable DAVE E2EE - EXPERIMENTAL - * @return reference to self - * @note This is NOT a synchronous blocking call! The bot isn't instantly ready to send or listen for audio, - * as we have to wait for the connection to the voice server to be established! - * e.g. wait for dpp::cluster::on_voice_ready event, and then send the audio within that event. - */ - discord_client& connect_voice(snowflake guild_id, snowflake channel_id, bool self_mute = false, bool self_deaf = false, bool enable_dave = false); - - /** - * @brief Disconnect from the connected voice channel on a guild - * - * @param guild_id The guild who's voice channel you wish to disconnect from - * @return reference to self - * @note This is NOT a synchronous blocking call! The bot isn't instantly disconnected. - */ - discord_client& disconnect_voice(snowflake guild_id); - - /** - * @brief Get the dpp::voiceconn object for a specific guild on this shard. - * - * @param guild_id The guild ID to retrieve the voice connection for - * @return voiceconn* The voice connection for the guild, or nullptr if there is no - * voice connection to this guild. - */ - voiceconn* get_voice(snowflake guild_id); -}; - -} diff --git a/include/dpp/discordevents.h b/include/dpp/discordevents.h deleted file mode 100644 index c603239..0000000 --- a/include/dpp/discordevents.h +++ /dev/null @@ -1,232 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Returns a snowflake id from a json field value, if defined, else returns 0 - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -uint64_t DPP_EXPORT snowflake_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets a snowflake id from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_snowflake_not_null(const nlohmann::json* j, const char *keyname, uint64_t &v); - -/** - * @brief Sets an array of snowflakes from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for the values - * @param v Value to change - */ -void DPP_EXPORT set_snowflake_array_not_null(const nlohmann::json* j, const char *keyname, std::vector &v); - -/** - * @brief Applies a function to each element of a json array. - * @param parent nlohmann::json instance to retrieve value from - * @param key key name to check for the values - * @param fn function to apply to each element - */ -void DPP_EXPORT for_each_json(nlohmann::json* parent, std::string_view key, const std::function &fn); - -/** - * @brief Sets an array of objects from a json field value, if defined, else does nothing - * @tparam T The class of which the array consists of. Must be derived from dpp::json_interface - * @param j nlohmann::json instance to retrieve value from - * @param key key name to check for the values - * @param v Value to change - */ -template void set_object_array_not_null(nlohmann::json* j, std::string_view key, std::vector& v) { - v.clear(); - for_each_json(j, key, [&v](nlohmann::json* elem) { - v.push_back(T{}.fill_from_json(elem)); - }); -} - -/** - * @brief Returns a string from a json field value, if defined, else returns an empty string. - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -std::string DPP_EXPORT string_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets a string from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_string_not_null(const nlohmann::json* j, const char *keyname, std::string &v); - -/** - * @brief This is a repeat of set_string_not_null, but takes in a iconhash. - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_iconhash_not_null(const nlohmann::json* j, const char *keyname, utility::iconhash &v); - -/** - * @brief Returns a double from a json field value, if defined, else returns 0. - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -double DPP_EXPORT double_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets a double from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_double_not_null(const nlohmann::json* j, const char *keyname, double &v); - -/** - * @brief Returns a 64 bit unsigned integer from a json field value, if defined, else returns 0. - * DO NOT use this for snowflakes, as usually snowflakes are wrapped in a string! - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -uint64_t DPP_EXPORT int64_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets an unsigned 64 bit integer from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_int64_not_null(const nlohmann::json* j, const char *keyname, uint64_t &v); - -/** - * @brief Returns a 32 bit unsigned integer from a json field value, if defined, else returns 0 - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -uint32_t DPP_EXPORT int32_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets an unsigned 32 bit integer from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_int32_not_null(const nlohmann::json* j, const char *keyname, uint32_t &v); - -/** - * @brief Returns a 16 bit unsigned integer from a json field value, if defined, else returns 0 - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -uint16_t DPP_EXPORT int16_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets an unsigned 16 bit integer from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_int16_not_null(const nlohmann::json* j, const char *keyname, uint16_t &v); - -/** - * @brief Returns an 8 bit unsigned integer from a json field value, if defined, else returns 0 - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -uint8_t DPP_EXPORT int8_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets an unsigned 8 bit integer from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_int8_not_null(const nlohmann::json* j, const char *keyname, uint8_t &v); - -/** - * @brief Returns a boolean value from a json field value, if defined, else returns false - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -bool DPP_EXPORT bool_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets a boolean from a json field value, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_bool_not_null(const nlohmann::json* j, const char *keyname, bool &v); - -/** - * @brief Returns a time_t from an ISO8601 timestamp field in a json value, if defined, else returns - * epoch value of 0. - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @return found value - */ -time_t DPP_EXPORT ts_not_null(const nlohmann::json* j, const char *keyname); - -/** - * @brief Sets an timestamp from a json field value containing an ISO8601 string, if defined, else does nothing - * @param j nlohmann::json instance to retrieve value from - * @param keyname key name to check for a value - * @param v Value to change - */ -void DPP_EXPORT set_ts_not_null(const nlohmann::json* j, const char *keyname, time_t &v); - -/** - * @brief Base64 encode data into a string. - * @param buf Raw binary buffer - * @param buffer_length Buffer length to encode - * @return The base64 encoded string - */ -std::string DPP_EXPORT base64_encode(unsigned char const* buf, unsigned int buffer_length); - -/** - * @brief Convert time_t unix epoch to std::string ISO date/time - * - * @param ts Timestamp to convert - * @return std::string Converted time/date string - */ -std::string DPP_EXPORT ts_to_string(time_t ts); - -} diff --git a/include/dpp/discordvoiceclient.h b/include/dpp/discordvoiceclient.h deleted file mode 100644 index 2fefa11..0000000 --- a/include/dpp/discordvoiceclient.h +++ /dev/null @@ -1,1267 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct OpusDecoder; -struct OpusEncoder; -struct OpusRepacketizer; - -namespace dpp { - -/** - * @brief Sample rate for OPUS (48khz) - */ -[[maybe_unused]] inline constexpr int32_t opus_sample_rate_hz = 48000; - -/** - * @brief Channel count for OPUS (stereo) - */ -[[maybe_unused]] inline constexpr int32_t opus_channel_count = 2; - -/** - * @brief Discord voice protocol version - */ -[[maybe_unused]] inline constexpr uint8_t voice_protocol_version = 8; - - -class audio_mixer; - -namespace dave::mls { - class session; -} - -// !TODO: change these to constexpr and rename every occurrence across the codebase -#define AUDIO_TRACK_MARKER (uint16_t)0xFFFF - -#define AUDIO_OVERLAP_SLEEP_SAMPLES 30 - -inline constexpr size_t send_audio_raw_max_length = 11520; - -inline constexpr size_t secret_key_size = 32; - -struct dave_state; - -/* -* @brief For holding a moving average of the number of current voice users, for applying a smooth gain ramp. -*/ -struct DPP_EXPORT moving_averager { - moving_averager() = default; - - moving_averager(uint64_t collection_count_new); - - moving_averager operator+=(int64_t value); - - operator float(); - -protected: - std::deque values{}; - uint64_t collectionCount{}; -}; - -// Forward declaration -class cluster; - -/** - * @brief An opus-encoded RTP packet to be sent out to a voice channel - */ -struct DPP_EXPORT voice_out_packet { - /** - * @brief Each string is a UDP packet. - * Generally these will be RTP. - */ - std::string packet; - - /** - * @brief Duration of packet - */ - uint64_t duration; -}; - -/** - * @brief Supported DAVE (Discord Audio Visual Encryption) protocol versions - */ -enum dave_version_t : uint8_t { - /** - * @brief DAVE disabled (default for now) - */ - dave_version_none = 0, - /** - * @brief DAVE enabled, version 1 (E2EE encryption on top of openssl) - */ - dave_version_1 = 1, -}; - -/** - * @brief Discord voice websocket opcode types - */ -enum voice_websocket_opcode_t : uint8_t { - voice_opcode_connection_identify = 0, - voice_opcode_connection_select_protocol = 1, - voice_opcode_connection_ready = 2, - voice_opcode_connection_heartbeat = 3, - voice_opcode_connection_description = 4, - voice_opcode_client_speaking = 5, - voice_opcode_connection_heartbeat_ack = 6, - voice_opcode_connection_resume = 7, - voice_opcode_connection_hello = 8, - voice_opcode_connection_resumed = 9, - voice_opcode_multiple_clients_connect = 11, - voice_opcode_client_disconnect = 13, - voice_opcode_media_sink = 15, - voice_client_flags = 18, - voice_client_platform = 20, - voice_client_dave_prepare_transition = 21, - voice_client_dave_execute_transition = 22, - voice_client_dave_transition_ready = 23, - voice_client_dave_prepare_epoch = 24, - voice_client_dave_mls_external_sender = 25, - voice_client_dave_mls_key_package = 26, - voice_client_dave_mls_proposals = 27, - voice_client_dave_mls_commit_message = 28, - voice_client_dave_announce_commit_transition = 29, - voice_client_dave_mls_welcome = 30, - voice_client_dave_mls_invalid_commit_welcome = 31, -}; - -/** - * @brief DAVE E2EE Binary frame header - */ -struct dave_binary_header_t { - /** - * @brief Sequence number - */ - uint16_t seq; - - /** - * @brief Opcode type - */ - uint8_t opcode; - - /** - * @brief Data package, an opaque structure passed to the - * Discord libdave functions. - */ - std::vector package; - - /** - * @brief Fill binary header from inbound buffer - * @param buffer inbound websocket buffer - */ - dave_binary_header_t(const std::string& buffer); - - /** - * Get the data package from the packed binary frame, as a vector of uint8_t - * for use in the libdave functions - * @return data blob - */ - [[nodiscard]] std::vector get_data() const; - - /** - * Get transition ID for process_commit and process_welcome - * - * @return Transition ID - */ - [[nodiscard]] uint16_t get_transition_id() const; - -private: - /** - * @brief Transition id, only valid when the opcode is - * commit and welcome state. Use get_transition_id() to obtain value. - */ - uint16_t transition_id; -}; - -/** - * @brief A callback for obtaining a user's privacy code. - * The privacy code is returned as the parameter to the function. - * - * This is a callback function because DAVE requires use of a very resource - * intensive SCRYPT call, which uses lots of ram and cpu and take significant - * time. - */ -using privacy_code_callback_t = std::function; - -/** @brief Implements a discord voice connection. - * Each discord_voice_client connects to one voice channel and derives from a websocket client. - */ -class DPP_EXPORT discord_voice_client : public websocket_client -{ - /** - * @brief Clean up resources - */ - void cleanup(); - - /** - * @brief A frame of silence packet - */ - static constexpr uint8_t silence_packet[3] = { 0xf8, 0xff, 0xfe }; - - /** - * @brief Mutex for outbound packet stream - */ - std::mutex stream_mutex; - - /** - * @brief Mutex for message queue - */ - std::shared_mutex queue_mutex; - - /** - * @brief Our public IP address - * - * Use discord_voice_client::discover_ip() to access this value - */ - std::string external_ip; - - /** - * @brief Queue of outbound messages - */ - std::deque message_queue; - - /** - * @brief Last connect time of voice session - */ - time_t connect_time{}; - - /* - * @brief For mixing outgoing voice data. - */ - std::unique_ptr mixer; - - /** - * @brief IP of UDP/RTP endpoint - */ - std::string ip; - - /** - * @brief Port number of UDP/RTP endpoint - */ - uint16_t port{}; - - /** - * @brief SSRC value - */ - uint64_t ssrc{}; - - /** - * @brief List of supported audio encoding modes - */ - std::vector modes; - - /** - * @brief Timescale in nanoseconds - */ - uint64_t timescale{}; - - /** - * @brief Output buffer - */ - std::vector outbuf; - - /** - * @brief Data type of RTP packet sequence number field. - */ - using rtp_seq_t = uint16_t; - using rtp_timestamp_t = uint32_t; - - /** - * @brief Keeps track of the voice payload to deliver to voice handlers. - */ - struct voice_payload { - /** - * @brief The sequence number of the RTP packet that generated this - * voice payload. - */ - rtp_seq_t seq; - - /** - * @brief The timestamp of the RTP packet that generated this voice - * payload. - * - * The timestamp is used to detect the order around where sequence - * number wraps around. - */ - rtp_timestamp_t timestamp; - - /** - * @brief The event payload that voice handlers receive. - */ - std::unique_ptr vr; - - /** - * @brief For priority_queue sorting. - * @return true if "this" has lower priority that "other", - * i.e. appears later in the queue; false otherwise. - */ - bool operator<(const voice_payload& other) const; - }; - - struct voice_payload_parking_lot { - /** - * @brief The range of RTP packet sequence number and timestamp in the lot. - * - * The minimum is used to drop packets that arrive too late. Packets - * less than the minimum have been delivered to voice handlers and - * there is no going back. Unfortunately we just have to drop them. - * - * The maximum is used, at flush time, to calculate the minimum for - * the next batch. The maximum is also updated every time we receive an - * RTP packet with a larger value. - */ - struct seq_range_t { - rtp_seq_t min_seq, max_seq; - rtp_timestamp_t min_timestamp, max_timestamp; - } range; - - /** - * @brief The queue of parked voice payloads. - * - * We group payloads and deliver them to handlers periodically as the - * handling of out-of-order RTP packets. Payloads in between flushes - * are parked and sorted in this queue. - */ - std::priority_queue parked_payloads; - - /** - * @brief The decoder ctls to be set on the decoder. - */ - std::vector> pending_decoder_ctls; - - /** - * @brief libopus decoder - * - * Shared with the voice courier thread that does the decoding. - * This is not protected by a mutex because only the courier thread - * uses the decoder. - */ - std::shared_ptr decoder; - }; - /** - * @brief Thread used to deliver incoming voice data to handlers. - */ - std::thread voice_courier; - - /** - * @brief Shared state between this voice client and the courier thread. - */ - struct courier_shared_state_t { - /** - * @brief Protects all following members. - */ - std::mutex mtx; - - /** - * @brief Signaled when there is a new payload to deliver or terminating state has changed. - */ - std::condition_variable signal_iteration; - - /** - * @brief Voice buffers to be reported to handler, grouped by speaker. - * - * Buffers are parked here and flushed every 500ms. - */ - std::map parked_voice_payloads; - - /** - * @brief Used to signal termination. - * - * @note Pending payloads are delivered first before termination. - */ - bool terminating = false; - } voice_courier_shared_state; - - /** - * @brief The run loop of the voice courier thread. - */ - static void voice_courier_loop(discord_voice_client&, courier_shared_state_t&); - - /** - * @brief If true, audio packet sending is paused - */ - bool paused{}; - - /** - * @brief Whether has sent 5 frame of silence before stopping on pause. - * - * This is to avoid unintended Opus interpolation with subsequent transmissions. - */ - bool sent_stop_frames{}; - - /** - * @brief Number of times we have tried to reconnect in the last few seconds - */ - size_t times_looped{0}; - - /** - * @brief Last time we reconnected - */ - time_t last_loop_time{0}; - -#ifdef HAVE_VOICE - /** - * @brief libopus encoder - */ - OpusEncoder* encoder{}; - - /** - * @brief libopus repacketizer - * (merges frames into one packet) - */ - OpusRepacketizer* repacketizer{}; - - /** - * @brief This holds the state information for DAVE E2EE. - * it is only allocated if E2EE is active on the voice channel. - */ - std::unique_ptr mls_state; - -#else - /** - * @brief libopus encoder - */ - void* encoder; - - /** - * @brief libopus repacketizer - * (merges frames into one packet) - */ - void* repacketizer; - - /** - * @brief This holds the state information for DAVE E2EE. - * it is only allocated if E2EE is active on the voice channel. - */ - std::unique_ptr mls_state{}; -#endif - - /** - * @brief The list of users that have E2EE potentially enabled for - * DAVE protocol. - */ - std::set dave_mls_user_list; - - /** - * @brief The list of users that have left the voice channel but - * not yet removed from MLS group. - */ - std::set dave_mls_pending_remove_list; - - /** - * @brief File descriptor for UDP connection - */ - dpp::socket fd{}; - - /** - * @brief Secret key for encrypting voice. - * If it has been sent, this contains a sequence of exactly 32 bytes - * (secret_key_size) and has_secret_key is set to true. - */ - std::array secret_key{}; - - /** - * @brief True if the voice client has a secret key - */ - bool has_secret_key{false}; - - /** - * @brief Sequence number of outbound audio. This is incremented - * once per frame sent. - */ - uint16_t sequence{}; - - /** - * @brief Last received sequence from gateway. - * - * Needed for heartbeat and resume payload. - */ - int32_t receive_sequence{}; - - /** - * @brief Timestamp value used in outbound audio. Each packet - * has the timestamp value which is incremented to match - * how many frames are sent. - */ - uint32_t timestamp{}; - - /** - * @brief Each packet should have a nonce, a 32-bit incremental - * integer value appended to payload. - * - * We should keep track of this value and increment it for each - * packet sent. - * - * Current initial value is hardcoded to 1. - */ - uint32_t packet_nonce{}; - - /** - * @brief Last sent packet high-resolution timestamp - */ - std::chrono::high_resolution_clock::time_point last_timestamp; - - /** - * @brief Fraction of the sleep that was not executed after the last audio packet was sent - */ - std::chrono::nanoseconds last_sleep_remainder{}; - - /** - * @brief Maps receiving ssrc to user id - */ - std::unordered_map ssrc_map; - - /** - * @brief This is set to true if we have started sending audio. - * When this moves from false to true, this causes the - * client to send the 'talking' notification to the websocket. - */ - bool sending{}; - - /** - * @brief Number of track markers in the buffer. For example if there - * are two track markers in the buffer there are 3 tracks. - * - * **Special case:** - * - * If the buffer is empty, there are zero tracks in the - * buffer. - */ - uint32_t tracks{}; - - /** - * @brief Meta data associated with each track. - * Arbitrary string that the user can set via - * dpp::discord_voice_client::add_marker - */ - std::vector track_meta; - - /** - * @brief Encoding buffer for opus repacketizer and encode - */ - uint8_t encode_buffer[65536]{}; - - /** - * @brief DAVE - Discord Audio Visual Encryption - * Used for E2EE encryption. dave_protocol_none is - * the default right now. - * @warning DAVE E2EE is an EXPERIMENTAL feature! - */ - dave_version_t dave_version; - - /** - * @brief Destination address for where packets go - * on the UDP socket - */ - address_t destination{}; - - - /** - * @brief Send data to UDP socket immediately. - * - * @param data data to send - * @param length length of data to send - * @return int bytes sent. Will return -1 if we cannot send - */ - int udp_send(const char* data, size_t length); - - /** - * @brief Receive data from UDP socket immediately. - * - * @param data data to receive - * @param max_length size of data receiving buffer - * @return int bytes received. -1 if there is an error - * (e.g. EAGAIN) - */ - int udp_recv(char* data, size_t max_length); - - /** - * @brief Called by socketengine when the socket is ready - * for writing, at this point we pick the head item off - * the buffer and send it. So long as it doesn't error - * completely, we pop it off the head of the queue. - */ - void write_ready(); - - /** - * @brief Called by socketengine when there is data to be - * read. At this point we insert that data into the - * input queue. - * @throw dpp::voice_exception if voice support is not compiled into D++ - */ - void read_ready(); - - /** - * @brief Send data to the UDP socket, using the buffer. - * - * @param packet packet data - * @param len length of packet - * @param duration duration of opus packet - * @param send_now send this packet right away without buffering. - * Do NOT set send_now to true outside write_ready. - */ - void send(const char* packet, size_t len, uint64_t duration, bool send_now = false); - - /** - * @brief Queue a message to be sent via the websocket - * - * @param j The JSON data of the message to be sent - * @param to_front If set to true, will place the message at the front of the queue not the back - * (this is for urgent messages such as heartbeat, presence, so they can take precedence over - * chunk requests etc) - */ - void queue_message(const std::string &j, bool to_front = false); - - /** - * @brief Clear the outbound message queue - * - */ - void clear_queue(); - - /** - * @brief Get the size of the outbound message queue - * - * @return The size of the queue - */ - size_t get_queue_size(); - - /** - * @brief Encode a byte buffer using opus codec. - * Multiple opus frames (2880 bytes each) will be encoded into one packet for sending. - * - * @param input Input data as raw bytes of PCM data - * @param inDataSize Input data length - * @param output Output data as an opus encoded packet - * @param outDataSize Output data length, should be at least equal to the input size. - * Will be adjusted on return to the actual compressed data size. - * @return size_t The compressed data size that was encoded. - * @throw dpp::voice_exception If data length to encode is invalid or voice support not compiled into D++ - */ - size_t encode(uint8_t *input, size_t inDataSize, uint8_t *output, size_t &outDataSize); - - /** - * Updates DAVE MLS ratchets for users in the VC - * @param force True to force updating of ratchets regardless of state - */ - void update_ratchets(bool force = false); - - /** - * @brief Called in constructor and on reconnection of websocket - */ - void setup(); - - /** - * @brief Events for UDP Socket IO - */ - dpp::socket_events udp_events; - -public: - - /** - * @brief Owning cluster - */ - class dpp::cluster* creator{}; - - /** - * @brief True when the thread is shutting down - */ - bool terminating{}; - - /** - * @brief The gain value for the end of the current voice iteration. - */ - float end_gain{}; - - /** - * @brief The gain value for the current voice iteration. - */ - float current_gain{}; - - /** - * @brief The amount to increment each successive sample for, for the current voice iteration. - */ - float increment{}; - - /** - * @brief Heartbeat interval for sending heartbeat keepalive - */ - uint32_t heartbeat_interval{}; - - /** - * @brief Last voice channel websocket heartbeat - */ - time_t last_heartbeat{}; - - /** - * @brief Discord voice session token - */ - std::string token; - - /** - * @brief Discord voice session id - */ - std::string sessionid; - - /** - * @brief Server ID - */ - snowflake server_id; - - /** - * @brief Moving averager. - */ - moving_averager moving_average; - - /** - * @brief Channel ID - */ - snowflake channel_id; - - /** - * @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. - * - * Discord voice engine is expecting audio data as if they were from - * some audio device, e.g. microphone, where the data become available - * as they get captured from the audio device. - * - * In case of recorded audio, unlike from a device, the audio data are - * usually instantly available in large chunks. Throttling is needed to - * simulate audio data coming from an audio device. In case of live audio, - * the throttling is by nature, so no extra throttling is needed. - * - * Using live audio mode for recorded audio can cause Discord to skip - * audio data because Discord does not expect to receive, say, 3 minutes' - * worth of audio data in 1 second. - * - * There are some inaccuracies in the throttling method used by the recorded - * audio mode on some systems (mainly Windows) which causes gaps and stutters - * in the resulting audio stream. The overlap audio mode provides a different - * implementation that fixes the issue. This method is slightly more CPU - * intensive, and should only be used if you encounter issues with recorded audio - * on your system. - * - * Use discord_voice_client::set_send_audio_type to change this value as - * it ensures thread safety. - */ - enum send_audio_type_t - { - satype_recorded_audio, - satype_live_audio, - satype_overlap_audio - } send_audio_type = -#ifdef _WIN32 - satype_overlap_audio; -#else - satype_recorded_audio; -#endif - - /** - * @brief Sets the gain for the specified user. - * - * Similar to the User Volume slider, controls the listening volume per user. - * Uses native Opus gain control, so clients don't have to perform extra - * audio processing. - * - * The gain setting will affect the both individual and combined voice audio. - * - * The gain value can also be set even before the user connects to the voice - * channel. - * - * @param user_id The ID of the user where the gain is to be controlled. - * @param factor Nonnegative factor to scale the amplitude by, where 1.f reverts - * to the default volume. - */ - void set_user_gain(snowflake user_id, float factor); - - /** - * @brief Log a message to whatever log the user is using. - * The logged message is passed up the chain to the on_log event in user code which can then do whatever - * it wants to do with it. - * @param severity The log level from dpp::loglevel - * @param msg The log message to output - */ - virtual void log(dpp::loglevel severity, const std::string &msg) const override; - - /** - * @brief Fires every second from the underlying socket I/O loop, used for sending heartbeats - * @throw dpp::exception if the socket needs to disconnect - */ - virtual void one_second_timer() override; - - /** - * @brief voice client is ready to stream audio. - * The voice client is considered ready if it has a secret key. - * - * @return true if ready to stream audio - */ - bool is_ready(); - - /** - * @brief Returns true if the voice client is connected to the websocket - * - * @return True if connected - */ - bool is_connected(); - - /** - * @brief Returns the connection time of the voice client - * - * @return dpp::utility::uptime Detail of how long the voice client has been connected for - */ - dpp::utility::uptime get_uptime(); - - /** - * @brief The time (in milliseconds) between each interval when parsing audio. - * - * @warning You should only change this if you know what you're doing. It is set to 500ms by default. - */ - uint16_t iteration_interval{500}; - - /** Constructor takes shard id, max shards and token. - * @param _cluster The cluster which owns this voice connection, for related logging, REST requests etc - * @param _channel_id The channel id to identify the voice connection as - * @param _server_id The server id (guild id) to identify the voice connection as - * @param _token The voice session token to use for identifying to the websocket - * @param _session_id The voice session id to identify with - * @param _host The voice server hostname to connect to (hostname:port format) - * @param enable_dave Enable DAVE E2EE - * @throw dpp::voice_exception Opus failed to initialise, or D++ is not compiled with voice support - * @warning DAVE E2EE is an EXPERIMENTAL feature! - */ - discord_voice_client(dpp::cluster* _cluster, snowflake _channel_id, snowflake _server_id, const std::string &_token, const std::string &_session_id, const std::string &_host, bool enable_dave = false); - - /** - * @brief Destroy the discord voice client object - */ - virtual ~discord_voice_client() override; - - /** - * @brief Handle JSON from the websocket. - * @param buffer The entire buffer content from the websocket client - * @param opcode Frame type, e.g. OP_TEXT, OP_BINARY - * @return bool True if a frame has been handled - * @throw dpp::exception If there was an error processing the frame, or connection to UDP socket failed - */ - virtual bool handle_frame(const std::string &buffer, ws_opcode opcode) override; - - /** - * @brief Handle a websocket error. - * @param errorcode The error returned from the websocket - */ - virtual void error(uint32_t errorcode) override; - - /** - * @brief Start and monitor websocket I/O - */ - void run(); - - /** - * @brief Send raw audio to the voice channel. - * - * You should send an audio packet of `send_audio_raw_max_length` (11520) bytes. - * Note that this function can be costly as it has to opus encode - * the PCM audio on the fly, and also encrypt it with openssl. - * - * @note Because this function encrypts and encodes packets before - * pushing them onto the output queue, if you have a complete stream - * ready to send and know its length it is advisable to call this - * method multiple times to enqueue the entire stream audio so that - * it is all encoded at once (unless you have set use_opus to false). - * **Constantly calling this from dpp::cluster::on_voice_buffer_send - * can, and will, eat a TON of cpu!** - * - * @param audio_data Raw PCM audio data. Channels are interleaved, - * with each channel's amplitude being a 16 bit value. - * - * @warning **The audio data needs to be 48000Hz signed 16 bit audio, otherwise, the audio will come through incorrectly!** - * - * @param length The length of the audio data. The length should - * be a multiple of 4 (2x 16 bit stereo channels) with a maximum - * length of `send_audio_raw_max_length`, which is a complete opus - * frame at highest quality. - * - * Generally when you're streaming and you know there will be - * more packet to come you should always provide packet data with - * length of `send_audio_raw_max_length`. - * Silence packet will be appended if length is less than - * `send_audio_raw_max_length` as discord expects to receive such - * specific packet size. This can cause gaps in your stream resulting - * in distorted audio if you have more packet to send later on. - * - * @return discord_voice_client& Reference to self - * - * @throw dpp::voice_exception If data length is invalid or voice support not compiled into D++ - */ - discord_voice_client& send_audio_raw(uint16_t* audio_data, const size_t length); - - /** - * @brief Send opus packets to the voice channel - * - * Some containers such as .ogg may contain OPUS - * encoded data already. In this case, we don't need to encode the - * frames using opus here. We can bypass the codec, only applying - * openssl to the stream. - * - * @param opus_packet Opus packets. Discord expects opus frames - * to be encoded at 48000Hz - * - * @param length The length of the audio data. - * - * @param duration Generally duration is 2.5, 5, 10, 20, 40 or 60 - * if the timescale is 1000000 (1ms) - * - * @param send_now Send this packet right away without buffering, - * this will skip duration calculation for the packet being sent - * and only safe to be set to true in write_ready. - * - * @return discord_voice_client& Reference to self - * - * @note It is your responsibility to ensure that packets of data - * sent to send_audio are correctly repacketized for streaming, - * e.g. that audio frames are not too large or contain - * an incorrect format. Discord will still expect the same frequency - * and bit width of audio and the same signedness. - * - * @throw dpp::voice_exception If data length is invalid or voice support not compiled into D++ - */ - discord_voice_client& send_audio_opus(const uint8_t* opus_packet, const size_t length, uint64_t duration, bool send_now = false); - - /** - * @brief Send opus packets to the voice channel - * - * Some containers such as .ogg may contain OPUS - * encoded data already. In this case, we don't need to encode the - * frames using opus here. We can bypass the codec, only applying - * opens to the stream. - * - * Duration is calculated internally - * - * @param opus_packet Opus packets. Discord expects opus frames - * to be encoded at 48000Hz - * - * @param length The length of the audio data. - * - * @return discord_voice_client& Reference to self - * - * @note It is your responsibility to ensure that packets of data - * sent to send_audio are correctly repacketized for streaming, - * e.g. that audio frames are not too large or contain - * an incorrect format. Discord will still expect the same frequency - * and bit width of audio and the same signedness. - * - * @throw dpp::voice_exception If data length is invalid or voice support not compiled into D++ - */ - discord_voice_client& send_audio_opus(const uint8_t* opus_packet, const size_t length); - - /** - * @brief Send silence to the voice channel - * - * @param duration How long to send silence for. With the standard - * timescale this is in milliseconds. Allowed values are 2.5, - * 5, 10, 20, 40 or 60 milliseconds. - * @return discord_voice_client& Reference to self - * @throw dpp::voice_exception if voice support is not compiled into D++ - */ - discord_voice_client& send_silence(const uint64_t duration); - - /** - * @brief Send stop frames to the voice channel. - * - * @param send_now send this packet right away without buffering. - * Do NOT set send_now to true outside write_ready. - * Also make sure you're not locking stream_mutex if you - * don't set send_now to true. - * - * @return discord_voice_client& Reference to self - * @throw dpp::voice_exception if voice support is not compiled into D++ - */ - discord_voice_client& send_stop_frames(bool send_now = false); - - /** - * @brief Sets the audio type that will be sent with send_audio_* methods. - * - * @see send_audio_type_t - */ - discord_voice_client& set_send_audio_type(send_audio_type_t type); - - /** - * @brief Set the timescale in nanoseconds. - * - * @param new_timescale Timescale to set. This defaults to 1000000, - * which means 1 millisecond. - * @return discord_voice_client& Reference to self - * @throw dpp::voice_exception If data length is invalid or voice support not compiled into D++ - */ - discord_voice_client& set_timescale(uint64_t new_timescale); - - /** - * @brief Get the current timescale, this will default to 1000000 - * which means 1 millisecond. - * - * @return uint64_t timescale in nanoseconds - */ - uint64_t get_timescale(); - - /** - * @brief Mark the voice connection as 'speaking'. - * This sends a JSON message to the voice websocket which tells discord - * that the user is speaking. The library automatically calls this for you - * whenever you send audio. - * - * @return discord_voice_client& Reference to self - */ - discord_voice_client& speak(); - - /** - * @brief Pause sending of audio - * - * @param pause True to pause, false to resume - * @return reference to self - */ - discord_voice_client& pause_audio(bool pause); - - /** - * @brief Immediately stop all audio. - * Clears the packet queue. - * @return reference to self - */ - discord_voice_client& stop_audio(); - - /** - * @brief Change the iteration interval time. - * - * @param interval The time (in milliseconds) between each interval when parsing audio. - * - * @return Reference to self. - */ - discord_voice_client& set_iteration_interval(uint16_t interval); - - /** - * @brief Get the iteration interval time (in milliseconds). - * - * @return iteration_interval - */ - uint16_t get_iteration_interval(); - - /** - * @brief Returns true if we are playing audio - * - * @return true if audio is playing - */ - bool is_playing(); - - /** - * @brief Get the number of seconds remaining - * of the audio output buffer - * - * @return float number of seconds remaining - */ - float get_secs_remaining(); - - /** - * @brief Get the number of tracks remaining - * in the output buffer. - * This is calculated by the number of track - * markers plus one. - * @return uint32_t Number of tracks in the - * buffer - */ - uint32_t get_tracks_remaining(); - - /** - * @brief Get the time remaining to send the - * audio output buffer in hours:minutes:seconds - * - * @return dpp::utility::uptime length of buffer - */ - dpp::utility::uptime get_remaining(); - - /** - * @brief Insert a track marker into the audio - * output buffer. - * A track marker is an arbitrary flag in the - * buffer contents that indicates the end of some - * block of audio of significance to the sender. - * This may be a song from a streaming site, or - * some voice audio/speech, a sound effect, or - * whatever you choose. You can later skip - * to the next marker using the - * dpp::discord_voice_client::skip_to_next_marker - * function. - * @param metadata Arbitrary information related to this - * track - * @return reference to self - */ - discord_voice_client& insert_marker(const std::string& metadata = ""); - - /** - * @brief Skip tp the next track marker, - * previously inserted by using the - * dpp::discord_voice_client::insert_marker - * function. If there are no markers in the - * output buffer, then this skips to the end - * of the buffer and is equivalent to the - * dpp::discord_voice_client::stop_audio - * function. - * @note It is possible to use this function - * while the output stream is paused. - * @return reference to self - */ - discord_voice_client& skip_to_next_marker(); - - /** - * @brief Get the metadata string associated with each inserted marker. - * - * @return const std::vector& list of metadata strings - */ - const std::vector get_marker_metadata(); - - /** - * @brief Returns true if the audio is paused. - * You can unpause with - * dpp::discord_voice_client::pause_audio. - * - * @return true if paused - */ - bool is_paused(); - - /** - * @brief Discord external IP detection. - * @return std::string Your external IP address - * @note This is a blocking operation that waits - * for a single packet from Discord's voice servers. - */ - std::string discover_ip(); - - /** - * @brief Returns true if end-to-end encryption is enabled - * for the active voice call (Discord Audio Visual - * Encryption, a.k.a. DAVE). - * - * @return True if end-to-end encrypted - */ - bool is_end_to_end_encrypted() const; - - /** - * @brief Returns the privacy code for the end to end encryption - * scheme ("DAVE"). if end-to-end encryption is not active, - * or is not yet established, this will return an empty - * string. - * - * @return A sequence of six five-digit integers which - * can be matched against the Discord client, in the - * privacy tab for the properties of the voice call. - */ - std::string get_privacy_code() const; - - /** - * @brief Returns the privacy code for a given user by id, - * if they are in the voice call, and enc-to-end encryption - * is enabled. - * - * @param user User ID to fetch the privacy code for - * @param callback Callback to call with the privacy code when - * the creation of the code is complete. - * @warning This call spawns a thread, as getting a user's - * privacy code is a CPU-intensive and memory-intensive operation - * which internally uses scrypt. - */ - void get_user_privacy_code(const dpp::snowflake user, privacy_code_callback_t callback) const; - - /** - * @brief Notify gateway ready for a DAVE transition. - * - * Fires Voice Ready event when appropriate. - * - * https://daveprotocol.com/#commit-handling - * - * @param data Websocket frame data - */ - void ready_for_transition(const std::string &data); - - /** - * @brief Reset dave session, send voice_client_dave_mls_invalid_commit_welcome - * payload with current transition Id and our new key package to gateway. - * - * https://daveprotocol.com/#recovery-from-invalid-commit-or-welcome - */ - void recover_from_invalid_commit_welcome(); - - /** - * @brief Execute pending protocol upgrade/downgrade to/from dave. - * @return true if did an upgrade/downgrade - */ - bool execute_pending_upgrade_downgrade(); - - /** - * @brief Reset dave session and prepare initial session group. - */ - void reinit_dave_mls_group(); - - /** - * @brief Process roster map from commit/welcome. - * @param rmap Roster map - */ - void process_mls_group_rosters(const std::map>& rmap); - - /** - * @brief Called on websocket disconnection - */ - void on_disconnect() override; -}; - -} - diff --git a/include/dpp/dispatcher.h b/include/dpp/dispatcher.h deleted file mode 100644 index a960633..0000000 --- a/include/dpp/dispatcher.h +++ /dev/null @@ -1,2319 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef DPP_NO_CORO -#include -#endif /* DPP_NO_CORO */ - -namespace dpp { - -/* Forward declaration */ -struct confirmation_callback_t; -class discord_client; -class discord_voice_client; - -/** - * @brief A function used as a callback for any REST based command - */ -using command_completion_event_t = std::function; - -/** - * @brief Route interaction event - * - * @param creator Creating cluster - * @param shard_id Shard ID or 0 - * @param d JSON data for the event - * @param raw Raw JSON string - * @param from_webhook True if the interaction comes from a webhook - * @return JSON interaction response, only valid when from_webhook is true - */ -namespace events { - std::string DPP_EXPORT internal_handle_interaction(cluster* creator, uint16_t shard_id, json &d, const std::string &raw, bool from_webhook); -} - -/** @brief Base event parameter struct. - * Each event you receive from the library will have its parameter derived from this class. - * The class contains the raw event data, and a pointer to the current shard's dpp::discord_client object. - * You can also use this object to cancel the current event, meaning that any listeners after yours do - * not get notified of the current event if you call it. - */ -struct DPP_EXPORT event_dispatch_t { -protected: - -public: - /** - * @brief Raw event data. - * If you are using json on your websocket, this will contain json, and if you are using - * ETF as your websocket protocol, it will contain raw ETF data. - */ - std::string raw_event = {}; - - /** - * @brief Shard the event came from. - */ - uint32_t shard = 0; - - /** - * @brief Cluster owning the event dispatch - */ - dpp::cluster* owner = nullptr; - - /** - * @brief Whether the event was cancelled using cancel_event(). - */ - mutable bool cancelled = false; - - /** - * @brief Construct a new event_dispatch_t object - */ - event_dispatch_t() = default; - - /** - * @brief Construct a new event_dispatch_t object - * - * @param rhs event_dispatch_t object to copy from - */ - event_dispatch_t(const event_dispatch_t& rhs) = default; - - /** - * @brief Construct a new event_dispatch_t object - * - * @param rhs event_dispatch_t object to move from - */ - event_dispatch_t(event_dispatch_t&& rhs) = default; - - /** - * @brief Construct a new event_dispatch_t object - * - * @param shard_id The shard the event originated on. - * @param raw Raw event data as JSON or ETF - */ - event_dispatch_t(dpp::cluster* creator, uint32_t shard_id, const std::string& raw); - - /** - * @brief Returns the shard object for the events shard id - * @return discord client object - */ - discord_client* from() const; - - /** - * @brief Construct a new event_dispatch_t object - * - * @param shard_id The shard the event originated on. - * @param raw Raw event data as JSON or ETF - */ - event_dispatch_t(dpp::cluster* creator, uint32_t shard_id, std::string&& raw); - - /** - * @brief Copy another event_dispatch_t object - * - * @param rhs The event to copy from - */ - event_dispatch_t &operator=(const event_dispatch_t& rhs) = default; - - /** - * @brief Move from another event_dispatch_t object - * - * @param rhs The event to move from - */ - event_dispatch_t &operator=(event_dispatch_t&& rhs) = default; - - /** - * @brief Destroy an event_dispatch_t object - * Protected because this object is to be derived from - */ - virtual ~event_dispatch_t() = default; - // ^^^^ THIS MUST BE VIRTUAL. It used to be interaction_create_t's destructor was virtual, - // however before gcc 8.4 a bug prevents inheriting constructors with a user-declared destructors. - // since we need to support gcc 8.3... this is the fix. see https://godbolt.org/z/4xrsPhjzv foo is event_dispatch_t, bar is interaction_create_t - - /** - * @brief Cancels the event in progress. Any other attached lambdas for this event after this one are not called. - * - * @warning This will modify the event object in a non-thread-safe manner. - * @return const event_dispatch_t& reference to self for chaining - */ - const event_dispatch_t& cancel_event() const; - - /** - * @brief Cancels the event in progress. Any other attached lambdas for this event after this one are not called. - * - * @warning This will modify the event object in a non-thread-safe manner. - * @return const event_dispatch_t& reference to self for chaining - */ - event_dispatch_t &cancel_event(); - - /** - * @brief Returns true if the event is cancelled. - * Note that event cancellation is a thread local state, and not stored in the object (because object which can - * be cancelled is `const` during the event, and cannot itself contain the changeable state). - * @return true if the event is cancelled - */ - bool is_cancelled() const; -}; - -/** - * @brief Log messages - */ -struct DPP_EXPORT log_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Severity. - */ - loglevel severity = ll_info; - - /** - * @brief Log Message - */ - std::string message = {}; -}; - -/** - * @brief Closure of socket (removal from socket engine) - */ -struct DPP_EXPORT socket_close_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Socket file descriptor - */ - socket fd{INVALID_SOCKET}; -}; - -namespace utility { - /** - * @brief Get a default logger that outputs to std::cout. - * e.g. - * ``` - * bot.on_log(dpp::utility::cout_logger()); - * ``` - * - * @return A logger for attaching to on_log - */ - std::function DPP_EXPORT cout_logger(); - - /** - * @brief The default callback handler for API calls. - * on error, sends the error to the logger. - * - * @return A lambda for attaching to an API callback - */ - command_completion_event_t DPP_EXPORT log_error(); -} // namespace utility - -/** - * @brief Add user to scheduled event - */ -struct DPP_EXPORT guild_scheduled_event_user_add_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief event user added to - */ - snowflake event_id = {}; - - /** - * @brief User being added - */ - snowflake user_id = {}; - - /** - * @brief Guild being added to - */ - snowflake guild_id = {}; -}; - -/** - * @brief Delete user from scheduled event - */ -struct DPP_EXPORT guild_scheduled_event_user_remove_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief event user removed from - */ - snowflake event_id = {}; - - /** - * @brief User being removed - */ - snowflake user_id = {}; - - /** - * @brief Guild being removed from - */ - snowflake guild_id = {}; -}; - -/** - * @brief Create scheduled event - */ -struct DPP_EXPORT guild_scheduled_event_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief created event - */ - scheduled_event created = {}; -}; - -/** - * @brief Create scheduled event - */ -struct DPP_EXPORT guild_scheduled_event_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief updated event - */ - scheduled_event updated = {}; -}; - -/** - * @brief Delete scheduled event - */ -struct DPP_EXPORT guild_scheduled_event_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief deleted event - */ - scheduled_event deleted = {}; -}; - -/** - * @brief Create automod rule - */ -struct DPP_EXPORT automod_rule_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief updated event - */ - automod_rule created = {}; -}; - -/** - * @brief Update automod rule - */ -struct DPP_EXPORT automod_rule_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief updated event - */ - automod_rule updated = {}; -}; - -/** - * @brief Delete automod rule - */ -struct DPP_EXPORT automod_rule_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief updated event - */ - automod_rule deleted = {}; -}; - -/** - * @brief Execute/trigger automod rule - */ -struct DPP_EXPORT automod_rule_execute_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief The id of the guild in which action was executed. - */ - snowflake guild_id = {}; - - /** - * @brief The action which was executed. - */ - automod_action action = {}; - - /** - * @brief The id of the rule which action belongs to. - */ - snowflake rule_id = {}; - - /** - * @brief The trigger type of rule which was triggered. - */ - automod_trigger_type rule_trigger_type = {}; - - /** - * @brief The id of the user which generated the content which triggered the rule. - */ - snowflake user_id = {}; - - /** - * @brief Optional: the id of the channel in which user content was posted. - */ - snowflake channel_id = {}; - - /** - * @brief Optional: the id of any user message which content belongs to. - */ - snowflake message_id = {}; - - /** - * @brief Optional: the id of any system auto moderation messages posted as a result of this action. - */ - snowflake alert_system_message_id = {}; - - /** - * @brief The user generated text content. - */ - std::string content = {}; - - /** - * @brief The word or phrase configured in the rule that triggered the rule (may be empty). - */ - std::string matched_keyword = {}; - - /** - * @brief The substring in content that triggered the rule (may be empty). - */ - std::string matched_content = {}; -}; - -/** - * @brief Create stage instance - */ -struct DPP_EXPORT stage_instance_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief created stage instance - */ - stage_instance created = {}; -}; - -/** - * @brief Update stage instance - */ -struct DPP_EXPORT stage_instance_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief updated stage instance - */ - stage_instance updated = {}; -}; - -/** - * @brief Delete stage instance - */ -struct DPP_EXPORT stage_instance_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief deleted stage instance - */ - stage_instance deleted = {}; -}; - -/** - * @brief Voice state update - */ -struct DPP_EXPORT voice_state_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Voice state - */ - voicestate state = {}; -}; - -/** - * @brief Create interaction - */ -struct DPP_EXPORT interaction_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Returns a generic http success confirmation - * @return success - */ - confirmation_callback_t success() const; - - /** - * @brief True if from a HTTP interaction webhook, false if from websocket - */ - bool from_webhook{false}; - - /** - * @brief If this interaction is created from a webhook server, - * it fills this value with a JSON string which is sent as the HTTP response. - * This is thread local so that it is preserved when the event is copied, we - * guarantee that the request/response is in the same thread so this will always - * be valid. - * @param response response to set - */ - void set_queued_response(const std::string& response) const; - - /** - * @brief Acknowledge interaction without displaying a message to the user, - * for use with button and select menu components. - * - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void reply(command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Send a reply for this interaction - * - * @param t Type of reply to send - * @param m Message object to send. Not all fields are supported by Discord. - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void reply(interaction_response_type t, const message& m, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Send a reply for this interaction - * - * @param t Type of reply to send - * @param mt The string value to send, for simple text only messages - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void reply(interaction_response_type t, const std::string& mt, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Send a reply for this interaction. - * Uses the default type of dpp::ir_channel_message_with_source, a simple message reply. - * - * @param m Message object to send. Not all fields are supported by Discord. - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void reply(const message& m, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Send a reply for this interaction. - * Uses the default type of dpp::ir_channel_message_with_source, a simple message reply. - * - * @param mt The string value to send, for simple text only messages - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void reply(const std::string& mt, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Reply to interaction with a dialog box - * - * @param mr Dialog box response to send - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void dialog(const interaction_modal_response& mr, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Edit the response for this interaction - * - * @param m Message object to send. Not all fields are supported by Discord. - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void edit_response(const message& m, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Edit the response for this interaction - * - * @param mt The string value to send, for simple text only messages - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void edit_response(const std::string& mt, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Set the bot to 'thinking' state where you have up to 15 minutes to respond - * - * @param ephemeral True if the thinking state should be ephemeral - * @param callback User function to execute when the api call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void thinking(bool ephemeral = false, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Get original response message for this interaction - * - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void get_original_response(command_completion_event_t callback) const; - - /** - * @brief Edit original response message for this interaction - * - * @param m Message object to send. Not all fields are supported by Discord. - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void edit_original_response(const message& m, command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Delete original response message for this interaction. This cannot be used on an ephemeral interaction response. - * - * @param callback Function to call when the API call completes. - * On success the callback will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - void delete_original_response(command_completion_event_t callback = utility::log_error()) const; - - /** - * @brief Get queued response when responding to a HTTP request - * @return response JSON - */ - std::string get_queued_response() const; - -#ifndef DPP_NO_CORO - /** - * @brief Acknowledge interaction without displaying a message to the user, - * for use with button and select menu components. - * - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply() const; - - /** - * @brief Send a reply for this interaction - * - * @param t Type of reply to send - * @param m Message object to send. Not all fields are supported by Discord. - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply(interaction_response_type t, const message& m) const; - - /** - * @brief Send a reply for this interaction - * - * @param t Type of reply to send - * @param mt The string value to send, for simple text only messages - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply(interaction_response_type t, const std::string& mt) const; - - /** - * @brief Send a reply for this interaction. - * Uses the default type of dpp::ir_channel_message_with_source, a simple message reply. - * - * @param m Message object to send. Not all fields are supported by Discord. - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply(const message& m) const; - - /** - * @brief Send a reply for this interaction. - * Uses the default type of dpp::ir_channel_message_with_source, a simple message reply. - * - * @param mt The string value to send, for simple text only messages - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply(const std::string& mt) const; - - /** - * @brief Reply to interaction with a dialog box - * - * @param mr Dialog box response to send - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_dialog(const interaction_modal_response& mr) const; - - /** - * @brief Edit the response for this interaction - * - * @param m Message object to send. Not all fields are supported by Discord. - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_edit_response(const message& m) const; - - /** - * @brief Edit the response for this interaction - * - * @param mt The string value to send, for simple text only messages - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_edit_response(const std::string& mt) const; - - /** - * @brief Set the bot to 'thinking' state where you have up to 15 minutes to respond - * - * @param ephemeral True if the thinking state should be ephemeral - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_thinking(bool ephemeral = false) const; - - /** - * @brief Get original response message for this interaction - * - * On success the result will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_get_original_response() const; - - /** - * @brief Edit original response message for this interaction - * - * @param m Message object to send. Not all fields are supported by Discord. - * On success the result will contain a dpp::message object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_edit_original_response(const message& m) const; - - /** - * @brief Delete original response message for this interaction. This cannot be used on an ephemeral interaction response. - * - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_delete_original_response() const; -#endif /* DPP_NO_CORO */ - - /** - * @brief command interaction - */ - interaction command = {}; - - /** - * @brief Get a slashcommand parameter - * - * @param name The name of the command line parameter to retrieve the value for - * @return command_value Returns the value of the first option that matches the given name. - * If no matches are found, an empty variant is returned. - * - * @throw dpp::logic_exception if the interaction is not for a command - */ - virtual command_value get_parameter(const std::string& name) const; -}; - -/** - * @brief User has issued a slash command - */ -struct DPP_EXPORT slashcommand_t : public interaction_create_t { - using interaction_create_t::interaction_create_t; - using interaction_create_t::operator=; -}; - -/** - * @brief Click on button - */ -struct DPP_EXPORT button_click_t : public interaction_create_t { -private: - using interaction_create_t::get_parameter; -public: - using interaction_create_t::interaction_create_t; - using interaction_create_t::operator=; - - /** - * @brief button custom id - */ - std::string custom_id = {}; - - /** - * @brief component type - */ - uint8_t component_type = {}; -}; - -/** - * @brief On form submitted. - */ -struct DPP_EXPORT form_submit_t : public interaction_create_t { -private: - using interaction_create_t::get_parameter; -public: - using interaction_create_t::interaction_create_t; - using interaction_create_t::operator=; - - /** - * @brief button custom id - */ - std::string custom_id = {}; - - /** - * @brief Message components for form reply - */ - std::vector components = {}; -}; - -/** - * @brief Discord requests that we fill a list of auto completion choices for a command option - */ -struct DPP_EXPORT autocomplete_t : public interaction_create_t { -private: - using interaction_create_t::get_parameter; -public: - using interaction_create_t::interaction_create_t; - using interaction_create_t::operator=; - - /** - * @brief Command ID - */ - dpp::snowflake id = {}; - - /** - * @brief Command name - */ - std::string name = {}; - - /** - * @brief auto completion options - */ - std::vector options = {}; -}; - -/** - * @brief Base class for context menu interactions, e.g. right click on - * user or message. - */ -struct DPP_EXPORT context_menu_t : public interaction_create_t { -private: - using interaction_create_t::get_parameter; -public: - using interaction_create_t::interaction_create_t; - using interaction_create_t::operator=; -}; - -/** - * @brief Event parameter for context menu interactions for messages - */ -struct DPP_EXPORT message_context_menu_t : public context_menu_t { -public: - using context_menu_t::context_menu_t; - using context_menu_t::operator=; - - /** - * @brief Related message - */ - message ctx_message = {}; - - /** - * @brief Get the message which was right-clicked on - * - * @return message right-clicked on - */ - const message& get_message() const; - - /** - * @brief Set the message object for this event - * - * @param m message to set - * @return message_context_menu_t& reference to self for fluent chaining - */ - message_context_menu_t& set_message(const message& m); -}; - -/** - * @brief Event parameter for context menu interactions for users - */ -struct DPP_EXPORT user_context_menu_t : public context_menu_t { -public: - using context_menu_t::context_menu_t; - using context_menu_t::operator=; - - /** - * @brief Related user - */ - user ctx_user = {}; - - /** - * @brief Get the user which was right-clicked on - * - * @return user right clicked on - */ - const user& get_user() const; - - /** - * @brief Set the user object for this event - * - * @param u user to set - * @return user_context_menu_t& reference to self for fluent chaining - */ - user_context_menu_t& set_user(const user& u); - -}; - -/** - * @brief Click on select - */ -struct DPP_EXPORT select_click_t : public interaction_create_t { -private: - using interaction_create_t::get_parameter; -public: - using interaction_create_t::interaction_create_t; - using interaction_create_t::operator=; - - /** - * @brief select menu custom id - */ - std::string custom_id = {}; - - /** - * @brief select menu values - */ - std::vector values = {}; - - /** - * @brief select menu component type (dpp::component_type) - */ - uint8_t component_type = {}; -}; - - -/** - * @brief Delete guild - */ -struct DPP_EXPORT guild_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Deleted guild - * - */ - guild deleted; - - /** - * @brief Guild ID deleted - * - */ - snowflake guild_id{0}; -}; - -/** - * @brief Update guild stickers - */ -struct DPP_EXPORT guild_stickers_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Updating guild - */ - guild updating_guild; - - /** - * @brief stickers being updated - */ - std::vector stickers = {}; -}; - -/** - * @brief Guild join request delete (user declined membership screening) - */ -struct DPP_EXPORT guild_join_request_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Deleted guild - */ - snowflake guild_id = {}; - - /** - * @brief user id - */ - snowflake user_id = {}; -}; - -/** - * @brief Delete channel - */ -struct DPP_EXPORT channel_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild channel is being deleted from - */ - guild deleting_guild; - - /** - * @brief channel being deleted - */ - channel deleted; -}; - -/** - * @brief Update channel - */ -struct DPP_EXPORT channel_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild channel is being updated on - */ - guild updating_guild; - - /** - * @brief channel being updated - */ - channel updated; -}; - -/** - * @brief Session ready - */ -struct DPP_EXPORT ready_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief websocket session id - */ - std::string session_id = {}; - - /** - * @brief shard id - */ - uint32_t shard_id = {}; - - /** - * @brief Array of guild IDs the bot is in, at the time of this event. - */ - std::vector guilds{}; - - /** - * @brief The number of guilds the bot is in, at the time of this event. - */ - uint32_t guild_count{0}; -}; - -/** - * @brief Message Deleted - */ -struct DPP_EXPORT message_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief message being deleted - */ - snowflake id{0}; - - /** - * @brief Channel the message was deleted on - * - */ - snowflake channel_id{0}; - - /** - * @brief Guild the message was deleted on - */ - snowflake guild_id{0}; - -}; - -/** - * @brief Guild member remove - */ -struct DPP_EXPORT guild_member_remove_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild user is being removed from - */ - guild removing_guild; - - /** - * @brief Guild ID removed from - */ - snowflake guild_id{0}; - - /** - * @brief user being removed - */ - user removed; -}; - -/** - * @brief Session resumed - */ -struct DPP_EXPORT resumed_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief websocket session id - */ - std::string session_id = {}; - - /** - * @brief shard id - */ - uint32_t shard_id = 0; -}; - -/** - * @brief Guild role create - */ -struct DPP_EXPORT guild_role_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild role is being created on - */ - guild creating_guild; - - /** - * @brief role being created - */ - role created; -}; - -/** - * @brief Typing start - */ -struct DPP_EXPORT typing_start_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild user is typing on - */ - guild typing_guild; - - /** - * @brief channel user is typing on - */ - channel typing_channel; - - /** - * @brief user who is typing. - * Can be nullptr if user is not cached - */ - user typing_user; - - /** - * @brief User id of user typing. - * Always set regardless of caching - */ - snowflake user_id = {}; - - /** - * @brief Time of typing event - */ - time_t timestamp = 0; -}; - -/** - * @brief Voice state update - */ -struct DPP_EXPORT voice_track_marker_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Voice client - */ - discord_voice_client* voice_client = nullptr; - - /** - * @brief Track metadata - */ - std::string track_meta = {}; -}; - - -/** - * @brief Message reaction add - */ -struct DPP_EXPORT message_reaction_add_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Guild reaction occurred on - */ - guild reacting_guild; - - /** - * @brief User who reacted - */ - user reacting_user = {}; - - /** - * @brief member data of user who reacted - */ - guild_member reacting_member = {}; - - /** - * @brief Channel ID the reaction happened on - */ - snowflake channel_id = {}; - - /** - * @brief channel the reaction happened on (Optional) - * @note only filled when the channel is cached - */ - channel reacting_channel; - - /** - * @brief emoji of reaction - */ - emoji reacting_emoji = {}; - - /** - * @brief message id of the message reacted upon - */ - snowflake message_id = {}; - - /** - * @brief ID of the user who authored the message which was reacted to (Optional) - */ - snowflake message_author_id = {}; -}; - -/** - * @brief Guild members chunk - */ -struct DPP_EXPORT guild_members_chunk_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild the members chunk is for - */ - guild adding; - - /** - * @brief list of members in the chunk - */ - guild_member_map members; -}; - -/** - * @brief Message reaction remove - */ -struct DPP_EXPORT message_reaction_remove_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Guild reaction occurred on - */ - guild reacting_guild; - - /** - * @brief User who reacted - */ - dpp::snowflake reacting_user_id = {}; - - /** - * @brief Channel ID the reaction was removed in - */ - snowflake channel_id = {}; - - /** - * @brief channel the reaction happened on (optional) - * @note only filled when the channel is cached - */ - channel reacting_channel; - - /** - * @brief emoji of reaction - */ - emoji reacting_emoji = {}; - - /** - * @brief message id of the message reacted upon - */ - snowflake message_id = {}; -}; - -/** - * @brief Create guild - */ -struct DPP_EXPORT guild_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild that was created - */ - guild created; - - /** - * @brief List of presences of all users on the guild. - * - * This is only filled if you have the GUILD_PRESENCES - * privileged intent. - */ - presence_map presences = {}; - - /** - * @brief List of scheduled events in the guild - */ - scheduled_event_map scheduled_events = {}; - - /** - * @brief List of stage instances in the guild - */ - stage_instance_map stage_instances = {}; - - /** - * @brief List of threads in the guild - */ - thread_map threads = {}; - - /** - * @brief List of stickers in the guild - */ - sticker_map stickers = {}; -}; - -/** - * @brief Create channel - */ -struct DPP_EXPORT channel_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild channel was created on - */ - guild creating_guild; - - /** - * @brief channel that was created - */ - channel created; -}; - -/** - * @brief Message remove emoji - */ -struct DPP_EXPORT message_reaction_remove_emoji_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Guild reaction occurred on - */ - guild reacting_guild; - - /** - * @brief Channel ID the reactions was removed in - */ - snowflake channel_id = {}; - - /** - * @brief channel the reaction happened on (optional) - * @note only filled when the channel is cached - */ - channel reacting_channel; - - /** - * @brief emoji of reaction - */ - emoji reacting_emoji = {}; - - /** - * @brief message id of the message reacted upon - */ - snowflake message_id = {}; -}; - -/** - * @brief Message delete bulk - */ -struct DPP_EXPORT message_delete_bulk_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild messages are being deleted upon - */ - guild deleting_guild; - - /** - * @brief user who is deleting the messages - */ - user deleting_user; - - /** - * @brief channel messages are being deleted from - */ - channel deleting_channel; - - /** - * @brief list of message ids of deleted messages - */ - std::vector deleted = {}; -}; - -/** - * @brief Guild role update - */ -struct DPP_EXPORT guild_role_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where roles are being updated - */ - guild updating_guild; - - /** - * @brief the role being updated - */ - role updated; -}; - -/** - * @brief Guild role delete - */ -struct DPP_EXPORT guild_role_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where role is being deleted - */ - guild deleting_guild; - - /** - * @brief role being deleted - */ - role deleted; - - /** - * @brief ID of the deleted role - */ - snowflake role_id = {}; -}; - -/** - * @brief Channel pins update - */ -struct DPP_EXPORT channel_pins_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where message is being pinned - */ - guild pin_guild; - - /** - * @brief channel where message is being pinned - */ - channel pin_channel; - - /** - * @brief timestamp of pin - */ - time_t timestamp = 0; -}; - -/** - * @brief Message remove all reactions - */ -struct DPP_EXPORT message_reaction_remove_all_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Guild reaction occurred on - */ - guild reacting_guild; - - /** - * @brief Channel ID the reactions was removed in - */ - snowflake channel_id = {}; - - /** - * @brief channel the reaction happened on (optional) - * @note only filled when the channel is cached - */ - channel reacting_channel; - - /** - * @brief message id of the message reacted upon - */ - snowflake message_id = {}; - -}; - -/** - * @brief Voice server update - */ -struct DPP_EXPORT voice_server_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild id where voice server updated - */ - snowflake guild_id = {}; - - /** - * @brief voice server token, used to connect to vc - */ - std::string token = {}; - - /** - * @brief voice server endpoint wss:// address - */ - std::string endpoint = {}; -}; - -/** - * @brief Guild emojis update - */ -struct DPP_EXPORT guild_emojis_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief snowflake ids of list of emojis - */ - std::vector emojis = {}; - - /** - * @brief guild where emojis are being updated - */ - guild updating_guild; -}; - -/** - * @brief Presence update - * - */ -struct DPP_EXPORT presence_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief rich presence being updated - */ - presence rich_presence = {}; -}; - -/** - * @brief Webhooks update - */ -struct DPP_EXPORT webhooks_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where webhooks are being updated - */ - guild webhook_guild; - - /** - * @brief channel where webhooks are being updated - */ - channel webhook_channel; -}; - -/** - * @brief Guild member add - */ -struct DPP_EXPORT guild_member_add_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild which gained new member - */ - guild adding_guild; - - /** - * @brief member which was added - */ - guild_member added = {}; -}; - -/** - * @brief Invite delete - */ -struct DPP_EXPORT invite_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief the deleted invite - */ - invite deleted_invite = {}; -}; - -/** - * @brief Guild update - */ -struct DPP_EXPORT guild_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild being updated - */ - guild updated; -}; - -/** - * @brief Guild integrations update - */ -struct DPP_EXPORT guild_integrations_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where integrations are being updated - */ - guild updating_guild; -}; - -/** - * @brief Guild member update - */ -struct DPP_EXPORT guild_member_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where member is being updated - */ - guild updating_guild; - - /** - * @brief member being updated - */ - guild_member updated = {}; -}; - -/** - * @brief Invite create - */ -struct DPP_EXPORT invite_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief created invite - */ - invite created_invite = {}; -}; - -/** - * @brief Message update - */ -struct DPP_EXPORT message_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief message being updated - */ - message msg = {}; -}; - -/** - * @brief User update - */ -struct DPP_EXPORT user_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief user being updated - */ - user updated = {}; -}; - -/** - * @brief Create message - */ -struct DPP_EXPORT message_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief message that was created (sent). - */ - message msg = {}; - /** - * @brief Send a text to the same channel as the channel_id in received event. - * @param m Text to send - * @param callback User function to execute once the API call completes. - * @note confirmation_callback_t::value contains a message object on success. On failure, value is undefined and confirmation_callback_t::is_error() is true. - */ - void send(const std::string& m, command_completion_event_t callback = utility::log_error()) const; - /** - * @brief Send a message to the same channel as the channel_id in received event. - * @param msg Message to send - * @param callback User function to execute once the API call completes. - * @note confirmation_callback_t::value contains a message object on success. On failure, value is undefined and confirmation_callback_t::is_error() is true. - */ - void send(const message& msg, command_completion_event_t callback = utility::log_error()) const; - /** - * @brief Send a message to the same channel as the channel_id in received event. - * @param msg Message to send - * @param callback User function to execute once the API call completes. - * @note confirmation_callback_t::value contains a message object on success. On failure, value is undefined and confirmation_callback_t::is_error() is true. - */ - void send(message&& msg, command_completion_event_t callback = utility::log_error()) const; - /** - * @brief Reply to the message received in the event. - * @param m Text to send - * @param mention_replied_user mentions (pings) the author of message replied to, if true - * @param callback User function to execute once the API call completes. - * @note confirmation_callback_t::value contains a message object on success. On failure, value is undefined and confirmation_callback_t::is_error() is true. - */ - void reply(const std::string& m, bool mention_replied_user = false, command_completion_event_t callback = utility::log_error()) const; - /** - * @brief Reply to the message received in the event. - * @param msg Message to send as a reply. - * @param mention_replied_user mentions (pings) the author of message replied to, if true - * @param callback User function to execute once the API call completes. - * @note confirmation_callback_t::value contains a message object on success. On failure, value is undefined and confirmation_callback_t::is_error() is true. - */ - void reply(const message& msg, bool mention_replied_user = false, command_completion_event_t callback = utility::log_error()) const; - /** - * @brief Reply to the message received in the event. - * @param msg Message to send as a reply. - * @param mention_replied_user mentions (pings) the author of message replied to, if true - * @param callback User function to execute once the API call completes. - * @note confirmation_callback_t::value contains a message object on success. On failure, value is undefined and confirmation_callback_t::is_error() is true. - */ - void reply(message&& msg, bool mention_replied_user = false, command_completion_event_t callback = utility::log_error()) const; - -#ifndef DPP_NO_CORO - /** - * @brief Send a text to the same channel as the channel_id in received event. - * - * @param m Text to send - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_send(const std::string& m) const; - - /** - * @brief Send a message to the same channel as the channel_id in received event. - * - * @param msg Message to send - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_send(const message& msg) const; - - /** - * @brief Send a message to the same channel as the channel_id in received event. - * - * @param msg Message to send - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_send(message&& msg) const; - - /** - * @brief Reply to the message received in the event. - * - * @param m Text to send as a reply. - * @param mention_replied_user mentions (pings) the author of message replied to, if true - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply(const std::string& m, bool mention_replied_user = false) const; - - /** - * @brief Reply to the message received in the event. - * - * @param msg Message to send as a reply. - * @param mention_replied_user mentions (pings) the author of message replied to, if true - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply(const message& msg, bool mention_replied_user = false) const; - - /** - * @brief Reply to the message received in the event. - * - * @param msg Message to send as a reply. - * @param mention_replied_user mentions (pings) the author of message replied to, if true - * On success the result will contain a dpp::confirmation object in confirmation_callback_t::value. On failure, the value is undefined and confirmation_callback_t::is_error() method will return true. You can obtain full error details with confirmation_callback_t::get_error(). - */ - dpp::async co_reply(message&& msg, bool mention_replied_user = false) const; -#endif /* DPP_NO_CORO */ -}; - -/** - * @brief Message poll vote add - */ -struct DPP_EXPORT message_poll_vote_add_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief ID of the user who added the vote - */ - snowflake user_id; - - /** - * @brief ID of the channel containing the vote - */ - snowflake channel_id; - - /** - * @brief ID of the message containing the vote - */ - snowflake message_id; - - /** - * @brief ID of the guild containing the vote or 0 for DMs - */ - snowflake guild_id; - - /** - * @brief ID of the answer in the message poll object - */ - uint32_t answer_id; -}; - -/** - * @brief Message poll vote remove - */ -struct DPP_EXPORT message_poll_vote_remove_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief ID of the user who added the vote - */ - snowflake user_id; - - /** - * @brief ID of the channel containing the vote - */ - snowflake channel_id; - - /** - * @brief ID of the message containing the vote - */ - snowflake message_id; - - /** - * @brief ID of the guild containing the vote or 0 for DMs - */ - snowflake guild_id; - - /** - * @brief ID of the answer in the message poll object - */ - uint32_t answer_id; -}; - -/** - * @brief Guild audit log entry create - */ -struct DPP_EXPORT guild_audit_log_entry_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief created audit log entry - */ - audit_entry entry = {}; -}; - -/** - * @brief Guild ban add - */ -struct DPP_EXPORT guild_ban_add_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where ban was added - */ - guild banning_guild; - - /** - * @brief user being banned - */ - user banned = {}; -}; - -/** - * @brief Guild ban remove - */ -struct DPP_EXPORT guild_ban_remove_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where ban is being removed - */ - guild unbanning_guild; - - /** - * @brief user being unbanned - */ - user unbanned = {}; -}; - -/** - * @brief Integration create - */ -struct DPP_EXPORT integration_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief created integration - */ - integration created_integration = {}; -}; - -/** - * @brief Integration update - */ -struct DPP_EXPORT integration_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief updated integration - */ - integration updated_integration = {}; -}; - -/** - * @brief Integration delete - */ -struct DPP_EXPORT integration_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief deleted integration - */ - integration deleted_integration = {}; -}; - -/** - * @brief Thread Create - */ -struct DPP_EXPORT thread_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where thread was created - */ - guild creating_guild; - - /** - * @brief thread created - */ - thread created = {}; -}; - -/** - * @brief Thread Update - */ -struct DPP_EXPORT thread_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where thread was updated - */ - guild updating_guild; - - /** - * @brief thread updated - */ - thread updated = {}; -}; - -/** - * @brief Thread Delete - */ -struct DPP_EXPORT thread_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where thread was deleted - */ - guild deleting_guild; - - /** - * @brief thread deleted - */ - thread deleted = {}; -}; - -/** - * @brief Thread List Sync - */ -struct DPP_EXPORT thread_list_sync_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief guild where thread list was synchronised - */ - guild updating_guild; - - /** - * @brief list of threads (channels) synchronised - */ - std::vector threads = {}; - - /** - * @brief list of thread members for the channels (threads) - */ - std::vector members = {}; -}; - -/** - * @brief Thread Member Update - */ -struct DPP_EXPORT thread_member_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief updated thread member - */ - thread_member updated = {}; -}; - -/** - * @brief Thread Members Update - */ -struct DPP_EXPORT thread_members_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief thread (channel) id - */ - snowflake thread_id = {}; - - /** - * @brief guild thread members updated on - */ - guild* updating_guild = nullptr; - - /** - * @brief new approximate member count - */ - uint8_t member_count = 0; - - /** - * @brief added members - */ - std::vector added = {}; - - /** - * @brief ids only of removed members - */ - std::vector removed_ids = {}; -}; - -/** - * @brief voice buffer send - * @warning The shard in `from` will ALWAYS be null. - */ -struct DPP_EXPORT voice_buffer_send_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief voice client where buffer was sent - */ - class discord_voice_client* voice_client = nullptr; - - /** - * @brief encoded size of sent buffer - */ - uint64_t buffer_size = 0; - - /** - * @brief number of packet waiting to be sent in the queue - */ - size_t packets_left = 0; -}; - -/** - * @brief voice ready - */ -struct DPP_EXPORT voice_ready_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief voice client which is ready - */ - discord_voice_client* voice_client = nullptr; - - /** - * @brief id of voice channel - */ - snowflake voice_channel_id = {}; -}; - -/** - * @brief voice receive packet - */ -struct DPP_EXPORT voice_receive_t : public event_dispatch_t { - friend class discord_voice_client; - - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief Construct a new voice receive t object - * - * @param creator The creating cluster - * @param shard_id Shard the voice channel exists on - * @param raw Raw event text as UDP packet. - * @param vc owning voice client pointer - * @param _user_id user id who is speaking, 0 for a mix of all user audio - * @param pcm user audio to set - * @param length length of user audio in bytes - */ - voice_receive_t(dpp::cluster* creator, uint32_t shard_id, const std::string& raw, class discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length); - - /** - * @brief Construct a new voice receive t object - * - * @param creator The creating cluster - * @param shard_id Shard the voice channel exists on - * @param raw Raw event text as UDP packet. - * @param vc owning voice client pointer - * @param _user_id user id who is speaking, 0 for a mix of all user audio - * @param pcm user audio to set - * @param length length of user audio in bytes - */ - voice_receive_t(dpp::cluster* creator, uint32_t shard_id, std::string&& raw, class discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length); - - /** - * @brief Voice client - */ - discord_voice_client* voice_client = nullptr; - - /** - * @brief Audio data, encoded as 48kHz stereo PCM or Opus, - * @deprecated Please switch to using audio_data. - */ - uint8_t* audio = nullptr; - - /** - * @brief Size of audio buffer - * @deprecated Please switch to using audio_data. - */ - size_t audio_size = 0; - - /** - * @brief Audio data, encoded as 48kHz stereo PCM or Opus, - */ - std::vector audio_data = {}; - - /** - * @brief User ID of speaker (zero if unknown) - */ - snowflake user_id = {}; - -protected: - /** - * @brief Reassign values outside of the constructor for use within discord_voice_client - * - * @param vc owning voice client pointer - * @param _user_id user id who is speaking, 0 for a mix of all user audio - * @param pcm user audio to set - * @param length length of user audio in bytes - */ - void reassign(discord_voice_client* vc, snowflake _user_id, const uint8_t* pcm, size_t length); -}; - -/** - * @brief voice client speaking event - */ -struct DPP_EXPORT voice_client_speaking_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief voice client where user is speaking - */ - discord_voice_client* voice_client = nullptr; - - /** - * @brief speaking user id - */ - snowflake user_id = {}; - - /** - * @brief ssrc value of speaking user - */ - uint32_t ssrc = 0; -}; - -/** - * @brief voice client disconnect event - */ -struct DPP_EXPORT voice_client_disconnect_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief voice client where user disconnected - */ - discord_voice_client* voice_client = nullptr; - - /** - * @brief user id of user who left vc - */ - snowflake user_id = {}; -}; - -/** - * @brief Discord voice platform types - */ -enum client_platform_t : uint8_t { - /** - * @brief Web, Desktop - */ - client_platform_desktop = 0, - /** - * @brief Mobile device - */ - client_platform_mobile = 1, -}; - -/** - * @brief voice client platform type notification event - */ -struct DPP_EXPORT voice_client_platform_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief voice client where user is - */ - discord_voice_client* voice_client = nullptr; - - /** - * @brief user id of user who left vc - */ - snowflake user_id = {}; - - /** - * @brief Client platform for the voice user - * Either desktop, or mobile - */ - client_platform_t platform = client_platform_desktop; -}; - -/** - * @brief Delete stage instance - */ -struct DPP_EXPORT entitlement_create_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief The created entitlement. - */ - entitlement created = {}; -}; - -/** - * @brief Delete stage instance - */ -struct DPP_EXPORT entitlement_update_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief The entitlement that was updated. - */ - entitlement updating_entitlement = {}; -}; - -/** - * @brief Delete stage instance - */ -struct DPP_EXPORT entitlement_delete_t : public event_dispatch_t { - using event_dispatch_t::event_dispatch_t; - using event_dispatch_t::operator=; - - /** - * @brief The deleted entitlement. - */ - entitlement deleted = {}; -}; - -} - diff --git a/include/dpp/dns.h b/include/dpp/dns.h deleted file mode 100644 index 067bba3..0000000 --- a/include/dpp/dns.h +++ /dev/null @@ -1,98 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include - -namespace dpp { - - /** - * @brief Represents a cached DNS result. - * Used by the ssl_connection class to store cached copies of dns lookups. - */ - struct DPP_EXPORT dns_cache_entry { - /** - * @brief Resolved address metadata - */ - addrinfo addr; - - /** - * @brief Resolved address as string. - * The metadata is needed to know what type of address it is. - * Do not do silly stuff like just looking to see if '.' is in it! - */ - std::string resolved_addr; - - /** - * @brief Time at which this cache entry is invalidated - */ - time_t expire_timestamp; - - /** - * @brief Get address length - * @return address length - */ - [[nodiscard]] int size() const; - - /** - * @brief Get the address_t that corresponds to this cache entry - * for use when connecting with ::connect() - * @param port Port number to connect to - * @return address_t prefilled with the IP and port number - */ - [[nodiscard]] const address_t get_connecting_address(uint16_t port) const; - - /** - * @brief Allocate a socket file descriptor for the given dns address - * @return File descriptor ready for calling connect(), or INVALID_SOCKET - * on failure. - */ - [[nodiscard]] socket make_connecting_socket() const; - }; - - /** - * @brief Cache container type - */ - using dns_cache_t = std::unordered_map>; - - /** - * @brief Resolve a hostname to an addrinfo - * - * @param hostname Hostname to resolve - * @param port A port number or named service, e.g. "80" - * @return dns_cache_entry* First IP address associated with the hostname DNS record - * @throw dpp::connection_exception On failure to resolve hostname - */ - DPP_EXPORT const dns_cache_entry *resolve_hostname(const std::string &hostname, const std::string &port); - } diff --git a/include/dpp/dpp.h b/include/dpp/dpp.h deleted file mode 100644 index fb10acb..0000000 --- a/include/dpp/dpp.h +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/include/dpp/dtemplate.h b/include/dpp/dtemplate.h deleted file mode 100644 index b0a2dc4..0000000 --- a/include/dpp/dtemplate.h +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Represents a guild template - */ -class DPP_EXPORT dtemplate : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - dtemplate& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build the JSON for this object - * - * @param with_id Add ID to output - * @return json JSON content - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Template code - */ - std::string code; - - /** - * @brief Template name - */ - std::string name; - - /** - * @brief Template description - */ - std::string description; - - /** - * @brief Usage counter - */ - uint32_t usage_count; - - /** - * @brief User ID of creator - */ - snowflake creator_id; - - /** - * @brief Creation date/time - * - */ - time_t created_at; - - /** - * @brief Last update date/time - */ - time_t updated_at; - - /** - * @brief Guild id the template is created from - */ - snowflake source_guild_id; - - /** - * @brief True if needs synchronising - */ - bool is_dirty; - - /** - * @brief Construct a new dtemplate object - */ - dtemplate(); - - /** - * @brief Destroy the dtemplate object - */ - virtual ~dtemplate() = default; -}; - -/** - * @brief A container of invites - */ -typedef std::unordered_map dtemplate_map; - -} diff --git a/include/dpp/emoji.h b/include/dpp/emoji.h deleted file mode 100644 index 7546ead..0000000 --- a/include/dpp/emoji.h +++ /dev/null @@ -1,252 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -#define MAX_EMOJI_SIZE 256 * 1024 - -/** - * @brief Flags for dpp::emoji - */ -enum emoji_flags : uint8_t { - /** - * @brief Emoji requires colons. - */ - e_require_colons = 0b00000001, - - /** - * @brief Managed (introduced by application) - */ - e_managed = 0b00000010, - - /** - * @brief Animated emoji. - */ - e_animated = 0b00000100, - - /** - * @brief Available (false if the guild doesn't meet boosting criteria, etc) - */ - e_available = 0b00001000, -}; - -/** - * @brief Represents an emoji for a dpp::guild - */ -class DPP_EXPORT emoji : public managed, public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Read class values from json object - * - * @param j A json object to read from - * @return A reference to self - */ - emoji& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build the json for this object - * - * @param with_id include the id in the JSON - * @return std::string json data - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Emoji name. - */ - std::string name{}; - - /** - * @brief Roles allowed to use this emoji. - */ - std::vector roles; - - /** - * @brief The id of the user that created this emoji. - */ - snowflake user_id; - - /** - * @brief Image data for the emoji, if uploading. - */ - utility::image_data image_data; - - /** - * @brief Flags for the emoji from dpp::emoji_flags. - */ - uint8_t flags{0}; - - /** - * @brief Construct a new emoji object - */ - emoji() = default; - - /** - * @brief Construct a new emoji object with name, ID and flags - * - * @param name The emoji's name - * @param id ID, if it has one (unicode does not) - * @param flags Emoji flags (emoji_flags) - */ - emoji(const std::string_view name, const snowflake id = 0, const uint8_t flags = 0); - - /** - * @brief Copy constructor, copies another emoji's data - * - * @param rhs Emoji to copy - */ - emoji(const emoji &rhs) = default; - - /** - * @brief Move constructor, moves another emoji's data to this - * - * @param rhs Emoji to move from - */ - emoji(emoji &&rhs) noexcept = default; - - /** - * @brief Destroy the emoji object - */ - ~emoji() override = default; - - /** - * @brief Copy assignment operator, copies another emoji's data - * - * @param rhs Emoji to copy - */ - emoji &operator=(const emoji &rhs) = default; - - /** - * @brief Move constructor, moves another emoji's data to this - * - * @param rhs Emoji to move from - */ - emoji &operator=(emoji &&rhs) noexcept = default; - - /** - * @brief Create a mentionable emoji - * @param name The name of the emoji. - * @param id The ID of the emoji. - * @param is_animated is emoji animated. - * @return std::string The formatted mention of the emoji. - */ - static std::string get_mention(std::string_view name, snowflake id, bool is_animated = false); - - /** - * @brief Emoji requires colons - * - * @return true Requires colons - * @return false Does not require colons - */ - bool requires_colons() const; - - /** - * @brief Emoji is managed - * - * @return true Is managed - * @return false Is not managed - */ - bool is_managed() const; - - /** - * @brief Emoji is animated - * - * @return true Is animated - * @return false Is noy animated - */ - bool is_animated() const; - - /** - * @brief Is available - * - * @return true Is available - * @return false Is unavailable - */ - bool is_available() const; - - /** - * @brief Load an image into the object - * - * @param image_blob Image binary data - * @param type Type of image. It can be one of `i_gif`, `i_jpg` or `i_png`. - * @return emoji& Reference to self - * @throw dpp::length_exception Image content exceeds discord maximum of 256 kilobytes - */ - emoji& load_image(std::string_view image_blob, const image_type type); - - /** - * @brief Load an image into the object - * - * @param data Image binary data - * @param size Size of the image. - * @param type Type of image. It can be one of `i_gif`, `i_jpg` or `i_png`. - * @return emoji& Reference to self - * @throw dpp::length_exception Image content exceeds discord maximum of 256 kilobytes - */ - emoji& load_image(const std::byte* data, uint32_t size, const image_type type); - - /** - * @brief Format to name if unicode, name:id if has id or a:name:id if animated - * - * @return Formatted name for reactions - */ - std::string format() const; - - /** - * @brief Get the mention/ping for the emoji - * - * @return std::string mention - */ - std::string get_mention() const; - - /** - * @brief Get the custom emoji url - * - * @param size The size of the emoji in pixels. It can be any power of two between 16 and 4096, - * otherwise the default sized emoji is returned. - * @param format The format to use for the emoji. It can be one of `i_webp`, `i_jpg`, `i_png` or `i_gif`. - * When passing `i_gif`, it returns an empty string for non-animated emojis. Consider using the `prefer_animated` parameter instead. - * @param prefer_animated Whether you prefer gif format. - * If true, it'll return gif format whenever the emoji is available as animated. - * @return std::string emoji url or an empty string, if the id is not set - */ - std::string get_url(uint16_t size = 0, const image_type format = i_png, bool prefer_animated = true) const; -}; - -/** - * @brief Group of emojis - */ -typedef std::unordered_map emoji_map; - -} diff --git a/include/dpp/entitlement.h b/include/dpp/entitlement.h deleted file mode 100644 index fd181d6..0000000 --- a/include/dpp/entitlement.h +++ /dev/null @@ -1,246 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief The type of entitlement. - * */ -enum entitlement_type : uint8_t { - /** - * @brief Entitlement was purchased by user - */ - PURCHASE = 1, - - /** - * @brief Entitlement for Discord Nitro subscription - */ - PREMIUM_SUBSCRIPTION = 2, - - /** - * @brief Entitlement was gifted by developer - */ - DEVELOPER_GIFT = 3, - - /** - * @brief Entitlement was purchased by a dev in application test mode - */ - TEST_MODE_PURCHASE = 4, - - /** - * @brief Entitlement was granted when the SKU was free - */ - FREE_PURCHASE = 5, - - /** - * @brief Entitlement was gifted by another user - */ - USER_GIFT = 6, - - /** - * @brief Entitlement was claimed by user for free as a Nitro Subscriber - */ - PREMIUM_PURCHASE = 7, - - /** - * @brief Entitlement was purchased as an app subscription - */ - APPLICATION_SUBSCRIPTION = 8, -}; - -/** - * @brief Entitlement flags. - */ -enum entitlement_flags : uint8_t { - /** - * @brief Entitlement was deleted - * - * @note Only discord staff can delete an entitlement via - * their internal tooling. It should rarely happen except in cases - * of fraud or chargeback. - */ - ent_deleted = 0b0000001, - - /** - * @brief Entitlement was consumed. - * - * @note A consumed entitlement is a used-up one-off purchase. - */ - ent_consumed = 0b0000010, -}; - -/** - * @brief A definition of a discord entitlement. - * - * An entitlement is a user's connection to an SKU, basically a subscription - * or a one-off purchase. - */ -class DPP_EXPORT entitlement : public managed, public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - entitlement& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build json for this entitlement object - * - * @param with_id include the ID in the json - * @return json JSON object - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief ID of the entitlement event - * - * Not sure if this remains constant, it does not relate to the SKU, - * user, guild or subscription. Do not use it for anything except state - * tracking. - */ - snowflake sku_id{0}; - - /** - * @brief ID of the parent application - */ - snowflake application_id{0}; - - /** - * @brief Subscription ID - * - * This is a unique identifier of the user or guilds subscription to the SKU. - * It won't ever change. - */ - snowflake subscription_id{0}; - - /** - * @brief Promotion id - * - * These are undocumented but given in examples in the docs. - */ - snowflake promotion_id{0}; - - /** - * @brief Gift Code Flags (undocumented) - * - * Undocumented, but given in examples in the docs. - */ - uint8_t gift_code_flags{0}; - - /** - * @brief Optional: ID of the user that is granted access to the entitlement's SKU - */ - snowflake user_id{0}; - - /** - * @brief Optional: ID of the user that is granted access to the entitlement's SKU - * - * If a guild is provided, according to the examples the user who triggered the - * purchase will also be passed in the user ID. The presence of a non-zero guild - * id snowflake is indication it is a guild subscription. - */ - snowflake guild_id{0}; - - /** - * @brief The type of entitlement. - */ - entitlement_type type = entitlement_type::APPLICATION_SUBSCRIPTION; - - /** - * @brief Optional: Start date at which the entitlement is valid. - * - * @note Not present when using test entitlements. - */ - time_t starts_at{0}; - - /** - * @brief Optional: Date at which the entitlement is no longer valid. - * - * @note Not present when using test entitlements. - */ - time_t ends_at{0}; - - /** - * @brief Flags bitmap from dpp::entitlement_flags - */ - uint16_t flags{0}; - - /** - * @brief Construct a new entitlement object - */ - entitlement() = default; - - /** - * @brief Construct a new entitlement object with sku_id, ID, application_id, type, and flags. - * - * @param sku_id The ID of the SKU. - * @param id The ID of the entitlement. - * @param application_id The ID of the parent application. - * @param type The type of entitlement (Should only ever be APPLICATION_SUBSCRIPTION unless you going to use this object as a parameter for dpp::cluster::entitlement_test_create). - * @param flags The flags for the SKU from dpp::entitlement_flags. - */ - entitlement(const snowflake sku_id, const snowflake id = 0, const snowflake application_id = 0, const entitlement_type type = dpp::entitlement_type::APPLICATION_SUBSCRIPTION, const uint8_t flags = 0); - - /** - * @brief Get the type of entitlement. - * - * @return entitlement_type Entitlement type - */ - [[nodiscard]] entitlement_type get_type() const; - - /** - * @brief Was the entitlement consumed? - * - * A consumed entitlement is a one off purchase which - * has been claimed as used by the application. for example - * in-app purchases. - * - * @return true if the entitlement was consumed. - */ - [[nodiscard]] bool is_consumed() const; - - /** - * @brief Was the entitlement deleted? - * - * @return true if the entitlement was deleted. - */ - [[nodiscard]] bool is_deleted() const; - -}; - -/** - * @brief Group of entitlements. - */ -typedef std::unordered_map entitlement_map; - -} diff --git a/include/dpp/etf.h b/include/dpp/etf.h deleted file mode 100644 index f4e9f1d..0000000 --- a/include/dpp/etf.h +++ /dev/null @@ -1,711 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Parts of this file inspired by, or outright copied from erlpack: - * https://github.com/discord/erlpack/ - * - * Acknowledgements: - * - * sysdep.h: - * Based on work by FURUHASHI Sadayuki in msgpack-python - * (https://github.com/msgpack/msgpack-python) - * - * Copyright (C) 2008-2010 FURUHASHI Sadayuki - * Licensed under the Apache License, Version 2.0 (the "License"). - * - ************************************************************************************/ - -#pragma once -#include -#include -#include - -namespace dpp { - -/** - * @brief Current ETF format version in use - */ -const uint8_t FORMAT_VERSION = 131; - -/** - * @brief Represents a token which identifies the type of value which follows it - * in the ETF binary structure. - */ -enum etf_token_type : uint8_t { - /** - * @brief 68 [Distribution header] - */ - ett_distribution = 'D', - - /** - * @brief 70 [Float64:IEEE float] - */ - ett_new_float = 'F', - - /** - * @brief 77 [UInt32:Len, UInt8:Bits, Len:Data] - */ - ett_bit_binary = 'M', - - /** - * @brief 80 [UInt4:UncompressedSize, N:ZlibCompressedData] - */ - ett_compressed = 'P', - - /** - * @brief 97 [UInt8:Int] - */ - ett_smallint = 'a', - - /** - * @brief 98 [Int32:Int] - */ - ett_integer = 'b', - - /** - * @brief 99 [31:Float String] Float in string format (formatted "%.20e", sscanf "%lf"). - * - * @note Superseded by ett_new_float. - */ - ett_float = 'c', - - /** - * @brief 100 [UInt16:Len, Len:AtomName] max Len is 255 - */ - ett_atom = 'd', - - /** - * @brief 101 [atom:Node, UInt32:ID, UInt8:Creation] - */ - ett_reference = 'e', - - /** - * @brief 102 [atom:Node, UInt32:ID, UInt8:Creation] - */ - ett_port = 'f', - - /** - * @brief 103 [atom:Node, UInt32:ID, UInt32:Serial, UInt8:Creation] - */ - ett_pid = 'g', - - /** - * @brief 104 [UInt8:Arity, N:Elements] - */ - ett_small_tuple = 'h', - - /** - * @brief 105 [UInt32:Arity, N:Elements] - */ - ett_large_tuple = 'i', - - /** - * @brief 106 empty list - */ - ett_nil = 'j', - - /** - * @brief 107 [UInt16:Len, Len:Characters] - */ - ett_string = 'k', - - /** - * @brief 108 [UInt32:Len, Elements, Tail] - */ - ett_list = 'l', - - /** - * @brief 109 [UInt32:Len, Len:Data] - */ - ett_binary = 'm', - - /** - * @brief 110 [UInt8:n, UInt8:Sign, n:nums] - */ - ett_bigint_small = 'n', - - /** - * @brief 111 [UInt32:n, UInt8:Sign, n:nums] - */ - ett_bigint_large = 'o', - - /** - * @brief 112 [UInt32:Size, UInt8:Arity, 16*Uint6-MD5:Uniq, UInt32:Index, UInt32:NumFree, atom:Module, int:OldIndex, int:OldUniq, pid:Pid, NunFree*ext:FreeVars] - */ - ett_new_function = 'p', - - /** - * @brief 113 [atom:Module, atom:Function, smallint:Arity] - */ - ett_export = 'q', - - /** - * @brief 114 [UInt16:Len, atom:Node, UInt8:Creation, Len*UInt32:ID] - */ - ett_new_reference = 'r', - - /** - * @brief 115 [UInt8:Len, Len:AtomName] - */ - ett_atom_small = 's', - - /** - * @brief 116 [UInt32:Airty, N:Pairs] - */ - ett_map = 't', - - /** - * @brief 117 [UInt4:NumFree, pid:Pid, atom:Module, int:Index, int:Uniq, NumFree*ext:FreeVars] - */ - ett_function = 'u', - - /** - * @brief 118 [UInt16:Len, Len:AtomName] max Len is 255 characters (up to 4 bytes per) - */ - ett_atom_utf8 = 'v', - - /** - * @brief 119 [UInt8:Len, Len:AtomName] - */ - ett_atom_utf8_small = 'w' -}; - -/** - * @brief Represents a buffer of bytes being encoded into ETF - */ -struct DPP_EXPORT etf_buffer { - /** - * @brief Raw buffer - */ - std::vector buf; - - /** - * @brief Current used length of buffer - * (this is different from buf.size() as it is pre-allocated - * using resize and may not all be in use) - */ - size_t length; - - /** - * @brief Construct a new etf buffer object - * - * @param initial initial buffer size to allocate - */ - etf_buffer(size_t initial); - - /** - * @brief Destroy the etf buffer object - */ - ~etf_buffer(); -}; - -/** - * @brief The etf_parser class can serialise and deserialise ETF (Erlang Term Format) - * into and out of an nlohmann::json object, so that layers above the websocket don't - * have to be any different for handling ETF. - */ -class DPP_EXPORT etf_parser { - /** - * @brief Current size of binary data - */ - size_t size; - - /** - * @brief Current offset into binary data - */ - size_t offset; - - /** - * @brief Pointer to binary ETF data to be decoded - */ - uint8_t* data; - - /** - * @brief Parse a single value, and if that value contains other - * values (e.g. an array or map) then call itself recursively. - * - * @return nlohmann::json JSON value from the ETF - */ - nlohmann::json inner_parse(); - - /** - * @brief Read 8 bits of data from the buffer - * - * @return uint8_t data retrieved - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - uint8_t read_8_bits(); - - /** - * @brief Read 16 bits of data from the buffer - * - * @return uint16_t data retrieved - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - uint16_t read_16_bits(); - - /** - * @brief Read 32 bits of data from the buffer - * - * @return uint32_t data retrieved - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - uint32_t read_32_bits(); - - /** - * @brief Read 64 bits of data from the buffer - * - * @return uint64_t data retrieved - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - uint64_t read_64_bits(); - - /** - * @brief Read string data from the buffer - * - * @param length Length of string to retrieve - * @return const char* data retrieved - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - const char* read_string(uint32_t length); - - /** - * @brief Process an 'atom' value. - * An atom is a "label" or constant value within the data, - * such as a key name, nullptr, or false. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json process_atom(const char* atom, uint16_t length); - - /** - * @brief Decode an 'atom' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_atom(); - - /** - * @brief Decode a small 'atom' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_small_atom(); - - /** - * @brief Decode a small integer value (0-255). - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_small_integer(); - - /** - * @brief Decode an integer value (-MAXINT -> MAXINT-1). - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_integer(); - - /** - * @brief Decode an array of values. - * - * @return nlohmann::json values converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_array(uint32_t length); - - /** - * @brief Decode a list of values. - * - * @return nlohmann::json values converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_list(); - - /** - * @brief Decode a 'tuple' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_tuple(uint32_t length); - - /** - * @brief Decode a nil 'atom' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_nil(); - - /** - * @brief Decode a map (object) value. - * Will recurse to evaluate each member variable. - * - * @return nlohmann::json values converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_map(); - - /** - * @brief Decode a floating point numeric value. - * (depreciated in erlang but still expected to be supported) - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_float(); - - /** - * @brief Decode a floating type numeric value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_new_float(); - - /** - * @brief Decode a 'bigint' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_bigint(uint32_t digits); - - /** - * @brief Decode a small 'bigint' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_bigint_small(); - - /** - * @brief Decode a large 'bigint' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_bigint_large(); - - /** - * @brief Decode a binary value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_binary(); - - /** - * @brief Decode a string value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_string(); - - /** - * @brief Decode a string list value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_string_as_list(); - - /** - * @brief Decode a 'small tuple' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_tuple_small(); - - /** - * @brief Decode a 'large tuple' value. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_tuple_large(); - - /** - * @brief Decode a compressed value. - * This is a zlib-compressed binary blob which contains another - * ETF object. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_compressed(); - - /** - * @brief Decode a 'reference' value. - * Erlang expects this to be supported, in practice Discord doesn't send these right now. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_reference(); - - /** - * @brief Decode a 'new reference' value. - * Erlang expects this to be supported, in practice Discord doesn't send these right now. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_new_reference(); - - /** - * @brief Decode a 'port' value. - * Erlang expects this to be supported, in practice Discord doesn't send these right now. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_port(); - - /** - * @brief Decode a 'PID' value. - * Erlang expects this to be supported, in practice Discord doesn't send these right now. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_pid(); - - /** - * @brief Decode an 'export' value. - * Erlang expects this to be supported, in practice Discord doesn't send these right now. - * - * @return nlohmann::json value converted to JSON - * @throw dpp::exception Data stream isn't long enough to fetch requested bits - */ - nlohmann::json decode_export(); - - /** - * @brief Write to output buffer for creation of ETF from JSON - * - * @param pk buffer struct - * @param bytes byte buffer to write - * @param l number of bytes to write - * @throw std::exception Buffer cannot be extended - */ - void buffer_write(etf_buffer *pk, const char *bytes, size_t l); - - /** - * @brief Append version number to ETF buffer - * - * @param b buffer to append to - * @throw std::exception Buffer cannot be extended - */ - void append_version(etf_buffer *b); - - /** - * @brief Append nil value to ETF buffer - * - * @param b buffer to append to - * @throw std::exception Buffer cannot be extended - */ - void append_nil(etf_buffer *b); - - /** - * @brief Append false value to ETF buffer - * - * @param b buffer to append to - * @throw std::exception Buffer cannot be extended - */ - void append_false(etf_buffer *b); - - /** - * @brief Append true value to ETF buffer - * - * @param b buffer to append to - * @throw std::exception Buffer cannot be extended - */ - void append_true(etf_buffer *b); - - /** - * @brief Append small integer value to ETF buffer - * - * @param b buffer to append to - * @param d double to append - * @throw std::exception Buffer cannot be extended - */ - void append_small_integer(etf_buffer *b, unsigned char d); - - /** - * @brief Append integer value to ETF buffer - * - * @param b buffer to append to - * @param d integer to append - * @throw std::exception Buffer cannot be extended - */ - void append_integer(etf_buffer *b, int32_t d); - - /** - * @brief Append 64 bit integer value to ETF buffer - * - * @param b buffer to append to - * @param d integer to append - * @throw std::exception Buffer cannot be extended - */ - void append_unsigned_long_long(etf_buffer *b, unsigned long long d); - - /** - * @brief Append 64 bit integer value to ETF buffer - * - * @param b buffer to append to - * @param d integer to append - * @throw std::exception Buffer cannot be extended - */ - void append_long_long(etf_buffer *b, long long d); - - /** - * @brief Append double value to ETF buffer - * - * @param b buffer to append to - * @param f double to append - * @throw std::exception Buffer cannot be extended - */ - void append_double(etf_buffer *b, double f); - - /** - * @brief Append atom value to ETF buffer - * - * @param b buffer to append to - * @param bytes pointer to string to append - * @param size size of string to append - * @throw std::exception Buffer cannot be extended - */ - void append_atom(etf_buffer *b, const char *bytes, size_t size); - - /** - * @brief Append utf8 atom value to ETF buffer - * - * @param b buffer to append to - * @param bytes pointer to string to append - * @param size size of string to append - * @throw std::exception Buffer cannot be extended - */ - void append_atom_utf8(etf_buffer *b, const char *bytes, size_t size); - - /** - * @brief Append binary value to ETF buffer - * - * @param b buffer to append to - * @param bytes pointer to string to append - * @param size size of string to append - * @throw std::exception Buffer cannot be extended - */ - void append_binary(etf_buffer *b, const char *bytes, size_t size); - - /** - * @brief Append string value to ETF buffer - * - * @param b buffer to append to - * @param bytes pointer to string to append - * @param size size of string to append - * @throw std::exception Buffer cannot be extended - */ - void append_string(etf_buffer *b, const char *bytes, size_t size); - - /** - * @brief Append tuple value to ETF buffer - * - * @param b buffer to append to - * @param size size of value to append - * @throw std::exception Buffer cannot be extended - */ - void append_tuple_header(etf_buffer *b, size_t size); - - /** - * @brief Append list terminator to ETF buffer - * - * @param b buffer to append to - * @throw std::exception Buffer cannot be extended - */ - void append_nil_ext(etf_buffer *b); - - /** - * @brief Append a list header value to ETF buffer - * - * @param b buffer to append to - * @param size size of values to append - * @throw std::exception Buffer cannot be extended - */ - void append_list_header(etf_buffer *b, size_t size); - - /** - * @brief Append a map header value to ETF buffer - * - * @param b buffer to append to - * @param size size of values to append - * @throw std::exception Buffer cannot be extended - */ - void append_map_header(etf_buffer *b, size_t size); - - /** - * @brief Build ETF buffer - * - * @param j JSON object to build from - * @param b Buffer to append to - * @throw std::exception Buffer cannot be extended - */ - void inner_build(const nlohmann::json* j, etf_buffer* b); - -public: - /** - * @brief Construct a new etf parser object - */ - etf_parser(); - - /** - * @brief Destroy the etf parser object - */ - ~etf_parser(); - - /** - * @brief Convert ETF binary content to nlohmann::json - * - * @param in Raw binary ETF data (generally from a websocket) - * @return nlohmann::json JSON data for use in the library - * @throw dpp::exception Malformed or otherwise invalid ETF content - */ - nlohmann::json parse(const std::string& in); - - /** - * @brief Create ETF binary data from nlohmann::json - * - * @param j JSON value to encode to ETF - * @return std::string raw ETF data. Note that this can - * and probably will contain null values, use std::string::data() - * and std::string::size() to manipulate or send it. - * @throw std::exception Not enough memory, or invalid data types/values - */ - std::string build(const nlohmann::json& j); -}; - -} diff --git a/include/dpp/event.h b/include/dpp/event.h deleted file mode 100644 index 1e34e1b..0000000 --- a/include/dpp/event.h +++ /dev/null @@ -1,159 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include - -#define event_decl(x,wstype) /** @brief Internal event handler for wstype websocket events. Called for each websocket message of this type. @internal */ \ - class x : public event { public: virtual void handle(class dpp::discord_client* client, nlohmann::json &j, const std::string &raw); }; - -/** - * @brief The events namespace holds the internal event handlers for each websocket event. - * These are handled internally and also dispatched to the user code if the event is hooked. - */ -namespace dpp::events { - -/** - * @brief An event object represents an event handled internally, passed from the websocket e.g. MESSAGE_CREATE. - */ -class DPP_EXPORT event { -public: - /** - * @brief Pure virtual method for event handler code - * @param client The creating shard - * @param j The json data of the event - * @param raw The raw event json - */ - virtual void handle(class discord_client* client, nlohmann::json &j, const std::string &raw) = 0; -}; - -/* Internal logger */ -event_decl(logger,LOG); - -/* Guilds */ -event_decl(guild_create,GUILD_CREATE); -event_decl(guild_update,GUILD_UPDATE); -event_decl(guild_delete,GUILD_DELETE); -event_decl(guild_ban_add,GUILD_BAN_ADD); -event_decl(guild_ban_remove,GUILD_BAN_REMOVE); -event_decl(guild_emojis_update,GUILD_EMOJIS_UPDATE); -event_decl(guild_integrations_update,GUILD_INTEGRATIONS_UPDATE); -event_decl(guild_join_request_delete,GUILD_JOIN_REQUEST_DELETE); -event_decl(guild_stickers_update,GUILD_STICKERS_UPDATE); - -/* Stage channels */ -event_decl(stage_instance_create,STAGE_INSTANCE_CREATE); -event_decl(stage_instance_update,STAGE_INSTANCE_UPDATE); -event_decl(stage_instance_delete,STAGE_INSTANCE_DELETE); - -/* Guild members */ -event_decl(guild_member_add,GUILD_MEMBER_ADD); -event_decl(guild_member_remove,GUILD_MEMBER_REMOVE); -event_decl(guild_members_chunk,GUILD_MEMBERS_CHUNK); -event_decl(guild_member_update,GUILD_MEMBERS_UPDATE); - -/* Guild roles */ -event_decl(guild_role_create,GUILD_ROLE_CREATE); -event_decl(guild_role_update,GUILD_ROLE_UPDATE); -event_decl(guild_role_delete,GUILD_ROLE_DELETE); - -/* Session state */ -event_decl(resumed,RESUMED); -event_decl(ready,READY); - -/* Channels */ -event_decl(channel_create,CHANNEL_CREATE); -event_decl(channel_update,CHANNEL_UPDATE); -event_decl(channel_delete,CHANNEL_DELETE); -event_decl(channel_pins_update,CHANNEL_PINS_UPDATE); - -/* Threads */ -event_decl(thread_create,THREAD_CREATE); -event_decl(thread_update,THREAD_UPDATE); -event_decl(thread_delete,THREAD_DELETE); -event_decl(thread_list_sync,THREAD_LIST_SYNC); -event_decl(thread_member_update,THREAD_MEMBER_UPDATE); -event_decl(thread_members_update,THREAD_MEMBERS_UPDATE); - -/* Messages */ -event_decl(message_create,MESSAGE_CREATE); -event_decl(message_update,MESSAGE_UPDATE); -event_decl(message_delete,MESSAGE_DELETE); -event_decl(message_delete_bulk,MESSAGE_DELETE_BULK); -event_decl(message_poll_vote_add,MESSAGE_POLL_VOTE_ADD); -event_decl(message_poll_vote_remove,MESSAGE_POLL_VOTE_REMOVE); - -/* Presence/typing */ -event_decl(presence_update,PRESENCE_UPDATE); -event_decl(typing_start,TYPING_START); - -/* Users (outside of guild) */ -event_decl(user_update,USER_UPDATE); - -/* Message reactions */ -event_decl(message_reaction_add,MESSAGE_REACTION_ADD); -event_decl(message_reaction_remove,MESSAGE_REACTION_REMOVE); -event_decl(message_reaction_remove_all,MESSAGE_REACTION_REMOVE_ALL); -event_decl(message_reaction_remove_emoji,MESSAGE_REACTION_REMOVE_EMOJI); - -/* Invites */ -event_decl(invite_create,INVITE_CREATE); -event_decl(invite_delete,INVITE_DELETE); - -/* Voice */ -event_decl(voice_state_update,VOICE_STATE_UPDATE); -event_decl(voice_server_update,VOICE_SERVER_UPDATE); - -/* Webhooks */ -event_decl(webhooks_update,WEBHOOKS_UPDATE); - -/* Application commands */ -event_decl(interaction_create,INTERACTION_CREATE); - -/* Integrations */ -event_decl(integration_create,INTEGRATION_CREATE); -event_decl(integration_update,INTEGRATION_UPDATE); -event_decl(integration_delete,INTEGRATION_DELETE); - -/* Scheduled events */ -event_decl(guild_scheduled_event_create,GUILD_SCHEDULED_EVENT_CREATE); -event_decl(guild_scheduled_event_update,GUILD_SCHEDULED_EVENT_UPDATE); -event_decl(guild_scheduled_event_delete,GUILD_SCHEDULED_EVENT_DELETE); -event_decl(guild_scheduled_event_user_add,GUILD_SCHEDULED_EVENT_USER_ADD); -event_decl(guild_scheduled_event_user_remove,GUILD_SCHEDULED_EVENT_USER_REMOVE); - -/* Auto moderation */ -event_decl(automod_rule_create, AUTO_MODERATION_RULE_CREATE); -event_decl(automod_rule_update, AUTO_MODERATION_RULE_UPDATE); -event_decl(automod_rule_delete, AUTO_MODERATION_RULE_DELETE); -event_decl(automod_rule_execute, AUTO_MODERATION_ACTION_EXECUTION); - -/* Audit log */ -event_decl(guild_audit_log_entry_create, GUILD_AUDIT_LOG_ENTRY_CREATE); - -/* Entitlements */ -event_decl(entitlement_create, ENTITLEMENT_CREATE); -event_decl(entitlement_update, ENTITLEMENT_UPDATE); -event_decl(entitlement_delete, ENTITLEMENT_DELETE); - -} diff --git a/include/dpp/event_router.h b/include/dpp/event_router.h deleted file mode 100644 index 656badf..0000000 --- a/include/dpp/event_router.h +++ /dev/null @@ -1,744 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -#ifndef DPP_NO_CORO - -template -class event_router_t; - -namespace detail { - -/** @brief Internal cogwheels for dpp::event_router_t */ -namespace event_router { - -/** @brief State of an owner of an event_router::awaitable */ -enum class awaiter_state { - /** @brief Awaitable is not being awaited */ - none, - /** @brief Awaitable is being awaited */ - waiting, - /** @brief Awaitable will be resumed imminently */ - resuming, - /** @brief Awaitable will be cancelled imminently */ - cancelling -}; - -/** - * @brief Awaitable object representing an event. - * A user can co_await on this object to resume the next time the event is fired, - * optionally with a condition. - */ -template -class awaitable { - friend class event_router_t; - - /** @brief Resume the coroutine waiting on this object */ - void resume() { - std_coroutine::coroutine_handle<>::from_address(handle).resume(); - } - - /** @brief Event router that will manage this object */ - event_router_t *self; - - /** @brief Predicate on the event, or nullptr for always match */ - std::function predicate = nullptr; - - /** @brief Event that triggered a resumption, to give to the resumer */ - const T *event = nullptr; - - /** @brief Coroutine handle, type-erased */ - void* handle = nullptr; - - /** @brief The state of the awaiting coroutine */ - std::atomic state = awaiter_state::none; - - /** Default constructor is accessible only to event_router_t */ - awaitable() = default; - - /** Normal constructor is accessible only to event_router_t */ - template - awaitable(event_router_t *router, F&& fun) : self{router}, predicate{std::forward(fun)} {} - -public: - /** This object is not copyable. */ - awaitable(const awaitable &) = delete; - - /** Move constructor. */ - awaitable(awaitable &&rhs) noexcept : self{rhs.self}, predicate{std::move(rhs.predicate)}, event{rhs.event}, handle{std::exchange(rhs.handle, nullptr)}, state{rhs.state.load(std::memory_order_relaxed)} {} - - /** This object is not copyable. */ - awaitable& operator=(const awaitable &) = delete; - - /** Move assignment operator. */ - awaitable& operator=(awaitable&& rhs) noexcept { - self = rhs.self; - predicate = std::move(rhs.predicate); - event = rhs.event; - handle = std::exchange(rhs.handle, nullptr); - state = rhs.state.load(std::memory_order_relaxed); - return *this; - } - - /** - * @brief Request cancellation. This will detach this object from the event router and resume the awaiter, which will be thrown dpp::task_cancelled::exception. - * - * @throw ??? As this resumes the coroutine, it may throw any exceptions at the caller. - */ - void cancel(); - - /** - * @brief First function called by the standard library when awaiting this object. Returns true if we need to suspend. - * - * @retval false always. - */ - [[nodiscard]] constexpr bool await_ready() const noexcept; - - /** - * @brief Second function called by the standard library when awaiting this object, after suspension. - * This will attach the object to its event router, to be resumed on the next event that satisfies the predicate. - * - * @return void never resume on call. - */ - void await_suspend(detail::std_coroutine::coroutine_handle<> caller); - - /** - * @brief Third and final function called by the standard library, called when resuming the coroutine. - * - * @throw @ref task_cancelled_exception if cancel() has been called - * @return const T& __Reference__ to the event that matched - */ - [[maybe_unused]] const T& await_resume(); -}; - -} - -} -#endif - -/** - * @brief A returned event handle for an event which was attached - */ -typedef size_t event_handle; - -/** - * @brief Handles routing of an event to multiple listeners. - * Multiple listeners may attach to the event_router_t by means of @ref operator()(F&&) "operator()". Passing a - * lambda into @ref operator()(F&&) "operator()" attaches to the event. - * - * @details Dispatchers of the event may call the @ref call() method to cause all listeners - * to receive the event. - * - * The @ref empty() method will return true if there are no listeners attached - * to the event_router_t (this can be used to save time by not constructing objects that - * nobody will ever see). - * - * The @ref detach() method removes an existing listener from the event, - * using the event_handle ID returned by @ref operator()(F&&) "operator()". - * - * This class is used by the library to route all websocket events to listening code. - * - * Example: - * - * @code{cpp} - * // Declare an event that takes log_t as its parameter - * event_router_t my_event; - * - * // Attach a listener to the event - * event_handle id = my_event([&](const log_t& cc) { - * std::cout << cc.message << "\n"; - * }); - * - * // Construct a log_t and call the event (listeners will receive the log_t object) - * log_t lt; - * lt.message = "foo"; - * my_event.call(lt); - * - * // Detach from an event using the handle returned by operator() - * my_event.detach(id); - * @endcode - * - * @tparam T type of single parameter passed to event lambda derived from event_dispatch_t - */ -template class event_router_t { -private: - friend class cluster; - - /** - * @brief Non-coro event handler type - */ - using regular_handler_t = std::function; - - /** - * @brief Type that event handlers will be stored as with DPP_CORO off. - * This is the ABI DPP_CORO has to match. - */ - using event_handler_abi_t = std::variant>; - -#ifndef DPP_NO_CORO - friend class detail::event_router::awaitable; - - /** @brief dpp::task coro event handler */ - using task_handler_t = std::function(const T&)>; - - /** @brief Type that event handlers are stored as */ - using event_handler_t = std::variant; - - DPP_CHECK_ABI_COMPAT(event_handler_t, event_handler_abi_t) -#else - /** - * @brief Type that event handlers are stored as - */ - using event_handler_t = event_handler_abi_t; -#endif - - /** - * @brief Identifier for the next event handler, will be given to the user on attaching a handler - */ - event_handle next_handle = 1; - - /** - * @brief Thread safety mutex - */ - mutable std::shared_mutex mutex; - - /** - * @brief Container of event listeners keyed by handle, - * as handles are handed out sequentially they will always - * be called in they order they are bound to the event - * as std::map is an ordered container. - */ - std::map dispatch_container; - -#ifndef DPP_NO_CORO - /** - * @brief Mutex for messing with coro_awaiters. - */ - mutable std::shared_mutex coro_mutex; - - /** - * @brief Vector containing the awaitables currently being awaited on for this event router. - */ - mutable std::vector *> coro_awaiters; -#else - /** - * @brief Dummy for ABI compatibility between DPP_CORO and not - */ - utility::dummy definitely_not_a_mutex; - - /** - * @brief Dummy for ABI compatibility between DPP_CORO and not - */ - utility::dummy> definitely_not_a_vector; -#endif - - /** - * @brief A function to be called whenever the method is called, to check - * some condition that is required for this event to trigger correctly. - */ - std::function warning; - - /** - * @brief Next handle to be given out by the event router - */ - -protected: - - /** - * @brief Set the warning callback object used to check that this - * event is capable of running properly - * - * @param warning_function A checking function to call - */ - void set_warning_callback(std::function warning_function) { - warning = warning_function; - } - - /** - * @brief Handle an event. This function should only be used without coro enabled, otherwise use handle_coro. - */ - void handle(const T& event) const { - if (warning) { - warning(event); - } - - std::shared_lock l(mutex); - for (const auto& [_, listener] : dispatch_container) { - if (!event.is_cancelled()) { - if (std::holds_alternative(listener)) { - std::get(listener)(event); - } else { - throw dpp::logic_exception("cannot handle a coroutine event handler with a library built without DPP_CORO"); - } - } - }; - } - -#ifndef DPP_NO_CORO - /** - * @brief Handle an event as a coroutine, ensuring the lifetime of the event object. - */ - dpp::job handle_coro(T event) const { - if (warning) { - warning(event); - } - - resume_awaiters(event); - - std::vector> tasks; - { - std::shared_lock l(mutex); - - for (const auto& [_, listener] : dispatch_container) { - if (!event.is_cancelled()) { - if (std::holds_alternative(listener)) { - tasks.push_back(std::get(listener)(event)); - } else if (std::holds_alternative(listener)) { - std::get(listener)(event); - } - } - }; - } - - for (dpp::task& t : tasks) { - co_await t; // keep the event object alive until all tasks finished - } - } - - /** - * @brief Attach a suspended coroutine to this event router via detail::event_router::awaitable. - * It will be resumed and detached when an event satisfying its condition completes, or it is cancelled. - * - * This is for internal usage only, the user way to do this is to co_await it (which will call this when suspending) - * This guarantees that the coroutine is indeed suspended and thus can be resumed at any time - * - * @param awaiter Awaiter to attach - */ - void attach_awaiter(detail::event_router::awaitable *awaiter) { - std::unique_lock lock{coro_mutex}; - - coro_awaiters.emplace_back(awaiter); - } - - /** - * @brief Detach an awaiting coroutine handle from this event router. - * This is mostly called when a detail::event_router::awaitable is cancelled. - * - * @param handle Coroutine handle to find in the attached coroutines - */ - void detach_coro(void *handle) { - std::unique_lock lock{coro_mutex}; - - coro_awaiters.erase(std::remove_if(coro_awaiters.begin(), coro_awaiters.end(), [handle](detail::event_router::awaitable const *awaiter) { return awaiter->handle == handle; }), coro_awaiters.end()); - } - - /** - * @brief Resume any awaiter whose predicate matches this event, or is null. - * - * @param event Event to compare and pass to accepting awaiters - */ - void resume_awaiters(const T& event) const { - std::vector*> to_resume; - std::unique_lock lock{coro_mutex}; - - for (auto it = coro_awaiters.begin(); it != coro_awaiters.end();) { - detail::event_router::awaitable* awaiter = *it; - - if (awaiter->predicate && !awaiter->predicate(event)) { - ++it; - } else { - using state_t = detail::event_router::awaiter_state; - - /** - * If state == none (was never awaited), do nothing - * If state == waiting, prevent resumption, resume on our end - * If state == resuming || cancelling, ignore - * - * Technically only cancelling || waiting should be possible here - * We do this by trying to exchange "waiting" with "resuming". If that returns false, this is presumed to be "cancelling" - */ - - state_t s = state_t::waiting; - if (awaiter->state.compare_exchange_strong(s, state_t::resuming)) { - to_resume.emplace_back(awaiter); - awaiter->event = &event; - - it = coro_awaiters.erase(it); - } else { - ++it; - } - } - } - lock.unlock(); - for (detail::event_router::awaitable* awaiter : to_resume) - awaiter->resume(); - } -#endif - -public: - /** - * @brief Construct a new event_router_t object. - */ - event_router_t() = default; - - /** - * @brief Destructor. Will cancel any coroutine awaiting on events. - * - * @throw ! Cancelling a coroutine will throw a dpp::task_cancelled_exception to it. - * This will be caught in this destructor, however, make sure no other exceptions are thrown in the coroutine after that or it will terminate. - */ - ~event_router_t() { -#ifndef DPP_NO_CORO - while (!coro_awaiters.empty()) { - // cancel all awaiters. here we cannot do the usual loop as we'd need to lock coro_mutex, and cancel() locks and modifies coro_awaiters - try { - coro_awaiters.back()->cancel(); - /* - * will resume coroutines and may throw ANY exception, including dpp::task_cancelled_exception cancel() throws at them. - * we catch that one. for the rest, good luck :) - * realistically the only way any other exception would pop up here is if someone catches dpp::task_cancelled_exception THEN throws another exception. - */ - } catch (const dpp::task_cancelled_exception &) { - // ok. likely we threw this one - } - } -#endif - } - - /** - * @brief Call all attached listeners. - * Listeners may cancel, by calling the event.cancel method. - * - * @param event Class to pass as parameter to all listeners. - */ - void call(const T& event) const { -#ifndef DPP_NO_CORO - handle_coro(event); -#else - handle(event); -#endif - }; - - /** - * @brief Call all attached listeners. - * Listeners may cancel, by calling the event.cancel method. - * - * @param event Class to pass as parameter to all listeners. - */ - void call(T&& event) const { -#ifndef DPP_NO_CORO - handle_coro(std::move(event)); -#else - handle(std::move(event)); -#endif - }; - -#ifndef DPP_NO_CORO - /** - * @brief Obtain an awaitable object that refers to an event with a certain condition. - * It can be co_await-ed to wait for the next event that satisfies this condition. - * On resumption the awaiter will be given __a reference__ to the event, - * saving it in a variable is recommended to avoid variable lifetime issues. - * - * @details Example: @code{cpp} - * dpp::task<> my_handler(const dpp::slashcommand_t& event) { - * co_await event.co_reply(dpp::message().add_component(dpp::component().add_component().set_label("click me!").set_id("test"))); - * - * dpp::button_click_t b = co_await c->on_button_click.with([](const dpp::button_click_t &event){ return event.custom_id == "test"; }); - * - * // do something on button click - * } - * @endcode - * - * This can be combined with dpp::when_any and other awaitables, for example dpp::cluster::co_sleep to create @ref expiring-buttons "expiring buttons". - * - * @warning On resumption the awaiter will be given a reference to the event. - * This means that variable may become dangling at the next co_await, be careful and save it in a variable - * if you need to. - * @param pred Predicate to check the event against. This should be a callable of the form `bool(const T&)` - * where T is the event type, returning true if the event is to match. - * @return awaitable An awaitable object that can be co_await-ed to await an event matching the condition. - */ - template -#ifndef _DOXYGEN_ - requires utility::callable_returns -#endif - auto when(Predicate&& pred) -#ifndef _DOXYGEN_ - noexcept(noexcept(std::function{std::declval()})) -#endif - { - return detail::event_router::awaitable{this, std::forward(pred)}; - } - - /** - * @brief Obtain an awaitable object that refers to any event. - * It can be co_await-ed to wait for the next event. - * - * @details Example: @code{cpp} - * dpp::task<> my_handler(const dpp::slashcommand_t& event) { - * co_await event.co_reply(dpp::message().add_component(dpp::component().add_component().set_label("click me!").set_id("test"))); - * - * dpp::button_click_t b = co_await c->on_message_create; - * - * // do something on button click - * } - * @endcode - * - * This can be combined with dpp::when_any and other awaitables, for example dpp::cluster::co_sleep to create expiring buttons. - * - * @warning On resumption the awaiter will be given a reference to the event. - * This means that variable may become dangling at the next co_await, be careful and save it in a variable - * if you need to. - * @return awaitable An awaitable object that can be co_await-ed to await an event matching the condition. - */ - [[nodiscard]] auto operator co_await() noexcept { - return detail::event_router::awaitable{this, nullptr}; - } -#endif - - /** - * @brief Returns true if the container of listeners is empty, - * i.e. there is nothing listening for this event right now. - * - * @retval true if there are no listeners - * @retval false if there are some listeners - */ - [[nodiscard]] bool empty() const { -#ifndef DPP_NO_CORO - std::shared_lock lock{mutex}; - std::shared_lock coro_lock{coro_mutex}; - - return dispatch_container.empty() && coro_awaiters.empty(); -#else - std::shared_lock lock{mutex}; - - return dispatch_container.empty(); -#endif - } - - /** - * @brief Returns true if any listeners are attached. - * - * This is the boolean opposite of event_router_t::empty(). - * @retval true if listeners are attached - * @retval false if no listeners are attached - */ - operator bool() const { - return !empty(); - } - -#ifdef _DOXYGEN_ - /** - * @brief Attach a callable to the event, adding a listener. - * The callable should either be of the form `void(const T&)` or - * `dpp::task(const T&)`, - * where T is the event type for this event router. - * - * This has the exact same behavior as using \ref attach(F&&) "attach". - * - * @see attach - * @param fun Callable to attach to event - * @return event_handle An event handle unique to this event, used to - * detach the listener from the event later if necessary. - */ - template - [[maybe_unused]] event_handle operator()(F&& fun); - - /** - * @brief Attach a callable to the event, adding a listener. - * The callable should either be of the form `void(const T&)` or - * `dpp::task(const T&)`, - * where T is the event type for this event router. - * - * @param fun Callable to attach to event - * @return event_handle An event handle unique to this event, used to - * detach the listener from the event later if necessary. - */ - template - [[maybe_unused]] event_handle attach(F&& fun); -#else /* not _DOXYGEN_ */ -# ifndef DPP_NO_CORO - /** - * @brief Attach a callable to the event, adding a listener. - * The callable should either be of the form `void(const T&)` or - * `dpp::task(const T&)`, where T is the event type for this event router. - * - * @param fun Callable to attach to event - * @return event_handle An event handle unique to this event, used to - * detach the listener from the event later if necessary. - */ - template - requires (utility::callable_returns, const T&> || utility::callable_returns) - [[maybe_unused]] event_handle operator()(F&& fun) { - return this->attach(std::forward(fun)); - } - - /** - * @brief Attach a callable to the event, adding a listener. - * The callable should either be of the form `void(const T&)` or - * `dpp::task(const T&)`, where T is the event type for this event router. - * - * @param fun Callable to attach to event - * @return event_handle An event handle unique to this event, used to - * detach the listener from the event later if necessary. - */ - template - requires (utility::callable_returns) - [[maybe_unused]] event_handle attach(F&& fun) { - std::unique_lock l(mutex); - event_handle h = next_handle++; - dispatch_container.emplace(std::piecewise_construct, std::forward_as_tuple(h), std::forward_as_tuple(std::in_place_type_t{}, std::forward(fun))); - return h; - } - - /** - * @brief Attach a callable to the event, adding a listener. - * The callable should either be of the form `void(const T&)` or - * `dpp::task(const T&)`, where T is the event type for this event router. - * - * @param fun Callable to attach to event - * @return event_handle An event handle unique to this event, used to - * detach the listener from the event later if necessary. - */ - template - requires (utility::callable_returns, const T&>) - [[maybe_unused]] event_handle attach(F&& fun) { - assert(dpp::utility::is_coro_enabled()); - - std::unique_lock l(mutex); - event_handle h = next_handle++; - dispatch_container.emplace(std::piecewise_construct, std::forward_as_tuple(h), std::forward_as_tuple(std::in_place_type_t{}, std::forward(fun))); - return h; - } -# else - /** - * @brief Attach a callable to the event, adding a listener. - * The callable should be of the form `void(const T&)` - * where T is the event type for this event router. - * - * @param fun Callable to attach to event - * @return event_handle An event handle unique to this event, used to - * detach the listener from the event later if necessary. - */ - template - [[maybe_unused]] std::enable_if_t, event_handle> operator()(F&& fun) { - return this->attach(std::forward(fun)); - } - - /** - * @brief Attach a callable to the event, adding a listener. - * The callable should be of the form `void(const T&)` - * where T is the event type for this event router. - *f - * @warning You cannot call this within an event handler. - * - * @param fun Callable to attach to event - * @return event_handle An event handle unique to this event, used to - * detach the listener from the event later if necessary. - */ - template - [[maybe_unused]] std::enable_if_t, event_handle> attach(F&& fun) { - std::unique_lock l(mutex); - event_handle h = next_handle++; - dispatch_container.emplace(h, std::forward(fun)); - return h; - } -# endif /* DPP_NO_CORO */ -#endif /* _DOXYGEN_ */ - /** - * @brief Detach a listener from the event using a previously obtained ID. - * - * @warning You cannot call this within an event handler. - * - * @param handle An ID obtained from @ref operator(F&&) "operator()" - * @retval true The event was successfully detached - * @retval false The ID is invalid (possibly already detached, or does not exist) - */ - [[maybe_unused]] bool detach(const event_handle& handle) { - std::unique_lock l(mutex); - return this->dispatch_container.erase(handle); - } -}; - -#ifndef DPP_NO_CORO - -namespace detail::event_router { - -template -void awaitable::cancel() { - awaiter_state s = awaiter_state::waiting; - /** - * If state == none (was never awaited), do nothing - * If state == waiting, prevent resumption, resume on our end - * If state == resuming || cancelling, ignore - */ - if (state.compare_exchange_strong(s, awaiter_state::cancelling)) { - self->detach_coro(handle); - resume(); - } -} - -template -constexpr bool awaitable::await_ready() const noexcept { - return false; -} - -template -void awaitable::await_suspend(detail::std_coroutine::coroutine_handle<> caller) { - state.store(awaiter_state::waiting); - handle = caller.address(); - self->attach_awaiter(this); -} - -template -const T &awaitable::await_resume() { - handle = nullptr; - predicate = nullptr; - if (state.exchange(awaiter_state::none, std::memory_order_relaxed) == awaiter_state::cancelling) { - throw dpp::task_cancelled_exception{"event_router::awaitable was cancelled"}; - } - return *std::exchange(event, nullptr); -} - -} -#endif - -} diff --git a/include/dpp/exception.h b/include/dpp/exception.h deleted file mode 100644 index c0d81a3..0000000 --- a/include/dpp/exception.h +++ /dev/null @@ -1,607 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Exception error codes possible for dpp::exception::code() - * - * This list is a combined list of Discord's error codes, HTTP error codes, - * zlib, opus and C library codes (e.g. DNS, socket etc). You may - * use these to easily identify a type of exception without having to resort - * to string comparison against dpp::exception::what() - * - * For detailed descriptions of each error code, see the text description - * returned in `what()`. - * - * @note Some exceptions MAY have error codes which are NOT in this list - * in the event a C library is updated and adds new codes we did not document - * here. In this case, or where the code is not specific, refer to `what()`. - */ -enum exception_error_code { - err_no_code_specified = 0, - err_zlib_see_errno = -1, - err_zlib_init_stream = -2, - err_zlib_init_data = -3, - err_zlib_init_mem = -4, - err_zlib_init_buffer = -5, - err_zlib_init_version = -6, - err_opus_bad_arg = -11, - err_opus_buffer_too_small = -12, - err_opus_internal_error = -13, - err_opus_invalid_packet = -14, - err_opus_unimplemented = -15, - err_opus_invalid_state = -16, - err_opus_alloc_fail = -17, - err_dns_bad_flags = -21, - err_name_or_service_unknown = -22, - err_dns_again = -23, - err_dns_fail = -24, - err_dns_family = -26, - err_dns_socket_type = -27, - err_dns_service = -28, - err_dns_memory = -30, - err_dns_system_error = -31, - err_dns_overflow = -32, - err_ssl_new = 1, - err_ssl_connect = 2, - err_write = 3, - err_ssl_write = 4, - err_no_sessions_left = 5, - err_auto_shard = 6, - err_reconnection = 7, - err_bind_failure = 8, - err_nonblocking_failure = 9, - err_voice_terminating = 10, - err_connect_failure = 11, - err_ssl_context = 12, - err_ssl_version = 13, - err_invalid_socket = 14, - err_socket_error = 15, - err_websocket_proto_already_set = 16, - err_command_handler_not_ready = 17, - err_no_owning_message = 18, - err_cancelled_event = 19, - err_event_status = 20, - err_event_start_time = 21, - err_event_end_time = 22, - err_command_has_caps = 23, - err_choice_autocomplete = 24, - err_interaction = 25, - err_too_many_component_rows = 26, - err_invalid_webhook = 27, - err_voice_state_timestamp = 28, - err_no_voice_support = 29, - err_invalid_voice_packet_length = 30, - err_opus = 31, - err_cant_start_shard = 32, - err_etf = 33, - err_cache = 34, - err_icon_size = 35, - err_massive_audio = 36, - err_unknown = 37, - err_bad_request = 400, - err_unauthorized = 401, - err_payment_required = 402, - err_forbidden = 403, - err_not_found = 404, - err_method_not_allowed = 405, - err_not_acceptable = 406, - err_proxy_auth_required = 407, - err_request_timeout = 408, - err_conflict = 409, - err_gone = 410, - err_length_required = 411, - err_precondition_failed = 412, - err_payload_too_large = 413, - err_uri_too_long = 414, - err_unsupported_media_type = 415, - err_range_not_satisfiable = 416, - err_expectation_failed = 417, - err_im_a_teapot = 418, - err_page_expired = 419, - err_twitter_rate_limited = 420, - err_misdirected_request = 421, - err_unprocessable_content = 422, - err_webdav_locked = 423, - err_webdav_failed_dependency = 424, - err_too_early = 425, - err_upgrade_required = 426, - err_precondition_required = 428, - err_rate_limited = 429, - err_request_headers_too_large = 431, - err_page_blocked = 450, - err_unavailable_for_legal_reasons = 451, - err_http_request_on_https_port = 497, - err_internal_server_error = 500, - err_not_implemented = 501, - err_bad_gateway = 502, - err_service_unavailable = 503, - err_gateway_timeout = 504, - err_http_version_not_supported = 505, - err_variant_also_negotiates = 506, - err_webdav_insufficient_storage = 507, - err_webdav_loop_detected = 508, - err_bandwidth_limit_exceeded = 509, - err_not_extended = 510, - err_network_auth_required = 511, - err_web_server_down = 521, - err_connection_timed_out = 522, - err_origin_unreachable = 523, - err_timeout = 524, - err_ssl_handshake_failed = 525, - err_invalid_ssl_certificate = 526, - err_railgun = 527, - err_cloudflare = 530, - err_websocket_unknown = 4000, - err_websocket_bad_opcode= 4001, - err_websocket_decode = 4002, - err_websocket_not_authenticated = 4003, - err_websocket_authentication_failed = 4004, - err_websocket_already_authenticated = 4005, - err_websocket_invalid_seq_number = 4007, - err_websocket_rate_limited = 4008, - err_websocket_session_timeout = 4009, - err_websocket_invalid_shard = 4010, - err_websocket_sharding_required = 4011, - err_websocket_invalid_api_version = 4012, - err_websocket_invalid_intents = 4013, - err_websocket_disallowed_intents = 4014, - err_websocket_voice_disconnected = 4014, - err_websocket_voice_server_crashed = 4015, - err_websocket_voice_unknown_encryption = 4016, - err_compression_stream = 6000, - err_compression_data = 6001, - err_compression_memory = 6002, - err_unknown_account = 10001, - err_unknown_application = 10002, - err_unknown_channel = 10003, - err_unknown_guild = 10004, - err_unknown_integration = 10005, - err_unknown_invite = 10006, - err_unknown_member = 10007, - err_unknown_message = 10008, - err_unknown_permission_overwrite = 10009, - err_unknown_provider = 10010, - err_unknown_role = 10011, - err_unknown_token = 10012, - err_unknown_user = 10013, - err_unknown_emoji = 10014, - err_unknown_webhook = 10015, - err_unknown_webhook_service = 10016, - err_unknown_session = 10020, - err_unknown_ban = 10026, - err_unknown_sku = 10027, - err_unknown_store_listing = 10028, - err_unknown_entitlement = 10029, - err_unknown_build = 10030, - err_unknown_lobby = 10031, - err_unknown_branch = 10032, - err_unknown_store_directory_layout = 10033, - err_unknown_redistributable = 10036, - err_unknown_gift_code = 10038, - err_unknown_stream = 10049, - err_unknown_premium_server_subscribe_cooldown = 10050, - err_unknown_guild_template = 10057, - err_unknown_discoverable_server_category = 10059, - err_unknown_sticker = 10060, - err_unknown_interaction = 10062, - err_unknown_application_command = 10063, - err_unknown_voice_state = 10065, - err_unknown_application_command_permissions = 10066, - err_unknown_stage_instance = 10067, - err_unknown_guild_member_verification_form = 10068, - err_unknown_guild_welcome_screen = 10069, - err_unknown_guild_scheduled_event = 10070, - err_unknown_guild_scheduled_event_user = 10071, - err_unknown_tag = 10087, - err_bots_cannot_use_this_endpoint = 20001, - err_only_bots_can_use_this_endpoint = 20002, - err_explicit_content = 20009, - err_unauthorized_for_application = 20012, - err_slowmode_rate_limit = 20016, - err_owner_only = 20018, - err_announcement_rate_limit = 20022, - err_under_minimum_age = 20024, - err_write_rate_limit = 20029, - err_stage_banned_words = 20031, - err_guild_premium_subscription_level_too_low = 20035, - err_guilds = 30001, - err_friends = 30002, - err_pins_for_the_channel = 30003, - err_recipients = 30004, - err_guild_roles = 30005, - err_webhooks = 30007, - err_emojis = 30008, - err_reactions = 30010, - err_group_dms = 30011, - err_guild_channels = 30013, - err_attachments_in_a_message = 30015, - err_invites = 30016, - err_animated_emojis = 30018, - err_server_members = 30019, - err_server_categories = 30030, - err_guild_already_has_a_template = 30031, - err_application_commands = 30032, - err_thread_participants = 30033, - err_daily_application_command_creates = 30034, - err_bans_for_non_guild_members_have_been_exceeded = 30035, - err_bans_fetches = 30037, - err_uncompleted_guild_scheduled_events = 30038, - err_stickers = 30039, - err_prune_requests = 30040, - err_guild_widget_settings_updates = 30042, - err_edits_to_messages_older_than_1_hour = 30046, - err_pinned_threads_in_a_forum_channel = 30047, - err_tags_in_a_forum_channel = 30048, - err_bitrate_is_too_high_for_channel_of_this_type = 30052, - err_premium_emojis = 30056, - err_webhooks_per_guild = 30058, - err_channel_permission_overwrites = 30060, - err_the_channels_for_this_guild_are_too_large = 30061, - err_unauthorized_invalid_token = 40001, - err_verify_your_account = 40002, - err_you_are_opening_direct_messages_too_fast = 40003, - err_send_messages_has_been_temporarily_disabled = 40004, - err_request_entity_too_large = 40005, - err_this_feature_has_been_temporarily_disabled_server_side = 40006, - err_the_user_is_banned_from_this_guild = 40007, - err_connection_has_been_revoked = 40012, - err_target_user_is_not_connected_to_voice = 40032, - err_this_message_has_already_been_crossposted = 40033, - err_an_application_command_with_that_name_already_exists = 40041, - err_application_interaction_failed_to_send = 40043, - err_cannot_send_a_message_in_a_forum_channel = 40058, - err_interaction_has_already_been_acknowledged = 40060, - err_tag_names_must_be_unique = 40061, - err_service_resource_is_being_rate_limited = 40062, - err_no_tags_available = 40066, - err_tag_required = 40067, - err_entitlement_already_granted = 40074, - err_missing_access = 50001, - err_invalid_account_type = 50002, - err_cannot_execute_action_on_a_dm_channel = 50003, - err_guild_widget_disabled = 50004, - err_cannot_edit_a_message_by_other_user = 50005, - err_cannot_send_empty_message = 50006, - err_cannot_send_messages_to_this_user = 50007, - err_cannot_send_messages_in_a_non_text_channel = 50008, - err_channel_verification_level_too_high = 50009, - err_oauth2_application_does_not_have_a_bot = 50010, - err_oauth2_application_limit = 50011, - err_invalid_oauth2_state = 50012, - err_permissions = 50013, - err_invalid_authentication_token = 50014, - err_note_was_too_long = 50015, - err_too_few_or_too_many_messages = 50016, - err_invalid_mfa_level = 50017, - err_invalid_pin = 50019, - err_invite_code_invalid = 50020, - err_system_message = 50021, - err_channel_type = 50024, - err_invalid_oauth2_access_token = 50025, - err_missing_required_oauth2_scope = 50026, - err_invalid_webhook_token = 50027, - err_invalid_role = 50028, - err_invalid_recipients = 50033, - err_too_old_to_bulk_delete = 50034, - err_invalid_form_body = 50035, - err_invite_error = 50036, - err_invalid_activity_action = 50039, - err_invalid_api_version_provided = 50041, - err_file_uploaded_exceeds_the_maximum_size = 50045, - err_invalid_file_uploaded = 50046, - err_cannot_self_redeem_this_gift = 50054, - err_invalid_guild = 50055, - err_invalid_sku = 50057, - err_invalid_request_origin = 50067, - err_invalid_message_type = 50068, - err_payment_source_required = 50070, - err_cannot_modify_a_system_webhook = 50073, - err_cannot_delete_a_channel_required_for_community_guilds = 50074, - err_cannot_edit_stickers_within_a_message = 50080, - err_invalid_sticker_sent = 50081, - err_tried_to_perform_an_operation_on_an_archived_thread = 50083, - err_invalid_thread_notification_settings = 50084, - err_before_value_is_earlier_than_the_thread_creation_date = 50085, - err_community_server_channels_must_be_text_channels = 50086, - err_bad_event_entity_type = 50091, - err_this_server_is_not_available_in_your_location = 50095, - err_monetization_enabled_in_order_to_perform_this_action = 50097, - err_more_boosts_to_perform_this_action = 50101, - err_the_request_body_contains_invalid_json = 50109, - err_owner_cannot_be_pending_member = 50131, - err_ownership_cannot_be_transferred_to_a_bot_user = 50132, - err_failed_to_resize_asset_below_the_maximum_size = 50138, - err_cannot_mix_subscription_and_non_subscription_roles_for_an_emoji = 50144, - err_cannot_convert_between_premium_emoji_and_normal_emoji = 50145, - err_uploaded_file_not_found = 50146, - err_voice_messages_do_not_support_additional_content = 50159, - err_voice_messages_must_have_a_single_audio_attachment = 50160, - err_voice_messages_must_have_supporting_metadata = 50161, - err_voice_messages_cannot_be_edited = 50162, - err_cannot_delete_guild_subscription_integration = 50163, - err_you_cannot_send_voice_messages_in_this_channel = 50173, - err_the_user_account_must_first_be_verified = 50178, - err_you_do_not_have_permission_to_send_this_sticker = 50600, - err_two_factor_is_required_for_this_operation = 60003, - err_no_users_with_discordtag_exist = 80004, - err_reaction_was_blocked = 90001, - err_user_cannot_use_burst_reactions = 90002, - err_application_not_yet_available = 110001, - err_api_resource_is_currently_overloaded = 130000, - err_the_stage_is_already_open = 150006, - err_cannot_reply_without_permission_to_read_message_history = 160002, - err_a_thread_has_already_been_created_for_this_message = 160004, - err_thread_is_locked = 160005, - err_active_threads = 160006, - err_active_announcement_threads = 160007, - err_invalid_json_for_uploaded_lottie_file = 170001, - err_uploaded_lotties_cannot_contain_rasterized_images = 170002, - err_sticker_maximum_framerate = 170003, - err_sticker_frame_count = 170004, - err_lottie_animation_dimensions = 170005, - err_sticker_frame_rate = 170006, - err_sticker_animation_duration = 170007, - err_cannot_update_a_finished_event = 180000, - err_failed_to_create_stage_needed_for_stage_event = 180002, - err_message_was_blocked_by_automatic_moderation = 200000, - err_title_was_blocked_by_automatic_moderation = 200001, - err_webhooks_posted_to_forum_channels_must_have_a_thread_name_or_thread_id = 220001, - err_webhooks_posted_to_forum_channels_cannot_have_both_a_thread_name_and_thread_id = 220002, - err_webhooks_can_only_create_threads_in_forum_channels = 220003, - err_webhook_services_cannot_be_used_in_forum_channels = 220004, - err_message_blocked_links = 240000, - err_cannot_enable_onboarding_requirements_are_not_met = 350000, - err_cannot_update_onboarding_below_requirements = 350001, -}; - -/** - * @brief The dpp::exception class derives from std::exception and supports some other - * ways of passing in error details such as via std::string. - */ -class exception : public std::exception -{ -protected: - /** - * @brief Exception message - */ - std::string msg; - - /** - * @brief Exception error code - */ - exception_error_code error_code; - -public: - - using std::exception::exception; - - /** - * @brief Construct a new exception object - */ - exception() = default; - - /** - * @brief Construct a new exception object - * - * @param what reason message - */ - explicit exception(const char* what) : msg(what), error_code(err_no_code_specified) { } - - /** - * @brief Construct a new exception object - * - * @param what reason message - * @param code Exception code - */ - explicit exception(exception_error_code code, const char* what) : msg(what), error_code(code) { } - - /** - * @brief Construct a new exception object - * - * @param what reason message - * @param len length of reason message - */ - exception(const char* what, size_t len) : msg(what, len), error_code(err_no_code_specified) { } - - /** - * @brief Construct a new exception object - * - * @param what reason message - */ - explicit exception(const std::string& what) : msg(what), error_code(err_no_code_specified) { } - - /** - * @brief Construct a new exception object - * - * @param what reason message - * @param code Exception code - */ - explicit exception(exception_error_code code, const std::string& what) : msg(what), error_code(code) { } - - /** - * @brief Construct a new exception object - * - * @param what reason message - */ - explicit exception(std::string&& what) : msg(std::move(what)) { } - - /** - * @brief Construct a new exception object - * - * @param what reason message - * @param code Exception code - */ - explicit exception(exception_error_code code, std::string&& what) : msg(std::move(what)), error_code(code) { } - - /** - * @brief Construct a new exception object (copy constructor) - */ - exception(const exception&) = default; - - /** - * @brief Construct a new exception object (move constructor) - */ - exception(exception&&) = default; - - /** - * @brief Destroy the exception object - */ - ~exception() override = default; - - /** - * @brief Copy assignment operator - * - * @return exception& reference to self - */ - exception & operator = (const exception &) = default; - - /** - * @brief Move assignment operator - * - * @return exception& reference to self - */ - exception & operator = (exception&&) = default; - - /** - * @brief Get exception message - * - * @return const char* error message - */ - [[nodiscard]] const char* what() const noexcept override { return msg.c_str(); }; - - /** - * @brief Get exception code - * - * @return exception_error_code error code - */ - [[nodiscard]] exception_error_code code() const noexcept { return error_code; }; - -}; - -#ifndef _DOXYGEN_ - #define derived_exception(name, ancestor) class name : public dpp::ancestor { \ - public: \ - using dpp::ancestor::ancestor; \ - name() = default; \ - explicit name(const char* what) : ancestor(what) { } \ - explicit name(exception_error_code code, const char* what) : ancestor(code, what) { } \ - name(const char* what, size_t len) : ancestor(what, len) { } \ - explicit name(const std::string& what) : ancestor(what) { } \ - explicit name(exception_error_code code, const std::string& what) : ancestor(code, what) { } \ - explicit name(std::string&& what) : ancestor(what) { } \ - explicit name(exception_error_code code, std::string&& what) : ancestor(code, what) { } \ - name(const name&) = default; \ - name(name&&) = default; \ - ~name() override = default; \ - name & operator = (const name &) = default; \ - name & operator = (name&&) = default; \ - [[nodiscard]] const char* what() const noexcept override { return msg.c_str(); }; \ - [[nodiscard]] exception_error_code code() const noexcept { return error_code; }; \ - }; -#endif - -#ifdef _DOXYGEN_ - /* - * THESE DEFINITIONS ARE NOT THE REAL DEFINITIONS USED BY PROGRAM CODE. - * - * They exist only to cause Doxygen to emit proper documentation for the derived exception types. - * Proper definitions are emitted by the `derived_exception` macro in the "else" section. - */ - - /** - * @brief Represents an error in logic, e.g. you asked the library to do something the Discord API does not support - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class logic_exception : public dpp::exception { }; - /** - * @brief Represents an error reading or writing to a file - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class file_exception : public dpp::exception { }; - /** - * @brief Represents an error establishing or maintaining a connection - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class connection_exception : public dpp::exception { }; - /** - * @brief Represents an error with voice processing - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class voice_exception : public dpp::exception { }; - /** - * @brief Represents an error on a REST API call, e.g. a HTTPS request - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class rest_exception : public dpp::exception { }; - /** - * @brief Represents invalid length of argument being passed to a function - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class length_exception : public dpp::exception { }; - /** - * @brief Represents inability to parse data, usually caused by malformed JSON or ETF - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class parse_exception : public dpp::exception { }; - /** - * @brief Represents invalid access to dpp's cache or its members, which may or may not exist. - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class cache_exception : public dpp::exception { }; - /** - * @brief Represents an attempt to construct a cluster with an invalid bot token. - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class invalid_token_exception : public dpp::rest_exception { }; -#ifndef DPP_NO_CORO - /** - * @brief Represents the cancellation of a task. Will be thrown to the awaiter of a cancelled task. - * @note This is a stub for documentation purposes. For full information on supported methods please see dpp::exception. - */ - class task_cancelled_exception : public dpp::exception { }; -#endif /* DPP_NO_CORO */ -#else - derived_exception(logic_exception, exception); - derived_exception(file_exception, exception); - derived_exception(connection_exception, exception); - derived_exception(voice_exception, exception); - derived_exception(encryption_exception, voice_exception); - derived_exception(decryption_exception, voice_exception); - derived_exception(rest_exception, exception); - derived_exception(invalid_token_exception, rest_exception); - derived_exception(length_exception, exception); - derived_exception(parse_exception, exception); - derived_exception(cache_exception, exception); -# ifndef DPP_NO_CORO - derived_exception(task_cancelled_exception, exception); -# endif /* DPP_NO_CORO */ -#endif - -} - diff --git a/include/dpp/export.h b/include/dpp/export.h deleted file mode 100644 index 9104d17..0000000 --- a/include/dpp/export.h +++ /dev/null @@ -1,148 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -/* Compile-time check for C++17. - * Either one of the following causes a compile time error: - * __cplusplus not defined at all (this means we are being compiled on a C compiler) - * MSVC defined and _MSVC_LANG < 201703L (Visual Studio, but not C++17 or newer) - * MSVC not defined and __cplusplus < 201703L (Non-visual studio, but not C++17 or newer) - * The additional checks are required because MSVC doesn't correctly set __cplusplus to 201703L, - * which is hugely non-standard, but apparently "it broke stuff" so they dont ever change it - * from C++98. Ugh. - */ -#if (!defined(__cplusplus) || (defined(_MSC_VER) && (!defined(_MSVC_LANG) || _MSVC_LANG < 201703L)) || (!defined(_MSC_VER) && __cplusplus < 201703L)) - #error "D++ Requires a C++17 compatible C++ compiler. Please ensure that you have enabled C++17 in your compiler flags." -#endif - -/* If not using c++20, define DPP_CPP17_COMPAT and DPP_NO_CORO if DPP_NO_CORO is not already defined. - */ -#if !(defined(__cplusplus) && __cplusplus >= 202002L) && !(defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define DPP_CPP17_COMPAT - #if !defined(DPP_CORO) || !DPP_CORO // Allow overriding this because why not - #ifndef DPP_NO_CORO - #define DPP_NO_CORO - #endif - #endif -#endif - -#ifndef DPP_STATIC - /* Dynamic linked build as shared object or dll */ - #ifdef DPP_BUILD - /* Building the library */ - #ifdef _WIN32 - #include - #define DPP_EXPORT __declspec(dllexport) - #else - #define DPP_EXPORT - #endif - #else - /* Including the library */ - #ifdef _WIN32 - #define DPP_EXPORT __declspec(dllimport) - #else - #define DPP_EXPORT - #endif - #endif -#else - /* Static linked build */ - #if defined(_WIN32) && defined(DPP_BUILD) - #include - #endif - #define DPP_EXPORT -#endif - -namespace dpp { - -/** - * @brief Represents a build configuration. On some platforms (e.g. Windows) release isn't compatible with debug, so we use this enum to detect it. - */ -enum class build_type { - /** - * @brief Universal build, works with both debug and release - */ - universal, - - /** - * @brief Debug build - */ - debug, - - /** - * @brief Release build - */ - release -}; - -template -extern bool DPP_EXPORT validate_configuration(); - -#if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_GAME) || defined(UE_EDITOR) || defined(UE_BUILD_SHIPPING_WITH_EDITOR) || defined(UE_BUILD_DOCS) - /* - * We need to tell DPP to NOT do the version checker if something from Unreal Engine is defined. - * We have to do this because UE is causing some weirdness where the version checker is broken and always errors. - * This is really only for DPP-UE. There is no reason to not do the version checker unless you are in Unreal Engine. - */ - #define DPP_BYPASS_VERSION_CHECKING -#endif /* UE */ - -#ifndef DPP_BUILD /* when including dpp */ - /** - * Version checking, making sure the program is in a configuration compatible with DPP's. - * - * Do NOT make these variables constexpr. - * We want them to initialize at runtime so the function can be pulled from the shared library object. - */ - #ifndef DPP_BYPASS_VERSION_CHECKING - #if defined(_WIN32) - #ifdef _DEBUG - inline const bool is_valid_config = validate_configuration(); - #else - inline const bool is_valid_config = validate_configuration(); - #endif /* _DEBUG */ - #else - inline const bool is_valid_config = validate_configuration(); - #endif /* _WIN32 */ - #endif /* !DPP_BYPASS_VERSION_CHECKING */ -#endif /* !DPP_BUILD */ - -} - -#ifdef _WIN32 - #ifndef NOMINMAX - #define NOMINMAX - #endif - - #include -#endif - -#ifdef _DOXYGEN_ - /** @brief Macro that expands to [[deprecated(reason)]] when including the library, nothing when building the library */ - #define DPP_DEPRECATED(reason) -#else /* !_DOXYGEN_ */ - #if defined(DPP_BUILD) || defined(DPP_NO_DEPRECATED) - /** @brief Macro that expands to [[deprecated(reason)]] when including the library, nothing when building the library */ - #define DPP_DEPRECATED(reason) - #else - /** @brief Macro that expands to [[deprecated(reason)]] when including the library, nothing when building the library */ - #define DPP_DEPRECATED(reason) [[deprecated(reason)]] - #endif -#endif /* _DOXYGEN_ */ diff --git a/include/dpp/guild.h b/include/dpp/guild.h deleted file mode 100644 index c255887..0000000 --- a/include/dpp/guild.h +++ /dev/null @@ -1,2053 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -class channel; -class cluster; - -/* Note from Archie: I'd like to move this soon (dpp::guild::region) and allow users to use a region enum. - * This would make it easier for people to be able to alter a channel region without having to get the text right. - */ - -/** - * @brief Represents voice regions for guilds and channels. - * @deprecated Deprecated in favour of per-channel regions. - * Please use dpp::channel::rtc_region instead. - */ -enum region : uint8_t { - /** - * @brief Brazil - */ - r_brazil, - - /** - * @brief Central Europe - */ - r_central_europe, - - /** - * @brief Hong Kong - */ - r_hong_kong, - - /** - * @brief India - */ - r_india, - - /** - * @brief Japan - */ - r_japan, - - /** - * @brief Russia - */ - r_russia, - - /** - * @brief Singapore - */ - r_singapore, - - /** - * @brief South Africa - */ - r_south_africa, - - /** - * @brief Sydney - */ - r_sydney, - - /** - * @brief US Central - */ - r_us_central, - - /** - * @brief US East Coast - */ - r_us_east, - - /** - * @brief US South - */ - r_us_south, - - /** - * @brief US West Coast - */ - r_us_west, - - /** - * @brief Western Europe - */ - r_western_europe -}; - -/** - * @brief The various flags that represent the status of a dpp::guild object - */ -enum guild_flags : uint32_t { - /** - * @brief Large guild - */ - g_large = 0b00000000000000000000000000000001, - - /** - * @brief Unavailable guild (inaccessible due to an outage) - */ - g_unavailable = 0b00000000000000000000000000000010, - - /** - * @brief Guild has widget enabled - */ - g_widget_enabled = 0b00000000000000000000000000000100, - - /** - * @brief Guild can have an invite splash image - */ - g_invite_splash = 0b00000000000000000000000000001000, - - /** - * @brief Guild can have VIP regions - */ - g_vip_regions = 0b00000000000000000000000000010000, - - /** - * @brief Guild can have a vanity url - */ - g_vanity_url = 0b00000000000000000000000000100000, - - /** - * @brief Guild is verified - */ - g_verified = 0b00000000000000000000000001000000, - - /** - * @brief Guild is partnered - */ - g_partnered = 0b00000000000000000000000010000000, - - /** - * @brief Community features enabled - */ - g_community = 0b00000000000000000000000100000000, - - /** - * @brief Guild has enabled role subscriptions - */ - g_role_subscription_enabled = 0b00000000000000000000001000000000, - - /** - * @brief Guild has access to create announcement channels - */ - g_news = 0b00000000000000000000010000000000, - - /** - * @brief Guild is discoverable in discovery - */ - g_discoverable = 0b00000000000000000000100000000000, - - /** - * @brief Guild is featureable - */ - g_featureable = 0b00000000000000000001000000000000, - - /** - * @brief Guild can have an animated icon (doesn't mean it actually has one though) - */ - g_animated_icon = 0b00000000000000000010000000000000, - - /** - * @brief Guild can have a banner image - */ - g_banner = 0b00000000000000000100000000000000, - - /** - * @brief Guild has a welcome screen - */ - g_welcome_screen_enabled = 0b00000000000000001000000000000000, - - /** - * @brief Guild has a member verification gate - */ - g_member_verification_gate = 0b00000000000000010000000000000000, - - /** - * @brief Guild has a preview - */ - g_preview_enabled = 0b00000000000000100000000000000000, - - /** - * @brief Guild join notifications are off - */ - g_no_join_notifications = 0b00000000000001000000000000000000, - - /** - * @brief Guild boost notifications are off - */ - g_no_boost_notifications = 0b00000000000010000000000000000000, - - /** - * @brief Guild has an actual animated icon (set by the icon hash starting with 'a_') - */ - g_has_animated_icon = 0b00000000000100000000000000000000, - - /** - * @brief Guild has an actual animated banner (set by the icon hash starting with 'a_') - */ - g_has_animated_banner = 0b00000000001000000000000000000000, - - /** - * @brief Guild setup tips are off - */ - g_no_setup_tips = 0b00000000010000000000000000000000, - - /** - * @brief "Wave to say hi" sticker prompt buttons are off - */ - g_no_sticker_greeting = 0b00000000100000000000000000000000, - - /** - * @brief Guild has enabled monetization - */ - g_monetization_enabled = 0b00000001000000000000000000000000, - - /** - * @brief Guild has increased custom sticker slots - */ - g_more_stickers = 0b00000010000000000000000000000000, - - /** - * @brief Guild has enabled the role subscription promo page - */ - g_creator_store_page_enabled = 0b00000100000000000000000000000000, - - /** - * @brief Guild is able to set role icons - */ - g_role_icons = 0b00001000000000000000000000000000, - - /** - * @brief Guild has access to the seven day archive time for threads - * @deprecated Removed by Discord - */ - g_seven_day_thread_archive = 0b00010000000000000000000000000000, - - /** - * @brief Guild has access to the three day archive time for threads - * @deprecated Removed by Discord - */ - g_three_day_thread_archive = 0b00100000000000000000000000000000, - - /** - * @brief Guild has enabled ticketed events - */ - g_ticketed_events = 0b01000000000000000000000000000000, - - /** - * @brief Guild can have channel banners - * @deprecated Removed by Discord - */ - g_channel_banners = 0b10000000000000000000000000000000, -}; - -/** - * @brief Additional boolean flag values for guild, as guild_flags is full - */ -enum guild_flags_extra : uint16_t { - /** - * @brief Guild has premium progress bar enabled - */ - g_premium_progress_bar_enabled = 0b0000000000000001, - - /** - * @brief Guild can have an animated banner (doesn't mean it actually has one though) - */ - g_animated_banner = 0b0000000000000010, - - /** - * @brief Guild has auto moderation - */ - g_auto_moderation = 0b0000000000000100, - - /** - * @brief Guild has paused invites, preventing new users from joining - */ - g_invites_disabled = 0b0000000000001000, - - /** - * @brief Guild has been set as support server of an app in the App Directory - */ - g_developer_support_server = 0b0000000000010000, - - /** - * @brief Guild role subscription purchase and renewal notifications are off - */ - g_no_role_subscription_notifications = 0b0000000000100000, - - /** - * @brief Guild role subscription sticker reply buttons are off - */ - g_no_role_subscription_notification_replies = 0b0000000001000000, - - /** - * @brief Guild has role subscriptions that can be purchased - */ - g_role_subscriptions_available_for_purchase = 0b0000000010000000, - - /** - * @brief Guild has disabled alerts for join raids in the configured safety alerts channel - */ - g_raid_alerts_disabled = 0b0000000100000000, -}; - -/** - * @brief Various flags that can be used to indicate the status of a guild member. - * @note Use the setter functions in dpp::guild_member and do not toggle the bits yourself. - */ -enum guild_member_flags : uint16_t { - /** - * @brief Member deafened in voice channel - */ - gm_deaf = 0b0000000000000001, - - /** - * @brief Member muted in voice channels - */ - gm_mute = 0b0000000000000010, - - /** - * @brief Member pending verification by membership screening - */ - gm_pending = 0b0000000000000100, - - /** - * @brief Member has animated guild-specific avatar - */ - gm_animated_avatar = 0b0000000000001000, - - /** - * @brief gm_deaf or gm_mute has been toggled - */ - gm_voice_action = 0b0000000000010000, - - /** - * @brief Member has left and rejoined the guild - */ - gm_did_rejoin = 0b0000000000100000, - - /** - * @brief Member has completed onboarding - */ - gm_completed_onboarding = 0b0000000001000000, - - /** - * @brief Member is exempt from guild verification requirements - */ - gm_bypasses_verification = 0b0000000010000000, - - /** - * @brief Member has started onboarding - */ - gm_started_onboarding = 0b0000000100000000, - - /** - * @brief Should change roles on next call to edit guild_member? - * @warning This is set by dpp::guild_member::add_role, dpp::guild_member::remove_role, and dpp::guild_member::set_roles. - * You should only ever use this value if you know what you're doing, otherwise stick to the three functions listed. - */ - gm_roles_action = 0b0000001000000000, - - /** - * @brief Should nicknames on next call to edit guild_member? - * @warning This is set by dpp::guild_member::set_nickname. - * You should only ever use this value if you know what you're doing, otherwise stick to the function listed. - */ - gm_nickname_action = 0b0000010000000000, -}; - -/** - * @brief Represents dpp::user membership upon a dpp::guild. - * This contains the user's nickname, guild roles, and any other guild-specific flags. - */ -class DPP_EXPORT guild_member : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Build json for the member object - * - * @param with_id Add ID to output - * @return json JSON object - */ - json to_json_impl(bool with_id = false) const; - -protected: - /** - * @brief Nickname. - * - * @note Empty string if they don't have a nickname on this guild - */ - std::string nickname; - - /** - * @brief List of roles this user has on this guild - */ - std::vector roles; - - /** - * @brief A set of flags built from the bitmask defined by dpp::guild_member_flags - */ - uint16_t flags; - - friend void from_json(const nlohmann::json& j, guild_member& gm); - -public: - /** - * @brief Guild id - */ - snowflake guild_id; - - /** - * @brief User id - */ - snowflake user_id; - - /** - * @brief User avatar. - * - * @note Per-server avatar is a nitro only feature. - */ - utility::iconhash avatar; - - /** - * @brief Timestamp of when the time out will be removed; until then, they cannot interact with the guild - */ - time_t communication_disabled_until; - - /** - * @brief Date and time the user joined the guild. - */ - time_t joined_at; - - /** - * @brief The Date and time the user started boosting. - */ - time_t premium_since; - - /** Default constructor */ - guild_member(); - - /** - * @brief Fill this object from a json object. - * @param j The json object to get data from - * @param g_id The guild id to associate the member with - * @param u_id The user id to associate the member with - * @return Reference to self for call chaining - */ - guild_member& fill_from_json(nlohmann::json* j, snowflake g_id, snowflake u_id); - - /** - * @brief Returns true if the user is in time-out (communication disabled) - * - * @return true user is in time-out - * @return false user is not in time-out - */ - bool is_communication_disabled() const; - - /** - * @brief Returns true if the user is deafened - * - * @return true user is deafened - * @return false user is not deafened - */ - bool is_deaf() const; - - /** - * @brief Returns true if the user is muted - * - * @return true user muted - * @return false user not muted - */ - bool is_muted() const; - - /** - * @brief Returns true if pending verification by membership screening - * - * @return true user has completed membership screening - * @return false user has not completed membership screening - */ - bool is_pending() const; - - /** - * @brief Returns true if the user has left and rejoined the guild - * - * @return true user has left and rejoined the guild - * @return false user has not rejoined - */ - bool has_rejoined() const; - - /** - * @brief Is this user also the guild member? - * @return true if the user is the guild owner. - * @return false if the user is not the guild owner or the guild is not in the cache. - * @note If the guild cache is disabled, this function will always return false. - */ - bool is_guild_owner() const; - - /** - * @brief Returns true if the user has completed onboarding - * - * @return true user has completed onboarding - * @return false user has not completed onboarding - */ - bool has_completed_onboarding() const; - - /** - * @brief Returns true if the user has started onboarding - * - * @return true user has started onboarding - * @return false user has not started onboarding yet - */ - bool has_started_onboarding() const; - - /** - * @brief Returns true if the user is exempt from guild verification requirements - * - * @return true user bypasses verification - * @return false user doesn't bypass verification - */ - bool has_bypasses_verification() const; - - /** - * @brief Returns true if the user's per-guild custom avatar is animated - * - * @return true user's custom avatar is animated - * @return false user's custom avatar is not animated - */ - bool has_animated_guild_avatar() const; - - /** - * @brief Returns the member's per guild avatar url if they have one, otherwise returns an empty string. - * - * @note per-server avatar is a nitro only feature so it might be not set. If you need the user avatar, use user::get_avatar_url. - * - * @param size The size of the avatar in pixels. It can be any power of two between 16 and 4096, - * otherwise the default sized avatar is returned. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg`, `i_png` or `i_gif`. - * When passing `i_gif`, it returns an empty string for non-animated images. Consider using the `prefer_animated` parameter instead. - * @param prefer_animated Whether you prefer gif format. - * If true, it'll return gif format whenever the image is available as animated. - * @return std::string avatar url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_avatar_url(uint16_t size = 0, const image_type format = i_png, bool prefer_animated = true) const; - - /** - * @brief Set the nickname - * - * @param nick Nickname to set - * - * @return guild_member& reference to self - */ - guild_member& set_nickname(const std::string& nick); - - /** - * @brief Get the nickname - * - * @return std::string nickname - */ - std::string get_nickname() const; - - /** - * @brief Get the roles - * - * @return std::vector roles - */ - const std::vector& get_roles() const; - - /** - * @brief Find the dpp::user object for this member. This is an alias for dpp::find_user - * @return dpp::user* Pointer to the user object. If not in cache, it returns nullptr - */ - user* get_user() const; - - /** - * @brief Check if this member is equal to another member object. - * @param other_member other member object to compare - * @return true if their user ids are equal, false otherwise. - */ - - bool operator == (guild_member const& other_member) const; - - /** - * @brief Set whether the user is exempt from guild verification requirements - * - * @param is_bypassing_verification value to set - * - * @return guild_member& reference to self - */ - guild_member& set_bypasses_verification(const bool is_bypassing_verification); - - /** - * @brief Set whether the user is muted in voice channels - * - * @param is_muted value to set, true if mute in voice channels - * - * @return guild_member& reference to self - */ - guild_member& set_mute(const bool is_muted); - - /** - * @brief Set whether the user is deafened in voice channels - * - * @param is_deafened value to set, true if deaf in voice channels - * - * @return guild_member& reference to self - */ - guild_member& set_deaf(const bool is_deafened); - - /** - * @brief Set communication_disabled_until - * - * @param timestamp timestamp until communication is disabled - * - * @return guild_member& reference to self - */ - guild_member& set_communication_disabled_until(const time_t timestamp); - - /** - * @brief Return a ping/mention for the user by nickname - * - * @return std::string mention - */ - std::string get_mention() const; - - /** - * @brief Add a role to this member - * @note This call sets the role change bit, which causes the new role - * list to be sent if this is passed to dpp::cluster::guild_edit_member - * or dpp::cluster::guild_add_member - * - * @param role_id Role ID to add - * @return guild_member& Reference to self - */ - guild_member& add_role(dpp::snowflake role_id); - - /** - * @brief Remove a role from this member - * @note This call sets the role change bit, which causes the new role - * list to be sent if this is passed to dpp::cluster::guild_edit_member - * or dpp::cluster::guild_add_member - * - * @param role_id Role ID to remove - * @return guild_member& Reference to self - */ - guild_member& remove_role(dpp::snowflake role_id); - - /** - * @brief Set a new role list for this member - * @note This call sets the role change bit, which causes the new role - * list to be sent if this is passed to dpp::cluster::guild_edit_member - * or dpp::cluster::guild_add_member - * - * @param role_ids Roles to set - * @return guild_member& Reference to self - */ - guild_member& set_roles(const std::vector &role_ids); - -}; - -/** - * @brief Defines a channel on a server's welcome screen - */ -struct DPP_EXPORT welcome_channel : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Read class values from json object - * - * @param j A json object to read from - * @return A reference to self - */ - welcome_channel& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build the json for this object - * - * @param with_id include the id in the JSON - * @return json JSON data - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief The description shown for the channel. - */ - std::string description; - - /** - * @brief The emoji name. - * - * @note name if custom, the unicode character if standard, or null if no emoji is set. - */ - std::string emoji_name; - - /** - * @brief The channel's id. - */ - snowflake channel_id; - - /** - * @brief The emoji id, if the emoji is custom. - */ - snowflake emoji_id; - - /** - * @brief Construct a new welcome channel object - */ - welcome_channel(); - - /** - * @brief Destroy the welcome channel object - */ - virtual ~welcome_channel() = default; - - /** - * @brief Set the channel ID of this welcome channel object - * - * @param _channel_id The channel ID to set - * @return Reference to self, so these method calls may be chained - */ - welcome_channel& set_channel_id(const snowflake _channel_id); - - /** - * @brief Set the description of this welcome channel object - * - * @param _description The description to set - * @return Reference to self, so these method calls may be chained - */ - welcome_channel& set_description(const std::string& _description); -}; - - -/** - * @brief Defines a server's welcome screen - */ -struct DPP_EXPORT welcome_screen : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Read class values from json object - * - * @param j A json object to read from - * @return A reference to self - */ - welcome_screen& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build the json for this object - * - * @param with_id include the id in the JSON - * @return std::string json data - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief The server description shown in the welcome screen - */ - std::string description; - - /** - * @brief The channels shown in the welcome screen (max 5) - */ - std::vector welcome_channels; - - /** - * @brief Construct a new welcome screen object - */ - welcome_screen() = default; - - /** - * @brief Destroy the welcome screen object - */ - virtual ~welcome_screen() = default; - - /** - * @brief Set the server description for this welcome screen object shown in the welcome screen - * - * @param s string The server description - * @return Reference to self, so these method calls may be chained - */ - welcome_screen& set_description(const std::string& s); -}; - -/** - * @brief Guild NSFW level. - * Used to represent just how naughty this guild is. Naughty guild, go sit in the corner. - * @note This is set by Discord, and cannot be set by any bot or user on the guild. - */ -enum guild_nsfw_level_t : uint8_t { - /** - * @brief Default setting, not configured - */ - nsfw_default = 0, - - /** - * @brief Explicit content may be in this guild - */ - nsfw_explicit = 1, - - /** - * @brief Safe for work content only - */ - nsfw_safe = 2, - - /** - * @brief Age restricted, 18+ - */ - nsfw_age_restricted = 3 -}; - -/** - * @brief explicit content filter level. - * This is set by a guild admin, but can be forced to a setting if the server is verified, - * partnered, official etc. - */ -enum guild_explicit_content_t : uint8_t { - /** - * @brief Media content will not be scanned. - */ - expl_disabled = 0, - - /** - * @brief Media content sent by members without roles will be scanned. - */ - expl_members_without_roles = 1, - - /** - * @brief Media content sent by all members will be scanned. - */ - expl_all_members = 2 -}; - -/** - * @brief MFA level for server. - * If set to elevated all moderators need MFA to perform specific actions such as kick or ban. - */ -enum mfa_level_t : uint8_t { - /** - * @brief MFA not elevated - */ - mfa_none = 0, - - /** - * @brief MFA elevated. - */ - mfa_elevated = 1 -}; - -/** - * @brief Guild verification level - */ -enum verification_level_t : uint8_t { - /** - * @brief Unrestricted. - */ - ver_none = 0, - - /** - * @brief Must have verified email on account. - */ - ver_low = 1, - - /** - * @brief Must be registered on Discord for longer than 5 minutes. - */ - ver_medium = 2, - - /** - * @brief Must be a member of the server for longer than 10 minutes. - */ - ver_high = 3, - - /** - * @brief Must have a verified phone number. - */ - ver_very_high = 4, -}; - -/** - * @brief Default message notification level - */ -enum default_message_notification_t : uint8_t { - /** - * @brief Members will receive notifications for all messages by default. - */ - dmn_all = 0, - - /** - * @brief Members will receive notifications only for messages that \@mention them by default. - */ - dmn_only_mentions = 1, -}; - -/** - * @brief The guild's premium tier. - */ -enum guild_premium_tier_t : uint8_t { - /** - * @brief Guild has not unlocked any Server Boost perks. - */ - tier_none = 0, - - /** - * @brief Guild has unlocked Server Boost level 1 perks. - */ - tier_1 = 1, - - /** - * @brief Guild has unlocked Server Boost level 2 perks. - */ - tier_2 = 2, - - /** - * @brief Guild has unlocked Server Boost level 3 perks. - */ - tier_3 = 3, -}; - -/** - * @brief Voice AFK timeout values for guild::afk_timeout - */ -enum guild_afk_timeout_t : uint8_t { - /** - * @brief AFK timeout disabled - */ - afk_off, - - /** - * @brief AFK timeout of 1 Minute - */ - afk_60, - - /** - * @brief AFK timeout of 5 Minutes - */ - afk_300, - - /** - * @brief AFK timeout of 15 Minutes - */ - afk_900, - - /** - * @brief AFK timeout of 30 Minutes - */ - afk_1800, - - /** - * @brief AFK timeout of 1 Hour - */ - afk_3600, -}; - -/** - * @brief Guild members container - */ -typedef std::unordered_map members_container; - -/** - * @brief Represents a guild on Discord (AKA a server) - */ -class DPP_EXPORT guild : public managed, public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - guild& fill_from_json_impl(nlohmann::json* j); - - /** Build a JSON from this object. - * @param with_id True if an ID is to be included in the JSON - * @return JSON - */ - json to_json_impl(bool with_id = false) const; - -public: - using json_interface::fill_from_json; - - /** - * @brief Guild name - */ - std::string name; - - /** - * @brief Server description - */ - std::string description; - - /** - * @brief Vanity url code for verified or partnered servers and boost level 3 - * @note This field cannot be set from the API. Attempts to change this value will be - * silently ignored even if the correct number of boosts or verified/partnered status exist. - * See: https://github.com/discord/discord-api-docs/issues/519 - */ - std::string vanity_url_code; - - /** - * @brief Roles defined on this server - */ - std::vector roles; - - /** - * @brief List of channels on this server - */ - std::vector channels; - - /** - * @brief List of threads on this server - */ - std::vector threads; - - /** - * @brief List of emojis - */ - std::vector emojis; - - /** - * @brief List of members in voice channels in the guild. - */ - std::map voice_members; - - /** - * @brief List of guild members. - * - * @note When you first receive the guild create event, - * this may be empty or near empty. This depends upon your - * dpp::intents and the size of your bot. - * It will be filled by guild member chunk requests. - */ - members_container members; - - /** - * @brief Welcome screen - */ - dpp::welcome_screen welcome_screen; - - /** - * @brief Guild icon - */ - utility::icon icon; - - /** - * @brief Guild splash - */ - utility::icon splash; - - /** - * @brief Guild discovery splash - */ - utility::icon discovery_splash; - - /** - * @brief Server banner - */ - utility::icon banner; - - /** - * @brief Snowflake id of guild owner - */ - snowflake owner_id; - - /** - * @brief Snowflake ID of AFK voice channel or 0 - */ - snowflake afk_channel_id; - - /** - * @brief ID of creating application, if any, or 0 - */ - snowflake application_id; - - /** - * @brief ID of system channel where discord update messages are sent - */ - snowflake system_channel_id; - - /** - * @brief ID of rules channel for communities - */ - snowflake rules_channel_id; - - /** - * @brief Public updates channel id or 0 - */ - snowflake public_updates_channel_id; - - /** - * @brief Snowflake ID of widget channel, or 0 - */ - snowflake widget_channel_id; - - /** - * @brief The id of the channel where admins and moderators of Community guilds receive safety alerts from Discord - */ - snowflake safety_alerts_channel_id; - - /** - * @brief Approximate member count. May be sent as zero - */ - uint32_t member_count; - - /** - * @brief Flags bitmask as defined by values within dpp::guild_flags - */ - uint32_t flags; - - /** - * @brief the maximum number of presences for the guild. - * @note Generally Discord always fills this with 0, apart from for the largest of guilds - */ - uint32_t max_presences; - - /** - * @brief the maximum number of members for the guild - */ - uint32_t max_members; - - /** - * @brief Additional flags (values from dpp::guild_flags_extra) - */ - uint16_t flags_extra; - - /** - * @brief Shard ID of the guild - */ - uint16_t shard_id; - - /** - * @brief Number of boosters - */ - uint16_t premium_subscription_count; - - /** - * @brief Voice AFK timeout before moving users to AFK channel - */ - guild_afk_timeout_t afk_timeout; - - /** - * @brief Maximum users in a video channel, or 0 - */ - uint8_t max_video_channel_users; - - /** - * @brief Setting for how notifications are to be delivered to users - */ - default_message_notification_t default_message_notifications; - - /** - * @brief Boost level - */ - guild_premium_tier_t premium_tier; - - /** - * @brief Verification level of server - */ - verification_level_t verification_level; - - /** - * @brief Whether or not explicit content filtering is enable and what setting it is - */ - guild_explicit_content_t explicit_content_filter; - - /** - * @brief If multi factor authentication is required for moderators or not - */ - mfa_level_t mfa_level; - - /** - * @brief Guild NSFW level - */ - guild_nsfw_level_t nsfw_level; - - /** Default constructor, zeroes all values */ - guild(); - - /** - * @brief Destroy the guild object - */ - virtual ~guild() = default; - - /** Read class values from json object - * @param shard originating shard - * @param j A json object to read from - * @return A reference to self - */ - guild& fill_from_json(class discord_client* shard, nlohmann::json* j); - - /** - * @brief Compute the base permissions for a member on this guild, - * before channel overwrites are applied. - * This method takes into consideration the following cases: - * - Guild owner - * - Guild roles including \@everyone - * - * @param user User to get permissions for - * @return permission permissions bitmask. If the member has administrator privileges, the bitmask returns with all flags set - * @note Requires role cache to be enabled (it's enabled by default). - * - * @warning The method will search for the guild member in the cache by the users id. - * If the guild member is not in cache, the method will always return 0. - */ - permission base_permissions(const class user* user) const; - - /** - * @brief Compute the base permissions for a member on this guild, - * before channel overwrites are applied. - * This method takes into consideration the following cases: - * - Guild owner - * - Guild roles including \@everyone - * - * @param member member to get permissions for - * @return permission permissions bitmask. If the member has administrator privileges, the bitmask returns with all flags set - * @note Requires role cache to be enabled (it's enabled by default). - */ - permission base_permissions(const guild_member &member) const; - - /** - * @brief Get the overall permissions for a member in this channel, including channel overwrites, role permissions and admin privileges. - * - * @param base_permissions base permissions before overwrites, - * from guild::base_permissions - * @param user The user to resolve the permissions for - * @param channel Channel to compute permission overwrites for - * @return permission Permission overwrites for the member. Made of bits in dpp::permissions. - * @note Requires role cache to be enabled (it's enabled by default). - * - * @warning The method will search for the guild member in the cache by the users id. - * If the guild member is not in cache, the method will always return 0. - */ - permission permission_overwrites(const uint64_t base_permissions, const user* user, const channel* channel) const; - - /** - * @brief Get the overall permissions for a member in this channel, including channel overwrites, role permissions and admin privileges. - * - * @param member The member to resolve the permissions for - * @param channel Channel to compute permission overwrites for - * @return permission Permission overwrites for the member. Made of bits in dpp::permissions. - * @note Requires role cache to be enabled (it's enabled by default). - */ - permission permission_overwrites(const guild_member &member, const channel &channel) const; - - /** - * @brief Rehash members map - */ - void rehash_members(); - - /** - * @brief Connect to a voice channel another guild member is in - * - * @param owner Cluster the user's shard is on - * @param user_id User id to join - * @param self_mute True if the bot should mute itself - * @param self_deaf True if the bot should deafen itself - * @param dave True to enable DAVE E2EE - * @warning DAVE is EXPERIMENTAL and subject to change. - * @return True if the user specified is in a vc, false if they aren't - * @note This is NOT a synchronous blocking call! The bot isn't instantly ready to send or listen for audio, - * as we have to wait for the connection to the voice server to be established! - * e.g. wait for dpp::cluster::on_voice_ready event, and then send the audio within that event. - */ - bool connect_member_voice(const cluster& owner, snowflake user_id, bool self_mute = false, bool self_deaf = false, bool dave = false); - - /** - * @brief Get the banner url of the guild if it have one, otherwise returns an empty string - * - * @param size The size of the banner in pixels. It can be any power of two between 16 and 4096, - * otherwise the default sized banner is returned. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg`, `i_png` or `i_gif`. - * Passing `i_gif` might result in an invalid url for non-animated images. Consider using the `prefer_animated` parameter instead. - * @param prefer_animated Whether you prefer gif format. - * If true, it'll return gif format whenever the image is available as animated. - * @return std::string banner url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_banner_url(uint16_t size = 0, const image_type format = i_png, bool prefer_animated = true) const; - - /** - * @brief Get the discovery splash url of the guild if it have one, otherwise returns an empty string - * - * @param size The size of the discovery splash in pixels. It can be any power of two between 16 and 4096, - * otherwise the default sized discovery splash is returned. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg` or `i_png`. - * @return std::string discovery splash url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_discovery_splash_url(uint16_t size = 0, const image_type format = i_png) const; - - /** - * @brief Get the icon url of the guild if it 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. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg`, `i_png` or `i_gif`. - * When passing `i_gif`, it returns an empty string for non-animated images. Consider using the `prefer_animated` parameter instead. - * @param prefer_animated Whether you prefer gif format. - * If true, it'll return gif format whenever the image is available as animated. - * @return std::string icon url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_icon_url(uint16_t size = 0, const image_type format = i_png, bool prefer_animated = true) const; - - /** - * @brief Get the splash url of the guild if it have one, otherwise returns an empty string - * - * @param size The size of the splash in pixels. It can be any power of two between 16 and 4096, - * otherwise the default sized splash is returned. - * @param format The format to use for the avatar. It can be one of `i_webp`, `i_jpg` or `i_png`. - * @return std::string splash url or an empty string, if required attributes are missing or an invalid format was passed - */ - std::string get_splash_url(uint16_t size = 0, const image_type format = i_png) const; - - /** - * @brief Set the name of the guild in the object - * Min length: 2, Max length: 100 (not including leading/trailing spaces) - * @param n Guild name - * @return guild& reference to self - * @throw dpp::length_exception if guild name is too short - */ - guild& set_name(const std::string& n); - - /** - * @brief Remove the guild banner. - * @return guild& Reference to self for chaining - */ - guild& remove_banner(); - - /** - * @brief Set the guild banner image. Server needs banner feature. - * Must be 16:9, and depending on nitro level, must be png or jpeg. - * Animated gif needs the animated banner server feature. - * @param format Image format. - * @param data Image data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_banner(image_type format, std::string_view data); - - /** - * @brief Set the guild banner image. Server needs banner feature. - * Must be 16:9, and depending on nitro level, must be png or jpeg. - * Animated gif needs the animated banner server feature. - * @param format Image format. - * @param data Image data in bytes - * @param size Size of the data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_banner(image_type format, const std::byte* data, uint32_t size); - - /** - * @brief Remove the guild discovery splash. - * @return guild& Reference to self for chaining - */ - guild& remove_discovery_splash(); - - /** - * @brief Set the guild discovery splash image. Server needs discoverable feature. - * Must be 16:9 and png or jpeg. - * @param format Image format. - * @param data Image data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_discovery_splash(image_type format, std::string_view data); - - /** - * @brief Set the guild discovery splash image. Server needs discoverable feature. - * Must be 16:9 and png or jpeg. - * @param format Image format. - * @param data Image data in bytes - * @param size Size of the data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_discovery_splash(image_type format, const std::byte* data, uint32_t size); - - /** - * @brief Remove the guild invite splash. - * @return guild& Reference to self for chaining - */ - guild& remove_splash(); - - /** - * @brief Set the guild invite splash image. Server needs invite splash feature. - * Must be 16:9 and png or jpeg. - * @param format Image format. - * @param data Image data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_splash(image_type format, std::string_view data); - - /** - * @brief Set the guild invite splash image. Server needs invite splash feature. - * Must be 16:9 and png or jpeg. - * @param format Image format. - * @param data Image data in bytes - * @param size Size of the data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_splash(image_type format, const std::byte* data, uint32_t size); - - /** - * @brief Remove the guild icon. - * @return guild& Reference to self for chaining - */ - guild& remove_icon(); - - /** - * @brief Set the guild icon image. - * Must be 1024x1024 and png or jpeg. Gif allowed only if the server has animated icon. - * @param format Image format. - * @param data Image data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_icon(image_type format, std::string_view data); - - /** - * @brief Set the 1024x1024 guild icon image. - * Must be png or jpeg. Gif allowed only if the server has animated icon. - * @param format Image format. - * @param data Image data in bytes - * @param size Size of the data in bytes - * @return guild& Reference to self for chaining - */ - guild& set_icon(image_type format, const std::byte* data, uint32_t size); - - /** - * @brief Is a large server (>250 users) - * @return bool is a large guild - */ - bool is_large() const; - - /** - * @brief Is unavailable due to outage (most other fields will be blank or outdated - * @return bool is unavailable - */ - bool is_unavailable() const; - - /** - * @brief Widget is enabled for this server - * @return bool widget enabled - */ - bool widget_enabled() const; - - /** - * @brief Guild has access to set an invite splash background - * @return bool can have an invite splash - */ - bool has_invite_splash() const; - - /** - * @brief Guild has access to set 384kbps bitrate in voice - * @return bool can have VIP voice regions - */ - bool has_vip_regions() const; - - /** - * @brief Guild has access to set a vanity URL - * @return bool can have vanity url - */ - bool has_vanity_url() const; - - /** - * @brief Guild is a verified server - * @return bool is verified - */ - bool is_verified() const; - - /** - * @brief Guild is a discord partnered server - * @return bool is discord partnered - */ - bool is_partnered() const; - - /** - * @brief Has enabled community - * @return bool has enabled community - */ - bool is_community() const; - - /** - * @brief Has enabled role subscriptions - * @return bool has enabled role subscriptions - */ - bool has_role_subscriptions() const; - - /** - * @brief Guild has access to create announcement channels - * @return bool has announcement channels features enabled - */ - bool has_news() const; - - /** - * @brief Guild is discoverable - * @return bool is discoverable - */ - bool is_discoverable() const; - - /** - * @brief Guild is featurable - * @return bool is featurable - */ - bool is_featureable() const; - - /** - * @brief Guild has access to set an animated guild banner image - * @return bool can have animated banner image - */ - bool has_animated_banner() const; - - /** - * @brief Guild has auto moderation features - * @return bool has auto moderation features - */ - bool has_auto_moderation() const; - - /** - * @brief Guild has been set as a support server on the App Directory - * @return bool has been set as a support server of an app in the app directory - */ - bool has_support_server() const; - - /** - * @brief Guild has role subscriptions that can be purchased - * @return bool has role subscriptions that can be purchased - */ - bool has_role_subscriptions_available_for_purchase() const; - - /** - * @brief Guild has disabled alerts for join raids in the configured safety alerts channel - * @return bool dpp::g_raid_alerts_disabled flag is set - */ - bool has_raid_alerts_disabled() const; - - /** - * @brief Guild has access to set an animated guild icon - * @return bool can have animated icon - */ - bool has_animated_icon() const; - - /** - * @brief Guild has access to set a guild banner image - * @return bool can have banner image - */ - bool has_banner() const; - - /** - * @brief Guild has enabled the welcome screen - * @return bool enabled welcome screen - */ - bool is_welcome_screen_enabled() const; - - /** - * @brief Guild has enabled membership screening - * @return bool has membership screening - */ - bool has_member_verification_gate() const; - - /** - * @brief Guild has preview enabled - * @return bool has preview - */ - bool is_preview_enabled() const; - - /** - * @brief Guild icon is actually an animated gif - * @return bool is animated gif - */ - bool has_animated_icon_hash() const; - - /** - * @brief Guild banner is actually an animated gif - * @return bool is animated gif - */ - bool has_animated_banner_hash() const; - - - /** - * @brief guild has access to monetization features - * @return bool - */ - bool has_monetization_enabled() const; - - /** - * @brief guild has increased custom sticker slots - * @return bool has more stickers - */ - bool has_more_stickers() const; - - /** - * @brief guild has enabled the role subscription promo page - * @return bool has role subscription promo page enabled - */ - bool has_creator_store_page() const; - - /** - * @brief guild is able to set role icons - * @return bool has role icons - */ - bool has_role_icons() const; - - /** - * @brief guild has access to the seven day archive time for threads - * @return bool has seven day thread archive - * @deprecated Removed by Discord - */ - bool has_seven_day_thread_archive() const; - - /** - * @brief guild has access to the three day archive time for threads - * @return bool has three day thread archive - * @deprecated Removed by Discord - */ - bool has_three_day_thread_archive() const; - - /** - * @brief guild has enabled ticketed events - * @return bool has ticketed events - */ - bool has_ticketed_events() const; - - /** - * @brief guild has access to channel banners feature - * @return bool has channel banners - * @deprecated Removed by Discord - */ - bool has_channel_banners() const; - - /** - * @brief True if the premium progress bar is enabled - * @return bool has progress bar enabled - */ - bool has_premium_progress_bar_enabled() const; - - /** - * @brief True if has paused invites, preventing new users from joining - * @return bool has paused invites - */ - bool has_invites_disabled() const; -}; - -/** - * @brief A container of guilds - */ -typedef std::unordered_map guild_map; - -/** - * @brief Represents a guild widget, simple web widget of member list - */ -class DPP_EXPORT guild_widget : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Build a guild widget from json - * - * @param j json to build from - * @return guild_widget& reference to self - */ - guild_widget& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build json for a guild widget - * - * @param with_id Add ID to output - * @return std::string guild widget stringified json - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Channel widget points to - */ - snowflake channel_id; - - /** - * @brief True if enabled - */ - bool enabled; - - /** - * @brief Construct a new guild widget object - */ - guild_widget(); -}; - -/** - * @brief The onboarding mode for the dpp::onboarding object. Defines the criteria used to satisfy Onboarding constraints that are required for enabling. - */ -enum onboarding_mode : uint8_t { - /** - * @brief Counts only Default Channels towards constraints. - */ - gom_default = 0, - - /** - * @brief Counts Default Channels and Questions towards constraints. - */ - gom_advanced = 1, -}; - -/** - * @brief The various types of dpp::onboarding_prompt - */ -enum onboarding_prompt_type : uint8_t { - /** - * @brief Multiple choice. - */ - opt_multiple_choice = 0, - - /** - * @brief Dropdown. - */ - opt_dropdown = 1, -}; - -/** - * @brief Various flags for dpp::onboarding_prompt - */ -enum onboarding_prompt_flags : uint8_t { - /** - * @brief Indicates whether users are limited to selecting one option for the prompt. - */ - opf_single_select = 1 << 0, - - /** - * @brief Indicates whether the prompt is required before a user completes the onboarding flow. - */ - opf_required = 1 << 1, - - /** - * @brief Indicates whether the prompt is present in the onboarding flow. - * If set, the prompt will only appear in the Channels & Roles tab - */ - opf_in_onboarding = 1 << 2, -}; - -/** - * @brief Represents an onboarding prompt option - */ -struct DPP_EXPORT onboarding_prompt_option : public managed, public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Read class values from json object - * - * @param j A json object to read from - * @return A reference to self - */ - onboarding_prompt_option& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build the json for this object - * - * @param with_id include the id in the JSON - * @return json data - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief IDs for channels a member is added to when the option is selected. - */ - std::vector channel_ids; - - /** - * @brief IDs for roles assigned to a member when the option is selected - */ - std::vector role_ids; - - /** - * @brief Emoji of the option - */ - dpp::emoji emoji; - - /** - * @brief Title of the option - */ - std::string title; - - /** - * @brief Description of the option - */ - std::string description; - - /** - * @brief Construct a new onboarding prompt option object - */ - onboarding_prompt_option(); - - /** - * @brief Destroy the onboarding prompt option object - */ - virtual ~onboarding_prompt_option() = default; - - /** - * @brief Set the emoji of this onboarding prompt option object - * - * @param _emoji The emoji to set - * @return Reference to self, so these method calls may be chained - */ - onboarding_prompt_option& set_emoji(const dpp::emoji& _emoji); - - /** - * @brief Set the title of this onboarding prompt option object - * - * @param _title The title to set - * @return Reference to self, so these method calls may be chained - */ - onboarding_prompt_option& set_title(const std::string& _title); - - /** - * @brief Set the description of this onboarding prompt option object - * - * @param _description The description to set - * @return Reference to self, so these method calls may be chained - */ - onboarding_prompt_option& set_description(const std::string& _description); -}; - -/** - * @brief Represents an onboarding prompt - */ -struct DPP_EXPORT onboarding_prompt : public managed, public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Read class values from json object - * - * @param j A json object to read from - * @return A reference to self - */ - onboarding_prompt& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build the json for this object - * - * @param with_id include the id in the JSON - * @return json data - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Type of prompt (defaults to dpp::opt_multiple_choice). - */ - onboarding_prompt_type type; - - /** - * @brief Options available within the prompt - */ - std::vector options; - - /** - * @brief Title of the prompt. - */ - std::string title; - - /** - * @brief A set of flags built from the bitmask defined by dpp::onboarding_prompt_flags - */ - uint8_t flags; - - /** - * @brief Construct a new onboarding prompt object - */ - onboarding_prompt(); - - /** - * @brief Destroy the onboarding prompt object - */ - virtual ~onboarding_prompt() = default; - - /** - * @brief Set the type of this onboarding prompt object - * - * @param _type The prompt type to set - * @return Reference to self, so these method calls may be chained - */ - onboarding_prompt& set_type(const onboarding_prompt_type _type); - - /** - * @brief Set the title of this onboarding prompt object - * - * @param _title The title to set - * @return Reference to self, so these method calls may be chained - */ - onboarding_prompt& set_title(const std::string& _title); - - /** - * @brief Indicates whether users are limited to selecting one option for the prompt - * @return bool True if the users are limited to selecting one option for the prompt - */ - bool is_single_select() const; - - /** - * @brief Indicates whether the prompt is required before a user completes the onboarding flow - * @return bool True if the prompt is required before a user completes the onboarding flow - */ - bool is_required() const; - - /** - * @brief Indicates whether the prompt is present in the onboarding flow - * @return bool True if the prompt is present in the onboarding flow. False if the prompt will only appear in the Channels & Roles tab - */ - bool is_in_onboarding() const; -}; - -/** - * @brief Represents a guild's onboarding flow - */ -struct DPP_EXPORT onboarding : public json_interface { -protected: - friend struct json_interface; - - /** - * @brief Read class values from json object - * - * @param j A json object to read from - * @return A reference to self - */ - onboarding& fill_from_json_impl(nlohmann::json* j); - - /** - * @brief Build the json for this object - * - * @param with_id include the id in the JSON - * @return json data - */ - json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief ID of the guild this onboarding is part of. - */ - snowflake guild_id; - - /** - * @brief Prompts shown during onboarding and in customize community. - */ - std::vector prompts; - - /** - * @brief Channel IDs that members get opted into automatically - */ - std::vector default_channel_ids; - - /** - * @brief Current mode of onboarding (defaults to dpp::gom_default) - */ - onboarding_mode mode; - - /** - * @brief Whether onboarding is enabled in the guild - */ - bool enabled; - - /** - * @brief Construct a new onboarding object - */ - onboarding(); - - /** - * @brief Destroy the onboarding object - */ - virtual ~onboarding() = default; - - /** - * @brief Set guild_id of this onboarding object - * - * @param id Guild ID to set - * @return Reference to self, so these method calls may be chained - */ - onboarding& set_guild_id(const snowflake id); - - /** - * @brief Set the mode of this onboarding object - * - * @param m onboarding_mode Mode to set - * @return Reference to self, so these method calls may be chained - */ - onboarding& set_mode(const onboarding_mode m); - - /** - * @brief Set the enabling of this onboarding object - * - * @param is_enabled bool Whether onboarding is enabled in the guild - * @return Reference to self, so these method calls may be chained - */ - onboarding& set_enabled(const bool is_enabled); -}; - -/** - * @brief helper function to deserialize a guild_member from json - * - * @see https://github.com/nlohmann/json#arbitrary-types-conversions - * - * @param j output json object - * @param gm guild_member to be deserialized - */ -void from_json(const nlohmann::json& j, guild_member& gm); - -/** - * @brief A container of guild members - */ -typedef std::unordered_map guild_member_map; - -/** - * @brief Get the guild_member from cache of given IDs - * - * @param guild_id ID of the guild to find guild_member for - * @param user_id ID of the user to find guild_member for - * - * @throw dpp::cache_exception if the guild or guild_member is not found in the cache - * @return guild_member the cached object, if found - */ -guild_member DPP_EXPORT find_guild_member(const snowflake guild_id, const snowflake user_id); - -} diff --git a/include/dpp/http_server.h b/include/dpp/http_server.h deleted file mode 100644 index 6846995..0000000 --- a/include/dpp/http_server.h +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Creates a simple HTTP server which listens on a TCP port for a - * plaintext or SSL incoming request, and passes that request to a callback - * to generate the response. - */ -struct DPP_EXPORT http_server : public socket_listener { - - /** - * @brief Request handler callback to use for all incoming HTTP(S) requests - */ - http_server_request_event request_handler; - - /** - * @brief Port we are listening on - */ - uint16_t bound_port; - - /** - * @brief Constructor for creation of a HTTP(S) server - * @param creator Cluster creator - * @param address address to bind to, use "0.0.0.0" to bind to all local addresses - * @param port port to bind to. You should generally use a port > 1024. - * @param handle_request Callback to call for each pending request - * @param private_key Private key PEM file for HTTPS/SSL. If empty, a plaintext server is created - * @param public_key Public key PEM file for HTTPS/SSL. If empty, a plaintext server is created - */ - http_server(cluster* creator, const std::string_view address, uint16_t port, http_server_request_event handle_request, const std::string& private_key = "", const std::string& public_key = ""); - - /** - * @brief Emplace a new request into the connection pool - * @param newfd file descriptor of new request - */ - void emplace(socket newfd) override; - - /** - * @brief Destructor - */ - virtual ~http_server() { - detail::release_ssl_context(bound_port); - } -}; - -} diff --git a/include/dpp/http_server_request.h b/include/dpp/http_server_request.h deleted file mode 100644 index 922772f..0000000 --- a/include/dpp/http_server_request.h +++ /dev/null @@ -1,260 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Callback type for HTTP server request callbacks - */ -using http_server_request_event = std::function; - -/* - * @brief Implements a HTTPS socket client based on the SSL client. - * @note plaintext HTTP without SSL is also supported via a "downgrade" setting - */ -class DPP_EXPORT http_server_request : public ssl_connection { - /** - * @brief The request body, e.g. form data - */ - std::string request_body; - - /** - * @brief Headers from the client - */ - http_headers request_headers; - - /** - * @brief Time at which the request should be abandoned - */ - time_t timeout; - - /** - * @brief Headers for our response - */ - http_headers response_headers; - - /** - * @brief Handler to handle the inbound request - */ - http_server_request_event handler{}; - - /** - * @brief Response body - */ - std::string response_body; - -protected: - - /** - * @brief The type of the request, e.g. GET, POST - */ - std::string request_type; - - /** - * @brief Path part of URL for HTTPS connection - */ - std::string path; - - /** - * @brief Current connection state - */ - http_state state; - - /** - * @brief HTTP status code for response - */ - uint16_t status{0}; - - /** - * @brief Start the connection - */ - virtual void connect() override; - - /** - * @brief Called when the output buffer is drained to empty - */ - void on_buffer_drained() override; - - /** - * @brief Maximum size of POST body - */ - [[nodiscard]] uint64_t get_max_post_size() const; - - /** - * @brief Maximum size of headers - */ - [[nodiscard]] uint64_t get_max_header_size() const; - - /** - * @brief Reply with an error message - * @param error_code error code - * @param message message - */ - void generate_error(uint16_t error_code, const std::string& message); - -public: - /** - * @brief If true the response timed out while waiting - */ - bool timed_out; - - /** - * @brief Get request state - * @return request state - */ - http_state get_state() const; - - /** - * @brief Get current response body - * @return response body - */ - std::string get_response_body() const; - - /** - * @brief Get current request body - * @return request body - */ - std::string get_request_body() const; - - /** - * @brief Get current status code - * @return status code - */ - uint16_t get_status() const; - - /** - * @brief Content length sent by client - */ - uint64_t content_length{ULLONG_MAX}; - - /** - * @brief Construct a new server request object. - * Server request objects are instantiated for an incoming server connection, as such they already - * have a file descriptor. - * @param creator creating owner - * @param fd file descriptor - * @param port Port the connection came in on - * @param plaintext_downgrade true if plaintext, false if SSL - * @param private_key if SSL, the path to the private key PEM - * @param public_key if SSL, the path to the public key PEM - * @param handle_request request handler callback - */ - http_server_request(cluster* creator, socket fd, uint16_t port, bool plaintext_downgrade, const std::string& private_key, const std::string& public_key, http_server_request_event handle_request); - - /** - * @brief Destroy the https client object - */ - virtual ~http_server_request() override; - - /** - * @brief Processes incoming data from the SSL socket input buffer. - * - * @param buffer The buffer contents. Can modify this value removing the head elements when processed. - */ - virtual bool handle_buffer(std::string &buffer) override; - - /** - * @brief Close HTTPS socket - */ - virtual void close() override; - - /** - * @brief Fires every second from the underlying socket I/O loop, used for timeouts - */ - virtual void one_second_timer() override; - - /** - * @brief Get a HTTP request header - * - * @param header_name Header name to find, case insensitive - * @return Header content or empty string if not found. - * If multiple values have the same header_name, this will return one of them. - * @see get_header_count to determine if multiple are present - * @see get_header_list to retrieve all entries of the same header_name - */ - [[nodiscard]] const std::string get_header(const std::string& header_name) const; - - /** - * @brief Get the number of headers with the same header name - * - * @param header_name - * @return the number of headers with this count - */ - [[nodiscard]] size_t get_header_count(const std::string& header_name) const; - - /** - * @brief Get a set of HTTP request headers with a common name - * - * @param header_name - * @return A list of headers with the same name, or an empty list if not found - */ - [[nodiscard]] std::list get_header_list(const std::string& header_name) const; - - /** - * @brief Get all HTTP request headers - * - * @return headers as a map - */ - [[nodiscard]] std::multimap get_headers() const; - - /** - * @brief Set a response header - * @param header header name - * @param value header value - * @return ref to self - */ - http_server_request& set_response_header(const std::string& header, const std::string& value); - - /** - * @brief Set the response content - * - * @param new_content response content - */ - http_server_request& set_response_body(const std::string& new_content); - - /** - * @brief Set the response HTTP status, e.g. - * 200 for OK, 404 for not found, 429 for rate limited etc. - * - * @param new_status HTTP status - */ - http_server_request& set_status(uint16_t new_status); - - /** - * @brief Get whole response as a string - */ - [[nodiscard]] std::string get_response(); -}; - -} diff --git a/include/dpp/httpsclient.h b/include/dpp/httpsclient.h deleted file mode 100644 index 95e52db..0000000 --- a/include/dpp/httpsclient.h +++ /dev/null @@ -1,357 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -static inline const std::string http_version = "DiscordBot (https://github.com/brainboxdotcc/DPP, " - + to_hex(DPP_VERSION_MAJOR, false) + "." + to_hex(DPP_VERSION_MINOR, false) + "." + to_hex(DPP_VERSION_PATCH, false) + ")"; - -static inline constexpr const char* DISCORD_HOST = "https://discord.com"; - -/** - * @brief HTTP connection status - */ -enum http_state : uint8_t { - /** - * @brief Sending/receiving HTTP headers and request body - */ - HTTPS_HEADERS, - - /** - * @brief Receiving body content. - */ - HTTPS_CONTENT, - - /** - * @brief Completed connection, as it was closed or the body is >= Content-Length - * - */ - HTTPS_DONE, - - /** - * @brief Received chunk length - * - */ - HTTPS_CHUNK_LEN, - - /** - * @brief Received chunk trailing CRLF - */ - HTTPS_CHUNK_TRAILER, - - /** - * @brief The last received chunk is the final chunk - */ - HTTPS_CHUNK_LAST, - - /** - * @brief Receiving contents of a chunk - */ - HTTPS_CHUNK_CONTENT -}; - -/** - * @brief Request headers - */ -typedef std::multimap http_headers; - -/** - * @brief Represents a multipart mime body and the correct top-level mime type - * If a non-multipart request is passed in, this is represented as a plain body - * and the application/json mime type. - */ -struct multipart_content { - /** - * @brief Multipart body - */ - std::string body; - - /** - * @brief MIME type - */ - std::string mimetype; -}; - -/** - * @brief Represents a HTTP scheme, hostname and port - * split into parts for easy use in https_client. - */ -struct http_connect_info { - /** - * @brief True if the connection should be SSL - */ - bool is_ssl{}; - - /** - * @brief The request scheme, e.g. 'https' or 'http' - */ - std::string scheme; - - /** - * @brief The request hostname part, e.g. 'discord.com' - */ - std::string hostname; - - /** - * @brief The port number, either determined from the scheme, - * or from the part of the hostname after a colon ":" character - */ - uint16_t port{}; -}; - -using https_client_completion_event = std::function; - -/** - * @brief Implements a HTTPS socket client based on the SSL client. - * @note plaintext HTTP without SSL is also supported via a "downgrade" setting - */ -class DPP_EXPORT https_client : public ssl_connection { - - /** - * @brief The type of the request, e.g. GET, POST - */ - std::string request_type; - - /** - * @brief Path part of URL for HTTPS connection - */ - std::string path; - - /** - * @brief The request body, e.g. form data - */ - std::string request_body; - - /** - * @brief The response body, e.g. file content or JSON - */ - std::string body; - - /** - * @brief The reported length of the content. If this is - * UULONG_MAX, then no length was reported by the server. - */ - uint64_t content_length; - - /** - * @brief Headers for the request, e.g. Authorization, etc. - */ - http_headers request_headers; - - /** - * @brief The status of the HTTP request from the server, - * e.g. 200 for OK, 404 for not found. A value of 0 means - * no request has been completed. - */ - uint16_t status; - - /** - * @brief The HTTP protocol to use - */ - std::string http_protocol; - - /** - * @brief Time at which the request should be abandoned - */ - time_t timeout; - - /** - * @brief If true the content is chunked encoding - */ - bool chunked; - - /** - * @brief Size of current chunk - */ - size_t chunk_size; - - /** - * @brief Number of bytes received in current chunk - */ - size_t chunk_receive; - - /** - * @brief Headers from the server's response, e.g. RateLimit - * headers, cookies, etc. - */ - std::multimap response_headers; - -protected: - /** - * @brief Start the connection - */ - virtual void connect() override; - - /** - * @brief Get request state - * @return request state - */ - http_state get_state(); - -public: - /** - * @brief If true the response timed out while waiting - */ - bool timed_out; - - /** - * @brief Function to call when HTTP request is completed - */ - https_client_completion_event completed; - - /** - * @brief Current connection state - */ - http_state state; - - /** - * @brief Connect to a specific HTTP(S) server and complete a request. - * - * The constructor will attempt the connection, and return the content. - * By the time the constructor completes, the HTTP request will be stored - * in the object. - * - * @note This is a blocking call. It starts a loop which runs non-blocking - * functions within it, but does not return until the request completes. - * See queues.cpp for how to make this asynchronous. - * - * @param hostname Hostname to connect to - * @param port Port number to connect to, usually 443 for SSL and 80 for plaintext - * @param urlpath path part of URL, e.g. "/api" - * @param verb Request verb, e.g. GET or POST - * @param req_body Request body, use dpp::https_client::build_multipart() to build a multipart MIME body (e.g. for multiple file upload) - * @param extra_headers Additional request headers, e.g. user-agent, authorization, etc - * @param plaintext_connection Set to true to make the connection plaintext (turns off SSL) - * @param request_timeout How many seconds before the connection is considered failed if not finished - * @param protocol Request HTTP protocol (default: 1.1) - * @param done Function to call when https_client request is completed - */ - https_client(cluster* creator, const std::string &hostname, uint16_t port = 443, const std::string &urlpath = "/", const std::string &verb = "GET", const std::string &req_body = "", const http_headers& extra_headers = {}, bool plaintext_connection = false, uint16_t request_timeout = 5, const std::string &protocol = "1.1", https_client_completion_event done = {}); - - /** - * @brief Destroy the https client object - */ - virtual ~https_client() override; - - /** - * @brief Build a multipart content from a set of files and some json - * - * @param json The json content - * @param filenames File names of files to send - * @param contents Contents of each of the files to send - * @param mimetypes MIME types of each of the files to send - * @return multipart mime content and headers - */ - static multipart_content build_multipart(const std::string &json, const std::vector& filenames = {}, const std::vector& contents = {}, const std::vector& mimetypes = {}); - - /** - * @brief Processes incoming data from the SSL socket input buffer. - * - * @param buffer The buffer contents. Can modify this value removing the head elements when processed. - */ - virtual bool handle_buffer(std::string &buffer) override; - - /** - * @brief Close HTTPS socket - */ - virtual void close() override; - - /** - * @brief Fires every second from the underlying socket I/O loop, used for timeouts - */ - virtual void one_second_timer() override; - - /** - * @brief Get a HTTP response header - * - * @param header_name Header name to find, case insensitive - * @return Header content or empty string if not found. - * If multiple values have the same header_name, this will return one of them. - * @see get_header_count to determine if multiple are present - * @see get_header_list to retrieve all entries of the same header_name - */ - const std::string get_header(std::string header_name) const; - - /** - * @brief Get the number of headers with the same header name - * - * @param header_name - * @return the number of headers with this count - */ - size_t get_header_count(std::string header_name) const; - - - /** - * @brief Get a set of HTTP response headers with a common name - * - * @param header_name - * @return A list of headers with the same name, or an empty list if not found - */ - const std::list get_header_list(std::string header_name) const; - - /** - * @brief Get all HTTP response headers - * - * @return headers as a map - */ - const std::multimap get_headers() const; - - /** - * @brief Get the response content - * - * @return response content - */ - const std::string get_content() const; - - /** - * @brief Get the response HTTP status, e.g. - * 200 for OK, 404 for not found, 429 for rate limited. - * A value of 0 indicates the request was not completed. - * - * @return uint16_t HTTP status - */ - uint16_t get_status() const; - - /** - * @brief Break down a scheme, hostname and port into - * a http_connect_info. - * - * All but the hostname portion are optional. The path component - * should not be passed to this function. - * - * @param url URL to break down - * @return Split URL - */ - static http_connect_info get_host_info(std::string url); -}; - -} diff --git a/include/dpp/integration.h b/include/dpp/integration.h deleted file mode 100644 index e5edfd1..0000000 --- a/include/dpp/integration.h +++ /dev/null @@ -1,353 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Where an app can be installed, also called its supported installation contexts. - */ -enum application_integration_types : uint8_t { - /** - * @brief Installable to servers - */ - ait_guild_install = 0, - /** - * @brief Installable to users - */ - ait_user_install = 1, -}; - -/** - * @brief Integration types - */ -enum integration_type : uint8_t { - /** - * @brief Twitch integration - */ - i_twitch, - - /** - * @brief YouTube integration - */ - i_youtube, - - /** - * @brief Discord integration - */ - i_discord, - - /** - * @brief Subscription - */ - i_guild_subscription, -}; - -/** - * @brief Integration flags - */ -enum integration_flags : uint8_t { - /** - * @brief Is this integration enabled? - */ - if_enabled = 0b00000001, - - /** - * @brief Is this integration syncing? - * @warning This is not provided for discord bot integrations. - */ - if_syncing = 0b00000010, - - /** - * @brief Whether emoticons should be synced for this integration (twitch only currently). - * @warning This is not provided for discord bot integrations. - */ - if_emoticons = 0b00000100, - - /** - * @brief Has this integration been revoked? - * @warning This is not provided for discord bot integrations. - */ - if_revoked = 0b00001000, - - /** - * @brief Kick user when their subscription expires, otherwise only remove the role that is specified by `role_id`. - * @warning This is not provided for discord bot integrations. - */ - if_expire_kick = 0b00010000, -}; - -/** - * @brief An application that has been integrated - */ -struct DPP_EXPORT integration_app { - /** - * @brief The id of the app. - */ - snowflake id; - - /** - * @brief The name of the app. - */ - std::string name; - - /** - * @brief The icon hash of the app. - */ - utility::iconhash icon; - - /** - * @brief The description of the app - */ - std::string description; - - /** - * @brief The bot associated with this application. - */ - class user* bot; -}; - -/** - * @brief The account information for an integration. - */ -struct DPP_EXPORT integration_account { - /** - * @brief ID of the account - */ - snowflake id; - - /** - * @brief Name of the account. - */ - std::string name; -}; - -/** - * @brief Represents an integration on a guild, e.g. a connection to twitch. - */ -class DPP_EXPORT integration : public managed, public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - integration& fill_from_json_impl(nlohmann::json* j); - - /** Build a json from this object. - * @param with_id Add ID to output - * @return JSON of the object - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Integration name. - */ - std::string name; - - /** - * @brief Integration type (twitch, youtube, discord, or guild_subscription). - */ - integration_type type; - - /** - * @brief Integration flags from dpp::integration_flags - */ - uint8_t flags; - - /** - * @brief ID that this integration uses for "subscribers". - * - * @warning This is not provided for discord bot integrations. - */ - snowflake role_id; - - /** - * @brief The grace period (in days) before expiring subscribers. - * - * @warning This is not provided for discord bot integrations. - */ - uint32_t expire_grace_period; - - /** - * @brief User for this integration - */ - user user_obj; - - /** - * @brief Integration account information - */ - integration_account account; - - /** - * @brief When this integration was last synced. - * - * @warning This is not provided for discord bot integrations. - */ - time_t synced_at; - - /** - * @brief How many subscribers this integration has. - * - * @warning This is not provided for discord bot integrations. - */ - uint32_t subscriber_count; - - /** - * @brief The bot/OAuth2 application for discord integrations. - */ - integration_app app; - - /** - * @brief The scopes the application has been authorized for. - */ - std::vector scopes; - - /** Default constructor */ - integration(); - - /** Default destructor */ - ~integration() = default; - - /** - * Are emoticons enabled for this integration? - * @warning This is not provided for discord bot integrations. - */ - bool emoticons_enabled() const; - - /** - * Is the integration enabled? - * @warning This is not provided for discord bot integrations. - */ - bool is_enabled() const; - - /** - * Is the integration syncing? - * @warning This is not provided for discord bot integrations. - */ - bool is_syncing() const; - - /** - * Has this integration been revoked? - * @warning This is not provided for discord bot integrations. - */ - bool is_revoked() const; - - /** - * Will the user be kicked if their subscription runs out to the integration? - * If false, the integration will simply remove the role that is specified by `role_id`. - * @warning This is not provided for discord bot integrations. - */ - bool expiry_kicks_user() const; -}; - -/** - * @brief The connection object that the user has attached. - */ -class DPP_EXPORT connection : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - connection& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief ID of the connection account. - */ - std::string id; - - /** - * @brief the username of the connection account. - */ - std::string name; - - /** - * @brief the service of the connection (twitch, youtube, discord, or guild_subscription). - */ - std::string type; - - /** - * @brief Optional: whether the connection is revoked. - */ - bool revoked; - - /** - * @brief Optional: an array of partial server integrations. - */ - std::vector integrations; - - /** - * @brief Whether the connection is verified. - */ - bool verified; - - /** - * @brief Whether friend sync is enabled for this connection. - */ - bool friend_sync; - - /** - * @brief Whether activities related to this connection will be shown in presence updates. - */ - bool show_activity; - - /** - * @brief Whether this connection has a corresponding third party OAuth2 token. - */ - bool two_way_link; - - /** - * @brief Visibility of this connection. - */ - bool visible; - - /** - * @brief Construct a new connection object - */ - connection(); -}; - -/** - * @brief A group of integrations - */ -typedef std::unordered_map integration_map; - -/** - * @brief A group of connections - */ -typedef std::unordered_map connection_map; - -} - diff --git a/include/dpp/intents.h b/include/dpp/intents.h deleted file mode 100644 index f2e82b0..0000000 --- a/include/dpp/intents.h +++ /dev/null @@ -1,155 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -namespace dpp { - -/** - * @brief intents are a bitmask of allowed events on your websocket. - * - * Some of these are known as Privileged intents (GUILD_MEMBERS and GUILD_PRESENCES) - * and require verification of a bot over 100 servers by discord via submission of - * your real life ID. - */ -enum intents { - /** - * @brief Intent for receipt of guild information. - */ - i_guilds = (1 << 0), - - /** - * @brief Intent for receipt of guild members. - */ - i_guild_members = (1 << 1), - - /** - * @brief Intent for receipt of guild bans. - */ - i_guild_bans = (1 << 2), - - /** - * @brief Intent for receipt of guild emojis. - */ - i_guild_emojis = (1 << 3), - - /** - * @brief Intent for receipt of guild integrations. - */ - i_guild_integrations = (1 << 4), - - /** - * @brief Intent for receipt of guild webhooks. - */ - i_guild_webhooks = (1 << 5), - - /** - * @brief Intent for receipt of guild invites. - */ - i_guild_invites = (1 << 6), - - /** - * @brief Intent for receipt of guild voice states. - */ - i_guild_voice_states = (1 << 7), - - /** - * @brief Intent for receipt of guild presences. - */ - i_guild_presences = (1 << 8), - - /** - * @brief Intent for receipt of guild messages. - */ - i_guild_messages = (1 << 9), - - /** - * @brief Intent for receipt of guild message reactions. - */ - i_guild_message_reactions = (1 << 10), - - /** - * @brief Intent for receipt of guild message typing notifications. - */ - i_guild_message_typing = (1 << 11), - - /** - * @brief Intent for receipt of direct messages (DMs). - */ - i_direct_messages = (1 << 12), - - /** - * @brief Intent for receipt of direct message reactions. - */ - i_direct_message_reactions = (1 << 13), - - /** - * @brief Intent for receipt of direct message typing notifications. - */ - i_direct_message_typing = (1 << 14), - - /** - * @brief Intent for receipt of message content. - */ - i_message_content = (1 << 15), - - /** - * @brief Scheduled events. - */ - i_guild_scheduled_events = (1 << 16), - - /** - * @brief Auto moderation configuration. - */ - i_auto_moderation_configuration = (1 << 20), - - /** - * @brief Auto moderation configuration. - */ - i_auto_moderation_execution = (1 << 21), - - /** - * @brief Default D++ intents (all non-privileged intents). - */ - i_default_intents = dpp::i_guilds | dpp::i_guild_bans | dpp::i_guild_emojis | dpp::i_guild_integrations | - dpp::i_guild_webhooks | dpp::i_guild_invites | dpp::i_guild_voice_states | - dpp::i_guild_messages | dpp::i_guild_message_reactions | dpp::i_guild_message_typing | - dpp::i_direct_messages | dpp::i_direct_message_typing | dpp::i_direct_message_reactions | - dpp::i_guild_scheduled_events | dpp::i_auto_moderation_configuration | - dpp::i_auto_moderation_execution, - - /** - * @brief Privileged intents requiring ID. - */ - i_privileged_intents = dpp::i_guild_members | dpp::i_guild_presences | dpp::i_message_content, - - /** - * @brief Every single intent (dpp::i_default_intents and dpp::i_privileged_intents). - */ - i_all_intents = dpp::i_default_intents | dpp::i_privileged_intents, - - /** - * @brief Unverified bots default intents. - */ - i_unverified_default_intents = dpp::i_default_intents | dpp::i_message_content -}; - -} diff --git a/include/dpp/invite.h b/include/dpp/invite.h deleted file mode 100644 index d1d9a93..0000000 --- a/include/dpp/invite.h +++ /dev/null @@ -1,245 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Invite target types for dpp::invite - */ -enum invite_target_t : uint8_t { - /** - * @brief Undefined invite target type. - */ - itt_none = 0, - - /** - * @brief Stream target type. - */ - itt_stream = 1, - - /** - * @brief Embedded Application target type. - */ - itt_embedded_application = 2, -}; - -/** - * @brief Represents an invite to a discord guild or channel - */ -class DPP_EXPORT invite : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - invite& fill_from_json_impl(nlohmann::json* j); - - /** Build JSON from this object. - * @param with_id Include ID in JSON - * @return The JSON of the invite - */ - virtual json to_json_impl(bool with_id = false) const; - -public: - /** - * @brief Invite code. - */ - std::string code; - - /** - * @brief Readonly expiration timestamp of this invite or 0 if the invite doesn't expire. - * @note Only returned from cluster::invite_get - */ - time_t expires_at; - - /** - * @brief Guild ID this invite is for. - */ - snowflake guild_id; - - /** - * @brief The partial guild this invite is for. - * @note Only filled in retrieved invites. - */ - guild destination_guild; - - /** - * @brief Channel ID this invite is for. - */ - snowflake channel_id; - - /** - * @brief The partial channel this invite is for. - * @note Only filled in retrieved invites. - */ - channel destination_channel; - - /** - * @brief User ID who created this invite. - * @deprecated Use the `inviter` field instead - */ - snowflake inviter_id; - - /** - * @brief User who created this invite. - */ - user inviter; - - /** - * @brief The user ID whose stream to display for this voice channel stream invite. - */ - snowflake target_user_id; - - /** - * @brief Target type for this voice channel invite. - */ - invite_target_t target_type; - - /** - * @brief Approximate number of online users. - * @note Only returned from cluster::invite_get - */ - uint32_t approximate_presence_count; - - /** - * @brief Approximate number of total users online and offline. - * @note Only returned from cluster::invite_get. - */ - uint32_t approximate_member_count; - - /** - * @brief Duration (in seconds) after which the invite expires, or 0 for no expiration. Defaults to 86400 (1 day). - * - * @note Must be between 0 and 604800 (7 days). - */ - uint32_t max_age; - - /** - * @brief Maximum number of uses, or 0 for unlimited. Defaults to 0. - * - * @note Must be between 0 and 100. - */ - uint8_t max_uses; - - /** - * @brief Whether this invite only grants temporary membership. - */ - bool temporary; - - /** - * @brief True if this invite should not replace or "attach to" similar invites. - */ - bool unique; - - /** - * @brief How many times this invite has been used. - */ - uint32_t uses; - - /** - * @note The stage instance data if there is a public stage instance in the stage channel this invite is for. - * @deprecated Deprecated - */ - stage_instance stage; - - /** - * @brief Timestamp at which the invite was created. - */ - time_t created_at; - - /** - * @brief Constructor. - */ - invite(); - - /** - * @brief Destructor. - */ - virtual ~invite() = default; - - /** - * @brief Set the max age after which the invite expires - * - * @param max_age_ The duration in seconds, or 0 for no expiration. Must be between 0 and 604800 (7 days) - * @return invite& reference to self for chaining of calls - */ - invite& set_max_age(const uint32_t max_age_); - - /** - * @brief Set the maximum number of uses for this invite - * - * @param max_uses_ Maximum number of uses, or 0 for unlimited. Must be between 0 and 100 - * @return invite& reference to self for chaining of calls - */ - invite& set_max_uses(const uint8_t max_uses_); - - /** - * @brief Set the target user id - * - * @param user_id The user ID whose stream to display for this voice channel stream invite - * @return invite& reference to self for chaining of calls - */ - invite& set_target_user_id(const snowflake user_id); - - /** - * @brief Set the target type for this voice channel invite - * - * @param type invite_target_t Target type - * @return invite& reference to self for chaining of calls - */ - invite& set_target_type(const invite_target_t type); - - /** - * @brief Set temporary property of this invite object - * - * @param is_temporary Whether this invite only grants temporary membership - * @return invite& reference to self for chaining of calls - */ - invite& set_temporary(const bool is_temporary); - - /** - * @brief Set unique property of this invite object - * - * @param is_unique True if this invite should not replace or "attach to" similar invites - * @return invite& reference to self for chaining of calls - */ - invite& set_unique(const bool is_unique); -}; - -/** - * @brief A container of invites - */ -typedef std::unordered_map invite_map; - -} diff --git a/include/dpp/isa/avx.h b/include/dpp/isa/avx.h deleted file mode 100644 index 6cae986..0000000 --- a/include/dpp/isa/avx.h +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#if defined _MSC_VER || defined __GNUC__ || defined __clang__ - -#include -#include -#include -#include - -namespace dpp { - - using avx_float = __m128; - - /** - * @brief A class for audio mixing operations using AVX instructions. - */ - class audio_mixer { - public: - - /** - * @brief The number of 32-bit values per CPU register. - */ - inline static constexpr int32_t byte_blocks_per_register{ 4 }; - - /** - * @brief Collect a single register worth of data from data_in, apply gain and increment, and store the result in data_out. - * This version uses AVX instructions. - * - * @param data_in Pointer to the input array of int32_t values. - * @param data_out Pointer to the output array of int16_t values. - * @param current_gain The gain to be applied to the elements. - * @param increment The increment value to be added to each element. - */ - inline void collect_single_register(int32_t* data_in, int16_t* data_out, float current_gain, float increment) { - avx_float current_samples_new{ _mm_mul_ps(gather_values(data_in), - _mm_add_ps(_mm_set1_ps(current_gain), _mm_mul_ps(_mm_set1_ps(increment), _mm_set_ps(0.0f, 1.0f, 2.0f, 3.0f)))) }; - - current_samples_new = _mm_blendv_ps(_mm_max_ps(current_samples_new, _mm_set1_ps(static_cast(std::numeric_limits::min()))), - _mm_min_ps(current_samples_new, _mm_set1_ps(static_cast(std::numeric_limits::max()))), - _mm_cmp_ps(current_samples_new, _mm_set1_ps(0.0f), _CMP_GE_OQ)); - - store_values(current_samples_new, data_out); - } - - /** - * @brief Combine a register worth of elements from decoded_data and store the result in up_sampled_vector. - * This version uses AVX instructions. - * - * @param up_sampled_vector Pointer to the array of int32_t values. - * @param decoded_data Pointer to the array of int16_t values. - */ - inline void combine_samples(int32_t* up_sampled_vector, const int16_t* decoded_data) { - auto newValues{ _mm_add_ps(gather_values(up_sampled_vector), gather_values(decoded_data)) }; - store_values(newValues, up_sampled_vector); - } - - protected: - /** - * @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. - * @tparam value_type The target value type for storage. - * @param values_to_store The 128-bit AVX vector containing values to store. - * @param storage_location Pointer to the storage location. - */ - template inline void store_values(const avx_float& values_to_store, value_type* storage_location) { - _mm_store_ps(values, values_to_store); - for (int64_t x = 0; x < byte_blocks_per_register; ++x) { - storage_location[x] = static_cast(values[x]); - } - } - - /** - * @brief Specialization for gathering non-float values into an AVX register. - * @tparam value_type The type of values being gathered. - * @tparam Indices Parameter pack of indices for gathering values. - * @return An AVX register containing gathered values. - */ - template inline avx_float gather_values(value_type* values_new) { - for (uint64_t x = 0; x < byte_blocks_per_register; ++x) { - values[x] = static_cast(values_new[x]); - } - return _mm_load_ps(values); - } - }; - -} - -#endif \ No newline at end of file diff --git a/include/dpp/isa/avx2.h b/include/dpp/isa/avx2.h deleted file mode 100644 index 29ed493..0000000 --- a/include/dpp/isa/avx2.h +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#if defined _MSC_VER || defined __GNUC__ || defined __clang__ - -#include -#include -#include -#include - -namespace dpp { - - using avx_2_float = __m256; - - /** - * @brief A class for audio mixing operations using AVX2 instructions. - */ - class audio_mixer { - public: - - /** - * @brief The number of 32-bit values per CPU register. - */ - inline static constexpr int32_t byte_blocks_per_register{ 8 }; - - /** - * @brief Collect a single register worth of data from data_in, apply gain and increment, and store the result in data_out. - * This version uses AVX2 instructions. - * - * @param data_in Pointer to the input array of int32_t values. - * @param data_out Pointer to the output array of int16_t values. - * @param current_gain The gain to be applied to the elements. - * @param increment The increment value to be added to each element. - */ - inline void collect_single_register(int32_t* data_in, int16_t* data_out, float current_gain, float increment) { - avx_2_float current_samples_new{ _mm256_mul_ps(gather_values(data_in), - _mm256_add_ps(_mm256_set1_ps(current_gain), - _mm256_mul_ps(_mm256_set1_ps(increment), _mm256_set_ps(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f)))) }; - - current_samples_new = - _mm256_blendv_ps(_mm256_max_ps(current_samples_new, _mm256_set1_ps(static_cast(std::numeric_limits::min()))), - _mm256_min_ps(current_samples_new, _mm256_set1_ps(static_cast(std::numeric_limits::max()))), - _mm256_cmp_ps(current_samples_new, _mm256_set1_ps(0.0f), _CMP_GE_OQ)); - - store_values(current_samples_new, data_out); - } - - /** - * @brief Combine a register worth of elements from decoded_data and store the result in up_sampled_vector. - * This version uses AVX2 instructions. - * - * @param up_sampled_vector Pointer to the array of int32_t values. - * @param decoded_data Pointer to the array of int16_t values. - * @param x Index to select a specific set of elements to combine. - */ - inline void combine_samples(int32_t* up_sampled_vector, const int16_t* decoded_data) { - auto newValues{ _mm256_add_ps(gather_values(up_sampled_vector), gather_values(decoded_data)) }; - store_values(newValues, up_sampled_vector); - } - - protected: - /** - * @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. - * @tparam value_type The target value type for storage. - * @param values_to_store The 256-bit AVX2 vector containing values to store. - * @param storage_location Pointer to the storage location. - */ - template inline void store_values(const avx_2_float& values_to_store, value_type* storage_location) { - _mm256_store_ps(values, values_to_store); - for (int64_t x = 0; x < byte_blocks_per_register; ++x) { - storage_location[x] = static_cast(values[x]); - } - } - - /** - * @brief Specialization for gathering non-float values into an AVX2 register. - * @tparam value_type The type of values being gathered. - * @tparam Indices Parameter pack of indices for gathering values. - * @return An AVX2 register containing gathered values. - */ - template inline avx_2_float gather_values(value_type* values_new) { - for (uint64_t x = 0; x < byte_blocks_per_register; ++x) { - values[x] = static_cast(values_new[x]); - } - return _mm256_load_ps(values); - } - }; - -} - -#endif \ No newline at end of file diff --git a/include/dpp/isa/avx512.h b/include/dpp/isa/avx512.h deleted file mode 100644 index 333a1a6..0000000 --- a/include/dpp/isa/avx512.h +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#if defined _MSC_VER || defined __GNUC__ || defined __clang__ - -#include -#include -#include -#include - -namespace dpp { - - using avx_512_float = __m512; - - /** - * @brief A class for audio mixing operations using AVX512 instructions. - */ - class audio_mixer { - public: - - /** - * @brief The number of 32-bit values per CPU register. - */ - inline static constexpr int32_t byte_blocks_per_register{ 16 }; - - /** - * @brief Collect a single register worth of data from data_in, apply gain and increment, and store the result in data_out. - * This version uses AVX512 instructions. - * - * @param data_in Pointer to the input array of int32_t values. - * @param data_out Pointer to the output array of int16_t values. - * @param current_gain The gain to be applied to the elements. - * @param increment The increment value to be added to each element. - */ - inline void collect_single_register(int32_t* data_in, int16_t* data_out, float current_gain, float increment) { - avx_512_float current_samples_new{ _mm512_mul_ps(gather_values(data_in), - _mm512_add_ps(_mm512_set1_ps(current_gain), - _mm512_mul_ps(_mm512_set1_ps(increment), - _mm512_set_ps(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f)))) }; - - __m512 lower_limit = _mm512_set1_ps(static_cast(std::numeric_limits::min())); - __m512 upper_limit = _mm512_set1_ps(static_cast(std::numeric_limits::max())); - - __mmask16 mask_ge = _mm512_cmp_ps_mask(current_samples_new, _mm512_set1_ps(0.0f), _CMP_GE_OQ); - - current_samples_new = _mm512_mask_max_ps(current_samples_new, mask_ge, current_samples_new, lower_limit); - current_samples_new = _mm512_mask_min_ps(current_samples_new, ~mask_ge, current_samples_new, upper_limit); - - store_values(current_samples_new, data_out); - } - - /** - * @brief Combine a register worth of elements from decoded_data and store the result in up_sampled_vector. - * This version uses AVX512 instructions. - * - * @param up_sampled_vector Pointer to the array of int32_t values. - * @param decoded_data Pointer to the array of int16_t values. - */ - inline void combine_samples(int32_t* up_sampled_vector, const int16_t* decoded_data) { - auto newValues{ _mm512_add_ps(gather_values(up_sampled_vector), gather_values(decoded_data)) }; - store_values(newValues, up_sampled_vector); - } - - protected: - /** - * @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. - * @tparam value_type The target value type for storage. - * @param values_to_store The 512-bit AVX512 vector containing values to store. - * @param storage_location Pointer to the storage location. - */ - template inline static void store_values(const avx_512_float& values_to_store, value_type* storage_location) { - _mm256_store_ps(values, values_to_store); - for (int64_t x = 0; x < byte_blocks_per_register; ++x) { - storage_location[x] = static_cast(values[x]); - } - } - - /** - * @brief Specialization for gathering non-float values into an AVX512 register. - * @tparam value_type The type of values being gathered. - * @tparam Indices Parameter pack of indices for gathering values. - * @return An AVX512 register containing gathered values. - */ - template inline avx_512_float gather_values(value_type* values_new) { - for (uint64_t x = 0; x < byte_blocks_per_register; ++x) { - values[x] = static_cast(values_new[x]); - } - return _mm512_load_ps(values); - } - }; - -} - -#endif \ No newline at end of file diff --git a/include/dpp/isa/fallback.h b/include/dpp/isa/fallback.h deleted file mode 100644 index 5d246d4..0000000 --- a/include/dpp/isa/fallback.h +++ /dev/null @@ -1,79 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#include -#include -#include -#include - -namespace dpp { - - /** - * @brief A class for audio mixing operations using x64 instructions. - */ - class audio_mixer { - public: - /* - * @brief The number of 32-bit values per CPU register. - */ - inline static constexpr int32_t byte_blocks_per_register{ 2 }; - - /** - * @brief Collect a single register worth of data from data_in, apply gain and increment, and store the result in data_out. - * This version uses x64 instructions. - * - * @param data_in Pointer to the input array of int32_t values. - * @param data_out Pointer to the output array of int16_t values. - * @param current_gain The gain to be applied to the elements. - * @param increment The increment value to be added to each element. - */ - inline static void collect_single_register(int32_t* data_in, int16_t* data_out, float current_gain, float increment) { - for (uint64_t x = 0; x < byte_blocks_per_register; ++x) { - auto increment_new = increment * x; - auto current_gain_new = current_gain + increment_new; - auto current_sample_new = data_in[x] * current_gain_new; - if (current_sample_new >= std::numeric_limits::max()) { - current_sample_new = std::numeric_limits::max(); - } - else if (current_sample_new <= std::numeric_limits::min()) { - current_sample_new = std::numeric_limits::min(); - } - data_out[x] = static_cast(current_sample_new); - } - } - - /** - * @brief Combine a register worth of elements from decoded_data and store the result in up_sampled_vector. - * This version uses x64 instructions. - * - * @param up_sampled_vector Pointer to the array of int32_t values. - * @param decoded_data Pointer to the array of int16_t values. - */ - inline static void combine_samples(int32_t* up_sampled_vector, const int16_t* decoded_data) { - for (uint64_t x = 0; x < byte_blocks_per_register; ++x) { - up_sampled_vector[x] += static_cast(decoded_data[x]); - } - - } - }; - -} diff --git a/include/dpp/isa/neon.h b/include/dpp/isa/neon.h deleted file mode 100644 index c3ee691..0000000 --- a/include/dpp/isa/neon.h +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#if defined _MSC_VER || defined __GNUC__ || defined __clang__ - -#include -#include -#include -#include - -namespace dpp { - - using neon_float = float32x4_t; - - /** - * @brief A class for audio mixing operations using ARM NEON instructions. - */ - class audio_mixer { - public: - - /** - * @brief The number of 32-bit values per CPU register. - */ - inline static constexpr int32_t byte_blocks_per_register{ 4 }; - - /** - * @brief Collect a single register worth of data from data_in, apply gain and increment, and store the result in data_out. - * This version uses ARM NEON instructions. - * - * @param data_in Pointer to the input array of int32_t values. - * @param data_out Pointer to the output array of int16_t values. - * @param current_gain The gain to be applied to the elements. - * @param increment The increment value to be added to each element. - */ - inline void collect_single_register(int32_t* data_in, int16_t* data_out, float current_gain, float increment) { - neon_float gathered_values = gather_values(data_in); - neon_float gain_vector = vdupq_n_f32(current_gain); - static constexpr float data[4] = { 0.0f, 1.0f, 2.0f, 3.0f }; - neon_float floats = vld1q_f32(data); - neon_float increment_vector = vmulq_f32(vdupq_n_f32(increment), floats); - neon_float current_samples_new = vmulq_f32(gathered_values, vaddq_f32(gain_vector, increment_vector)); - - // Clamping the values between int16_t min and max - neon_float min_val = vdupq_n_f32(static_cast(std::numeric_limits::min())); - neon_float max_val = vdupq_n_f32(static_cast(std::numeric_limits::max())); - - current_samples_new = vmaxq_f32(current_samples_new, min_val); - current_samples_new = vminq_f32(current_samples_new, max_val); - - store_values(current_samples_new, data_out); - } - - /** - * @brief Combine a register worth of elements from decoded_data and store the result in up_sampled_vector. - * This version uses ARM NEON instructions. - * - * @param up_sampled_vector Pointer to the array of int32_t values. - * @param decoded_data Pointer to the array of int16_t values. - */ - inline void combine_samples(int32_t* up_sampled_vector, const int16_t* decoded_data) { - neon_float up_sampled = gather_values(up_sampled_vector); - neon_float decoded = gather_values(decoded_data); - neon_float newValues = vaddq_f32(up_sampled, decoded); - store_values(newValues, up_sampled_vector); - } - - protected: - /** - * @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 NEON vector to a storage location. - * @tparam value_type The target value type for storage. - * @param values_to_store The 128-bit NEON vector containing values to store. - * @param storage_location Pointer to the storage location. - */ - template inline void store_values(const neon_float& values_to_store, value_type* storage_location) { - vst1q_f32(values, values_to_store); - for (int64_t x = 0; x < byte_blocks_per_register; ++x) { - storage_location[x] = static_cast(values[x]); - } - } - - /** - * @brief Specialization for gathering non-float values into a NEON register. - * @tparam value_type The type of values being gathered. - * @return A NEON register containing gathered values. - */ - template inline neon_float gather_values(value_type* values_new) { - for (uint64_t x = 0; x < byte_blocks_per_register; ++x) { - values[x] = static_cast(values_new[x]); - } - return vld1q_f32(values); - } - }; - -} // namespace dpp - -#endif \ No newline at end of file diff --git a/include/dpp/isa_detection.h b/include/dpp/isa_detection.h deleted file mode 100644 index 54b641a..0000000 --- a/include/dpp/isa_detection.h +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once - -#if AVX_TYPE == 1024 - #include "isa/neon.h" -#elif AVX_TYPE == 512 - #include "isa/avx512.h" -#elif AVX_TYPE == 2 - #include "isa/avx2.h" -#elif AVX_TYPE == 1 - #include "isa/avx.h" -#else - #include "isa/fallback.h" -#endif diff --git a/include/dpp/json.h b/include/dpp/json.h deleted file mode 100644 index 14f95ff..0000000 --- a/include/dpp/json.h +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#ifdef DPP_USE_EXTERNAL_JSON - #include -#else - #include -#endif - -namespace dpp { - -using json = nlohmann::json; - -} diff --git a/include/dpp/json_fwd.h b/include/dpp/json_fwd.h deleted file mode 100644 index 6f4ecb3..0000000 --- a/include/dpp/json_fwd.h +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#ifdef DPP_USE_EXTERNAL_JSON - #include -#else - #include -#endif - -namespace dpp { - -using json = nlohmann::json; - -} diff --git a/include/dpp/json_interface.h b/include/dpp/json_interface.h deleted file mode 100644 index 720b7a2..0000000 --- a/include/dpp/json_interface.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2022 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ - -#pragma once -#include -#include - -namespace dpp { - -/** - * @brief Represents an interface for an object that can optionally implement functions - * for converting to and from nlohmann::json. The methods are only present if the actual object - * also has those methods. - * - * @tparam T Type of class that implements the interface - */ -template -struct json_interface { - /** - * @brief Convert object from nlohmann::json - * - * @param j nlohmann::json object - * @return T& Reference to self for fluent calling - */ - template ().fill_from_json_impl(std::declval()))> - T& fill_from_json(nlohmann::json* j) { - return static_cast(this)->fill_from_json_impl(j); - } - - /** - * @brief Convert object to nlohmann::json - * - * @param with_id Whether to include the ID or not - * @note Some fields are conditionally filled, do not rely on all fields being present - * @return json Json built from the structure - */ - template ().to_json_impl(bool{}))> - auto to_json(bool with_id = false) const { - return static_cast(this)->to_json_impl(with_id); - } - - /** - * @brief Convert object to json string - * - * @param with_id Whether to include the ID or not - * @note Some fields are conditionally filled, do not rely on all fields being present - * @return std::string Json built from the structure - */ - template ().to_json_impl(bool{}))> - std::string build_json(bool with_id = false) const { - return to_json(with_id).dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace); - } -}; - -} diff --git a/include/dpp/managed.h b/include/dpp/managed.h deleted file mode 100644 index 66d6b21..0000000 --- a/include/dpp/managed.h +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include - -namespace dpp { - -/** @brief The managed class is the base class for various types that can - * be stored in a cache that are identified by a dpp::snowflake id. - */ -class DPP_EXPORT managed { -public: - /** - * @brief Unique ID of object set by Discord. - * This value contains a timestamp, worker ID, internal server ID, and an incrementing value. - * Only the timestamp is relevant to us as useful metadata. - */ - snowflake id = {}; - - /** - * @brief Constructor, initialises id to 0. - */ - managed() = default; - - /** - * @brief Constructor, initialises ID - * @param nid ID to set - */ - managed(const snowflake nid) : id{nid} {} - - /** - * @brief Copy constructor - * @param rhs Object to copy - */ - managed(const managed &rhs) = default; - - /** - * @brief Move constructor - * - * Effectively equivalent to copy constructor - * @param rhs Object to move from - */ - managed(managed &&rhs) = default; - - /** - * @brief Destroy the managed object - */ - virtual ~managed() = default; - - /** - * @brief Copy assignment operator - * @param rhs Object to copy - */ - managed &operator=(const managed& rhs) = default; - - /** - * @brief Move assignment operator - * @param rhs Object to move from - */ - managed &operator=(managed&& rhs) = default; - - /** - * @brief Get the creation time of this object according to Discord. - * - * @return double creation time inferred from the snowflake ID. - * The minimum possible value is the first second of 2015. - */ - constexpr double get_creation_time() const noexcept { - return id.get_creation_time(); - }; - - /** - * @brief Comparison operator for comparing two managed objects by id - * - * @param other Other object to compare against - * @return true objects are the same id - * @return false objects are not the same id - */ - constexpr bool operator==(const managed& other) const noexcept { - return id == other.id; - } - - /** - * @brief Comparison operator for comparing two managed objects by id - * - * @param other Other object to compare against - * @return true objects are not the same id - * @return false objects are the same id - */ - constexpr bool operator!=(const managed& other) const noexcept { - return id != other.id; - } -}; - -} diff --git a/include/dpp/message.h b/include/dpp/message.h deleted file mode 100644 index 26068de..0000000 --- a/include/dpp/message.h +++ /dev/null @@ -1,3016 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace dpp { - -/** - * @brief Represents the type of a component - */ -enum component_type : uint8_t { - /** - * @brief Action row, a container for other components. - */ - cot_action_row = 1, - - /** - * @brief Clickable button. - */ - cot_button = 2, - - /** - * @brief Select menu for picking from defined text options. - */ - cot_selectmenu = 3, - - /** - * @brief Text input. - */ - cot_text = 4, - - /** - * @brief Select menu for users. - */ - cot_user_selectmenu = 5, - - /** - * @brief Select menu for roles. - */ - cot_role_selectmenu = 6, - - /** - * @brief Select menu for mentionables (users and roles). - */ - cot_mentionable_selectmenu = 7, - - /** - * @brief Select menu for channels. - */ - cot_channel_selectmenu = 8, - - /** - * @brief Section - * @note Available in components v2 only - */ - cot_section = 9, - - /** - * @brief Simple text - * @note Available in components v2 only - */ - cot_text_display = 10, - - /** - * @brief Image thumbnail, clickable to expand - * @note Available in components v2 only - */ - cot_thumbnail = 11, - - /** - * @brief Collection of media (images, videos) - * @note Available in components v2 only - */ - cot_media_gallery = 12, - - /** - * @brief File attachment from the uploads of the message - * @note Available in components v2 only - */ - cot_file = 13, - - /** - * @brief Separator between sections or other components - * @note Available in components v2 only - */ - cot_separator = 14, - - /** - * @brief Content inventory entry - */ - cot_content_inventory_entry = 16, - - /** - * @brief Container for other components - * @note Available in components v2 only - */ - cot_container = 17, -}; - -/** - * @brief An emoji reference for a component (select menus included) or a poll. - * - * To set an emoji on your button or poll answer, you must set one of either the name or id fields. - * The easiest way for buttons is to use the dpp::component::set_emoji method. - * - * @note This is a **very** scaled down version of dpp::emoji, we advise that you refrain from using this. - */ -struct partial_emoji { - /** - * @brief The name of the emoji. - * - * For built in unicode emojis, set this to the - * actual unicode value of the emoji e.g. "😄" - * and not for example ":smile:" - */ - std::string name{}; - - /** - * @brief The emoji ID value for emojis that are custom - * ones belonging to a guild. - * - * The same rules apply as with other emojis, - * that the bot must be on the guild where the emoji resides - * and it must be available for use - * (e.g. not disabled due to lack of boosts, etc) - */ - dpp::snowflake id{0}; - - /** - * @brief Is the emoji animated? - * - * @note Only applies to custom emojis. - */ - bool animated{false}; -}; - -/** - * @brief An emoji for a component. Alias to partial_emoji, for backwards compatibility. - * - * @see partial_emoji - */ -using component_emoji = partial_emoji; - -/** - * @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 { - /** - * @brief Intended for short single-line text. - */ - text_short = 1, - - /** - * @brief Intended for much longer inputs. - */ - text_paragraph = 2, -}; - -/** - * @brief Represents the style of a button - */ -enum component_style : uint8_t { - /** - * @brief Blurple; Primary - */ - cos_primary = 1, - - /** - * @brief Grey; Secondary - */ - cos_secondary, - - /** - * @brief Green; Success - */ - cos_success, - - /** - * @brief Red; danger - */ - cos_danger, - - /** - * @brief An external hyperlink to a website, requires url to be set - * @note Will not work unless url is set - */ - cos_link, - - /** - * @brief Premium upsell button, requires sku_id to be set - * @note Will not work unless sku is set - */ - cos_premium, -}; - -/** - * Represents the type of a dpp::component_default_value - * - * @note They're different to discord's value types - */ -enum component_default_value_type: uint8_t { - cdt_user = 0, - cdt_role = 1, - cdt_channel = 2, -}; - -/** - * @brief A Default value structure for components - */ -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 - */ - dpp::snowflake id; -}; - -/** - * @brief An option for a select component - */ -struct DPP_EXPORT select_option : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - select_option& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @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 - */ - bool is_default; - - /** - * @brief The emoji for the select option. - */ - partial_emoji emoji; - - /** - * @brief Construct a new select option object - */ - select_option(); - - /** - * @brief Destructs the select option object. - */ - virtual ~select_option() = default; - - /** - * @brief Construct a new select option object - * - * @param label Label of option - * @param value Value of option - * @param description Description of option - */ - select_option(std::string_view label, std::string_view value, std::string_view description = ""); - - /** - * @brief Set the label - * - * @param l the user-facing name of the option. It will be truncated to the maximum length of 100 UTF-8 characters. - * @return select_option& reference to self for chaining - */ - select_option& set_label(std::string_view l); - - /** - * @brief Set the value - * - * @param v value to set. It will be truncated to the maximum length of 100 UTF-8 characters. - * @return select_option& reference to self for chaining - */ - select_option& set_value(std::string_view v); - - /** - * @brief Set the description - * - * @param d description to set. It will be truncated to the maximum length of 100 UTF-8 characters. - * @return select_option& reference to self for chaining - */ - select_option& set_description(std::string_view d); - - /** - * @brief Set the emoji - * - * @param n emoji name - * @param id emoji id for custom emojis - * @param animated true if animated emoji - * @return select_option& reference to self for chaining - */ - select_option& set_emoji(std::string_view n, dpp::snowflake id = 0, bool animated = false); - - /** - * @brief Set the option as default - * - * @param def true to set the option as default - * @return select_option& reference to self for chaining - */ - select_option& set_default(bool def); - - /** - * @brief Set the emoji as animated - * - * @param anim true if animated - * @return select_option& reference to self for chaining - */ - select_option& set_animated(bool anim); -}; - -/** - * @brief Loading state for "unfurled" media, e.g. thumbnails and images in a message or component - */ -enum media_loading_state : uint8_t { - - /** - * @brief Loading state is unknown - */ - ls_unknown = 0, - - /** - * @brief Discord is loading the media - */ - ls_loading = 1, - - /** - * @brief The image was processed and loaded successfully - */ - ls_loaded_success = 2, - - /** - * @brief The media was not found - */ - ls_not_found = 3, -}; - -/** - * @brief An video, image or thumbnail in a dpp::embed or dpp::component (v2) - */ -struct DPP_EXPORT embed_image { - /** - * @brief URL to image or video. - */ - std::string url; - - /** - * @brief Proxied image url. - */ - std::string proxy_url; - - /** - * @brief Height (calculated by discord). - */ - uint32_t height{0}; - - /** - * @brief Width (calculated by discord). - */ - uint32_t width{0}; - - /** - * @brief Media loading state - */ - media_loading_state loading_state{ls_unknown}; - - /** - * @brief placeholder - */ - std::string placeholder; - - /** - * @brief Placeholder version - */ - uint8_t placeholder_version{1}; - - /** - * @brief Content type - */ - std::string content_type; - - /** - * @brief Flags (documented as present, but contents not documented) - */ - uint32_t flags{0}; -}; - -/** - * @brief Spacing types for components v2 separator - */ -enum separator_spacing : uint8_t { - - /** - * @brief Small separator - */ - sep_small = 1, - - /** - * @brief Large separator - */ - sep_large = 2, -}; - -/** - * @brief Represents the component object. - * A component is a clickable button or drop down list - * within a discord message, where the buttons emit - * on_button_click events when the user interacts with - * them. - * - * You should generally define one component object and - * then insert one or more additional components into it - * using component::add_component(), so that the parent - * object is an action row and the child objects are buttons. - */ -class DPP_EXPORT component : public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - component& fill_from_json_impl(nlohmann::json* j); - -public: - /** - * @brief Component type, either a button or action row - */ - component_type type; - - /** - * @brief Sub components, buttons on an action row - */ - std::vector components; - - /** - * @brief Component label (for buttons, text inputs). - * Maximum of 80 characters. - */ - std::string label; - - /** - * @brief Component style (for buttons). - */ - component_style style; - - /** - * @brief Text style (for text inputs). - */ - text_style_type text_style; - - /** - * @brief Component id (for buttons, menus, text inputs). - * Maximum of 100 characters. - */ - std::string custom_id; - - /** - * @brief URL for link types (dpp::cos_link). - * Maximum of 512 characters. - */ - std::string url; - - /** - * @brief The SKU ID for premium upsell buttons - */ - dpp::snowflake sku_id; - - /** - * @brief Placeholder text for select menus and text inputs (max 150 characters) - */ - std::string placeholder; - - /** - * @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; - - /** - * @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; - - /** - * @brief Minimum length for text input (0-4000) - */ - int32_t min_length; - - /** - * @brief Maximum length for text input (1-4000) - */ - int32_t max_length; - - /** - * @brief Select options for select menus. - * - * @warning Only required and available for select menus of type dpp::cot_selectmenu - */ - std::vector options; - - /** - * @brief List of channel types (dpp::channel_type) to include in the channel select component (dpp::cot_channel_selectmenu) - */ - std::vector channel_types; - - /** - * @brief List of default values for auto-populated select menu 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; - - /** - * @brief Disabled flag (for buttons) - */ - bool disabled; - - /** - * @brief Whether the text input is required to be filled - */ - bool required; - - /** - * @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; - - /** - * @brief The emoji for this component. - */ - partial_emoji emoji; - - /** - * @brief Text content for section and text display types (v2) - */ - std::string content; - - /** - * @brief accessory component for components which support it (v2) - * Can be a button or a thumbnail. - */ - std::shared_ptr accessory; - - /** - * @brief Description for media items (v2) - */ - std::string description; - - /** - * @brief Spoiler state for media and file items - */ - bool spoiler; - - /** - * @brief can be set for separator types (v2) - */ - bool is_divider; - - /** - * @brief Valid for separator types (v2) - */ - separator_spacing spacing; - - /** - * @brief Unfurled media for thumbnail objects (v2) - */ - std::optional thumbnail; - - /** - * @brief Unfurled file URL for file objects (v2) - * Should be in the format "attachment://..." - */ - std::optional file; - - /** - * @brief Media gallery items for media galleries (v2) - */ - std::vector> media_gallery_items; - - /** - * @brief Accent colour for container types (v2) - */ - std::optional accent; - - /** - * @brief Constructor - */ - component(); - - /** - * @brief Destructor - */ - virtual ~component() = default; - - /** - * @brief Add a channel type to include in the channel select component (dpp::cot_channel_selectmenu) - * - * @param ct The dpp::channel_type - * @return component& reference to self - */ - component& add_channel_type(uint8_t ct); - - /** - * @brief For text content types, set content - * @note Ignored for other types - * @param text text to set - * @return - */ - component& set_content(const std::string& text); - - /** - * @brief Set divider visibility for separator type (v2) - * @param divider true to show a visible divider - * @return self - */ - component& set_divider(bool divider); - - /** - * @brief Set accent colour for container type (v2) - * @param accent_colour Accent colour for container - * @return self - */ - component& set_accent(uint32_t accent_colour); - - /** - * @brief Set separator spacing for separator type (v2) - * @param sep_spacing separator spacing, small or large - * @return self - */ - component& set_spacing(separator_spacing sep_spacing); - - /** - * @brief Set the attachment url for file type components. - * The format of the attachment url should be of the type - * "attachment://...". - * @param attachment_url url to attachment. Should have been - * attached via add_file(). - * @return self - */ - component& set_file(std::string_view attachment_url); - - /** - * @brief Add a media gallery item to a media gallery type (v2) - * @param media_gallery_item item to add - * @return - */ - component& add_media_gallery_item(const component& media_gallery_item); - - /** - * @brief For media types, set description - * @note Ignored for other types - * @param text text to set - * @return - */ - component& set_description(const std::string& text); - - /** - * @brief For media and file component types, set spoiler status - * @note Ignored for other types - * @param spoiler_enable True to enable spoiler masking - * @return - */ - component& set_spoiler(bool spoiler_enable); - - /** - * @brief Set component thumbnail for thumbnail type (v2. - * @param url The embed thumbnail url (only supports http(s) and attachments) - * @return A reference to self so this method may be "chained". - */ - component& set_thumbnail(std::string_view url); - - /** - * @brief Set accessory component for components which support it. - * Can be a button or a thumbnail image. - * @param accessory_component accessory component - * @return - */ - component& set_accessory(const component& accessory_component); - - /** - * @brief Set the type of the component. Button components - * (type dpp::cot_button) should always be contained within - * an action row (type dpp::cot_action_row). As described - * below, many of the other methods automatically set this - * to the correct type so usually you should not need to - * manually call component::set_type(). - * - * @param ct The component type - * @return component& reference to self - */ - component& set_type(component_type ct); - - /** - * @brief Set the SKU ID for a premium upsell button - * This is only valid for premium upsell buttons of type - * cos_premium. It indicates which premium package to - * link to when the button is clicked. - * - * @param sku The SKU ID - * @return component& reference to self - */ - component& set_sku_id(dpp::snowflake sku); - - /** - * @brief Set the text style of a text component - * @note Sets type to `cot_text` - * - * @param ts Text style type to set - * @return component& reference to self - */ - component& set_text_style(text_style_type ts); - - /** - * @brief Set the label of the component, e.g. button text. - * For action rows, this field is ignored. Setting the - * label will auto-set the type to dpp::cot_button. - * - * @param label Label text to set. It will be truncated to the maximum length of 80 UTF-8 characters. - * @return component& Reference to self - */ - component& set_label(std::string_view label); - - /** - * @brief Set the default value of the text input component. - * For action rows, this field is ignored. Setting the - * value will auto-set the type to dpp::cot_text. - * - * @param val Value text to set. It will be truncated to the maximum length of 4000 UTF-8 characters. - * @return component& Reference to self - */ - component& set_default_value(std::string_view val); - - /** - * @brief Set the url for dpp::cos_link types. - * Calling this function sets the style to dpp::cos_link - * and the type to dpp::cot_button. - * - * @param url URL to set. It will be truncated to the maximum length of 512 UTF-8 characters. - * @return component& reference to self. - */ - component& set_url(std::string_view url); - - /** - * @brief Set the style of the component, e.g. button colour. - * For action rows, this field is ignored. Setting the - * style will auto-set the type to dpp::cot_button. - * - * @param cs Component style to set - * @return component& reference to self - */ - component& set_style(component_style cs); - - /** - * @brief Set the id of the component. - * For action rows, this field is ignored. Setting the - * id will auto-set the type to dpp::cot_button. - * - * @param id Custom ID string to set. This ID will be sent - * for any on_button_click events related to the button. - * @note The maximum length of the Custom ID is 100 UTF-8 codepoints. - * If your Custom ID is longer than this, it will be truncated. - * @return component& Reference to self - */ - component& set_id(std::string_view id); - - /** - * @brief Set the component to disabled. - * Defaults to false on all created components. - * - * @param disable True to disable the component, False to enable the component. - * @return component& Reference to self - */ - component& set_disabled(bool disable); - - /** - * @brief Set if this component is required. - * Defaults to false on all created components. - * - * @param require True to require this, false to make it optional. - * @return component& Reference to self - */ - component& set_required(bool require); - - /** - * @brief Set the placeholder - * - * @param placeholder placeholder string. It will be truncated to the - * maximum length of 150 UTF-8 characters for select menus, and 100 UTF-8 - * characters for modals. - * @return component& Reference to self - */ - component& set_placeholder(std::string_view placeholder); - - /** - * @brief Set the minimum number of items that must be chosen for a select menu - * - * @param min_values min value to set (0-25) - * @return component& Reference to self - */ - component& set_min_values(uint32_t min_values); - - /** - * @brief Set the maximum number of items that can be chosen for a select menu - * - * @param max_values max value to set (0-25) - * @return component& Reference to self - */ - component& set_max_values(uint32_t max_values); - - /** - * @brief Set the minimum input length for a text input - * - * @param min_l min length to set (0-4000) - * @return component& Reference to self - */ - component& set_min_length(uint32_t min_l); - - /** - * @brief Set the maximum input length for a text input - * - * @param max_l max length to set (1-4000) - * @return component& Reference to self - */ - component& set_max_length(uint32_t max_l); - - /** - * @brief Add a select option - * - * @param option option to add - * @return component& Reference to self - */ - component& add_select_option(const select_option &option); - - /** - * @brief Add a sub-component, only valid for action rows. - * Adding subcomponents to a component will automatically - * set this component's type to dpp::cot_action_row. - * - * @note Automatic creation of action rows is retained for backwards - * compatibility with components v1. If you want to add components v2, - * and do not want automatic creation of action rows, use - * dpp::component::add_component_v2() instead. - * - * @param c The sub-component to add - * @return component& reference to self - */ - component& add_component(const component& c); - - /** - * @brief Add a sub-component, does not automatically create - * action rows. This should be used for components v2 where - * you do not want to add action rows automatically. - * - * @param c The sub-component to add - * @return component& reference to self - */ - component& add_component_v2(const component& c); - - /** - * @brief Add a default value. - * - * @param id Default value. ID of a user, role, or channel - * @param type The type this default value represents - */ - component& add_default_value(const snowflake id, const component_default_value_type type); - - /** - * @brief Set the emoji of the current sub-component. - * - * @warning Only valid for buttons. - * - * @note Adding an emoji to a component will - * automatically set this components type to - * dpp::cot_button. **One or both of name and id must be set**. - * For a built in unicode emoji, you only need set name, - * and should set it to a unicode character e.g. "😄". - * For custom emojis, set the name to the name of the emoji - * on the guild, and the id to the emoji's ID. - * Setting the animated boolean is only valid for custom - * emojis. - * - * @param name Emoji name, or unicode character to use - * @param id Emoji id, for custom emojis only. - * @param animated True if the custom emoji is animated. - * @return component& Reference to self - */ - component& set_emoji(std::string_view name, dpp::snowflake id = 0, bool animated = false); -}; - -/** - * @brief A footer in a dpp::embed - */ -struct DPP_EXPORT embed_footer { - /** - * @brief Footer text - */ - std::string text; - - /** - * @brief Footer icon url. - * - * @warning Only supports http(s) and attachments. - */ - std::string icon_url; - - /** - * @brief Proxied icon url. - */ - std::string proxy_url; - - /** - * @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 so this method may be "chained". - */ - embed_footer& set_text(std::string_view t); - - /** - * @brief Set footer's icon url. - * @param i url to set as footer icon url - * @return A reference to self so this method may be "chained". - */ - embed_footer& set_icon(std::string_view i); - - /** - * @brief Set footer's proxied icon url. - * @param p url to set as footer proxied icon url - * @return A reference to self so this method may be "chained". - */ - embed_footer& set_proxy(std::string_view p); -}; - -/** - * @brief Embed provider in a dpp::embed. Received from discord but cannot be sent - */ -struct DPP_EXPORT embed_provider { - /** - * @brief Provider name. - */ - std::string name; - - /** - * @brief Provider URL. - */ - std::string url; -}; - -/** - * @brief Author within a dpp::embed object - */ -struct DPP_EXPORT embed_author { - /** - * @brief Author name. - */ - std::string name; - - /** - * @brief Author url. - * - * @warning Only supports http(s). - */ - std::string url; - - /** - * @brief Author icon url. - * - * @warning Only supports http(s) and attachments. - */ - std::string icon_url; - - /** - * @brief Proxied icon url. - */ - std::string proxy_icon_url; -}; - -/** - * @brief A dpp::embed may contain zero or more fields. - */ -struct DPP_EXPORT embed_field { - /** - * @brief Name of field (max length 256). - */ - std::string name; - - /** - * @brief Value of field (max length 1024). - */ - std::string value; - - /** - * @brief True if the field is to be displayed inline. - */ - bool is_inline; -}; - -/** - * @brief A rich embed for display within a dpp::message. - */ -struct DPP_EXPORT embed { - /** - * @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(); - - /** - * @brief Constructor to build embed from json object - * @param j JSON to read content from - */ - embed(nlohmann::json* j); - - /** - * @brief Destructor - */ - ~embed(); - - /** - * @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 so this method may be "chained". - */ - embed& set_title(std::string_view text); - - /** - * @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 so this method may be "chained". - */ - embed& set_description(std::string_view text); - - /** - * @brief Set the footer of the embed. - * @param f the footer to set - * @return A reference to self so this method may be "chained". - */ - embed& set_footer(const embed_footer& f); - - /** - * @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(std::string_view text, std::string_view icon_url); - - /** - * @brief Set embed colour. - * @param col The colour of the embed - * @return A reference to self so this method may be "chained". - */ - embed& set_color(uint32_t col); - - /** - * @brief Set embed colour. - * @param col The colour of the embed - * @return A reference to self so this method may be "chained". - */ - embed& set_colour(uint32_t col); - - /** - * @brief Set embed timestamp. - * @param tstamp The timestamp to show in the footer, should be in UTC - * @return A reference to self so this method may be "chained". - */ - embed& set_timestamp(time_t tstamp); - - /** - * @brief Set embed url. - * @param url the url of the embed - * @return A reference to self so this method may be "chained". - */ - embed& set_url(std::string_view url); - - /** - * @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 so this method may be "chained". - */ - embed& add_field(std::string_view name, std::string_view value, bool is_inline = false); - - /** - * @brief Set embed author. - * @param a The author to set - * @return A reference to self so this method may be "chained". - */ - embed& set_author(const dpp::embed_author& a); - - /** - * @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 so this method may be "chained". - */ - embed& set_author(std::string_view name, std::string_view url, std::string_view icon_url); - - /** - * @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 so this method may be "chained". - */ - embed& set_provider(std::string_view name, std::string_view url); - - /** - * @brief Set embed image. - * @param url The embed image URL (only supports http(s) and attachments) - * @return A reference to self so this method may be "chained". - */ - embed& set_image(std::string_view url); - - /** - * @brief Set embed video. - * @param url The embed video url - * @return A reference to self so this method may be "chained". - */ - embed& set_video(std::string_view url); - - /** - * @brief Set embed thumbnail. - * @param url The embed thumbnail url (only supports http(s) and attachments) - * @return A reference to self so this method may be "chained". - */ - embed& set_thumbnail(std::string_view url); -}; - -/** - * @brief Represents a reaction to a dpp::message. - */ -struct DPP_EXPORT reaction { - /** - * @brief Total number of times this emoji has been used to react (including super reacts) - */ - uint32_t count; - - /** - * @brief Count of super reactions - */ - uint32_t count_burst; - - /** - * @brief Count of normal reactions - */ - uint32_t count_normal; - - /** - * @brief ID of emoji for reaction - */ - snowflake emoji_id; - - /** - * @brief Name of emoji, if applicable - */ - std::string emoji_name; - - /** - * @brief Whether your bot reacted using this emoji - */ - bool me; - - /** - * @brief Whether your bot super-reacted using this emoji - */ - bool me_burst; - - /** - * @brief HEX colors used for super reaction. - * - * @note Stored as integers. - */ - std::vector burst_colors; - - /** - * @brief Constructs a new reaction object. - */ - reaction(); - - /** - * @brief Constructs a new reaction object from a JSON object. - * @param j The JSON to read data from - */ - reaction(nlohmann::json* j); - - /** - * @brief Destructs the reaction object. - */ - ~reaction() = default; -}; - -/** - * @brief Bitmask flags for a dpp::attachment - */ -enum attachment_flags : uint8_t { - /** - * @brief This attachment has been edited using the remix feature on mobile. - */ - a_is_remix = 1 << 2, -}; - -/** - * @brief Represents an attachment in a dpp::message - */ -struct DPP_EXPORT attachment { - /** - * @brief ID of attachment. - */ - snowflake id; - - /** - * @brief Size of the attachment in bytes. - */ - uint32_t size; - - /** - * @brief File name of the attachment. - */ - std::string filename; - - /** - * @brief Optional: Description of the attachment. - * Max 1024 characters. - */ - std::string description; - - /** - * @brief URL which points to the attachment. - */ - std::string url; - - /** - * @brief Proxied URL which points to the attachment. - */ - std::string proxy_url; - - /** - * @brief Width of the attachment, if applicable. - */ - uint32_t width; - - /** - * @brief Height of the attachment, if applicable. - */ - uint32_t height; - - /** - * @brief MIME type of the attachment, if applicable. - */ - std::string content_type; - - /** - * @brief Whether this attachment is ephemeral, if applicable. - */ - bool ephemeral; - - /** - * @brief The duration of the audio file. - * - * @note Currently for voice messages. - */ - double duration_secs; - - /** - * @brief Base64 encoded bytearray representing a sampled waveform. - * - * @note Currently for voice messages. - */ - std::string waveform; - - /** - * @brief Flags made from dpp::attachment_flags. - */ - uint8_t flags; - - /** - * @brief Owning message - */ - struct message* owner; - - /** - * @brief Constructs a new attachment object. - * @param o Owning dpp::message object - */ - attachment(struct message* o); - - /** - * @brief Constructs a new attachment object from a JSON object. - * @param o Owning dpp::message object - * @param j JSON to read information from - */ - attachment(struct message* o, nlohmann::json* j); - - /** - * @brief Destructs the attachment object. - */ - ~attachment() = default; - - /** - * @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. - * @throw dpp::logic_exception If there is no owner associated with this attachment that - * itself has an owning cluster, this method will throw a dpp::logic_exception when called. - */ - void download(http_completion_event callback) const; - - /** - * @brief Returns true if remixed - * - * @return true if remixed - */ - bool is_remix() const; - - /** - * @brief Returns expiration timestamp for attachment's URL - * - * @return timestamp of URL expiration - */ - time_t get_expire_time() const; - - /** - * @brief Returns creation timestamp for attachment's URL - * - * @return timestamp of URL creation - */ - time_t get_issued_time() const; -}; - -/** - * @brief Represents the type of a sticker - */ -enum sticker_type : uint8_t { - /** - * @brief An official sticker in a pack. - */ - st_standard = 1, - - /** - * @brief Guild sticker. - */ - st_guild = 2 -}; - -/** - * @brief The file format (png, apng, lottie) of a sticker - */ -enum sticker_format : uint8_t { - sf_png = 1, - sf_apng = 2, - sf_lottie = 3, - sf_gif = 4, -}; - -/** - * @brief Represents stickers received in messages - */ -struct DPP_EXPORT sticker : public managed, public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - sticker& fill_from_json_impl(nlohmann::json* j); - - /** Build JSON from this object. - * @param with_id True if the ID is to be set in the JSON structure - * @return The JSON of the invite - */ - virtual json to_json_impl(bool with_id = true) const; - -public: - /** - * @brief Optional: for standard stickers, id of the pack the sticker is from - */ - snowflake pack_id; - - /** - * @brief The name of the sticker. - */ - std::string name; - - /** - * @brief Description of the sticker - * - * @note This may be empty. - */ - 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 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 - */ - sticker(); - - virtual ~sticker() = default; - - /** - * @brief Get the sticker url. - * - * @return std::string The sticker url or an empty string, if the id is empty - */ - std::string get_url() const; - - /** - * @brief Set the filename - * - * @param fn filename - * @return message& reference to self - */ - sticker& set_filename(std::string_view fn); - - /** - * @brief Set the file content - * - * @param fc raw file content - * @return message& reference to self - */ - sticker& set_file_content(std::string_view fc); - -}; - -/** - * @brief Represents a sticker pack (the built in groups of stickers that all nitro users get to use) - */ -struct DPP_EXPORT sticker_pack : public managed, public json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - sticker_pack& fill_from_json_impl(nlohmann::json* j); - - /** Build JSON from this object. - * @param with_id True if the ID is to be set in the JSON structure - * @return The JSON of the invite - */ - virtual json to_json_impl(bool with_id = true) const; - -public: - /** - * @brief The stickers in the pack. - */ - std::map stickers{}; - - /** - * @brief Name of the sticker pack. - */ - std::string name{}; - - /** - * @brief ID of the pack's SKU. - */ - snowflake sku_id{0}; - - /** - * @brief Optional: ID of a sticker in the pack which is shown as the pack's icon. - */ - snowflake cover_sticker_id{0}; - - /** - * @brief Description of the sticker pack. - */ - std::string description{}; - - /** - * @brief ID of the sticker pack's banner image. - */ - snowflake banner_asset_id{}; -}; - -/** - * @brief Poll layout types - * - * @note At the time of writing Discord only has 1, "The, uhm, default layout type." - * @see https://discord.com/developers/docs/resources/poll#layout-type - */ -enum poll_layout_type { - /** - * @brief According to Discord, quote, "The, uhm, default layout type." - */ - pl_default = 1 -}; - -/** - * @brief Structure representing a poll media, for example the poll question or a possible poll answer. - * - * @see https://discord.com/developers/docs/resources/poll#poll-media-object-poll-media-object-structure - */ -struct poll_media { - /** - * @brief Text of the media - */ - std::string text{}; - - /** - * @brief Emoji of the media. - */ - partial_emoji emoji{}; -}; - -/** - * @brief Represents an answer in a poll. - * - * @see https://discord.com/developers/docs/resources/poll#poll-answer-object-poll-answer-object-structure - */ -struct poll_answer { - /** - * @brief ID of the answer. Only sent by the Discord API, this is a dead field when creating a poll. - * - * @warn At the time of writing the Discord API warns users not to rely on anything regarding sequence or "first value" of this field. - */ - uint32_t id{0}; - - /** - * @brief Data of the answer. - * - * @see poll_media - */ - poll_media media{}; -}; - -/** - * @brief Represents the results of a poll - * - * @see https://discord.com/developers/docs/resources/poll#poll-results-object-poll-results-object-structure - */ -struct poll_results { - /** - * @brief Represents a reference to an answer and its count of votes - * - * @see https://discord.com/developers/docs/resources/poll#poll-results-object-poll-answer-count-object-structure - */ - struct answer_count { - /** - * @brief ID of the answer. Relates to an answer in the answers field - * - * @see poll_answer::answer_id - */ - uint32_t answer_id{0}; - - /** - * @brief Number of votes for this answer - */ - uint32_t count{0}; - - /** - * @brief Whether the current user voted - */ - bool me_voted{false}; - }; - - /** - * @brief Whether the poll has finalized, and the answers are precisely counted - * - * @note Discord states that due to the way they count and cache answers, - * while a poll is running the count of answers might not be accurate. - */ - bool is_finalized{false}; - - /** - * @brief Count of votes for each answer. If an answer is not present in this list, - * then its vote count is 0 - */ - std::map answer_counts; -}; - -/** - * @brief Represents a poll. - * - * @see https://discord.com/developers/docs/resources/poll - */ -struct DPP_EXPORT poll { - /** - * @brief Poll question. At the time of writing only the text field is supported by Discord - * - * @see media - */ - poll_media question{}; - - /** - * @brief List of answers of the poll. - * - * @note At the time of writing this can contain up to 10 answers - * @see answer - */ - std::map answers{}; - - /** - * @brief When retriving a poll from the API, this is the timestamp at which the poll will expire. - * When creating a poll, this is the number of hours the poll should be up for, up to 7 days (168 hours), and this field will be rounded. - */ - double expiry{24.0}; - - /** - * @brief Whether a user can select multiple answers - */ - bool allow_multiselect{false}; - - /** - * @brief Layout type of the poll. Defaults to, well, pl_default - * - * @see poll_layout_type - */ - poll_layout_type layout_type{pl_default}; - - /** - * @brief The (optional) results of the poll. This field may or may not be present, and its absence means "unknown results", not "no results". - * - * @note Quote from Discord: "The results field may be not present in certain responses where, as an implementation detail, - * we do not fetch the poll results in our backend. This should be treated as "unknown results", - * as opposed to "no results". You can keep using the results if you have previously received them through other means." - * - * @see https://discord.com/developers/docs/resources/poll#poll-results-object - */ - std::optional results{std::nullopt}; - - /** - * @brief Set the question for this poll - * - * @param text Text for the question - * @return self for method chaining - */ - poll& set_question(std::string_view text); - - /** - * @brief Set the duration of the poll in hours - * - * @param hours Duration of the poll in hours, max 7 days (168 hours) at the time of writing - * @return self for method chaining - */ - poll& set_duration(uint32_t hours) noexcept; - - /** - * @brief Set if the poll should allow multi-selecting - * - * @param allow Should allow multi-select? - * @return self for method chaining - */ - poll& set_allow_multiselect(bool allow) noexcept; - - /** - * @brief Add an answer to this poll - * - * @note At the time of writing this, a poll can have up to 10 answers - * @param media Data of the answer - * @return self for method chaining - */ - poll& add_answer(const poll_media& media); - - /** - * @brief Add an answer to this poll - * - * @note At the time of writing this, a poll can have up to 10 answers - * @param text Text for the answer - * @param emoji_id Optional emoji - * @param is_animated Whether the emoji is animated - * @return self for method chaining - */ - poll& add_answer(std::string_view text, snowflake emoji_id = 0, bool is_animated = false); - - /** - * @brief Add an answer to this poll - * - * @note At the time of writing this, a poll can have up to 10 answers - * @param text Text for the answer - * @param emoji Optional emoji - * @return self for method chaining - */ - poll& add_answer(std::string_view text, std::string_view emoji); - - /** - * @brief Add an answer to this poll - * - * @note At the time of writing this, a poll can have up to 10 answers - * @param text Text for the answer - * @param e Optional emoji - * @return self for method chaining - */ - poll& add_answer(std::string_view text, const emoji& e); - - /** - * @brief Helper to get the question text - * - * @return question.text - */ - [[nodiscard]] const std::string& get_question_text() const noexcept; - - /** - * @brief Helper to find an answer by ID - * - * @param id ID to find - * @return Pointer to the answer with the matching ID, or nullptr if not found - */ - [[nodiscard]] const poll_media* find_answer(uint32_t id) const noexcept; - - /** - * @brief Helper to find the vote count in the results - * - * @param answer_id ID of the answer to find - * @return std::optional Optional count of votes. An empty optional means Discord did not send the results, it does not mean 0. It can also mean the poll does not have an answer with this ID - * @see https://discord.com/developers/docs/resources/poll#poll-results-object - */ - [[nodiscard]] std::optional get_vote_count(uint32_t answer_id) const noexcept; -}; - -/** - * @brief Bitmask flags for a dpp::message - */ -enum message_flags : uint16_t { - /** - * @brief This message has been published to subscribed channels (via Channel Following). - */ - m_crossposted = 1 << 0, - - /** - * @brief This message originated from a message in another channel (via Channel Following). - */ - m_is_crosspost = 1 << 1, - - /** - * @brief Do not include any embeds when serializing this message. - */ - m_suppress_embeds = 1 << 2, - - /** - * @brief The source message for this crosspost has been deleted (via Channel Following). - */ - m_source_message_deleted = 1 << 3, - - /** - * @brief This message came from the urgent message system. - */ - m_urgent = 1 << 4, - - /** - * @brief This message has an associated thread, with the same id as the message. - */ - m_has_thread = 1 << 5, - - /** - * @brief This message is only visible to the user who invoked the Interaction. - */ - m_ephemeral = 1 << 6, - - /** - * @brief This message is an Interaction Response and the bot is "thinking". - */ - m_loading = 1 << 7, - - /** - * @brief This message failed to mention some roles and add their members to the thread. - */ - m_thread_mention_failed = 1 << 8, - - /** - * @brief This message will not trigger push and desktop notifications. - */ - m_suppress_notifications = 1 << 12, - - /** - * @brief This message is a voice message. - */ - m_is_voice_message = 1 << 13, - - /** - * @brief Contains forwarded snapshot - */ - m_has_snapshot = 1 << 14, - - /** - * @brief Message components vector contains v2 components - */ - m_using_components_v2 = 1 << 15, -}; - -/** - * @brief Represents possible values for the dpp::embed type field. - * These are loosely defined by the API docs and do not influence how the client renders embeds. - * - * @note The only type a bot can send is dpp::embed_type::emt_rich. - */ -namespace embed_type { - /** - * @brief Rich text - */ - const std::string emt_rich = "rich"; - - /** - * @brief Image - */ - const std::string emt_image = "image"; - - /** - * @brief Video link - */ - const std::string emt_video = "video"; - - /** - * @brief Animated gif - */ - const std::string emt_gifv = "gifv"; - - /** - * @brief Article - */ - const std::string emt_article = "article"; - - /** - * @brief Link URL - */ - const std::string emt_link = "link"; - - /** - * @brief Auto moderation filter - */ - const std::string emt_automod = "auto_moderation_message"; -} // namespace embed_type - -/** - * @brief Message types for dpp::message::type - */ -enum message_type : uint8_t { - /** - * @brief Default - */ - mt_default = 0, - - /** - * @brief Add recipient - */ - mt_recipient_add = 1, - - /** - * @brief Remove recipient - */ - mt_recipient_remove = 2, - - /** - * @brief Call - */ - mt_call = 3, - - /** - * @brief Channel name change - */ - mt_channel_name_change = 4, - - /** - * @brief Channel icon change - */ - mt_channel_icon_change = 5, - - /** - * @brief Message pinned - */ - mt_channel_pinned_message = 6, - - /** - * @brief Member joined - */ - mt_guild_member_join = 7, - - /** - * @brief Boost - */ - mt_user_premium_guild_subscription = 8, - - /** - * @brief Boost level 1 - */ - mt_user_premium_guild_subscription_tier_1 = 9, - - /** - * @brief Boost level 2 - */ - mt_user_premium_guild_subscription_tier_2 = 10, - - /** - * @brief Boost level 3 - */ - mt_user_premium_guild_subscription_tier_3 = 11, - - /** - * @brief Follow channel - */ - mt_channel_follow_add = 12, - - /** - * @brief Disqualified from discovery - */ - mt_guild_discovery_disqualified = 14, - - /** - * @brief Re-qualified for discovery - */ - mt_guild_discovery_requalified = 15, - - /** - * @brief Discovery grace period warning 1 - */ - mt_guild_discovery_grace_period_initial_warning = 16, - - /** - * @brief Discovery grace period warning 2 - */ - mt_guild_discovery_grace_period_final_warning = 17, - - /** - * @brief Thread Created - */ - mt_thread_created = 18, - - /** - * @brief Reply - */ - mt_reply = 19, - - /** - * @brief Application command - */ - mt_application_command = 20, - - /** - * @brief Thread starter message - */ - mt_thread_starter_message = 21, - - /** - * @brief Invite reminder - */ - mt_guild_invite_reminder = 22, - - /** - * @brief Context Menu Command - */ - mt_context_menu_command = 23, - - /** - * @brief Auto moderation action - */ - mt_auto_moderation_action = 24, - - /** - * @brief Role subscription purchase - */ - mt_role_subscription_purchase = 25, - - /** - * @brief Interaction premium upsell - * @depreciated Replaced with buttons with a style of cos_premium - * This message type may stop working at any point - */ - mt_interaction_premium_upsell = 26, - - /** - * @brief Stage start - */ - mt_stage_start = 27, - - /** - * @brief Stage end - */ - mt_stage_end = 28, - - /** - * @brief Stage speaker - */ - mt_stage_speaker = 29, - - /** - * @brief Stage topic - */ - mt_stage_topic = 31, - - /** - * @brief Guild application premium subscription - */ - mt_application_premium_subscription = 32, -}; - -/** - * @brief Represents the caching policy of a cache in the library. - */ -enum cache_policy_setting_t { - /** - * @brief request aggressively on seeing new guilds, and also store missing data from messages. - * This is the default behaviour and the least memory-efficient option. Memory usage will increase - * over time, initially quite rapidly, and then linearly over time. It is the least cpu-intensive - * setting. - */ - cp_aggressive = 0, - - /** - * @brief only cache when there is relevant activity, e.g. a message to the bot. - * This is a good middle-ground, memory usage will increase linearly over time. - */ - cp_lazy = 1, - - /** - * @brief Don't cache anything. Fill details when we see them. - * This is the most memory-efficient option but consumes more CPU time - */ - cp_none = 2 -}; - -/** - * @brief Represents the caching policy of the cluster. - * - * Channels and guilds are always cached as these caches are used - * internally by the library. The memory usage of these is minimal. - * - * All default to 'aggressive' which means to actively attempt to cache, - * going out of the way to fill the caches completely. On large bots this - * can take a LOT of RAM. - */ -struct DPP_EXPORT cache_policy_t { - /** - * @brief Caching policy for users and guild members - */ - cache_policy_setting_t user_policy = cp_aggressive; - - /** - * @brief Caching policy for emojis - */ - cache_policy_setting_t emoji_policy = cp_aggressive; - - /** - * @brief Caching policy for roles - */ - cache_policy_setting_t role_policy = cp_aggressive; - - /** - * @brief Caching policy for roles - */ - cache_policy_setting_t channel_policy = cp_aggressive; - - /** - * @brief Caching policy for roles - */ - cache_policy_setting_t guild_policy = cp_aggressive; -}; - -/** - * @brief Contains a set of predefined cache policies for use when constructing a dpp::cluster - */ -namespace cache_policy { - - /** - * @brief A shortcut constant for all caching enabled for use in dpp::cluster constructor - */ - inline constexpr cache_policy_t cpol_default = { cp_aggressive, cp_aggressive, cp_aggressive, cp_aggressive, cp_aggressive }; - - /** - * @brief A shortcut constant for a more balanced caching policy for use in dpp::cluster constructor - */ - inline constexpr cache_policy_t cpol_balanced = { cp_lazy, cp_lazy, cp_lazy, cp_aggressive, cp_aggressive }; - - /** - * @brief A shortcut constant for all caching disabled for use in dpp::cluster constructor - */ - inline constexpr cache_policy_t cpol_none = { cp_none, cp_none, cp_none, cp_none, cp_none }; - -}; - -/** - * @brief Metadata about the interaction, including the source of the interaction and relevant server and user IDs. - */ -struct DPP_EXPORT interaction_metadata_type { - - /** - * @brief ID of the interaction - */ - snowflake id; - - /** - * @brief User who triggered the interaction - */ - uint8_t type; - - /** - * @brief User who triggered the interaction - */ - user usr; - - /** - * @brief ID of the original response message, present only on follow-up messages - */ - snowflake original_response_message_id; - - /** - * @brief ID of the message that contained interactive component, present only on messages created from component interactions - */ - snowflake interacted_message_id; - - // FIXME: Add this field sometime - /** - * @brief Metadata for the interaction that was used to open the modal, present only on modal submit interactions - */ - // interaction_metadata_type triggering_interaction_metadata; -}; - -/** - * @brief Message Reference type - */ -enum DPP_EXPORT message_ref_type : uint8_t { - /** - * A reply or crosspost - */ - mrt_default = 0, - /** - * A forwarded message - */ - mrt_forward = 1, -}; - -template struct message_snapshot { - std::vector messages; -}; - - /** - * @brief Represents messages sent and received on Discord - */ -struct DPP_EXPORT message : public managed, json_interface { -protected: - friend struct json_interface; - - /** Read class values from json object - * @param j A json object to read from - * @return A reference to self - */ - inline message& fill_from_json_impl(nlohmann::json *j) { - return fill_from_json(j, {cp_aggressive, cp_aggressive, cp_aggressive}); - } - - /** Build a JSON from this object. - * @param with_id True if an ID is to be included in the JSON - * @return JSON - */ - inline json to_json_impl(bool with_id = false) const { - return to_json(with_id, false); - } -public: - /** - * @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; - - /** - * @brief Pre-generated components as JSON. This overrides the components - * array if it is set. - */ - json components_json; - - /** - * @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; - - /** - * @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; - - /** - * @brief Any attached files. - */ - std::vector attachments; - - /** - * @brief Up to 10 dpp::embed objects. - */ - std::vector embeds; - - /** - * @brief Optional: reactions to the message. - */ - std::vector reactions; - - /** - * @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; - - /** - * @brief Partial stickers. Only id, name and format_type are filled - */ - std::vector stickers; - - /** - * @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 { - /** - * @brief Message reference type, set to 1 to forward a message - */ - message_ref_type type{mrt_default}; - /** - * @brief ID of the originating message. - */ - snowflake message_id; - - /** - * @brief ID of the originating message's channel. - */ - snowflake channel_id; - - /** - * @brief ID of the originating message's guild. - */ - snowflake guild_id; - - /** - * @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; - - /** - * @brief Message snapshots for a forwarded message - */ - message_snapshot message_snapshots; - - /** - * @brief Reference to an interaction - */ - struct message_interaction_struct { - /** - * @brief ID of the interaction. - */ - snowflake id; - - /** - * @brief Type of interaction. - */ - uint8_t type; - - /** - * @brief Name of the application command. - */ - std::string name; - - /** - * @brief The user who invoked the interaction. - */ - user usr; - } interaction; - - /** - * @brief Sent if the message is sent as a result of an interaction - */ - interaction_metadata_type interaction_metadata; - - /** - * @brief Allowed mentions details - */ - struct allowed_ref { - /** - * @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 - */ - std::vector roles; - } allowed_mentions; - - /** - * @brief The cluster which created this message object. - */ - class cluster* owner; - - /** - * @brief Message type. - */ - message_type type; - - /** - * @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; - - /** - * @brief Whether this message mentions everyone. - */ - bool mention_everyone; - - /** - * @brief Optional poll attached to this message - */ - std::optional attached_poll; - - /** - * @brief Construct a new message object - */ - message(); - - /* - * @brief Construct a new message object - * @param m Message to copy - */ - message(const message& m) = default; - - /* - * @brief Construct a new message object - * @param m Message to move - */ - message(message&& m) = default; - - /** - * @brief Construct a new message object - * @param o Owning cluster, passed down to various things such as dpp::attachment. - * Owning cluster is optional (can be nullptr) and if nulled, will prevent some functions - * such as attachment::download from functioning (they will throw, if used) - */ - message(class cluster* o); - - /** - * @brief Construct a new message object with a channel and content - * - * @param channel_id The channel to send the message to - * @param content The content of the message. It will be truncated to the maximum length of 4000 UTF-8 characters. - * @param type The message type to create - */ - message(snowflake channel_id, std::string_view content, message_type type = mt_default); - - /** - * @brief Construct a new message object with content - * - * @param _embed An embed to send - */ - message(const embed& _embed); - - /** - * @brief Construct a new message object with a channel and content - * - * @param channel_id The channel to send the message to - * @param _embed An embed to send - */ - message(snowflake channel_id, const embed& _embed); - - /** - * @brief Construct a new message object with content - * - * @param content The content of the message. It will be truncated to the maximum length of 4000 UTF-8 characters. - * @param type The message type to create - */ - message(std::string_view content, message_type type = mt_default); - - /** - * @brief Destroy the message object - */ - ~message() override = default; - - /** - * @brief Copy a message object - * - * @param m Message to copy - * @return message& Reference to self - */ - message &operator=(const message& m) = default; - - /** - * @brief Move a message object - * - * @param m Message to move - * @return message& Reference to self - */ - message &operator=(message&& m) = default; - - /** - * @brief Set the original message reference for replies/crossposts - * - * @param _message_id message id to reply to - * @param _guild_id guild id to reply to (optional) - * @param _channel_id channel id to reply to (optional) - * @param fail_if_not_exists true if the message send should fail if these values are invalid (optional) - * @param type Type of reference - * @return message& reference to self - */ - message& set_reference(snowflake _message_id, snowflake _guild_id = 0, snowflake _channel_id = 0, bool fail_if_not_exists = false, message_ref_type type = mrt_default); - - /** - * @brief Set the allowed mentions object for pings on the message - * - * @param _parse_users whether or not to parse users in the message content or embeds, default false - * @param _parse_roles whether or not to parse roles in the message content or embeds, default false - * @param _parse_everyone whether or not to parse everyone/here in the message content or embeds, default false - * @param _replied_user if set to true and this is a reply, then ping the user we reply to, default false - * @param users list of user ids to allow pings for, default an empty vector - * @param roles list of role ids to allow pings for, default an empty vector - * @return message& reference to self - */ - message& set_allowed_mentions(bool _parse_users = false, bool _parse_roles = false, bool _parse_everyone = false, bool _replied_user = false, const std::vector &users = {}, const std::vector &roles = {}); - - using json_interface::fill_from_json; - using json_interface::to_json; - - /** Fill this object from json. - * @param j JSON object to fill from - * @param cp Cache policy for user records, whether or not we cache users when a message is received - * @return A reference to self - */ - message& fill_from_json(nlohmann::json* j, cache_policy_t cp); - - /** Build JSON from this object. - * @param with_id True if the ID is to be included in the built JSON - * @param is_interaction_response Set to true if this message is intended to be included in an interaction response. - * This will exclude some fields that are not valid in interactions at this time. - * @return The JSON text of the message - */ - virtual json to_json(bool with_id, bool is_interaction_response) const; - - /** - * @brief Returns true if the message was crossposted to other servers - * - * @return true if crossposted - */ - bool is_crossposted() const; - - /** - * @brief Returns true if posted from other servers announcement channel via webhook - * - * @return true if posted from other server - */ - bool is_crosspost() const; - - /** - * @brief True if embeds have been removed - * - * @return true if embeds removed - */ - bool suppress_embeds() const; - - /** - * @brief Set whether embeds should be suppressed - * - * @param suppress whether embeds should be suppressed - * @return message& reference to self - */ - message& suppress_embeds(bool suppress); - - /** - * @brief True if source message was deleted - * - * @return true if source message deleted - */ - bool is_source_message_deleted() const; - - /** - * @brief True if urgent - * - * @return true if urgent - */ - bool is_urgent() const; - - /** - * @brief True if has thread attached - * - * @return true if has thread attached - */ - bool has_thread() const; - - /** - * @brief True if ephemeral (visible only to issuer of a slash command) - * - * @return true if ephemeral - */ - bool is_ephemeral() const; - - /** - * @brief True if loading - * - * @return true if loading - */ - bool is_loading() const; - - /** - * @brief Returns true if this message failed to mention some roles and add their members to the thread - * - * @return true if this message failed to mention some roles and add their members to the thread - */ - bool is_thread_mention_failed() const; - - /** - * @brief True if the message will not trigger push and desktop notifications - * - * @return True if notifications suppressed - */ - bool suppress_notifications() const; - - /** - * @brief True if the message is a voice message - * - * @return True if voice message - */ - bool is_voice_message() const; - - /** - * @brief True if the message has a snapshot - * - * @return True if voice message - */ - bool has_snapshot() const; - - /** - * @brief True if the message is using components v2 - * - * @return True if voice message - */ - bool is_using_components_v2() const; - - /** - * @brief Add a component to a message - * - * @note If the component type you add is only available in - * components v2, this method will automatically add the - * m_using_components_v2 flag to your message. - * - * @param c component to add - * @return message& reference to self - */ - message& add_component(const component& c); - - /** - * @brief Add pre-generated components to a message - * - * @note This is intended to accept pre-generated component - * json from external tools such as https://discord.builders - * - * @param json components json to add. The JSON will be validated - * @return message& reference to self - */ - message& add_json_components(const std::string& json); - - /** - * @brief Add a component to a message - * - * @note If the component type you add is only available in - * components v2, this method will automatically add the - * m_using_components_v2 flag to your message. - * - * This is an alias of add_component() for readability when - * using components v2, so you can use add_component_v2() - * everywhere. It does exactly the same as add_component(). - * - * @param c component to add - * @return message& reference to self - */ - message& add_component_v2(const component& c); - - /** - * @brief Add an embed to message - * - * @param e embed to add - * @return message& reference to self - */ - message& add_embed(const embed& e); - - /** - * @brief Add a sticker to this message - * - * As of writing this, a message can only contain up to 3 stickers - * @param s sticker to add - * @return message& reference to self - */ - message& add_sticker(const sticker& s); - - /** - * @brief Add a sticker to this message - * - * As of writing this, a message can only contain up to 3 stickers - * @param id id of the sticker to add - * @return message& reference to self - */ - message& add_sticker(const snowflake& id); - - /** - * @brief Set the flags - * - * @param f flags to set from dpp::message_flags - * @return message& reference to self - */ - message& set_flags(uint16_t f); - - /** - * @brief Set the message type - * - * @param t type to set - * @return message& reference to self - */ - message& set_type(message_type t); - - /** - * @brief Set the filename of the last file in list - * - * @param fn filename - * @return message& reference to self - * @deprecated Use message::add_file instead - */ - message& set_filename(std::string_view fn); - - /** - * @brief Set the file content of the last file in list - * - * @param fc raw file content - * @return message& reference to self - * @deprecated Use message::add_file instead - */ - message& set_file_content(std::string_view fc); - - /** - * @brief Add a file to the message - * - * @param filename filename - * @param filecontent raw file content - * @param filemimetype optional mime type of the file - * @return message& reference to self - */ - message& add_file(std::string_view filename, std::string_view filecontent, std::string_view filemimetype = ""); - - /** - * @brief Set the message content - * - * @param c message content. It will be truncated to the maximum length of 4000 UTF-8 characters. - * @return message& reference to self - */ - message& set_content(std::string_view c); - - /** - * @brief Set the channel id - * - * @param _channel_id channel id - * @return message& reference to self - */ - message& set_channel_id(snowflake _channel_id); - - /** - * @brief Set the channel id - * - * @param _guild_id channel id - * @return message& reference to self - */ - message& set_guild_id(snowflake _guild_id); - - /** - * @brief Returns true if the message is from a DM - * - * @return true if message is a DM - */ - bool is_dm() const; - - /** - * @brief Returns true if message has remixed attachment - * - * @return true if message has remixed attachment - */ - bool has_remix_attachment() const; - - /** - * @brief Returns URL to message - * - * @return string of URL to message - */ - std::string get_url() const; - - /** - * @brief Convenience method to set the poll - * - * @return message& Self reference for method chaining - */ - message& set_poll(const poll& p); - - /** - * @brief Convenience method to get the poll attached to this message - * - * @throw std::bad_optional_access if has_poll() == false - * @return const poll& Poll attached to this object - */ - [[nodiscard]] const poll& get_poll() const; - - /** - * @brief Method to check if the message has a poll - * - * @return bool Whether the message has a poll - */ - [[nodiscard]] bool has_poll() const noexcept; -}; - -/** - * @brief A group of messages - */ -typedef std::unordered_map message_map; - -/** - * @brief A group of stickers - */ -typedef std::unordered_map sticker_map; - -/** - * @brief A group of sticker packs - */ -typedef std::unordered_map sticker_pack_map; - -} diff --git a/include/dpp/misc-enum.h b/include/dpp/misc-enum.h deleted file mode 100644 index d9ac781..0000000 --- a/include/dpp/misc-enum.h +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************************ - * - * D++, A Lightweight C++ library for Discord - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright 2021 Craig Edwards and D++ contributors - * (https://github.com/brainboxdotcc/DPP/graphs/contributors) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ************************************************************************************/ -#pragma once -#include -#include -#include - -namespace dpp { - -/** - * @brief Supported image types for profile pictures and CDN endpoints - */ -enum image_type : uint8_t { - /** - * @brief image/png - */ - i_png, - - /** - * @brief image/jpeg. - */ - i_jpg, - - /** - * @brief image/gif. - */ - i_gif, - - /** - * @brief Webp. - */ - i_webp, -}; - -/** - * @brief Log levels - */ -enum loglevel { - /** - * @brief Trace - */ - ll_trace = 0, - - /** - * @brief Debug - */ - ll_debug, - - /** - * @brief Information - */ - ll_info, - - /** - * @brief Warning - */ - ll_warning, - - /** - * @brief Error - */ - ll_error, - - /** - * @brief Critical - */ - ll_critical -}; - -} diff --git a/include/dpp/nlohmann/json.hpp b/include/dpp/nlohmann/json.hpp deleted file mode 100644 index 6f018a0..0000000 --- a/include/dpp/nlohmann/json.hpp +++ /dev/null @@ -1,24596 +0,0 @@ -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - -/****************************************************************************\ - * Note on documentation: The source files contain links to the online * - * documentation of the public API at https://json.nlohmann.me. This URL * - * contains the most recent documentation and should also be applicable to * - * previous versions; documentation for deprecated functions is not * - * removed, but marked deprecated. See "Generate documentation" section in * - * file docs/README.md. * -\****************************************************************************/ - -#ifndef INCLUDE_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#ifndef JSON_NO_IO - #include // istream, ostream -#endif // JSON_NO_IO -#include // random_access_iterator_tag -#include // unique_ptr -#include // accumulate -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// This file contains all macro definitions affecting or depending on the ABI - -#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK - #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) - #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2 - #warning "Already included a different version of the library!" - #endif - #endif -#endif - -#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum) - -#ifndef JSON_DIAGNOSTICS - #define JSON_DIAGNOSTICS 0 -#endif - -#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 -#endif - -#if JSON_DIAGNOSTICS - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag -#else - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS -#endif - -#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp -#else - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION - #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 -#endif - -// Construct the namespace ABI tags component -#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b -#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ - NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) - -#define NLOHMANN_JSON_ABI_TAGS \ - NLOHMANN_JSON_ABI_TAGS_CONCAT( \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ - NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) - -// Construct the namespace version component -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ - _v ## major ## _ ## minor ## _ ## patch -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) - -#if NLOHMANN_JSON_NAMESPACE_NO_VERSION -#define NLOHMANN_JSON_NAMESPACE_VERSION -#else -#define NLOHMANN_JSON_NAMESPACE_VERSION \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ - NLOHMANN_JSON_VERSION_MINOR, \ - NLOHMANN_JSON_VERSION_PATCH) -#endif - -// Combine namespace components -#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b -#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ - NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) - -#ifndef NLOHMANN_JSON_NAMESPACE -#define NLOHMANN_JSON_NAMESPACE \ - nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN -#define NLOHMANN_JSON_NAMESPACE_BEGIN \ - namespace nlohmann \ - { \ - inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) \ - { -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_END -#define NLOHMANN_JSON_NAMESPACE_END \ - } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ - } // namespace nlohmann -#endif - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // nullptr_t -#include // exception -#include // runtime_error -#include // to_string -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // uint8_t -#include // string - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // declval, pair -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -// https://en.cppreference.com/w/cpp/experimental/is_detected -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -template class Op, class... Args> -using is_detected = typename detector::value_t; - -template class Op, class... Args> -struct is_detected_lazy : is_detected { }; - -template class Op, class... Args> -using detected_t = typename detector::type; - -template class Op, class... Args> -using detected_or = detector; - -template class Op, class... Args> -using detected_or_t = typename detected_or::type; - -template class Op, class... Args> -using is_detected_exact = std::is_same>; - -template class Op, class... Args> -using is_detected_convertible = - std::is_convertible, To>; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - - -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson -// SPDX-License-Identifier: MIT - -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) -#if defined(JSON_HEDLEY_VERSION) - #undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 15 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) - #undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) - #undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) - #undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) - #undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) - #undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) - #undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) - #undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) - #undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) - #undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) - #undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) - #undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) - #undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) - #undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) - #undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(JSON_HEDLEY_MSVC_VERSION) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) - #undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #undef JSON_HEDLEY_INTEL_CL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) - #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) - #undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) - #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) - #undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) - #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) - #undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) - #undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) - #undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) - #undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) - #undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) - #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) - #undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) - #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) - #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) - #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) - #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) - #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) - #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) - #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) - #undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) - #if defined(_RELEASE_PATCHLEVEL) - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) - #else - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) - #undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) - #undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) - #if __VER__ > 1000 - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) - #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) - #undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) - #undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) - #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) - #undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) - #undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) - #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) - #undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) - #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) - #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) - #undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) - #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) - #undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #undef JSON_HEDLEY_MCST_LCC_VERSION -#endif -#if defined(__LCC__) && defined(__LCC_MINOR__) - #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) - #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) - #undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_CRAY_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) && \ - !defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if \ - defined(__has_attribute) && \ - ( \ - (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ - ) -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) - #undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else - #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) - #undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) - #undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) - #undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else - #define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) - #undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) - #undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) - #undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else - #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) - #undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) - #undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) - #undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else - #define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) - #undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) - #undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) - #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else - #define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) - #undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) - #undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) - #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_PUSH - #define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) - #undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) - #undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else - #define JSON_HEDLEY_DEPRECATED(since) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) - #undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else - #define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif defined(_Check_return_) /* SAL */ - #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else - #define JSON_HEDLEY_WARN_UNUSED_RESULT - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) - #undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else - #define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) - #undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NO_RETURN __noreturn -#elif \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) - #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else - #define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) - #undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) - #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else - #define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) - #undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) - #undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) - #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) - #else - #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) - #endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) - #if defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) - #else - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) - #endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) - #if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) - #else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() - #endif -#else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - -JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") - #pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) - #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) - #if defined(__clang__) - #pragma clang diagnostic ignored "-Wvariadic-macros" - #elif defined(JSON_HEDLEY_GCC_VERSION) - #pragma GCC diagnostic ignored "-Wvariadic-macros" - #endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) - #undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else - #define JSON_HEDLEY_NON_NULL(...) -#endif -JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) - #undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) - #undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) - #endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) - #define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) - #undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) - #undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) - #undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) - #undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) - #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) - #undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_MALLOC __declspec(restrict) -#else - #define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) - #undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) - #undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else - #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) - #undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT _Restrict -#else - #define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) - #undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) - #define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) - #define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_INLINE __inline -#else - #define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) - #undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) - #undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else - #define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) - #undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) - #undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) - #undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) - #undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else - #define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) - #undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ - #define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else - #define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) - #undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ - #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else - #define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) - #undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else - #define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) - #undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) - #undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif -/* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) (0) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) - #undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) - #undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) - #undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { - #define JSON_HEDLEY_END_C_DECLS } - #define JSON_HEDLEY_C_DECL extern "C" -#else - #define JSON_HEDLEY_BEGIN_C_DECLS - #define JSON_HEDLEY_END_C_DECLS - #define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) - #undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) - #undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) - #elif defined(NULL) - #define JSON_HEDLEY_NULL NULL - #else - #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) - #endif -#elif defined(NULL) - #define JSON_HEDLEY_NULL NULL -#else - #define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) - #undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) - #undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) - #undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) - #undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) - #undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) - #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#else - #define JSON_HEDLEY_FLAGS -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) - #undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) - #undef JSON_HEDLEY_EMPTY_BASES -#endif -#if \ - (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else - #define JSON_HEDLEY_EMPTY_BASES -#endif - -/* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) - #undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) - #undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) - #undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) - #undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - - -// This file contains all internal macro definitions (except those affecting ABI) -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// #include - - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// C++ language standard detection -// if the user manually specified the used c++ version this is skipped -#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) - #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 - #endif - // the cpp 11 flag is always specified because it is the minimal required version - #define JSON_HAS_CPP_11 -#endif - -#ifdef __has_include - #if __has_include() - #include - #endif -#endif - -#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) - #ifdef JSON_HAS_CPP_17 - #if defined(__cpp_lib_filesystem) - #define JSON_HAS_FILESYSTEM 1 - #elif defined(__cpp_lib_experimental_filesystem) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif !defined(__has_include) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #endif - - // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ - #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__clang_major__) && __clang_major__ < 7 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support - #if defined(_MSC_VER) && _MSC_VER < 1914 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before iOS 13 - #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before macOS Catalina - #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - #endif -#endif - -#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_FILESYSTEM - #define JSON_HAS_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_THREE_WAY_COMPARISON - #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ - && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L - #define JSON_HAS_THREE_WAY_COMPARISON 1 - #else - #define JSON_HAS_THREE_WAY_COMPARISON 0 - #endif -#endif - -#ifndef JSON_HAS_RANGES - // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error - #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 - #define JSON_HAS_RANGES 0 - #elif defined(__cpp_lib_ranges) - #define JSON_HAS_RANGES 1 - #else - #define JSON_HAS_RANGES 0 - #endif -#endif - -#ifdef JSON_HAS_CPP_17 - #define JSON_INLINE_VARIABLE inline -#else - #define JSON_INLINE_VARIABLE -#endif - -#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) - #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] -#else - #define JSON_NO_UNIQUE_ADDRESS -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdocumentation" - #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - -// allow disabling exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #include - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow overriding assert -#if !defined(JSON_ASSERT) - #include // assert - #define JSON_ASSERT(x) assert(x) -#endif - -// allow to access some private functions (needed by the test suite) -#if defined(JSON_TESTS_PRIVATE) - #define JSON_PRIVATE_UNLESS_TESTED public -#else - #define JSON_PRIVATE_UNLESS_TESTED private -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer, \ - class BinaryType> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); -#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - - -// inspired from https://stackoverflow.com/a/26745591 -// allows to call any std function as if (e.g. with begin): -// using std::begin; begin(x); -// -// it allows using the detected idiom to retrieve the return type -// of such an expression -#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ - namespace detail { \ - using std::std_name; \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - } \ - \ - namespace detail2 { \ - struct std_name##_tag \ - { \ - }; \ - \ - template \ - std_name##_tag std_name(T&&...); \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - \ - template \ - struct would_call_std_##std_name \ - { \ - static constexpr auto const value = ::nlohmann::detail:: \ - is_detected_exact::value; \ - }; \ - } /* namespace detail2 */ \ - \ - template \ - struct would_call_std_##std_name : detail2::would_call_std_##std_name \ - { \ - } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_EXPLICIT -#else - #define JSON_EXPLICIT explicit -#endif - -#ifndef JSON_DISABLE_ENUM_SERIALIZATION - #define JSON_DISABLE_ENUM_SERIALIZATION 0 -#endif - -#ifndef JSON_USE_GLOBAL_UDLS - #define JSON_USE_GLOBAL_UDLS 1 -#endif - -#if JSON_HAS_THREE_WAY_COMPARISON - #include // partial_ordering -#endif - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/////////////////////////// -// JSON type enumeration // -/////////////////////////// - -/*! -@brief the JSON type enumeration - -This enumeration collects the different JSON types. It is internally used to -distinguish the stored values, and the functions @ref basic_json::is_null(), -@ref basic_json::is_object(), @ref basic_json::is_array(), -@ref basic_json::is_string(), @ref basic_json::is_boolean(), -@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), -@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), -@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and -@ref basic_json::is_structured() rely on it. - -@note There are three enumeration entries (number_integer, number_unsigned, and -number_float), because the library distinguishes these three types for numbers: -@ref basic_json::number_unsigned_t is used for unsigned integers, -@ref basic_json::number_integer_t is used for signed integers, and -@ref basic_json::number_float_t is used for floating-point numbers or to -approximate integers which do not fit in the limits of their respective type. - -@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON -value with the default value for a given type - -@since version 1.0.0 -*/ -enum class value_t : std::uint8_t -{ - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function -}; - -/*! -@brief comparison operator for JSON types - -Returns an ordering that is similar to Python: -- order: null < boolean < number < object < array < string < binary -- furthermore, each type is not smaller than itself -- discarded values are not comparable -- binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - -@since version 1.0.0 -*/ -#if JSON_HAS_THREE_WAY_COMPARISON - inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* -#else - inline bool operator<(const value_t lhs, const value_t rhs) noexcept -#endif -{ - static constexpr std::array order = {{ - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast(lhs); - const auto r_index = static_cast(rhs); -#if JSON_HAS_THREE_WAY_COMPARISON - if (l_index < order.size() && r_index < order.size()) - { - return order[l_index] <=> order[r_index]; // *NOPAD* - } - return std::partial_ordering::unordered; -#else - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -#endif -} - -// GCC selects the built-in operator< over an operator rewritten from -// a user-defined spaceship operator -// Clang, MSVC, and ICC select the rewritten candidate -// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) -#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) -inline bool operator<(const value_t lhs, const value_t rhs) noexcept -{ - return std::is_lt(lhs <=> rhs); // *NOPAD* -} -#endif - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/*! -@brief replace all occurrences of a substring by another string - -@param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t -@param[in] f the substring to replace with @a t -@param[in] t the string to replace @a f - -@pre The search string @a f must not be empty. **This precondition is -enforced with an assertion.** - -@since version 2.0.0 -*/ -template -inline void replace_substring(StringType& s, const StringType& f, - const StringType& t) -{ - JSON_ASSERT(!f.empty()); - for (auto pos = s.find(f); // find first occurrence of f - pos != StringType::npos; // make sure f was found - s.replace(pos, f.size(), t), // replace with t, and - pos = s.find(f, pos + t.size())) // find next occurrence of f - {} -} - -/*! - * @brief string escaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to escape - * @return escaped string - * - * Note the order of escaping "~" to "~0" and "/" to "~1" is important. - */ -template -inline StringType escape(StringType s) -{ - replace_substring(s, StringType{"~"}, StringType{"~0"}); - replace_substring(s, StringType{"/"}, StringType{"~1"}); - return s; -} - -/*! - * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string - * - * Note the order of escaping "~1" to "/" and "~0" to "~" is important. - */ -template -static void unescape(StringType& s) -{ - replace_substring(s, StringType{"~1"}, StringType{"/"}); - replace_substring(s, StringType{"~0"}, StringType{"~"}); -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // size_t - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-FileCopyrightText: 2018 The Abseil Authors -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include // index_sequence, make_index_sequence, index_sequence_for - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -using uncvref_t = typename std::remove_cv::type>::type; - -#ifdef JSON_HAS_CPP_14 - -// the following utilities are natively available in C++14 -using std::enable_if_t; -using std::index_sequence; -using std::make_index_sequence; -using std::index_sequence_for; - -#else - -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; - -// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h -// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. - -//// START OF CODE FROM GOOGLE ABSEIL - -// integer_sequence -// -// Class template representing a compile-time integer sequence. An instantiation -// of `integer_sequence` has a sequence of integers encoded in its -// type through its template arguments (which is a common need when -// working with C++11 variadic templates). `absl::integer_sequence` is designed -// to be a drop-in replacement for C++14's `std::integer_sequence`. -// -// Example: -// -// template< class T, T... Ints > -// void user_function(integer_sequence); -// -// int main() -// { -// // user_function's `T` will be deduced to `int` and `Ints...` -// // will be deduced to `0, 1, 2, 3, 4`. -// user_function(make_integer_sequence()); -// } -template -struct integer_sequence -{ - using value_type = T; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -// index_sequence -// -// A helper template for an `integer_sequence` of `size_t`, -// `absl::index_sequence` is designed to be a drop-in replacement for C++14's -// `std::index_sequence`. -template -using index_sequence = integer_sequence; - -namespace utility_internal -{ - -template -struct Extend; - -// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. -template -struct Extend, SeqSize, 0> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; -}; - -template -struct Extend, SeqSize, 1> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; -}; - -// Recursion helper for 'make_integer_sequence'. -// 'Gen::type' is an alias for 'integer_sequence'. -template -struct Gen -{ - using type = - typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; -}; - -template -struct Gen -{ - using type = integer_sequence; -}; - -} // namespace utility_internal - -// Compile-time sequences of integers - -// make_integer_sequence -// -// This template alias is equivalent to -// `integer_sequence`, and is designed to be a drop-in -// replacement for C++14's `std::make_integer_sequence`. -template -using make_integer_sequence = typename utility_internal::Gen::type; - -// make_index_sequence -// -// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, -// and is designed to be a drop-in replacement for C++14's -// `std::make_index_sequence`. -template -using make_index_sequence = make_integer_sequence; - -// index_sequence_for -// -// Converts a typename pack into an index sequence of the same length, and -// is designed to be a drop-in replacement for C++14's -// `std::index_sequence_for()` -template -using index_sequence_for = make_index_sequence; - -//// END OF CODE FROM GOOGLE ABSEIL - -#endif - -// dispatch utility (taken from ranges-v3) -template struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template -struct static_const -{ - static JSON_INLINE_VARIABLE constexpr T value{}; -}; - -#ifndef JSON_HAS_CPP_17 - template - constexpr T static_const::value; -#endif - -template -inline constexpr std::array make_array(Args&& ... args) -{ - return std::array {{static_cast(std::forward(args))...}}; -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // numeric_limits -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval -#include // tuple - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // random_access_iterator_tag - -// #include - -// #include - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -struct iterator_types {}; - -template -struct iterator_types < - It, - void_t> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template -struct iterator_traits -{ -}; - -template -struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types -{ -}; - -template -struct iterator_traits::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); - -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); - -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ - #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - #include // int64_t, uint64_t - #include // map - #include // allocator - #include // string - #include // vector - - // #include - - - /*! - @brief namespace for Niels Lohmann - @see https://github.com/nlohmann - @since version 1.0.0 - */ - NLOHMANN_JSON_NAMESPACE_BEGIN - - /*! - @brief default JSONSerializer template argument - - This serializer ignores the template arguments and uses ADL - ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) - for serialization. - */ - template - struct adl_serializer; - - /// a class to store JSON values - /// @sa https://json.nlohmann.me/api/basic_json/ - template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector> - class basic_json; - - /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document - /// @sa https://json.nlohmann.me/api/json_pointer/ - template - class json_pointer; - - /*! - @brief default specialization - @sa https://json.nlohmann.me/api/json/ - */ - using json = basic_json<>; - - /// @brief a minimal map-like container that preserves insertion order - /// @sa https://json.nlohmann.me/api/ordered_map/ - template - struct ordered_map; - - /// @brief specialization that maintains the insertion order of object keys - /// @sa https://json.nlohmann.me/api/ordered_json/ - using ordered_json = basic_json; - - NLOHMANN_JSON_NAMESPACE_END - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -NLOHMANN_JSON_NAMESPACE_BEGIN -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ - -///////////// -// helpers // -///////////// - -// Note to maintainers: -// -// Every trait in this file expects a non CV-qualified type. -// The only exceptions are in the 'aliases for detected' section -// (i.e. those of the form: decltype(T::member_function(std::declval()))) -// -// In this case, T has to be properly CV-qualified to constraint the function arguments -// (e.g. to_json(BasicJsonType&, const T&)) - -template struct is_basic_json : std::false_type {}; - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct is_basic_json : std::true_type {}; - -// used by exceptions create() member functions -// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t -// false_type otherwise -template -struct is_basic_json_context : - std::integral_constant < bool, - is_basic_json::type>::type>::value - || std::is_same::value > -{}; - -////////////////////// -// json_ref helpers // -////////////////////// - -template -class json_ref; - -template -struct is_json_ref : std::false_type {}; - -template -struct is_json_ref> : std::true_type {}; - -////////////////////////// -// aliases for detected // -////////////////////////// - -template -using mapped_type_t = typename T::mapped_type; - -template -using key_type_t = typename T::key_type; - -template -using value_type_t = typename T::value_type; - -template -using difference_type_t = typename T::difference_type; - -template -using pointer_t = typename T::pointer; - -template -using reference_t = typename T::reference; - -template -using iterator_category_t = typename T::iterator_category; - -template -using to_json_function = decltype(T::to_json(std::declval()...)); - -template -using from_json_function = decltype(T::from_json(std::declval()...)); - -template -using get_template_function = decltype(std::declval().template get()); - -// trait checking if JSONSerializer::from_json(json const&, udt&) exists -template -struct has_from_json : std::false_type {}; - -// trait checking if j.get is valid -// use this trait instead of std::is_constructible or std::is_convertible, -// both rely on, or make use of implicit conversions, and thus fail when T -// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) -template -struct is_getable -{ - static constexpr bool value = is_detected::value; -}; - -template -struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if JSONSerializer::from_json(json const&) exists -// this overload is used for non-default-constructible user-defined-types -template -struct has_non_default_from_json : std::false_type {}; - -template -struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if BasicJsonType::json_serializer::to_json exists -// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. -template -struct has_to_json : std::false_type {}; - -template -struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -template -using detect_key_compare = typename T::key_compare; - -template -struct has_key_compare : std::integral_constant::value> {}; - -// obtains the actual object key comparator -template -struct actual_object_comparator -{ - using object_t = typename BasicJsonType::object_t; - using object_comparator_t = typename BasicJsonType::default_object_comparator_t; - using type = typename std::conditional < has_key_compare::value, - typename object_t::key_compare, object_comparator_t>::type; -}; - -template -using actual_object_comparator_t = typename actual_object_comparator::type; - -/////////////////// -// is_ functions // -/////////////////// - -// https://en.cppreference.com/w/cpp/types/conjunction -template struct conjunction : std::true_type { }; -template struct conjunction : B { }; -template -struct conjunction -: std::conditional(B::value), conjunction, B>::type {}; - -// https://en.cppreference.com/w/cpp/types/negation -template struct negation : std::integral_constant < bool, !B::value > { }; - -// Reimplementation of is_constructible and is_default_constructible, due to them being broken for -// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). -// This causes compile errors in e.g. clang 3.5 or gcc 4.9. -template -struct is_default_constructible : std::is_default_constructible {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - - -template -struct is_constructible : std::is_constructible {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - - -template -struct is_iterator_traits : std::false_type {}; - -template -struct is_iterator_traits> -{ - private: - using traits = iterator_traits; - - public: - static constexpr auto value = - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value; -}; - -template -struct is_range -{ - private: - using t_ref = typename std::add_lvalue_reference::type; - - using iterator = detected_t; - using sentinel = detected_t; - - // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator - // and https://en.cppreference.com/w/cpp/iterator/sentinel_for - // but reimplementing these would be too much work, as a lot of other concepts are used underneath - static constexpr auto is_iterator_begin = - is_iterator_traits>::value; - - public: - static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; -}; - -template -using iterator_t = enable_if_t::value, result_of_begin())>>; - -template -using range_value_t = value_type_t>>; - -// The following implementation of is_complete_type is taken from -// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ -// and is written by Xiang Fan who agreed to using it in this library. - -template -struct is_complete_type : std::false_type {}; - -template -struct is_complete_type : std::true_type {}; - -template -struct is_compatible_object_type_impl : std::false_type {}; - -template -struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - is_constructible::value && - is_constructible::value; -}; - -template -struct is_compatible_object_type - : is_compatible_object_type_impl {}; - -template -struct is_constructible_object_type_impl : std::false_type {}; - -template -struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - (is_constructible::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); -}; - -template -struct is_constructible_object_type - : is_constructible_object_type_impl {}; - -template -struct is_compatible_string_type -{ - static constexpr auto value = - is_constructible::value; -}; - -template -struct is_constructible_string_type -{ - // launder type through decltype() to fix compilation failure on ICPC -#ifdef __INTEL_COMPILER - using laundered_type = decltype(std::declval()); -#else - using laundered_type = ConstructibleStringType; -#endif - - static constexpr auto value = - conjunction < - is_constructible, - is_detected_exact>::value; -}; - -template -struct is_compatible_array_type_impl : std::false_type {}; - -template -struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < - is_detected::value&& - is_iterator_traits>>::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 - !std::is_same>::value >> -{ - static constexpr bool value = - is_constructible>::value; -}; - -template -struct is_compatible_array_type - : is_compatible_array_type_impl {}; - -template -struct is_constructible_array_type_impl : std::false_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t::value >> - : std::true_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same::value&& - !is_compatible_string_type::value&& - is_default_constructible::value&& -(std::is_move_assignable::value || - std::is_copy_assignable::value)&& -is_detected::value&& -is_iterator_traits>>::value&& -is_detected::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 -!std::is_same>::value&& - is_complete_type < - detected_t>::value >> -{ - using value_type = range_value_t; - - static constexpr bool value = - std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, - value_type >::value; -}; - -template -struct is_constructible_array_type - : is_constructible_array_type_impl {}; - -template -struct is_compatible_integer_type_impl : std::false_type {}; - -template -struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral::value&& - std::is_integral::value&& - !std::is_same::value >> -{ - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits; - using CompatibleLimits = std::numeric_limits; - - static constexpr auto value = - is_constructible::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; -}; - -template -struct is_compatible_integer_type - : is_compatible_integer_type_impl {}; - -template -struct is_compatible_type_impl: std::false_type {}; - -template -struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t::value >> -{ - static constexpr bool value = - has_to_json::value; -}; - -template -struct is_compatible_type - : is_compatible_type_impl {}; - -template -struct is_constructible_tuple : std::false_type {}; - -template -struct is_constructible_tuple> : conjunction...> {}; - -template -struct is_json_iterator_of : std::false_type {}; - -template -struct is_json_iterator_of : std::true_type {}; - -template -struct is_json_iterator_of : std::true_type -{}; - -// checks if a given type T is a template specialization of Primary -template