diff --git a/README.md b/README.md index c3946ac502..d049b15ecd 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ The library runs ideally on **Linux**. ### Mac OS X and FreeBSD The library is well-functional and stable on **Mac OS X** and **FreeBSD** too. + +### Raspberry Pi For running your bot on a **Raspberry Pi**, we offer a prebuilt .deb package for ARM64, ARM6, and ARM7 so that you do not have to wait for it to compile. ### Windows diff --git a/docpages/INDEX.md b/docpages/INDEX.md index 1629fcbf5f..549233556e 100644 --- a/docpages/INDEX.md +++ b/docpages/INDEX.md @@ -27,7 +27,7 @@ The following downloads are for the most recent version: * [ARM7 Linux .deb (32 bit Raspberry Pi 3, 4)](https://dl.dpp.dev/latest/linux-rpi-arm7hf) * [ARM64 Linux .deb (64 bit Raspberry Pi 4, Smartphones)](https://dl.dpp.dev/latest/linux-rpi-arm64) -You can find further releases in other architectures and formats or the source code on the [GitHub Repository](https://github.com/brainboxdotcc/DPP/releases). For a realtime JSON format list of download all download links, click [here](https://dl.dpp.dev/json) +You can find further releases in other architectures and formats or the source code on the [GitHub Repository](https://github.com/brainboxdotcc/DPP/releases). For a realtime JSON format list of all download links, click [here](https://dl.dpp.dev/json) ## Library features @@ -45,10 +45,20 @@ You can find further releases in other architectures and formats or the source c ## Supported Operating Systems -The library runs great on **Linux**. **Windows** is also supported and we offer ready made compiled DLL and LIB files for easy integration into any windows visual studio 2019/2022 project. -**Mac OS X** and **FreeBSD** is also functional and stable, as is running your bot on a **Raspberry Pi** — we offer a prebuilt .deb for ARM64, ARMv6 and ARMv7 to save on having to wait for it to compile. +### Linux +The library runs ideally on **Linux**. -The library may work fine in other operating systems too, if you run a D++ bot on something not listed here please let us know! +### Mac OS X and FreeBSD +The library is well-functional and stable on **Mac OS X** and **FreeBSD** too. + +### Raspberry Pi +For running your bot on a **Raspberry Pi**, we offer a prebuilt .deb package for ARM64, ARM6, and ARM7 so that you do not have to wait for it to compile. + +### Windows +**Windows** is well-supported with ready-made compiled DLL and LIB files, please check out our [Windows Bot Template repository](https://github.com/brainboxdotcc/windows-bot-template). The Windows Bot repository can be cloned and integrated immediately into any Visual Studio 2019 and 2022 project in a matter of minutes. + +### Other OS +The library should work fine on other operating systems as well, and if you run a D++ bot on something not listed here, please let us know! ## Getting started * [GitHub Repository](https://github.com/brainboxdotcc/DPP) diff --git a/include/dpp/appcommand.h b/include/dpp/appcommand.h index e089801791..0446498ab3 100644 --- a/include/dpp/appcommand.h +++ b/include/dpp/appcommand.h @@ -73,10 +73,13 @@ enum command_option_type : uint8_t { /** * @brief This type is a variant that can hold any of the potential - * native data types represented by the enum above. + * 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; @@ -282,14 +285,12 @@ void to_json(nlohmann::json& j, const command_option& opt); /** * @brief Response types when responding to an interaction within on_interaction_create. - * Do not use ir_acknowledge or ir::channel_message, as these are deprecated in the - * Discord API spec. They are listed in this enum for completeness. */ enum interaction_response_type { - ir_pong = 1, //!< ACK a Ping + ir_pong = 1, //!< Acknowledge a Ping ir_channel_message_with_source = 4, //!< respond to an interaction with a message - ir_deferred_channel_message_with_source = 5, //!< ACK an interaction and edit a response later, the user sees a loading state - ir_deferred_update_message = 6, //!< for components, ACK an interaction and edit the original message later; the user does not see a loading state + ir_deferred_channel_message_with_source = 5, //!< Acknowledge an interaction and edit a response later, the user sees a loading state + ir_deferred_update_message = 6, //!< for components, acknowledge an interaction and edit the original message later; the user does not see a loading state ir_update_message = 7, //!< for components, edit the message the component was attached to ir_autocomplete_reply = 8, //!< Reply to autocomplete interaction. Be sure to do this within 500ms of the interaction! ir_modal_dialog = 9, //!< A modal dialog box diff --git a/include/dpp/auditlog.h b/include/dpp/auditlog.h index de85e684c6..5022c7f925 100644 --- a/include/dpp/auditlog.h +++ b/include/dpp/auditlog.h @@ -136,6 +136,10 @@ enum audit_type { aut_automod_rule_delete = 142, /// Auto moderation block message aut_automod_block_message = 143, + /// Message was flagged by AutoMod + aut_automod_flag_to_channel = 144, + /// Member was timed out by AutoMod + aut_automod_user_communication_disabled = 145, }; /** @@ -148,7 +152,7 @@ struct DPP_EXPORT audit_change { std::string old_value; /** * The property name that was changed, e.g. `nick` for nickname changes - * @note For dpp::audit_type::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 + * @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; }; @@ -157,6 +161,8 @@ struct DPP_EXPORT audit_change { * @brief Extra information for an audit log entry */ struct DPP_EXPORT audit_extra { + std::string automod_rule_name; //!< Name of the Auto Moderation rule that was triggered + std::string automod_rule_trigger_type; //!< Trigger type of the Auto Moderation rule that was triggered std::string delete_member_days; //!< number of days after which inactive members were kicked std::string members_removed; //!< number of members removed by the prune snowflake channel_id; //!< channel in which the entities were targeted diff --git a/include/dpp/automod.h b/include/dpp/automod.h index bcb0ded2d4..aade98259f 100644 --- a/include/dpp/automod.h +++ b/include/dpp/automod.h @@ -160,7 +160,7 @@ struct DPP_EXPORT automod_metadata : public json_interface { std::vector allow_list; /** - * @brief Total number of mentions (role & user) allowed per message (Maximum of 50) + * @brief Total number of unique role and user mentions allowed per message (Maximum of 50) */ uint8_t mention_total_limit; diff --git a/include/dpp/channel.h b/include/dpp/channel.h index 4625d327f6..8ab5b13e0c 100644 --- a/include/dpp/channel.h +++ b/include/dpp/channel.h @@ -54,7 +54,7 @@ enum channel_type : uint8_t { CHANNEL_PRIVATE_THREAD = 12, //!< a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission CHANNEL_STAGE = 13, //!< a "stage" channel, like a voice channel with one authorised speaker CHANNEL_DIRECTORY = 14, //!< the channel in a [hub](https://support.discord.com/hc/en-us/articles/4406046651927-Discord-Student-Hubs-FAQ) containing the listed servers - CHANNEL_FORUM = 15 //!< forum channel, coming soon(tm) + CHANNEL_FORUM = 15 //!< forum channel that can only contain threads }; /** @brief Our flags as stored in the object @@ -560,7 +560,10 @@ class DPP_EXPORT thread : public channel { /** Thread metadata (threads) */ thread_metadata metadata; - /** Number of messages (not including the initial message or deleted messages) of the thread. If the thread was created before July 1, 2022, it stops counting at 50 */ + /** + * @brief Number of messages (not including the initial message or deleted messages) of the thread. + * For threads created before July 1, 2022, the message count is inaccurate when it's greater than 50. + */ uint8_t message_count; /** Approximate count of members in a thread (threads) */ diff --git a/include/dpp/cluster.h b/include/dpp/cluster.h index 7d44380bee..4fb25db766 100644 --- a/include/dpp/cluster.h +++ b/include/dpp/cluster.h @@ -1514,7 +1514,7 @@ class DPP_EXPORT cluster { * 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 list of 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(). + * 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()); @@ -1527,7 +1527,7 @@ class DPP_EXPORT cluster { * overwriting existing commands that are registered globally for this application. Updates will be available in all guilds after 1 hour. * 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 list of 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(). + * 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()); diff --git a/include/dpp/guild.h b/include/dpp/guild.h index 1cbda56fc9..fcea97e20f 100644 --- a/include/dpp/guild.h +++ b/include/dpp/guild.h @@ -138,6 +138,8 @@ enum guild_flags_extra : uint8_t { g_animated_banner = 0b00000010, /** Guild has auto moderation */ g_auto_moderation = 0b00000100, + /** Guild has paused invites, preventing new users from joining */ + g_invites_disabled = 0b00001000, }; /** @@ -385,6 +387,48 @@ enum verification_level_t : uint8_t { ver_very_high = 4, }; +/** + * @brief Default message notification level + */ +enum default_message_notification_t: uint8_t { + /// members will receive notifications for all messages by default + dmn_all = 0, + /// members will receive notifications only for messages that \@mention them by default + dmn_only_mentions = 1, +}; + +/** + * @brief Premium tier + */ +enum guild_premium_tier_t: uint8_t { + /// guild has not unlocked any Server Boost perks + tier_none = 0, + /// guild has unlocked Server Boost level 1 perks + tier_1 = 1, + /// guild has unlocked Server Boost level 2 perks + tier_2 = 2, + /// 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 { + /// AFK timeout disabled + afk_off, + /// AFK timeout of 1 Minute + afk_60, + /// AFK timeout of 5 Minutes + afk_300, + /// AFK timeout of 15 Minutes + afk_900, + /// AFK timeout of 30 Minutes + afk_1800, + /// AFK timeout of 1 Hour + afk_3600, +}; + /** @brief Guild members container */ typedef std::unordered_map members_container; @@ -492,17 +536,17 @@ class DPP_EXPORT guild : public managed, public json_interface { /** Number of boosters */ uint16_t premium_subscription_count; - /** Maximum users in a video channel, or 0 */ - uint16_t max_video_channel_users; - /** Voice AFK timeout before moving users to AFK channel */ - uint8_t afk_timeout; + guild_afk_timeout_t afk_timeout; + + /** Maximum users in a video channel, or 0 */ + uint8_t max_video_channel_users; /** Setting for how notifications are to be delivered to users */ - uint8_t default_message_notifications; + default_message_notification_t default_message_notifications; /** Boost level */ - uint8_t premium_tier; + guild_premium_tier_t premium_tier; /** Verification level of server */ verification_level_t verification_level; @@ -850,6 +894,12 @@ class DPP_EXPORT guild : public managed, public json_interface { * @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; }; /** A container of guilds */ diff --git a/include/dpp/integration.h b/include/dpp/integration.h index 2260a916ac..a1de296193 100644 --- a/include/dpp/integration.h +++ b/include/dpp/integration.h @@ -145,6 +145,7 @@ class DPP_EXPORT connection { bool verified; //!< whether the connection is verified bool friend_sync; //!< whether friend sync is enabled for this connection bool show_activity; //!< whether activities related to this connection will be shown in presence updates + bool two_way_link; //!< Whether this connection has a corresponding third party OAuth2 token bool visible; //!< visibility of this connection /** diff --git a/include/dpp/snowflake.h b/include/dpp/snowflake.h index 681fc7123d..2eb0205d1c 100644 --- a/include/dpp/snowflake.h +++ b/include/dpp/snowflake.h @@ -30,7 +30,7 @@ namespace dpp { /** @brief A container for a 64 bit unsigned value representing many things on discord. - * This value is known in distributed computing as a snowflak value. + * This value is known in distributed computing as a snowflake value. * * Snowflakes are: * diff --git a/src/dpp/auditlog.cpp b/src/dpp/auditlog.cpp index 0e747a82a4..4e5915d750 100644 --- a/src/dpp/auditlog.cpp +++ b/src/dpp/auditlog.cpp @@ -51,6 +51,8 @@ auditlog& auditlog::fill_from_json(nlohmann::json* j) { if (ai.contains("options")) { auto &o = ai["options"]; audit_extra opts; + opts.automod_rule_name = string_not_null(&o, "auto_moderation_rule_name"); + opts.automod_rule_trigger_type = string_not_null(&o, "auto_moderation_rule_trigger_type"); opts.channel_id = snowflake_not_null(&o, "channel_id"); opts.count = string_not_null(&o, "count"); opts.delete_member_days = string_not_null(&o, "delete_member_days"); diff --git a/src/dpp/guild.cpp b/src/dpp/guild.cpp index 730a7959f8..fbe5268c4d 100644 --- a/src/dpp/guild.cpp +++ b/src/dpp/guild.cpp @@ -39,7 +39,8 @@ const std::mapflags_extra & g_premium_progress_bar_enabled; } +bool guild::has_invites_disabled() const { + return this->flags_extra & g_invites_disabled; +} + bool guild::has_channel_banners() const { return this->flags & g_channel_banners; } @@ -370,7 +375,17 @@ std::string guild::build_json(bool with_id) const { j["afk_channel_id"] = afk_channel_id; } if (afk_timeout) { - j["afk_timeout"] = afk_timeout; + if (afk_timeout == afk_60) { + j["afk_timeout"] = 60; + } else if (afk_timeout == afk_300) { + j["afk_timeout"] = 300; + } else if (afk_timeout == afk_900) { + j["afk_timeout"] = 900; + } else if (afk_timeout == afk_1800) { + j["afk_timeout"] = 1800; + } else if (afk_timeout == afk_3600) { + j["afk_timeout"] = 3600; + } } if (widget_enabled()) { j["widget_channel_id"] = widget_channel_id; @@ -467,11 +482,23 @@ guild& guild::fill_from_json(discord_client* shard, nlohmann::json* d) { this->flags |= dpp::g_no_sticker_greeting; } + if (d->contains("afk_timeout")) { + if ((*d)["afk_timeout"] == 60) { + this->afk_timeout = afk_60; + } else if ((*d)["afk_timeout"] == 300) { + this->afk_timeout = afk_300; + } else if ((*d)["afk_timeout"] == 900) { + this->afk_timeout = afk_900; + } else if ((*d)["afk_timeout"] == 1800) { + this->afk_timeout = afk_1800; + } else if ((*d)["afk_timeout"] == 3600) { + this->afk_timeout = afk_3600; + } + } set_snowflake_not_null(d, "afk_channel_id", this->afk_channel_id); - set_int8_not_null(d, "afk_timeout", this->afk_timeout); set_snowflake_not_null(d, "widget_channel_id", this->widget_channel_id); this->verification_level = (verification_level_t)int8_not_null(d, "verification_level"); - set_int8_not_null(d, "default_message_notifications", this->default_message_notifications); + this->default_message_notifications = (default_message_notification_t)int8_not_null(d, "default_message_notifications"); this->explicit_content_filter = (guild_explicit_content_t)int8_not_null(d, "explicit_content_filter"); this->mfa_level = (mfa_level_t)int8_not_null(d, "mfa_level"); set_snowflake_not_null(d, "application_id", this->application_id); @@ -498,10 +525,10 @@ guild& guild::fill_from_json(discord_client* shard, nlohmann::json* d) { } this->banner = _banner; } - set_int8_not_null(d, "premium_tier", this->premium_tier); + this->premium_tier = (guild_premium_tier_t)int8_not_null(d, "premium_tier"); set_int16_not_null(d, "premium_subscription_count", this->premium_subscription_count); set_snowflake_not_null(d, "public_updates_channel_id", this->public_updates_channel_id); - set_int16_not_null(d, "max_video_channel_users", this->max_video_channel_users); + set_int8_not_null(d, "max_video_channel_users", this->max_video_channel_users); set_int32_not_null(d, "max_presences", this->max_presences); set_int32_not_null(d, "max_members", this->max_members); diff --git a/src/dpp/integration.cpp b/src/dpp/integration.cpp index 0d7ffba035..efec9b75fa 100644 --- a/src/dpp/integration.cpp +++ b/src/dpp/integration.cpp @@ -127,6 +127,7 @@ connection& connection::fill_from_json(nlohmann::json* j) { this->verified = bool_not_null(j, "verified"); this->friend_sync = bool_not_null(j, "friend_sync"); this->show_activity = bool_not_null(j, "show_activity"); + this->two_way_link = bool_not_null(j, "two_way_link"); this->visible = (int32_not_null(j, "visibility") == 1); if (j->contains("integrations")) { integrations.reserve((*j)["integrations"].size());